|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "tools/gn/scheduler.h" | 
|  | #include "tools/gn/test_with_scheduler.h" | 
|  | #include "tools/gn/test_with_scope.h" | 
|  | #include "util/test/test.h" | 
|  |  | 
|  | using ActionTargetGenerator = TestWithScheduler; | 
|  |  | 
|  | // Tests that actions can't have output substitutions. | 
|  | TEST_F(ActionTargetGenerator, ActionOutputSubstitutions) { | 
|  | TestWithScope setup; | 
|  | Scope::ItemVector items_; | 
|  | setup.scope()->set_item_collector(&items_); | 
|  |  | 
|  | // First test one with no substitutions, this should be valid. | 
|  | TestParseInput input_good( | 
|  | R"(action("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/one.txt" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_good.has_error()); | 
|  |  | 
|  | // This should run fine. | 
|  | Err err; | 
|  | input_good.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_FALSE(err.has_error()) << err.message(); | 
|  |  | 
|  | // Same thing with a pattern in the output should fail. | 
|  | TestParseInput input_bad( | 
|  | R"(action("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/{{source_name_part}}.txt" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_bad.has_error()); | 
|  |  | 
|  | // This should run fine. | 
|  | input_bad.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_TRUE(err.has_error()); | 
|  | } | 
|  |  | 
|  | // Tests that arg and response file substitutions are validated for | 
|  | // action_foreach targets. | 
|  | TEST_F(ActionTargetGenerator, ActionForeachSubstitutions) { | 
|  | TestWithScope setup; | 
|  | Scope::ItemVector items_; | 
|  | setup.scope()->set_item_collector(&items_); | 
|  |  | 
|  | // Args listing a response file but missing a response file definition should | 
|  | // fail. | 
|  | TestParseInput input_missing_resp_file( | 
|  | R"(action_foreach("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/{{source_name_part}}" ] | 
|  | args = [ "{{response_file_name}}" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_missing_resp_file.has_error()); | 
|  | Err err; | 
|  | input_missing_resp_file.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_TRUE(err.has_error()); | 
|  |  | 
|  | // Adding a response file definition should pass. | 
|  | err = Err(); | 
|  | TestParseInput input_resp_file( | 
|  | R"(action_foreach("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/{{source_name_part}}" ] | 
|  | args = [ "{{response_file_name}}" ] | 
|  | response_file_contents = [ "{{source_name_part}}" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_resp_file.has_error()); | 
|  | input_resp_file.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_FALSE(err.has_error()) << err.message(); | 
|  |  | 
|  | // Defining a response file but not referencing it should fail. | 
|  | err = Err(); | 
|  | TestParseInput input_missing_rsp_args( | 
|  | R"(action_foreach("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/{{source_name_part}}" ] | 
|  | args = [ "{{source_name_part}}" ] | 
|  | response_file_contents = [ "{{source_name_part}}" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_missing_rsp_args.has_error()); | 
|  | input_missing_rsp_args.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_TRUE(err.has_error()) << err.message(); | 
|  |  | 
|  | // Bad substitutions in args. | 
|  | err = Err(); | 
|  | TestParseInput input_bad_args( | 
|  | R"(action_foreach("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/{{source_name_part}}" ] | 
|  | args = [ "{{response_file_name}} {{ldflags}}" ] | 
|  | response_file_contents = [ "{{source_name_part}}" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_bad_args.has_error()); | 
|  | input_bad_args.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_TRUE(err.has_error()) << err.message(); | 
|  |  | 
|  | // Bad substitutions in response file contents. | 
|  | err = Err(); | 
|  | TestParseInput input_bad_rsp( | 
|  | R"(action_foreach("foo") { | 
|  | script = "//foo.py" | 
|  | sources = [ "//bar.txt" ] | 
|  | outputs = [ "//out/Debug/{{source_name_part}}" ] | 
|  | args = [ "{{response_file_name}}" ] | 
|  | response_file_contents = [ "{{source_name_part}} {{ldflags}}" ] | 
|  | })"); | 
|  | ASSERT_FALSE(input_bad_rsp.has_error()); | 
|  | input_bad_rsp.parsed()->Execute(setup.scope(), &err); | 
|  | ASSERT_TRUE(err.has_error()) << err.message(); | 
|  | } |