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 "testing/gtest/include/gtest/gtest.h"
6#include "tools/gn/test_with_scope.h"
7
8TEST(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
27TEST(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".
56TEST(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