1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <algorithm>
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <sstream>
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "tools/gn/ninja_action_target_writer.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "tools/gn/substitution_list.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/target.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "tools/gn/test_with_scope.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLine) {
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TestWithScope setup;
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.set_output_type(Target::ACTION_FOREACH);
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().outputs() = SubstitutionList::MakeForTest(
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "//out/Debug/gen/a b{{source_name_part}}.h",
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "//out/Debug/gen/{{source_name_part}}.cc");
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::ostringstream out;
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NinjaActionTargetWriter writer(&target, out);
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SourceFile source("//foo/bar.in");
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::vector<OutputFile> output_files;
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  writer.WriteOutputFilesForBuildLine(source, &output_files);
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(" gen/a$ bbar.h gen/bar.cc", out.str());
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Tests an action with no sources.
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST(NinjaActionTargetWriter, ActionNoSources) {
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestWithScope setup;
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  target.set_output_type(Target::ACTION);
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  target.action_values().set_script(SourceFile("//foo/script.py"));
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  target.inputs().push_back(SourceFile("//foo/included.txt"));
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  target.action_values().outputs() =
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      SubstitutionList::MakeForTest("//out/Debug/foo.out");
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  setup.settings()->set_target_os(Settings::LINUX);
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "/usr/bin/python")));
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::ostringstream out;
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  NinjaActionTargetWriter writer(&target, out);
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  writer.Run();
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const char expected[] =
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "rule __foo_bar___rule\n"
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "  command = /usr/bin/python ../../foo/script.py\n"
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "  description = ACTION //foo:bar()\n"
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "  restat = 1\n"
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          "../../foo/included.txt\n"
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "\n"
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n"
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "\n"
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "build obj/foo/bar.stamp: stamp foo.out\n";
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(expected, out.str());
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Makes sure that we write sources as input dependencies for actions with
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// both sources and inputs (ACTION_FOREACH treats the sources differently).
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, ActionWithSources) {
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TestWithScope setup;
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.set_output_type(Target::ACTION);
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.action_values().set_script(SourceFile("//foo/script.py"));
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/source.txt"));
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  target.inputs().push_back(SourceFile("//foo/included.txt"));
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().outputs() =
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SubstitutionList::MakeForTest("//out/Debug/foo.out");
9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Posix.
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  {
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    setup.settings()->set_target_os(Settings::LINUX);
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "/usr/bin/python")));
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::ostringstream out;
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaActionTargetWriter writer(&target, out);
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    writer.Run();
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const char expected_linux[] =
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "rule __foo_bar___rule\n"
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  command = /usr/bin/python ../../foo/script.py\n"
11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  description = ACTION //foo:bar()\n"
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        "  restat = 1\n"
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "../../foo/included.txt ../../foo/source.txt\n"
11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "\n"
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n"
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "\n"
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "build obj/foo/bar.stamp: stamp foo.out\n";
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_EQ(expected_linux, out.str());
12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Windows.
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  {
12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Note: we use forward slashes here so that the output will be the same on
12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Linux and Windows.
12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "C:/python/python.exe")));
13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    setup.settings()->set_target_os(Settings::WIN);
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::ostringstream out;
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaActionTargetWriter writer(&target, out);
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    writer.Run();
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const char expected_win[] =
13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "rule __foo_bar___rule\n"
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "  command = C$:/python/python.exe gyp-win-tool action-wrapper environment.x86 __foo_bar___rule.$unique_name.rsp\n"
13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  description = ACTION //foo:bar()\n"
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  restat = 1\n"
14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  rspfile = __foo_bar___rule.$unique_name.rsp\n"
1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "  rspfile_content = C$:/python/python.exe ../../foo/script.py\n"
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "../../foo/included.txt ../../foo/source.txt\n"
14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "\n"
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        "build foo.out: __foo_bar___rule | obj/foo/bar.inputdeps.stamp\n"
14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "\n"
14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "build obj/foo/bar.stamp: stamp foo.out\n";
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_EQ(expected_win, out.str());
15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, ForEach) {
15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  TestWithScope setup;
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Some dependencies that the action can depend on. Use actions for these
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // so they have a nice platform-independent stamp file that can appear in the
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // output (rather than having to worry about how the current platform names
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // binaries).
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Target dep(setup.settings(), Label(SourceDir("//foo/"), "dep"));
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  dep.set_output_type(Target::ACTION);
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  dep.visibility().SetPublic();
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  dep.SetToolchain(setup.toolchain());
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(dep.OnResolved(&err));
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Target datadep(setup.settings(), Label(SourceDir("//foo/"), "datadep"));
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  datadep.set_output_type(Target::ACTION);
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  datadep.visibility().SetPublic();
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  datadep.SetToolchain(setup.toolchain());
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(datadep.OnResolved(&err));
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.set_output_type(Target::ACTION_FOREACH);
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  target.private_deps().push_back(LabelTargetPair(&dep));
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  target.data_deps().push_back(LabelTargetPair(&datadep));
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input1.txt"));
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input2.txt"));
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.action_values().set_script(SourceFile("//foo/script.py"));
184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().args() = SubstitutionList::MakeForTest(
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "-i",
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "{{source}}",
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      "--out=foo bar{{source_name_part}}.o");
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().outputs() = SubstitutionList::MakeForTest(
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "//out/Debug/{{source_name_part}}.out");
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  target.inputs().push_back(SourceFile("//foo/included.txt"));
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Posix.
198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  {
199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    setup.settings()->set_target_os(Settings::LINUX);
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "/usr/bin/python")));
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::ostringstream out;
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaActionTargetWriter writer(&target, out);
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    writer.Run();
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const char expected_linux[] =
208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "rule __foo_bar___rule\n"
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "  command = /usr/bin/python ../../foo/script.py -i ${in} "
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            // Escaping is different between Windows and Posix.
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN)
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            "\"--out=foo$ bar${source_name_part}.o\"\n"
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            "--out=foo\\$ bar${source_name_part}.o\n"
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  description = ACTION //foo:bar()\n"
217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  restat = 1\n"
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "../../foo/included.txt obj/foo/dep.stamp\n"
220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "\n"
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            "obj/foo/bar.inputdeps.stamp\n"
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  source_name_part = input1\n"
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            "obj/foo/bar.inputdeps.stamp\n"
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  source_name_part = input2\n"
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "\n"
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        "build obj/foo/bar.stamp: "
22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            "stamp input1.out input2.out || obj/foo/datadep.stamp\n";
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    std::string out_str = out.str();
23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN)
23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    std::replace(out_str.begin(), out_str.end(), '\\', '/');
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(expected_linux, out_str);
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Windows.
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  {
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "C:/python/python.exe")));
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    setup.settings()->set_target_os(Settings::WIN);
243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::ostringstream out;
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaActionTargetWriter writer(&target, out);
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    writer.Run();
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const char expected_win[] =
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "rule __foo_bar___rule\n"
2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "  command = C$:/python/python.exe gyp-win-tool action-wrapper "
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            "environment.x86 __foo_bar___rule.$unique_name.rsp\n"
25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  description = ACTION //foo:bar()\n"
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  restat = 1\n"
254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  rspfile = __foo_bar___rule.$unique_name.rsp\n"
2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "  rspfile_content = C$:/python/python.exe ../../foo/script.py -i "
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN)
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "${in} \"--out=foo$ bar${source_name_part}.o\"\n"
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "${in} --out=foo\\$ bar${source_name_part}.o\n"
26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "../../foo/included.txt obj/foo/dep.stamp\n"
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "\n"
2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "build input1.out: __foo_bar___rule ../../foo/input1.txt | "
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            "obj/foo/bar.inputdeps.stamp\n"
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  unique_name = 0\n"
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  source_name_part = input1\n"
2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "build input2.out: __foo_bar___rule ../../foo/input2.txt | "
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            "obj/foo/bar.inputdeps.stamp\n"
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  unique_name = 1\n"
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "  source_name_part = input2\n"
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        "\n"
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        "build obj/foo/bar.stamp: "
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            "stamp input1.out input2.out || obj/foo/datadep.stamp\n";
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_EQ(expected_win, out.str());
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST(NinjaActionTargetWriter, ForEachWithDepfile) {
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TestWithScope setup;
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
28523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.set_output_type(Target::ACTION_FOREACH);
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input1.txt"));
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  target.sources().push_back(SourceFile("//foo/input2.txt"));
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  target.action_values().set_script(SourceFile("//foo/script.py"));
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  target.SetToolchain(setup.toolchain());
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(target.OnResolved(&err));
29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SubstitutionPattern depfile;
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      depfile.Parse("//out/Debug/gen/{{source_name_part}}.d", NULL, &err));
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().set_depfile(depfile);
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().args() = SubstitutionList::MakeForTest(
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "-i",
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "{{source}}",
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "--out=foo bar{{source_name_part}}.o");
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target.action_values().outputs() = SubstitutionList::MakeForTest(
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      "//out/Debug/{{source_name_part}}.out");
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  target.inputs().push_back(SourceFile("//foo/included.txt"));
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Posix.
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    setup.settings()->set_target_os(Settings::LINUX);
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "/usr/bin/python")));
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::ostringstream out;
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaActionTargetWriter writer(&target, out);
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    writer.Run();
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char expected_linux[] =
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "rule __foo_bar___rule\n"
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "  command = /usr/bin/python ../../foo/script.py -i ${in} "
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN)
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            "\"--out=foo$ bar${source_name_part}.o\"\n"
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            "--out=foo\\$ bar${source_name_part}.o\n"
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
32723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  description = ACTION //foo:bar()\n"
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  restat = 1\n"
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "../../foo/included.txt\n"
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "\n"
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "build input1.out: __foo_bar___rule ../../foo/input1.txt"
333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            " | obj/foo/bar.inputdeps.stamp\n"
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  source_name_part = input1\n"
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  depfile = gen/input1.d\n"
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "build input2.out: __foo_bar___rule ../../foo/input2.txt"
337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            " | obj/foo/bar.inputdeps.stamp\n"
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  source_name_part = input2\n"
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  depfile = gen/input2.d\n"
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "\n"
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_EQ(expected_linux, out.str());
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Windows.
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL(
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "C:/python/python.exe")));
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    setup.settings()->set_target_os(Settings::WIN);
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::ostringstream out;
35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    NinjaActionTargetWriter writer(&target, out);
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    writer.Run();
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char expected_win[] =
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "rule __foo_bar___rule\n"
3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "  command = C$:/python/python.exe gyp-win-tool action-wrapper "
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            "environment.x86 __foo_bar___rule.$unique_name.rsp\n"
35923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        "  description = ACTION //foo:bar()\n"
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  restat = 1\n"
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  rspfile = __foo_bar___rule.$unique_name.rsp\n"
3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        "  rspfile_content = C$:/python/python.exe ../../foo/script.py -i "
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_WIN)
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "${in} \"--out=foo$ bar${source_name_part}.o\"\n"
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "${in} --out=foo\\$ bar${source_name_part}.o\n"
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "build obj/foo/bar.inputdeps.stamp: stamp ../../foo/script.py "
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "../../foo/included.txt\n"
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "\n"
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "build input1.out: __foo_bar___rule ../../foo/input1.txt"
372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            " | obj/foo/bar.inputdeps.stamp\n"
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  unique_name = 0\n"
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  source_name_part = input1\n"
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  depfile = gen/input1.d\n"
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        "build input2.out: __foo_bar___rule ../../foo/input2.txt"
377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            " | obj/foo/bar.inputdeps.stamp\n"
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  unique_name = 1\n"
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  source_name_part = input2\n"
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "  depfile = gen/input2.d\n"
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "\n"
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "build obj/foo/bar.stamp: stamp input1.out input2.out\n";
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_EQ(expected_win, out.str());
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
386