• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "gn/test_with_scope.h"
6 #include "util/test/test.h"
7 
TEST(FunctionForeach,CollisionOnLoopVar)8 TEST(FunctionForeach, CollisionOnLoopVar) {
9   TestWithScope setup;
10   TestParseInput input(
11       "a = 5\n"
12       "i = 6\n"
13       "foreach(i, [1, 2, 3]) {\n"  // Use same loop var name previously defined.
14       "  print(\"$a $i\")\n"
15       "  a = a + 1\n"  // Test for side effects inside loop.
16       "}\n"
17       "print(\"$a $i\")");  // Make sure that i goes back to original value.
18   ASSERT_FALSE(input.has_error());
19 
20   Err err;
21   input.parsed()->Execute(setup.scope(), &err);
22   ASSERT_FALSE(err.has_error()) << err.message();
23 
24   EXPECT_EQ("5 1\n6 2\n7 3\n8 6\n", setup.print_output());
25 }
26 
TEST(FunctionForeach,UniqueLoopVar)27 TEST(FunctionForeach, UniqueLoopVar) {
28   TestWithScope setup;
29   TestParseInput input_good(
30       "foreach(i, [1, 2, 3]) {\n"
31       "  print(i)\n"
32       "}\n");
33   ASSERT_FALSE(input_good.has_error());
34 
35   Err err;
36   input_good.parsed()->Execute(setup.scope(), &err);
37   ASSERT_FALSE(err.has_error()) << err.message();
38 
39   EXPECT_EQ("1\n2\n3\n", setup.print_output());
40   setup.print_output().clear();
41 
42   // Same thing but try to use the loop var after loop is done. It should be
43   // undefined and throw an error.
44   TestParseInput input_bad(
45       "foreach(i, [1, 2, 3]) {\n"
46       "  print(i)\n"
47       "}\n"
48       "print(i)");
49   ASSERT_FALSE(input_bad.has_error());  // Should parse OK.
50 
51   input_bad.parsed()->Execute(setup.scope(), &err);
52   ASSERT_TRUE(err.has_error());  // Shouldn't actually run.
53 }
54 
55 // Checks that the identifier used as the list is marked as "used".
TEST(FunctionForeach,MarksIdentAsUsed)56 TEST(FunctionForeach, MarksIdentAsUsed) {
57   TestWithScope setup;
58   TestParseInput input_good(
59       "a = [1, 2]\n"
60       "foreach(i, a) {\n"
61       "  print(i)\n"
62       "}\n");
63   ASSERT_FALSE(input_good.has_error());
64 
65   Err err;
66   input_good.parsed()->Execute(setup.scope(), &err);
67   ASSERT_FALSE(err.has_error()) << err.message();
68 
69   EXPECT_EQ("1\n2\n", setup.print_output());
70   setup.print_output().clear();
71 
72   // Check for unused vars.
73   EXPECT_TRUE(setup.scope()->CheckForUnusedVars(&err));
74   EXPECT_FALSE(err.has_error());
75 }
76 
77 // Checks that the list can be modified during iteration without crashing.
TEST(FunctionForeach,ListModification)78 TEST(FunctionForeach, ListModification) {
79   TestWithScope setup;
80   TestParseInput input_grow(
81       "a = [1, 2]\n"
82       "foreach(i, a) {\n"
83       "  print(i)\n"
84       "  if (i <= 8) {\n"
85       "    a += [ i + 2 ]\n"
86       "  }\n"
87       "}\n"
88       "print(a)");
89   ASSERT_FALSE(input_grow.has_error());
90 
91   Err err;
92   input_grow.parsed()->Execute(setup.scope(), &err);
93   ASSERT_FALSE(err.has_error()) << err.message();
94 
95   // The result of the loop should have been unaffected by the mutations of
96   // the list variable inside the loop, but the modifications made to it
97   // should have been persisted.
98   EXPECT_EQ("1\n2\n[1, 2, 3, 4]\n", setup.print_output());
99   setup.print_output().clear();
100 }
101