| Index: tools/gn/operators_unittest.cc
|
| diff --git a/tools/gn/operators_unittest.cc b/tools/gn/operators_unittest.cc
|
| index 16d626f0b33effb1f752437dc9f2c39359ef3666..529c883aa47659eaf0b89f7bd5eb26e9ff276608 100644
|
| --- a/tools/gn/operators_unittest.cc
|
| +++ b/tools/gn/operators_unittest.cc
|
| @@ -22,6 +22,15 @@ bool IsValueStringEqualing(const Value& v, const char* s) {
|
| return v.string_value() == s;
|
| }
|
|
|
| +// Returns a list populated with a single literal Value corresponding to the
|
| +// given token. The token must outlive the list (since the list will just
|
| +// copy the reference).
|
| +scoped_ptr<ListNode> ListWithLiteral(const Token& token) {
|
| + scoped_ptr<ListNode> list(new ListNode);
|
| + list->append_item(scoped_ptr<ParseNode>(new LiteralNode(token)));
|
| + return list.Pass();
|
| +}
|
| +
|
| } // namespace
|
|
|
| TEST(Operators, SourcesAppend) {
|
| @@ -50,21 +59,21 @@ TEST(Operators, SourcesAppend) {
|
| // Append an integer.
|
| const char integer_value[] = "5";
|
| Token integer(Location(), Token::INTEGER, integer_value);
|
| - node.set_right(scoped_ptr<ParseNode>(new LiteralNode(integer)));
|
| + node.set_right(ListWithLiteral(integer).PassAs<ParseNode>());
|
| node.Execute(setup.scope(), &err);
|
| EXPECT_FALSE(err.has_error());
|
|
|
| // Append a string that doesn't match the pattern, it should get appended.
|
| const char string_1_value[] = "\"good\"";
|
| Token string_1(Location(), Token::STRING, string_1_value);
|
| - node.set_right(scoped_ptr<ParseNode>(new LiteralNode(string_1)));
|
| + node.set_right(ListWithLiteral(string_1).PassAs<ParseNode>());
|
| node.Execute(setup.scope(), &err);
|
| EXPECT_FALSE(err.has_error());
|
|
|
| // Append a string that does match the pattern, it should be a no-op.
|
| const char string_2_value[] = "\"foo-rm\"";
|
| Token string_2(Location(), Token::STRING, string_2_value);
|
| - node.set_right(scoped_ptr<ParseNode>(new LiteralNode(string_2)));
|
| + node.set_right(ListWithLiteral(string_2).PassAs<ParseNode>());
|
| node.Execute(setup.scope(), &err);
|
| EXPECT_FALSE(err.has_error());
|
|
|
| @@ -84,3 +93,61 @@ TEST(Operators, SourcesAppend) {
|
| EXPECT_TRUE(IsValueStringEqualing(value->list_value()[1], "good"));
|
| EXPECT_TRUE(IsValueStringEqualing(value->list_value()[2], "good"));
|
| }
|
| +
|
| +// Note that the SourcesAppend test above tests the basic list + list features,
|
| +// this test handles the other cases.
|
| +TEST(Operators, ListAppend) {
|
| + Err err;
|
| + TestWithScope setup;
|
| +
|
| + // Set up "foo" with an empty list.
|
| + const char foo[] = "foo";
|
| + setup.scope()->SetValue(foo, Value(NULL, Value::LIST), NULL);
|
| +
|
| + // Set up the operator.
|
| + BinaryOpNode node;
|
| + const char token_value[] = "+=";
|
| + Token op(Location(), Token::PLUS_EQUALS, token_value);
|
| + node.set_op(op);
|
| +
|
| + // Append to the foo variable.
|
| + Token identifier_token(Location(), Token::IDENTIFIER, foo);
|
| + node.set_left(scoped_ptr<ParseNode>(new IdentifierNode(identifier_token)));
|
| +
|
| + // Append a list with a list, the result should be a nested list.
|
| + scoped_ptr<ListNode> outer_list(new ListNode);
|
| + const char twelve_str[] = "12";
|
| + Token twelve(Location(), Token::INTEGER, twelve_str);
|
| + outer_list->append_item(ListWithLiteral(twelve).PassAs<ParseNode>());
|
| + node.set_right(outer_list.PassAs<ParseNode>());
|
| +
|
| + Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
|
| + node.right(), &err);
|
| + EXPECT_FALSE(err.has_error());
|
| +
|
| + // Return from the operator should always be "none", it should update the
|
| + // value only.
|
| + EXPECT_EQ(Value::NONE, ret.type());
|
| +
|
| + // The value should be updated with "[ [ 12 ] ]"
|
| + Value result = *setup.scope()->GetValue(foo);
|
| + ASSERT_EQ(Value::LIST, result.type());
|
| + ASSERT_EQ(1u, result.list_value().size());
|
| + ASSERT_EQ(Value::LIST, result.list_value()[0].type());
|
| + ASSERT_EQ(1u, result.list_value()[0].list_value().size());
|
| + ASSERT_EQ(Value::INTEGER, result.list_value()[0].list_value()[0].type());
|
| + ASSERT_EQ(12, result.list_value()[0].list_value()[0].int_value());
|
| +
|
| + // Try to append an integer and a string directly (e.g. foo += "hi").
|
| + // This should fail.
|
| + const char str_str[] = "\"hi\"";
|
| + Token str(Location(), Token::STRING, str_str);
|
| + node.set_right(scoped_ptr<ParseNode>(new LiteralNode(str)));
|
| + ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err);
|
| + EXPECT_TRUE(err.has_error());
|
| + err = Err();
|
| +
|
| + node.set_right(scoped_ptr<ParseNode>(new LiteralNode(twelve)));
|
| + ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err);
|
| + EXPECT_TRUE(err.has_error());
|
| +}
|
|
|