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 "base/strings/string_number_conversions.h"
6#include "testing/gtest/include/gtest/gtest.h"
7#include "tools/gn/test_with_scope.h"
8
9TEST(Template, Basic) {
10  TestWithScope setup;
11  TestParseInput input(
12      "template(\"foo\") {\n"
13      "  print(target_name)\n"
14      "  print(invoker.bar)\n"
15      "}\n"
16      "foo(\"lala\") {\n"
17      "  bar = 42\n"
18      "}");
19  ASSERT_FALSE(input.has_error());
20
21  Err err;
22  input.parsed()->Execute(setup.scope(), &err);
23  ASSERT_FALSE(err.has_error()) << err.message();
24
25  EXPECT_EQ("lala\n42\n", setup.print_output());
26}
27
28TEST(Template, UnusedTargetNameShouldThrowError) {
29  TestWithScope setup;
30  TestParseInput input(
31      "template(\"foo\") {\n"
32      "  print(invoker.bar)\n"
33      "}\n"
34      "foo(\"lala\") {\n"
35      "  bar = 42\n"
36      "}");
37  ASSERT_FALSE(input.has_error());
38
39  Err err;
40  input.parsed()->Execute(setup.scope(), &err);
41  EXPECT_TRUE(err.has_error());
42}
43
44TEST(Template, UnusedInvokerShouldThrowError) {
45  TestWithScope setup;
46  TestParseInput input(
47      "template(\"foo\") {\n"
48      "  print(target_name)\n"
49      "}\n"
50      "foo(\"lala\") {\n"
51      "  bar = 42\n"
52      "}");
53  ASSERT_FALSE(input.has_error());
54
55  Err err;
56  input.parsed()->Execute(setup.scope(), &err);
57  EXPECT_TRUE(err.has_error());
58}
59
60TEST(Template, UnusedVarInInvokerShouldThrowError) {
61  TestWithScope setup;
62  TestParseInput input(
63      "template(\"foo\") {\n"
64      "  print(target_name)\n"
65      "  print(invoker.bar)\n"
66      "}\n"
67      "foo(\"lala\") {\n"
68      "  bar = 42\n"
69      "  baz = [ \"foo\" ]\n"
70      "}");
71  ASSERT_FALSE(input.has_error());
72
73  Err err;
74  input.parsed()->Execute(setup.scope(), &err);
75  EXPECT_TRUE(err.has_error());
76}
77
78// Previous versions of the template implementation would copy templates by
79// value when it makes a closure. Doing a sequence of them means that every new
80// one copies all previous ones, which gives a significant blow-up in memory.
81// If this test doesn't crash with out-of-memory, it passed.
82TEST(Template, MemoryBlowUp) {
83  TestWithScope setup;
84  std::string code;
85  for (int i = 0; i < 100; i++)
86    code += "template(\"test" + base::IntToString(i) + "\") {}\n";
87
88  TestParseInput input(code);
89
90  Err err;
91  input.parsed()->Execute(setup.scope(), &err);
92  ASSERT_FALSE(input.has_error());
93}
94