Home | History | Annotate | Download | only in gn
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "testing/gtest/include/gtest/gtest.h"
      6 #include "tools/gn/input_file.h"
      7 #include "tools/gn/parse_tree.h"
      8 #include "tools/gn/scope.h"
      9 #include "tools/gn/test_with_scope.h"
     10 
     11 TEST(ParseTree, Accessor) {
     12   TestWithScope setup;
     13 
     14   // Make a pretend parse node with proper tracking that we can blame for the
     15   // given value.
     16   InputFile input_file(SourceFile("//foo"));
     17   Token base_token(Location(&input_file, 1, 1, 1), Token::IDENTIFIER, "a");
     18   Token member_token(Location(&input_file, 1, 1, 1), Token::IDENTIFIER, "b");
     19 
     20   AccessorNode accessor;
     21   accessor.set_base(base_token);
     22 
     23   scoped_ptr<IdentifierNode> member_identifier(
     24       new IdentifierNode(member_token));
     25   accessor.set_member(member_identifier.Pass());
     26 
     27   // The access should fail because a is not defined.
     28   Err err;
     29   Value result = accessor.Execute(setup.scope(), &err);
     30   EXPECT_TRUE(err.has_error());
     31   EXPECT_EQ(Value::NONE, result.type());
     32 
     33   // Define a as a Scope. It should still fail because b isn't defined.
     34   err = Err();
     35   setup.scope()->SetValue("a",
     36       Value(NULL, scoped_ptr<Scope>(new Scope(setup.scope()))), NULL);
     37   result = accessor.Execute(setup.scope(), &err);
     38   EXPECT_TRUE(err.has_error());
     39   EXPECT_EQ(Value::NONE, result.type());
     40 
     41   // Define b, accessor should succeed now.
     42   const int64 kBValue = 42;
     43   err = Err();
     44   setup.scope()->GetMutableValue("a", false)->scope_value()->SetValue(
     45       "b", Value(NULL, kBValue), NULL);
     46   result = accessor.Execute(setup.scope(), &err);
     47   EXPECT_FALSE(err.has_error());
     48   ASSERT_EQ(Value::INTEGER, result.type());
     49   EXPECT_EQ(kBValue, result.int_value());
     50 }
     51 
     52 TEST(ParseTree, BlockUnusedVars) {
     53   TestWithScope setup;
     54 
     55   // Printing both values should be OK.
     56   TestParseInput input_all_used(
     57       "{\n"
     58       "  a = 12\n"
     59       "  b = 13\n"
     60       "  print(\"$a $b\")\n"
     61       "}");
     62   EXPECT_FALSE(input_all_used.has_error());
     63 
     64   Err err;
     65   input_all_used.parsed()->Execute(setup.scope(), &err);
     66   EXPECT_FALSE(err.has_error());
     67 
     68   // Skipping one should throw an unused var error.
     69   TestParseInput input_unused(
     70       "{\n"
     71       "  a = 12\n"
     72       "  b = 13\n"
     73       "  print(\"$a\")\n"
     74       "}");
     75   EXPECT_FALSE(input_unused.has_error());
     76 
     77   input_unused.parsed()->Execute(setup.scope(), &err);
     78   EXPECT_TRUE(err.has_error());
     79 
     80   // Also verify that the unused variable has the correct origin set. The
     81   // origin will point to the value assigned to the variable (in this case, the
     82   // "13" assigned to "b".
     83   EXPECT_EQ(3, err.location().line_number());
     84   EXPECT_EQ(7, err.location().char_offset());
     85 
     86 }
     87 
     88 TEST(ParseTree, OriginForDereference) {
     89   TestWithScope setup;
     90   TestParseInput input(
     91       "a = 6\n"
     92       "get_target_outputs(a)");
     93   EXPECT_FALSE(input.has_error());
     94 
     95   Err err;
     96   input.parsed()->Execute(setup.scope(), &err);
     97   EXPECT_TRUE(err.has_error());
     98 
     99   // The origin for the "not a string" error message should be where the value
    100   // was dereferenced (the "a" on the second line).
    101   EXPECT_EQ(2, err.location().line_number());
    102   EXPECT_EQ(20, err.location().char_offset());
    103 }
    104