1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "tools/gn/test_with_scope.h"
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(FunctionForeach, CollisionOnLoopVar) {
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestWithScope setup;
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestParseInput input(
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "a = 5\n"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "i = 6\n"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "foreach(i, [1, 2, 3]) {\n"  // Use same loop var name previously defined.
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  print(\"$a $i\")\n"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  a = a + 1\n"  // Test for side effects inside loop.
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "}\n"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "print(\"$a $i\")");  // Make sure that i goes back to original value.
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(input.has_error());
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Err err;
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  input.parsed()->Execute(setup.scope(), &err);
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(err.has_error()) << err.message();
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ("5 1\n6 2\n7 3\n8 6\n", setup.print_output());
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(FunctionForeach, UniqueLoopVar) {
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestWithScope setup;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestParseInput input_good(
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "foreach(i, [1, 2, 3]) {\n"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  print(i)\n"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "}\n");
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(input_good.has_error());
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Err err;
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  input_good.parsed()->Execute(setup.scope(), &err);
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(err.has_error()) << err.message();
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ("1\n2\n3\n", setup.print_output());
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  setup.print_output().clear();
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Same thing but try to use the loop var after loop is done. It should be
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // undefined and throw an error.
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestParseInput input_bad(
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "foreach(i, [1, 2, 3]) {\n"
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  print(i)\n"
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "}\n"
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "print(i)");
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_FALSE(input_bad.has_error());  // Should parse OK.
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  input_bad.parsed()->Execute(setup.scope(), &err);
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(err.has_error());  // Shouldn't actually run.
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Checks that the identifier used as the list is marked as "used".
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(FunctionForeach, MarksIdentAsUsed) {
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestWithScope setup;
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestParseInput input_good(
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "a = [1, 2]\n"
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "foreach(i, a) {\n"
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "  print(i)\n"
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "}\n");
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_FALSE(input_good.has_error());
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Err err;
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  input_good.parsed()->Execute(setup.scope(), &err);
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_FALSE(err.has_error()) << err.message();
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ("1\n2\n", setup.print_output());
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  setup.print_output().clear();
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Check for unused vars.
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(setup.scope()->CheckForUnusedVars(&err));
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(err.has_error());
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
76