• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gn/functions.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "gn/parse_tree.h"
11 #include "gn/test_with_scope.h"
12 #include "gn/value.h"
13 #include "util/test/test.h"
14 
TEST(Functions,Assert)15 TEST(Functions, Assert) {
16   TestWithScope setup;
17 
18   // Verify cases where the assertion passes.
19   std::vector<std::string> assert_pass_examples = {
20       R"gn(assert(true))gn",
21       R"gn(assert(true, "This message is ignored for passed assertions."))gn",
22   };
23   for (const auto& assert_pass_example : assert_pass_examples) {
24     TestParseInput input(assert_pass_example);
25     ASSERT_FALSE(input.has_error());
26     Err err;
27     input.parsed()->Execute(setup.scope(), &err);
28     ASSERT_FALSE(err.has_error()) << assert_pass_example;
29   }
30 
31   // Verify case where the assertion fails, with no message.
32   {
33     TestParseInput input("assert(false)");
34     ASSERT_FALSE(input.has_error());
35     Err err;
36     input.parsed()->Execute(setup.scope(), &err);
37     ASSERT_TRUE(err.has_error());
38     ASSERT_EQ(err.message(), "Assertion failed.");
39   }
40 
41   // Verify case where the assertion fails, with a message.
42   {
43     TestParseInput input("assert(false, \"What failed\")");
44     ASSERT_FALSE(input.has_error());
45     Err err;
46     input.parsed()->Execute(setup.scope(), &err);
47     ASSERT_TRUE(err.has_error());
48     ASSERT_EQ(err.message(), "Assertion failed.");
49     ASSERT_EQ(err.help_text(), "What failed");
50   }
51 
52   // Verify usage errors are detected.
53   std::vector<std::string> bad_usage_examples = {
54       // Number of arguments.
55       R"gn(assert())gn",
56       R"gn(assert(1, 2, 3))gn",
57 
58       // Argument types.
59       R"gn(assert(1))gn",
60       R"gn(assert("oops"))gn",
61       R"gn(assert(true, 1))gn",
62       R"gn(assert(true, []))gn",
63   };
64   for (const auto& bad_usage_example : bad_usage_examples) {
65     TestParseInput input(bad_usage_example);
66     ASSERT_FALSE(input.has_error());
67     Err err;
68     input.parsed()->Execute(setup.scope(), &err);
69     ASSERT_TRUE(err.has_error()) << bad_usage_example;
70     // We are checking for usage errors, not assertion failures.
71     ASSERT_NE(err.message(), "Assertion failed.") << bad_usage_example;
72   }
73 }
74 
TEST(Functions,Defined)75 TEST(Functions, Defined) {
76   TestWithScope setup;
77 
78   FunctionCallNode function_call;
79   Err err;
80 
81   // Test an undefined identifier.
82   Token undefined_token(Location(), Token::IDENTIFIER, "undef");
83   ListNode args_list_identifier_undefined;
84   args_list_identifier_undefined.append_item(
85       std::make_unique<IdentifierNode>(undefined_token));
86   Value result = functions::RunDefined(setup.scope(), &function_call,
87                                        &args_list_identifier_undefined, &err);
88   ASSERT_EQ(Value::BOOLEAN, result.type());
89   EXPECT_FALSE(result.boolean_value());
90 
91   // Define a value that's itself a scope value.
92   const char kDef[] = "def";  // Defined variable name.
93   setup.scope()->SetValue(
94       kDef, Value(nullptr, std::make_unique<Scope>(setup.scope())), nullptr);
95 
96   // Test the defined identifier.
97   Token defined_token(Location(), Token::IDENTIFIER, kDef);
98   ListNode args_list_identifier_defined;
99   args_list_identifier_defined.append_item(
100       std::make_unique<IdentifierNode>(defined_token));
101   result = functions::RunDefined(setup.scope(), &function_call,
102                                  &args_list_identifier_defined, &err);
103   ASSERT_EQ(Value::BOOLEAN, result.type());
104   EXPECT_TRUE(result.boolean_value());
105 
106   // Should also work by passing an accessor node so you can do
107   // "defined(def.foo)" to see if foo is defined on the def scope.
108   std::unique_ptr<AccessorNode> undef_accessor =
109       std::make_unique<AccessorNode>();
110   undef_accessor->set_base(defined_token);
111   undef_accessor->set_member(std::make_unique<IdentifierNode>(undefined_token));
112   ListNode args_list_accessor_defined;
113   args_list_accessor_defined.append_item(std::move(undef_accessor));
114   result = functions::RunDefined(setup.scope(), &function_call,
115                                  &args_list_accessor_defined, &err);
116   ASSERT_EQ(Value::BOOLEAN, result.type());
117   EXPECT_FALSE(result.boolean_value());
118 
119   // Should also work by pasing an accessor node so you can do
120   // "defined(def["foo"])" to see if foo is defined on the def scope.
121   std::unique_ptr<AccessorNode> subscript_accessor =
122       std::make_unique<AccessorNode>();
123   subscript_accessor->set_base(defined_token);
124   subscript_accessor->set_subscript(
125       std::make_unique<LiteralNode>(Token(Location(), Token::STRING, "foo")));
126   ListNode args_list_subscript_accessor_defined;
127   args_list_subscript_accessor_defined.append_item(
128       std::move(subscript_accessor));
129   result = functions::RunDefined(setup.scope(), &function_call,
130                                  &args_list_subscript_accessor_defined, &err);
131   ASSERT_EQ(Value::BOOLEAN, result.type());
132   EXPECT_FALSE(result.boolean_value());
133 }
134 
135 // Tests that an error is thrown when a {} is supplied to a function that
136 // doesn't take one.
TEST(Functions,FunctionsWithBlock)137 TEST(Functions, FunctionsWithBlock) {
138   TestWithScope setup;
139   Err err;
140 
141   // No scope to print() is OK.
142   TestParseInput print_no_scope("print(6)");
143   EXPECT_FALSE(print_no_scope.has_error());
144   Value result = print_no_scope.parsed()->Execute(setup.scope(), &err);
145   EXPECT_FALSE(err.has_error());
146 
147   // Passing a scope should pass parsing (it doesn't know about what kind of
148   // function it is) and then throw an error during execution.
149   TestParseInput print_with_scope("print(foo) {}");
150   EXPECT_FALSE(print_with_scope.has_error());
151   result = print_with_scope.parsed()->Execute(setup.scope(), &err);
152   EXPECT_TRUE(err.has_error());
153   err = Err();
154 
155   // defined() is a special function so test it separately.
156   TestParseInput defined_no_scope("defined(foo)");
157   EXPECT_FALSE(defined_no_scope.has_error());
158   result = defined_no_scope.parsed()->Execute(setup.scope(), &err);
159   EXPECT_FALSE(err.has_error());
160 
161   // A block to defined should fail.
162   TestParseInput defined_with_scope("defined(foo) {}");
163   EXPECT_FALSE(defined_with_scope.has_error());
164   result = defined_with_scope.parsed()->Execute(setup.scope(), &err);
165   EXPECT_TRUE(err.has_error());
166 }
167 
TEST(Functions,SplitList)168 TEST(Functions, SplitList) {
169   TestWithScope setup;
170 
171   TestParseInput input(
172       // Empty input with varying result items.
173       "out1 = split_list([], 1)\n"
174       "out2 = split_list([], 3)\n"
175       "print(\"empty = $out1 $out2\")\n"
176 
177       // One item input.
178       "out3 = split_list([1], 1)\n"
179       "out4 = split_list([1], 2)\n"
180       "print(\"one = $out3 $out4\")\n"
181 
182       // Multiple items.
183       "out5 = split_list([1, 2, 3, 4, 5, 6, 7, 8, 9], 2)\n"
184       "print(\"many = $out5\")\n"
185 
186       // Rounding.
187       "out6 = split_list([1, 2, 3, 4, 5, 6], 4)\n"
188       "print(\"rounding = $out6\")\n");
189   ASSERT_FALSE(input.has_error());
190 
191   Err err;
192   input.parsed()->Execute(setup.scope(), &err);
193   ASSERT_FALSE(err.has_error()) << err.message();
194 
195   EXPECT_EQ(
196       "empty = [[]] [[], [], []]\n"
197       "one = [[1]] [[1], []]\n"
198       "many = [[1, 2, 3, 4, 5], [6, 7, 8, 9]]\n"
199       "rounding = [[1, 2], [3, 4], [5], [6]]\n",
200       setup.print_output());
201 }
202 
TEST(Functions,StringJoin)203 TEST(Functions, StringJoin) {
204   TestWithScope setup;
205 
206   // Verify outputs when string_join() is called correctly.
207   {
208     TestParseInput input(R"gn(
209         # No elements in the list and empty separator.
210         print("<" + string_join("", []) + ">")
211 
212         # No elements in the list.
213         print("<" + string_join(" ", []) + ">")
214 
215         # One element in the list.
216         print(string_join("|", ["a"]))
217 
218         # Multiple elements in the list.
219         print(string_join(" ", ["a", "b", "c"]))
220 
221         # Multi-character separator.
222         print(string_join("-.", ["a", "b", "c"]))
223 
224         # Empty separator.
225         print(string_join("", ["x", "y", "z"]))
226 
227         # Empty string list elements.
228         print(string_join("x", ["", "", ""]))
229 
230         # Empty string list elements and separator
231         print(string_join("", ["", "", ""]))
232         )gn");
233     ASSERT_FALSE(input.has_error());
234 
235     Err err;
236     input.parsed()->Execute(setup.scope(), &err);
237     ASSERT_FALSE(err.has_error()) << err.message();
238 
239     EXPECT_EQ(
240         "<>\n"
241         "<>\n"
242         "a\n"
243         "a b c\n"
244         "a-.b-.c\n"
245         "xyz\n"
246         "xx\n"
247         "\n",
248         setup.print_output())
249         << setup.print_output();
250   }
251 
252   // Verify usage errors are detected.
253   std::vector<std::string> bad_usage_examples = {
254       // Number of arguments.
255       R"gn(string_join())gn",
256       R"gn(string_join(["oops"]))gn",
257       R"gn(string_join("kk", [], "oops"))gn",
258 
259       // Argument types.
260       R"gn(string_join(1, []))gn",
261       R"gn(string_join("kk", "oops"))gn",
262       R"gn(string_join(["oops"], []))gn",
263 
264       // Non-string elements in list of strings.
265       R"gn(string_join("kk", [1]))gn",
266       R"gn(string_join("kk", ["hello", 1]))gn",
267       R"gn(string_join("kk", ["hello", []]))gn",
268   };
269   for (const auto& bad_usage_example : bad_usage_examples) {
270     TestParseInput input(bad_usage_example);
271     ASSERT_FALSE(input.has_error());
272 
273     Err err;
274     input.parsed()->Execute(setup.scope(), &err);
275     ASSERT_TRUE(err.has_error()) << bad_usage_example;
276   }
277 }
278 
TEST(Functions,StringReplace)279 TEST(Functions, StringReplace) {
280   TestWithScope setup;
281 
282   TestParseInput input(
283       // Replace all occurrences of string.
284       "out1 = string_replace(\"abbcc\", \"b\", \"d\")\n"
285       "print(out1)\n"
286 
287       // Replace only the first occurrence.
288       "out2 = string_replace(\"abbcc\", \"b\", \"d\", 1)\n"
289       "print(out2)\n"
290 
291       // Duplicate string to be replaced.
292       "out3 = string_replace(\"abbcc\", \"b\", \"bb\")\n"
293       "print(out3)\n"
294 
295       // Handle overlapping occurrences.
296       "out4 = string_replace(\"aaa\", \"aa\", \"b\")\n"
297       "print(out4)\n");
298   ASSERT_FALSE(input.has_error());
299 
300   Err err;
301   input.parsed()->Execute(setup.scope(), &err);
302   ASSERT_FALSE(err.has_error()) << err.message();
303 
304   EXPECT_EQ(
305       "addcc\n"
306       "adbcc\n"
307       "abbbbcc\n"
308       "ba\n",
309       setup.print_output());
310 }
311 
TEST(Functions,StringSplit)312 TEST(Functions, StringSplit) {
313   TestWithScope setup;
314 
315   // Verify outputs when string_join() is called correctly.
316   {
317     TestParseInput input(R"gn(
318         # Split on all whitespace: empty string.
319         print(string_split(""))
320 
321         # Split on all whitespace: string is only whitespace
322         print(string_split("      "))
323 
324         # Split on all whitespace: leading, trailing, runs; one element.
325         print(string_split("hello"))
326         print(string_split("  hello"))
327         print(string_split("  hello   "))
328         print(string_split("hello   "))
329 
330         # Split on all whitespace: leading, trailing, runs; multiple elements.
331         print(string_split("a b"))          # Pre-stripped
332         print(string_split("  a b"))        # Leading whitespace
333         print(string_split("  a b  "))      # Leading & trailing whitespace
334         print(string_split("a b  "))        # Trailing whitespace
335         print(string_split("a  b  "))       # Whitespace run between words
336         print(string_split(" a b cc ddd"))  # More & multi-character elements
337 
338         # Split on string.
339         print(string_split("", "|"))           # Empty string
340         print(string_split("|", "|"))          # Only a separator
341         print(string_split("||", "|"))         # Only separators
342         print(string_split("ab", "|"))         # String is missing separator
343         print(string_split("a|b", "|"))        # Two elements
344         print(string_split("|a|b", "|"))       # Leading separator
345         print(string_split("a|b|", "|"))       # Trailing separator
346         print(string_split("||x", "|"))        # Leading consecutive separators
347         print(string_split("x||", "|"))        # Trailing consecutive separators
348         print(string_split("a|bb|ccc", "|"))   # Multiple elements
349         print(string_split(".x.x.x.", ".x."))  # Self-overlapping separators 1
350         print(string_split("x.x.x.", ".x."))   # Self-overlapping separators 2
351         )gn");
352     ASSERT_FALSE(input.has_error());
353 
354     Err err;
355     input.parsed()->Execute(setup.scope(), &err);
356     ASSERT_FALSE(err.has_error()) << err.message();
357 
358     EXPECT_EQ(
359         // Split on all whitespace: empty string.
360         "[]\n"
361 
362         // Split on all whitespace: string is only whitespace.
363         "[]\n"
364 
365         // Split on all whitespace: leading, trailing, runs; one element.
366         "[\"hello\"]\n"
367         "[\"hello\"]\n"
368         "[\"hello\"]\n"
369         "[\"hello\"]\n"
370 
371         // Split on all whitespace: leading, trailing, runs; multiple elements.
372         "[\"a\", \"b\"]\n"
373         "[\"a\", \"b\"]\n"
374         "[\"a\", \"b\"]\n"
375         "[\"a\", \"b\"]\n"
376         "[\"a\", \"b\"]\n"
377         "[\"a\", \"b\", \"cc\", \"ddd\"]\n"
378 
379         // Split on string.
380         "[\"\"]\n"                    // Empty string (like Python)
381         "[\"\", \"\"]\n"              // Only a separator
382         "[\"\", \"\", \"\"]\n"        // Only separators
383         "[\"ab\"]\n"                  // String is missing separator
384         "[\"a\", \"b\"]\n"            // Two elements
385         "[\"\", \"a\", \"b\"]\n"      // Leading
386         "[\"a\", \"b\", \"\"]\n"      // Trailing
387         "[\"\", \"\", \"x\"]\n"       // Leading consecutive separators
388         "[\"x\", \"\", \"\"]\n"       // Trailing consecutive separators
389         "[\"a\", \"bb\", \"ccc\"]\n"  // Multiple elements
390         "[\"\", \"x\", \"\"]\n"       // Self-overlapping separators 1
391         "[\"x\", \"x.\"]\n"           // Self-overlapping separators 2
392         ,
393         setup.print_output())
394         << setup.print_output();
395   }
396 
397   // Verify usage errors are detected.
398   std::vector<std::string> bad_usage_examples = {
399       // Number of arguments.
400       R"gn(string_split())gn",
401       R"gn(string_split("a", "b", "c"))gn",
402 
403       // Argument types.
404       R"gn(string_split(1))gn",
405       R"gn(string_split(["oops"]))gn",
406       R"gn(string_split("kk", 1))gn",
407       R"gn(string_split("kk", ["oops"]))gn",
408 
409       // Empty separator argument.
410       R"gn(string_split("kk", ""))gn",
411   };
412   for (const auto& bad_usage_example : bad_usage_examples) {
413     TestParseInput input(bad_usage_example);
414     ASSERT_FALSE(input.has_error());
415     Err err;
416     input.parsed()->Execute(setup.scope(), &err);
417     ASSERT_TRUE(err.has_error()) << bad_usage_example;
418   }
419 }
420 
TEST(Functions,DeclareArgs)421 TEST(Functions, DeclareArgs) {
422   TestWithScope setup;
423   Err err;
424 
425   // It is not legal to read the value of an argument declared in a
426   // declare_args() from inside the call, but outside the call and in
427   // a separate call should work.
428 
429   TestParseInput reading_from_same_call(R"(
430       declare_args() {
431         foo = true
432         bar = foo
433       })");
434   reading_from_same_call.parsed()->Execute(setup.scope(), &err);
435   ASSERT_TRUE(err.has_error());
436 
437   TestParseInput reading_from_outside_call(R"(
438       declare_args() {
439         foo = true
440       }
441 
442       bar = foo
443       assert(bar)
444       )");
445   err = Err();
446   reading_from_outside_call.parsed()->Execute(setup.scope(), &err);
447   ASSERT_FALSE(err.has_error());
448 
449   TestParseInput reading_from_different_call(R"(
450       declare_args() {
451         foo = true
452       }
453 
454       declare_args() {
455         bar = foo
456       }
457 
458       assert(bar)
459       )");
460   err = Err();
461   TestWithScope setup2;
462   reading_from_different_call.parsed()->Execute(setup2.scope(), &err);
463   ASSERT_FALSE(err.has_error());
464 }
465 
TEST(Functions,NotNeeded)466 TEST(Functions, NotNeeded) {
467   TestWithScope setup;
468 
469   TestParseInput input("not_needed({ a = 1 }, \"*\")");
470   ASSERT_FALSE(input.has_error());
471 
472   Err err;
473   input.parsed()->Execute(setup.scope(), &err);
474   ASSERT_FALSE(err.has_error())
475       << err.message() << err.location().Describe(true);
476 }
477 
TEST(Template,PrintStackTraceWithOneTemplate)478 TEST(Template, PrintStackTraceWithOneTemplate) {
479   TestWithScope setup;
480   TestParseInput input(
481       "template(\"foo\") {\n"
482       "  print(target_name)\n"
483       "  print(invoker.foo_value)\n"
484       "  print_stack_trace()\n"
485       "}\n"
486       "foo(\"lala\") {\n"
487       "  foo_value = 42\n"
488       "}");
489   ASSERT_FALSE(input.has_error());
490 
491   Err err;
492   input.parsed()->Execute(setup.scope(), &err);
493   ASSERT_FALSE(err.has_error()) << err.message();
494 
495   EXPECT_EQ(
496       "lala\n"
497       "42\n"
498       "print_stack_trace() initiated at:  //test:4  using: "
499       "//toolchain:default\n"
500       "  foo(\"lala\")  //test:6\n"
501       "  print_stack_trace()  //test:4\n",
502       setup.print_output());
503 }
504 
TEST(Template,PrintStackTraceWithNoTemplates)505 TEST(Template, PrintStackTraceWithNoTemplates) {
506   TestWithScope setup;
507   TestParseInput input("print_stack_trace()\n");
508   ASSERT_FALSE(input.has_error());
509 
510   Err err;
511   input.parsed()->Execute(setup.scope(), &err);
512   ASSERT_FALSE(err.has_error()) << err.message() << "\n\n" << err.help_text();
513 
514   EXPECT_EQ(
515       "print_stack_trace() initiated at:  //test:1  using: "
516       "//toolchain:default\n"
517       "  print_stack_trace()  //test:1\n",
518       setup.print_output());
519 }
520 
TEST(Template,PrintStackTraceWithNestedTemplates)521 TEST(Template, PrintStackTraceWithNestedTemplates) {
522   TestWithScope setup;
523   TestParseInput input(
524       "template(\"foo\") {\n"
525       "  print(target_name)\n"
526       "  print(invoker.foo_value)\n"
527       "  print_stack_trace()\n"
528       "}\n"
529       "template(\"baz\") {\n"
530       "  foo(\"${target_name}.foo\") {\n"
531       "    foo_value = invoker.bar\n"
532       "  }\n"
533       "}\n"
534       "baz(\"lala\") {\n"
535       "  bar = 42\n"
536       "}");
537   ASSERT_FALSE(input.has_error());
538 
539   Err err;
540   input.parsed()->Execute(setup.scope(), &err);
541   ASSERT_FALSE(err.has_error()) << err.message() << "\n\n" << err.help_text();
542 
543   EXPECT_EQ(
544       "lala.foo\n"
545       "42\n"
546       "print_stack_trace() initiated at:  //test:4  using: "
547       "//toolchain:default\n"
548       "  baz(\"lala\")  //test:11\n"
549       "  foo(\"lala.foo\")  //test:7\n"
550       "  print_stack_trace()  //test:4\n",
551       setup.print_output());
552 }
553 
TEST(Template,PrintStackTraceWithNonTemplateScopes)554 TEST(Template, PrintStackTraceWithNonTemplateScopes) {
555   TestWithScope setup;
556   TestParseInput input(
557       "template(\"foo\") {\n"
558       "  print(target_name)\n"
559       "  if (defined(invoker.foo_value)) {\n"
560       "    print(invoker.foo_value)\n"
561       "    print_stack_trace()\n"
562       "  }\n"
563       "}\n"
564       "template(\"baz\") {\n"
565       "  foo(\"${target_name}.foo\") {\n"
566       "    foo_value = invoker.bar\n"
567       "  }\n"
568       "}\n"
569       "baz(\"lala\") {\n"
570       "  bar = 42\n"
571       "}");
572   ASSERT_FALSE(input.has_error());
573 
574   Err err;
575   input.parsed()->Execute(setup.scope(), &err);
576   ASSERT_FALSE(err.has_error()) << err.message() << "\n\n" << err.help_text();
577 
578   EXPECT_EQ(
579       "lala.foo\n"
580       "42\n"
581       "print_stack_trace() initiated at:  //test:5  using: "
582       "//toolchain:default\n"
583       "  baz(\"lala\")  //test:13\n"
584       "  foo(\"lala.foo\")  //test:9\n"
585       "  print_stack_trace()  //test:5\n",
586       setup.print_output());
587 }
588 
TEST(Template,PrintStackTraceWithNonTemplateScopesBetweenTemplateInvocations)589 TEST(Template, PrintStackTraceWithNonTemplateScopesBetweenTemplateInvocations) {
590   TestWithScope setup;
591   TestParseInput input(
592       "template(\"foo\") {\n"
593       "  print(target_name)\n"
594       "  if (defined(invoker.foo_value)) {\n"
595       "    print(invoker.foo_value)\n"
596       "    print_stack_trace()\n"
597       "  }\n"
598       "}\n"
599       "template(\"baz\") {\n"
600       "  if (invoker.bar == 42) {\n"
601       "    foo(\"${target_name}.foo\") {\n"
602       "      foo_value = invoker.bar\n"
603       "    }\n"
604       "  }\n"
605       "}\n"
606       "baz(\"lala\") {\n"
607       "  bar = 42\n"
608       "}");
609   ASSERT_FALSE(input.has_error());
610   Err err;
611   input.parsed()->Execute(setup.scope(), &err);
612   ASSERT_FALSE(err.has_error()) << err.message() << "\n\n" << err.help_text();
613 
614   EXPECT_EQ(
615       "lala.foo\n"
616       "42\n"
617       "print_stack_trace() initiated at:  //test:5  using: "
618       "//toolchain:default\n"
619       "  baz(\"lala\")  //test:15\n"
620       "  foo(\"lala.foo\")  //test:10\n"
621       "  print_stack_trace()  //test:5\n",
622       setup.print_output());
623 }
624 
TEST(Template,PrintStackTraceWithTemplateDefinedWithinATemplate)625 TEST(Template, PrintStackTraceWithTemplateDefinedWithinATemplate) {
626   TestWithScope setup;
627   TestParseInput input(
628       "template(\"foo\") {\n"
629       "  print(target_name)\n"
630       "  if (defined(invoker.foo_value)) {\n"
631       "    template(\"foo_internal\") {"
632       "      print(target_name)\n"
633       "      print(invoker.foo_internal_value)\n"
634       "      print_stack_trace()\n"
635       "    }\n"
636       "    foo_internal(target_name+\".internal\") {"
637       "      foo_internal_value = invoker.foo_value\n"
638       "    }\n"
639       "  }\n"
640       "}\n"
641       "template(\"baz\") {\n"
642       "  if (invoker.bar == 42) {\n"
643       "    foo(\"${target_name}.foo\") {\n"
644       "      foo_value = invoker.bar\n"
645       "    }\n"
646       "  }\n"
647       "}\n"
648       "baz(\"lala\") {\n"
649       "  bar = 42\n"
650       "}");
651   ASSERT_FALSE(input.has_error());
652   Err err;
653   input.parsed()->Execute(setup.scope(), &err);
654   ASSERT_FALSE(err.has_error()) << err.message() << "\n\n" << err.help_text();
655 
656   EXPECT_EQ(
657       "lala.foo\n"
658       "lala.foo.internal\n"
659       "42\n"
660       "print_stack_trace() initiated at:  //test:6  using: "
661       "//toolchain:default\n"
662       "  baz(\"lala\")  //test:19\n"
663       "  foo(\"lala.foo\")  //test:14\n"
664       "  foo_internal(\"lala.foo.internal\")  //test:8\n"
665       "  print_stack_trace()  //test:6\n",
666       setup.print_output());
667 }
668