Add the ability to code generated prepopulated static nested structs
[chromium-blink-merge.git] / tools / gn / functions_unittest.cc
blob6a6c679094a92662fd68068193cb41b011997a3a
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.
5 #include "testing/gtest/include/gtest/gtest.h"
6 #include "tools/gn/functions.h"
7 #include "tools/gn/parse_tree.h"
8 #include "tools/gn/test_with_scope.h"
9 #include "tools/gn/value.h"
11 TEST(Functions, Defined) {
12 TestWithScope setup;
14 FunctionCallNode function_call;
15 Err err;
17 // Test an undefined identifier.
18 Token undefined_token(Location(), Token::IDENTIFIER, "undef");
19 ListNode args_list_identifier_undefined;
20 args_list_identifier_undefined.append_item(
21 scoped_ptr<ParseNode>(new IdentifierNode(undefined_token)));
22 Value result = functions::RunDefined(setup.scope(), &function_call,
23 &args_list_identifier_undefined, &err);
24 ASSERT_EQ(Value::BOOLEAN, result.type());
25 EXPECT_FALSE(result.boolean_value());
27 // Define a value that's itself a scope value.
28 const char kDef[] = "def"; // Defined variable name.
29 setup.scope()->SetValue(
30 kDef, Value(nullptr, scoped_ptr<Scope>(new Scope(setup.scope()))),
31 nullptr);
33 // Test the defined identifier.
34 Token defined_token(Location(), Token::IDENTIFIER, kDef);
35 ListNode args_list_identifier_defined;
36 args_list_identifier_defined.append_item(
37 scoped_ptr<ParseNode>(new IdentifierNode(defined_token)));
38 result = functions::RunDefined(setup.scope(), &function_call,
39 &args_list_identifier_defined, &err);
40 ASSERT_EQ(Value::BOOLEAN, result.type());
41 EXPECT_TRUE(result.boolean_value());
43 // Should also work by passing an accessor node so you can do
44 // "defined(def.foo)" to see if foo is defined on the def scope.
45 scoped_ptr<AccessorNode> undef_accessor(new AccessorNode);
46 undef_accessor->set_base(defined_token);
47 undef_accessor->set_member(scoped_ptr<IdentifierNode>(
48 new IdentifierNode(undefined_token)));
49 ListNode args_list_accessor_defined;
50 args_list_accessor_defined.append_item(undef_accessor.Pass());
51 result = functions::RunDefined(setup.scope(), &function_call,
52 &args_list_accessor_defined, &err);
53 ASSERT_EQ(Value::BOOLEAN, result.type());
54 EXPECT_FALSE(result.boolean_value());
57 // Tests that an error is thrown when a {} is supplied to a function that
58 // doesn't take one.
59 TEST(Functions, FunctionsWithBlock) {
60 TestWithScope setup;
61 Err err;
63 // No scope to print() is OK.
64 TestParseInput print_no_scope("print(6)");
65 EXPECT_FALSE(print_no_scope.has_error());
66 Value result = print_no_scope.parsed()->Execute(setup.scope(), &err);
67 EXPECT_FALSE(err.has_error());
69 // Passing a scope should pass parsing (it doesn't know about what kind of
70 // function it is) and then throw an error during execution.
71 TestParseInput print_with_scope("print(foo) {}");
72 EXPECT_FALSE(print_with_scope.has_error());
73 result = print_with_scope.parsed()->Execute(setup.scope(), &err);
74 EXPECT_TRUE(err.has_error());
75 err = Err();
77 // defined() is a special function so test it separately.
78 TestParseInput defined_no_scope("defined(foo)");
79 EXPECT_FALSE(defined_no_scope.has_error());
80 result = defined_no_scope.parsed()->Execute(setup.scope(), &err);
81 EXPECT_FALSE(err.has_error());
83 // A block to defined should fail.
84 TestParseInput defined_with_scope("defined(foo) {}");
85 EXPECT_FALSE(defined_with_scope.has_error());
86 result = defined_with_scope.parsed()->Execute(setup.scope(), &err);
87 EXPECT_TRUE(err.has_error());