OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/operators.h" | 5 #include "tools/gn/operators.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 | 28 |
29 // Returns a list populated with a single literal Value corresponding to the | 29 // Returns a list populated with a single literal Value corresponding to the |
30 // given token. The token must outlive the list (since the list will just | 30 // given token. The token must outlive the list (since the list will just |
31 // copy the reference). | 31 // copy the reference). |
32 std::unique_ptr<ListNode> ListWithLiteral(const Token& token) { | 32 std::unique_ptr<ListNode> ListWithLiteral(const Token& token) { |
33 std::unique_ptr<ListNode> list(new ListNode); | 33 std::unique_ptr<ListNode> list(new ListNode); |
34 list->append_item(std::unique_ptr<ParseNode>(new LiteralNode(token))); | 34 list->append_item(std::unique_ptr<ParseNode>(new LiteralNode(token))); |
35 return list; | 35 return list; |
36 } | 36 } |
37 | 37 |
| 38 // This parse node is for passing to tests. It returns a canned value for |
| 39 // Execute(). |
| 40 class TestParseNode : public ParseNode { |
| 41 public: |
| 42 TestParseNode(const Value& v) : value_(v) { |
| 43 } |
| 44 |
| 45 Value Execute(Scope* scope, Err* err) const override { |
| 46 return value_; |
| 47 } |
| 48 LocationRange GetRange() const override { |
| 49 return LocationRange(); |
| 50 } |
| 51 Err MakeErrorDescribing(const std::string& msg, |
| 52 const std::string& help) const override { |
| 53 return Err(this, msg); |
| 54 } |
| 55 void Print(std::ostream& out, int indent) const override { |
| 56 } |
| 57 |
| 58 private: |
| 59 Value value_; |
| 60 }; |
| 61 |
38 } // namespace | 62 } // namespace |
39 | 63 |
40 TEST(Operators, SourcesAppend) { | 64 TEST(Operators, SourcesAppend) { |
41 Err err; | 65 Err err; |
42 TestWithScope setup; | 66 TestWithScope setup; |
43 | 67 |
44 // Set up "sources" with an empty list. | 68 // Set up "sources" with an empty list. |
45 const char sources[] = "sources"; | 69 const char sources[] = "sources"; |
46 setup.scope()->SetValue(sources, Value(nullptr, Value::LIST), nullptr); | 70 setup.scope()->SetValue(sources, Value(nullptr, Value::LIST), nullptr); |
47 | 71 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 node.set_right(std::unique_ptr<ParseNode>(new LiteralNode(str))); | 175 node.set_right(std::unique_ptr<ParseNode>(new LiteralNode(str))); |
152 ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err); | 176 ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err); |
153 EXPECT_TRUE(err.has_error()); | 177 EXPECT_TRUE(err.has_error()); |
154 err = Err(); | 178 err = Err(); |
155 | 179 |
156 node.set_right(std::unique_ptr<ParseNode>(new LiteralNode(twelve))); | 180 node.set_right(std::unique_ptr<ParseNode>(new LiteralNode(twelve))); |
157 ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err); | 181 ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err); |
158 EXPECT_TRUE(err.has_error()); | 182 EXPECT_TRUE(err.has_error()); |
159 } | 183 } |
160 | 184 |
| 185 TEST(Operators, ListRemove) { |
| 186 Err err; |
| 187 TestWithScope setup; |
| 188 |
| 189 const char foo_str[] = "foo"; |
| 190 const char bar_str[] = "bar"; |
| 191 Value test_list(nullptr, Value::LIST); |
| 192 test_list.list_value().push_back(Value(nullptr, foo_str)); |
| 193 test_list.list_value().push_back(Value(nullptr, bar_str)); |
| 194 test_list.list_value().push_back(Value(nullptr, foo_str)); |
| 195 |
| 196 // Set up "var" with an the test list. |
| 197 const char var_str[] = "var"; |
| 198 setup.scope()->SetValue(var_str, test_list, nullptr); |
| 199 |
| 200 // Set up the operator. |
| 201 BinaryOpNode node; |
| 202 const char token_value[] = "-="; |
| 203 Token op(Location(), Token::MINUS_EQUALS, token_value); |
| 204 node.set_op(op); |
| 205 |
| 206 // Do -= on the var. |
| 207 Token identifier_token(Location(), Token::IDENTIFIER, var_str); |
| 208 node.set_left( |
| 209 std::unique_ptr<ParseNode>(new IdentifierNode(identifier_token))); |
| 210 |
| 211 // Subtract a list consisting of "foo". |
| 212 Value foo_list(nullptr, Value::LIST); |
| 213 foo_list.list_value().push_back(Value(nullptr, foo_str)); |
| 214 std::unique_ptr<ParseNode> outer_list(new TestParseNode(foo_list)); |
| 215 node.set_right(std::move(outer_list)); |
| 216 |
| 217 Value result = ExecuteBinaryOperator( |
| 218 setup.scope(), &node, node.left(), node.right(), &err); |
| 219 EXPECT_FALSE(err.has_error()); |
| 220 |
| 221 // -= returns an empty value to reduce the possibility of writing confusing |
| 222 // cases like foo = bar += 1. |
| 223 EXPECT_EQ(Value::NONE, result.type()); |
| 224 |
| 225 // The "var" variable should have been updated. Both instances of "foo" are |
| 226 // deleted. |
| 227 const Value* new_value = setup.scope()->GetValue(var_str); |
| 228 ASSERT_TRUE(new_value); |
| 229 ASSERT_EQ(Value::LIST, new_value->type()); |
| 230 ASSERT_EQ(1u, new_value->list_value().size()); |
| 231 ASSERT_EQ(Value::STRING, new_value->list_value()[0].type()); |
| 232 EXPECT_EQ("bar", new_value->list_value()[0].string_value()); |
| 233 } |
| 234 |
161 TEST(Operators, ShortCircuitAnd) { | 235 TEST(Operators, ShortCircuitAnd) { |
162 Err err; | 236 Err err; |
163 TestWithScope setup; | 237 TestWithScope setup; |
164 | 238 |
165 // Set up the operator. | 239 // Set up the operator. |
166 BinaryOpNode node; | 240 BinaryOpNode node; |
167 const char token_value[] = "&&"; | 241 const char token_value[] = "&&"; |
168 Token op(Location(), Token::BOOLEAN_AND, token_value); | 242 Token op(Location(), Token::BOOLEAN_AND, token_value); |
169 node.set_op(op); | 243 node.set_op(op); |
170 | 244 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 // Set right as foo, but don't define a value for it. | 276 // Set right as foo, but don't define a value for it. |
203 const char foo[] = "foo"; | 277 const char foo[] = "foo"; |
204 Token identifier_token(Location(), Token::IDENTIFIER, foo); | 278 Token identifier_token(Location(), Token::IDENTIFIER, foo); |
205 node.set_right( | 279 node.set_right( |
206 std::unique_ptr<ParseNode>(new IdentifierNode(identifier_token))); | 280 std::unique_ptr<ParseNode>(new IdentifierNode(identifier_token))); |
207 | 281 |
208 Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(), | 282 Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(), |
209 node.right(), &err); | 283 node.right(), &err); |
210 EXPECT_FALSE(err.has_error()); | 284 EXPECT_FALSE(err.has_error()); |
211 } | 285 } |
OLD | NEW |