| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iostream> | 5 #include <iostream> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
| 9 #include "tools/gn/input_file.h" | 9 #include "tools/gn/input_file.h" |
| 10 #include "tools/gn/parser.h" | 10 #include "tools/gn/parser.h" |
| 11 #include "tools/gn/tokenizer.h" | 11 #include "tools/gn/tokenizer.h" |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 bool GetTokens(const InputFile* input, std::vector<Token>* result) { | 15 bool GetTokens(const InputFile* input, std::vector<Token>* result) { |
| 16 result->clear(); | 16 result->clear(); |
| 17 Err err; | 17 Err err; |
| 18 *result = Tokenizer::Tokenize(input, &err); | 18 *result = Tokenizer::Tokenize(input, &err); |
| 19 return !err.has_error(); | 19 return !err.has_error(); |
| 20 } | 20 } |
| 21 | 21 |
| 22 void DoParserPrintTest(const char* input, const char* expected) { | 22 void DoParserPrintTest(const char* input, const char* expected) { |
| 23 std::vector<Token> tokens; | 23 std::vector<Token> tokens; |
| 24 InputFile input_file(SourceFile("/test")); | 24 InputFile input_file(SourceFile("/test")); |
| 25 input_file.SetContents(input); | 25 input_file.SetContents(input); |
| 26 ASSERT_TRUE(GetTokens(&input_file, &tokens)); | 26 ASSERT_TRUE(GetTokens(&input_file, &tokens)); |
| 27 | 27 |
| 28 Err err; | 28 Err err; |
| 29 scoped_ptr<ParseNode> result = Parser::Parse(tokens, &err); | 29 scoped_ptr<ParseNode> result = Parser::Parse(tokens, &err); |
| 30 if (!result) |
| 31 err.PrintToStdout(); |
| 30 ASSERT_TRUE(result); | 32 ASSERT_TRUE(result); |
| 31 | 33 |
| 32 std::ostringstream collector; | 34 std::ostringstream collector; |
| 33 result->Print(collector, 0); | 35 result->Print(collector, 0); |
| 34 | 36 |
| 35 EXPECT_EQ(expected, collector.str()); | 37 EXPECT_EQ(expected, collector.str()); |
| 36 } | 38 } |
| 37 | 39 |
| 38 void DoExpressionPrintTest(const char* input, const char* expected) { | 40 void DoExpressionPrintTest(const char* input, const char* expected) { |
| 39 std::vector<Token> tokens; | 41 std::vector<Token> tokens; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 210 |
| 209 TEST(Parser, Assignment) { | 211 TEST(Parser, Assignment) { |
| 210 DoParserPrintTest("a=2", | 212 DoParserPrintTest("a=2", |
| 211 "BLOCK\n" | 213 "BLOCK\n" |
| 212 " BINARY(=)\n" | 214 " BINARY(=)\n" |
| 213 " IDENTIFIER(a)\n" | 215 " IDENTIFIER(a)\n" |
| 214 " LITERAL(2)\n"); | 216 " LITERAL(2)\n"); |
| 215 } | 217 } |
| 216 | 218 |
| 217 TEST(Parser, Accessor) { | 219 TEST(Parser, Accessor) { |
| 218 DoParserPrintTest("a=b[2]", | 220 // Accessor indexing. |
| 221 DoParserPrintTest("a=b[c+2]", |
| 219 "BLOCK\n" | 222 "BLOCK\n" |
| 220 " BINARY(=)\n" | 223 " BINARY(=)\n" |
| 221 " IDENTIFIER(a)\n" | 224 " IDENTIFIER(a)\n" |
| 222 " ACCESSOR\n" | 225 " ACCESSOR\n" |
| 223 " b\n" // AccessorNode is a bit weird in that it holds | 226 " b\n" // AccessorNode is a bit weird in that it holds |
| 224 // a Token, not a ParseNode for the base. | 227 // a Token, not a ParseNode for the base. |
| 228 " BINARY(+)\n" |
| 229 " IDENTIFIER(c)\n" |
| 230 " LITERAL(2)\n"); |
| 231 DoParserErrorTest("a = b[1][0]", 1, 5); |
| 232 |
| 233 // Member accessors. |
| 234 DoParserPrintTest("a=b.c+2", |
| 235 "BLOCK\n" |
| 236 " BINARY(=)\n" |
| 237 " IDENTIFIER(a)\n" |
| 238 " BINARY(+)\n" |
| 239 " ACCESSOR\n" |
| 240 " b\n" |
| 241 " IDENTIFIER(c)\n" |
| 225 " LITERAL(2)\n"); | 242 " LITERAL(2)\n"); |
| 226 DoParserErrorTest("a = b[1][0]", 1, 5); | 243 DoParserErrorTest("a = b.c.d", 1, 6); // Can't nest accessors (currently). |
| 244 DoParserErrorTest("a.b = 5", 1, 1); // Can't assign to accessors (currently). |
| 227 } | 245 } |
| 228 | 246 |
| 229 TEST(Parser, Condition) { | 247 TEST(Parser, Condition) { |
| 230 DoParserPrintTest("if(1) { a = 2 }", | 248 DoParserPrintTest("if(1) { a = 2 }", |
| 231 "BLOCK\n" | 249 "BLOCK\n" |
| 232 " CONDITION\n" | 250 " CONDITION\n" |
| 233 " LITERAL(1)\n" | 251 " LITERAL(1)\n" |
| 234 " BLOCK\n" | 252 " BLOCK\n" |
| 235 " BINARY(=)\n" | 253 " BINARY(=)\n" |
| 236 " IDENTIFIER(a)\n" | 254 " IDENTIFIER(a)\n" |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 DoParserPrintTest(input, expected); | 490 DoParserPrintTest(input, expected); |
| 473 } | 491 } |
| 474 | 492 |
| 475 TEST(Parser, HangingIf) { | 493 TEST(Parser, HangingIf) { |
| 476 DoParserErrorTest("if", 1, 1); | 494 DoParserErrorTest("if", 1, 1); |
| 477 } | 495 } |
| 478 | 496 |
| 479 TEST(Parser, NegatingList) { | 497 TEST(Parser, NegatingList) { |
| 480 DoParserErrorTest("executable(\"wee\") { sources =- [ \"foo.cc\" ] }", 1, 30); | 498 DoParserErrorTest("executable(\"wee\") { sources =- [ \"foo.cc\" ] }", 1, 30); |
| 481 } | 499 } |
| OLD | NEW |