Home | History | Annotate | Download | only in gn
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/strings/string_util.h"
      6 #include "base/strings/utf_string_conversions.h"
      7 #include "build/build_config.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 #include "tools/gn/filesystem_utils.h"
     10 #include "tools/gn/target.h"
     11 
     12 TEST(FilesystemUtils, FileExtensionOffset) {
     13   EXPECT_EQ(std::string::npos, FindExtensionOffset(""));
     14   EXPECT_EQ(std::string::npos, FindExtensionOffset("foo/bar/baz"));
     15   EXPECT_EQ(4u, FindExtensionOffset("foo."));
     16   EXPECT_EQ(4u, FindExtensionOffset("f.o.bar"));
     17   EXPECT_EQ(std::string::npos, FindExtensionOffset("foo.bar/"));
     18   EXPECT_EQ(std::string::npos, FindExtensionOffset("foo.bar/baz"));
     19 }
     20 
     21 TEST(FilesystemUtils, FindExtension) {
     22   std::string input;
     23   EXPECT_EQ("", FindExtension(&input).as_string());
     24   input = "foo/bar/baz";
     25   EXPECT_EQ("", FindExtension(&input).as_string());
     26   input = "foo.";
     27   EXPECT_EQ("", FindExtension(&input).as_string());
     28   input = "f.o.bar";
     29   EXPECT_EQ("bar", FindExtension(&input).as_string());
     30   input = "foo.bar/";
     31   EXPECT_EQ("", FindExtension(&input).as_string());
     32   input = "foo.bar/baz";
     33   EXPECT_EQ("", FindExtension(&input).as_string());
     34 }
     35 
     36 TEST(FilesystemUtils, FindFilenameOffset) {
     37   EXPECT_EQ(0u, FindFilenameOffset(""));
     38   EXPECT_EQ(0u, FindFilenameOffset("foo"));
     39   EXPECT_EQ(4u, FindFilenameOffset("foo/"));
     40   EXPECT_EQ(4u, FindFilenameOffset("foo/bar"));
     41 }
     42 
     43 TEST(FilesystemUtils, RemoveFilename) {
     44   std::string s;
     45 
     46   RemoveFilename(&s);
     47   EXPECT_STREQ("", s.c_str());
     48 
     49   s = "foo";
     50   RemoveFilename(&s);
     51   EXPECT_STREQ("", s.c_str());
     52 
     53   s = "/";
     54   RemoveFilename(&s);
     55   EXPECT_STREQ("/", s.c_str());
     56 
     57   s = "foo/bar";
     58   RemoveFilename(&s);
     59   EXPECT_STREQ("foo/", s.c_str());
     60 
     61   s = "foo/bar/baz.cc";
     62   RemoveFilename(&s);
     63   EXPECT_STREQ("foo/bar/", s.c_str());
     64 }
     65 
     66 TEST(FilesystemUtils, FindDir) {
     67   std::string input;
     68   EXPECT_EQ("", FindDir(&input));
     69   input = "/";
     70   EXPECT_EQ("/", FindDir(&input));
     71   input = "foo/";
     72   EXPECT_EQ("foo/", FindDir(&input));
     73   input = "foo/bar/baz";
     74   EXPECT_EQ("foo/bar/", FindDir(&input));
     75 }
     76 
     77 TEST(FilesystemUtils, FindLastDirComponent) {
     78   SourceDir empty;
     79   EXPECT_EQ("", FindLastDirComponent(empty));
     80 
     81   SourceDir root("/");
     82   EXPECT_EQ("", FindLastDirComponent(root));
     83 
     84   SourceDir srcroot("//");
     85   EXPECT_EQ("", FindLastDirComponent(srcroot));
     86 
     87   SourceDir regular1("//foo/");
     88   EXPECT_EQ("foo", FindLastDirComponent(regular1));
     89 
     90   SourceDir regular2("//foo/bar/");
     91   EXPECT_EQ("bar", FindLastDirComponent(regular2));
     92 }
     93 
     94 TEST(FilesystemUtils, EnsureStringIsInOutputDir) {
     95   SourceDir output_dir("//out/Debug/");
     96 
     97   // Some outside.
     98   Err err;
     99   EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir, "//foo", NULL, &err));
    100   EXPECT_TRUE(err.has_error());
    101   err = Err();
    102   EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir, "//out/Debugit", NULL,
    103                                          &err));
    104   EXPECT_TRUE(err.has_error());
    105 
    106   // Some inside.
    107   err = Err();
    108   EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir, "//out/Debug/", NULL,
    109                                         &err));
    110   EXPECT_FALSE(err.has_error());
    111   EXPECT_TRUE(EnsureStringIsInOutputDir(output_dir, "//out/Debug/foo", NULL,
    112                                         &err));
    113   EXPECT_FALSE(err.has_error());
    114 
    115   // Pattern but no template expansions are allowed.
    116   EXPECT_FALSE(EnsureStringIsInOutputDir(output_dir, "{{source_gen_dir}}",
    117                                          NULL, &err));
    118   EXPECT_TRUE(err.has_error());
    119 }
    120 
    121 TEST(FilesystemUtils, IsPathAbsolute) {
    122   EXPECT_TRUE(IsPathAbsolute("/foo/bar"));
    123   EXPECT_TRUE(IsPathAbsolute("/"));
    124   EXPECT_FALSE(IsPathAbsolute(""));
    125   EXPECT_FALSE(IsPathAbsolute("//"));
    126   EXPECT_FALSE(IsPathAbsolute("//foo/bar"));
    127 
    128 #if defined(OS_WIN)
    129   EXPECT_TRUE(IsPathAbsolute("C:/foo"));
    130   EXPECT_TRUE(IsPathAbsolute("C:/"));
    131   EXPECT_TRUE(IsPathAbsolute("C:\\foo"));
    132   EXPECT_TRUE(IsPathAbsolute("C:\\"));
    133   EXPECT_TRUE(IsPathAbsolute("/C:/foo"));
    134   EXPECT_TRUE(IsPathAbsolute("/C:\\foo"));
    135 #endif
    136 }
    137 
    138 TEST(FilesystemUtils, MakeAbsolutePathRelativeIfPossible) {
    139   std::string dest;
    140 
    141 #if defined(OS_WIN)
    142   EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\base\\foo",
    143                                                  &dest));
    144   EXPECT_EQ("//foo", dest);
    145   EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("C:\\base", "/C:/base/foo",
    146                                                  &dest));
    147   EXPECT_EQ("//foo", dest);
    148   EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("c:\\base", "C:\\base\\foo\\",
    149                                                  &dest));
    150   EXPECT_EQ("//foo\\", dest);
    151 
    152   EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base", "C:\\ba", &dest));
    153   EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("C:\\base",
    154                                                   "C:\\/notbase/foo",
    155                                                   &dest));
    156 #else
    157 
    158   EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo/", &dest));
    159   EXPECT_EQ("//foo/", dest);
    160   EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base", "/base/foo", &dest));
    161   EXPECT_EQ("//foo", dest);
    162   EXPECT_TRUE(MakeAbsolutePathRelativeIfPossible("/base/", "/base/foo/",
    163                                                  &dest));
    164   EXPECT_EQ("//foo/", dest);
    165 
    166   EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/ba", &dest));
    167   EXPECT_FALSE(MakeAbsolutePathRelativeIfPossible("/base", "/notbase/foo",
    168                                                   &dest));
    169 #endif
    170 }
    171 
    172 TEST(FilesystemUtils, InvertDir) {
    173   EXPECT_TRUE(InvertDir(SourceDir()) == "");
    174   EXPECT_TRUE(InvertDir(SourceDir("/")) == "");
    175   EXPECT_TRUE(InvertDir(SourceDir("//")) == "");
    176 
    177   EXPECT_TRUE(InvertDir(SourceDir("//foo/bar")) == "../../");
    178   EXPECT_TRUE(InvertDir(SourceDir("//foo\\bar")) == "../../");
    179   EXPECT_TRUE(InvertDir(SourceDir("/foo/bar/")) == "../../");
    180 }
    181 
    182 TEST(FilesystemUtils, NormalizePath) {
    183   std::string input;
    184 
    185   NormalizePath(&input);
    186   EXPECT_EQ("", input);
    187 
    188   input = "foo/bar.txt";
    189   NormalizePath(&input);
    190   EXPECT_EQ("foo/bar.txt", input);
    191 
    192   input = ".";
    193   NormalizePath(&input);
    194   EXPECT_EQ("", input);
    195 
    196   input = "..";
    197   NormalizePath(&input);
    198   EXPECT_EQ("..", input);
    199 
    200   input = "foo//bar";
    201   NormalizePath(&input);
    202   EXPECT_EQ("foo/bar", input);
    203 
    204   input = "//foo";
    205   NormalizePath(&input);
    206   EXPECT_EQ("//foo", input);
    207 
    208   input = "foo/..//bar";
    209   NormalizePath(&input);
    210   EXPECT_EQ("bar", input);
    211 
    212   input = "foo/../../bar";
    213   NormalizePath(&input);
    214   EXPECT_EQ("../bar", input);
    215 
    216   input = "/../foo";  // Don't go aboe the root dir.
    217   NormalizePath(&input);
    218   EXPECT_EQ("/foo", input);
    219 
    220   input = "//../foo";  // Don't go above the root dir.
    221   NormalizePath(&input);
    222   EXPECT_EQ("//foo", input);
    223 
    224   input = "../foo";
    225   NormalizePath(&input);
    226   EXPECT_EQ("../foo", input);
    227 
    228   input = "..";
    229   NormalizePath(&input);
    230   EXPECT_EQ("..", input);
    231 
    232   input = "./././.";
    233   NormalizePath(&input);
    234   EXPECT_EQ("", input);
    235 
    236   input = "../../..";
    237   NormalizePath(&input);
    238   EXPECT_EQ("../../..", input);
    239 
    240   input = "../";
    241   NormalizePath(&input);
    242   EXPECT_EQ("../", input);
    243 
    244   // Backslash normalization.
    245   input = "foo\\..\\..\\bar";
    246   NormalizePath(&input);
    247   EXPECT_EQ("../bar", input);
    248 }
    249 
    250 TEST(FilesystemUtils, RebaseSourceAbsolutePath) {
    251   // Degenerate case.
    252   EXPECT_EQ(".", RebaseSourceAbsolutePath("//", SourceDir("//")));
    253   EXPECT_EQ(".",
    254             RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//foo/bar/")));
    255 
    256   // Going up the tree.
    257   EXPECT_EQ("../foo",
    258             RebaseSourceAbsolutePath("//foo", SourceDir("//bar/")));
    259   EXPECT_EQ("../foo/",
    260             RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/")));
    261   EXPECT_EQ("../../foo",
    262             RebaseSourceAbsolutePath("//foo", SourceDir("//bar/moo")));
    263   EXPECT_EQ("../../foo/",
    264             RebaseSourceAbsolutePath("//foo/", SourceDir("//bar/moo")));
    265 
    266   // Going down the tree.
    267   EXPECT_EQ("foo/bar",
    268             RebaseSourceAbsolutePath("//foo/bar", SourceDir("//")));
    269   EXPECT_EQ("foo/bar/",
    270             RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//")));
    271 
    272   // Going up and down the tree.
    273   EXPECT_EQ("../../foo/bar",
    274             RebaseSourceAbsolutePath("//foo/bar", SourceDir("//a/b/")));
    275   EXPECT_EQ("../../foo/bar/",
    276             RebaseSourceAbsolutePath("//foo/bar/", SourceDir("//a/b/")));
    277 
    278   // Sharing prefix.
    279   EXPECT_EQ("foo",
    280             RebaseSourceAbsolutePath("//a/foo", SourceDir("//a/")));
    281   EXPECT_EQ("foo/",
    282             RebaseSourceAbsolutePath("//a/foo/", SourceDir("//a/")));
    283   EXPECT_EQ("foo",
    284             RebaseSourceAbsolutePath("//a/b/foo", SourceDir("//a/b/")));
    285   EXPECT_EQ("foo/",
    286             RebaseSourceAbsolutePath("//a/b/foo/", SourceDir("//a/b/")));
    287   EXPECT_EQ("foo/bar",
    288             RebaseSourceAbsolutePath("//a/b/foo/bar", SourceDir("//a/b/")));
    289   EXPECT_EQ("foo/bar/",
    290             RebaseSourceAbsolutePath("//a/b/foo/bar/", SourceDir("//a/b/")));
    291 
    292   // One could argue about this case. Since the input doesn't have a slash it
    293   // would normally not be treated like a directory and we'd go up, which is
    294   // simpler. However, since it matches the output directory's name, we could
    295   // potentially infer that it's the same and return "." for this.
    296   EXPECT_EQ("../bar",
    297             RebaseSourceAbsolutePath("//foo/bar", SourceDir("//foo/bar/")));
    298 }
    299 
    300 TEST(FilesystemUtils, DirectoryWithNoLastSlash) {
    301   EXPECT_EQ("", DirectoryWithNoLastSlash(SourceDir()));
    302   EXPECT_EQ("/.", DirectoryWithNoLastSlash(SourceDir("/")));
    303   EXPECT_EQ("//.", DirectoryWithNoLastSlash(SourceDir("//")));
    304   EXPECT_EQ("//foo", DirectoryWithNoLastSlash(SourceDir("//foo/")));
    305   EXPECT_EQ("/bar", DirectoryWithNoLastSlash(SourceDir("/bar/")));
    306 }
    307 
    308 TEST(FilesystemUtils, SourceDirForPath) {
    309 #if defined(OS_WIN)
    310   base::FilePath root(L"C:\\source\\foo\\");
    311   EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
    312             base::FilePath(L"C:\\foo\\bar")).value());
    313   EXPECT_EQ("/", SourceDirForPath(root,
    314             base::FilePath(L"/")).value());
    315   EXPECT_EQ("//", SourceDirForPath(root,
    316             base::FilePath(L"C:\\source\\foo")).value());
    317   EXPECT_EQ("//bar/", SourceDirForPath(root,
    318             base::FilePath(L"C:\\source\\foo\\bar\\")). value());
    319   EXPECT_EQ("//bar/baz/", SourceDirForPath(root,
    320             base::FilePath(L"C:\\source\\foo\\bar\\baz")).value());
    321 
    322   // Should be case-and-slash-insensitive.
    323   EXPECT_EQ("//baR/", SourceDirForPath(root,
    324             base::FilePath(L"c:/SOURCE\\Foo/baR/")).value());
    325 
    326   // Some "weird" Windows paths.
    327   EXPECT_EQ("/foo/bar/", SourceDirForPath(root,
    328             base::FilePath(L"/foo/bar/")).value());
    329   EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
    330             base::FilePath(L"C:foo/bar/")).value());
    331 
    332   // Also allow absolute GN-style Windows paths.
    333   EXPECT_EQ("/C:/foo/bar/", SourceDirForPath(root,
    334             base::FilePath(L"/C:/foo/bar")).value());
    335   EXPECT_EQ("//bar/", SourceDirForPath(root,
    336             base::FilePath(L"/C:/source/foo/bar")).value());
    337 
    338 #else
    339   base::FilePath root("/source/foo/");
    340   EXPECT_EQ("/foo/bar/", SourceDirForPath(root,
    341             base::FilePath("/foo/bar/")).value());
    342   EXPECT_EQ("/", SourceDirForPath(root,
    343             base::FilePath("/")).value());
    344   EXPECT_EQ("//", SourceDirForPath(root,
    345             base::FilePath("/source/foo")).value());
    346   EXPECT_EQ("//bar/", SourceDirForPath(root,
    347             base::FilePath("/source/foo/bar/")).value());
    348   EXPECT_EQ("//bar/baz/", SourceDirForPath(root,
    349             base::FilePath("/source/foo/bar/baz/")).value());
    350 
    351   // Should be case-sensitive.
    352   EXPECT_EQ("/SOURCE/foo/bar/", SourceDirForPath(root,
    353             base::FilePath("/SOURCE/foo/bar/")).value());
    354 #endif
    355 }
    356 
    357 TEST(FilesystemUtils, GetToolchainDirs) {
    358   BuildSettings build_settings;
    359   build_settings.SetBuildDir(SourceDir("//out/Debug/"));
    360 
    361   // The default toolchain.
    362   Settings default_settings(&build_settings, "");
    363   Label default_toolchain_label(SourceDir("//toolchain/"), "default");
    364   default_settings.set_toolchain_label(default_toolchain_label);
    365   default_settings.set_default_toolchain_label(default_toolchain_label);
    366 
    367   // Default toolchain out dir.
    368   EXPECT_EQ("//out/Debug/",
    369             GetToolchainOutputDir(&default_settings).value());
    370   EXPECT_EQ("//out/Debug/",
    371             GetToolchainOutputDir(&build_settings, default_toolchain_label,
    372                                   true).value());
    373 
    374   // Default toolchain gen dir.
    375   EXPECT_EQ("//out/Debug/gen/",
    376             GetToolchainGenDir(&default_settings).value());
    377   EXPECT_EQ("gen/",
    378             GetToolchainGenDirAsOutputFile(&default_settings).value());
    379   EXPECT_EQ("//out/Debug/gen/",
    380             GetToolchainGenDir(&build_settings, default_toolchain_label,
    381                                true).value());
    382 
    383   // Check a secondary toolchain.
    384   Settings other_settings(&build_settings, "two/");
    385   Label other_toolchain_label(SourceDir("//toolchain/"), "two");
    386   default_settings.set_toolchain_label(other_toolchain_label);
    387   default_settings.set_default_toolchain_label(default_toolchain_label);
    388 
    389   // Secondary toolchain out dir.
    390   EXPECT_EQ("//out/Debug/two/",
    391             GetToolchainOutputDir(&other_settings).value());
    392   EXPECT_EQ("//out/Debug/two/",
    393             GetToolchainOutputDir(&build_settings, other_toolchain_label,
    394                                   false).value());
    395 
    396   // Secondary toolchain gen dir.
    397   EXPECT_EQ("//out/Debug/two/gen/",
    398             GetToolchainGenDir(&other_settings).value());
    399   EXPECT_EQ("two/gen/",
    400             GetToolchainGenDirAsOutputFile(&other_settings).value());
    401   EXPECT_EQ("//out/Debug/two/gen/",
    402             GetToolchainGenDir(&build_settings, other_toolchain_label,
    403                                false).value());
    404 }
    405 
    406 TEST(FilesystemUtils, GetOutDirForSourceDir) {
    407   BuildSettings build_settings;
    408   build_settings.SetBuildDir(SourceDir("//out/Debug/"));
    409 
    410   // Test the default toolchain.
    411   Settings default_settings(&build_settings, "");
    412   EXPECT_EQ("//out/Debug/obj/",
    413             GetOutputDirForSourceDir(
    414                 &default_settings, SourceDir("//")).value());
    415   EXPECT_EQ("obj/",
    416             GetOutputDirForSourceDirAsOutputFile(
    417                 &default_settings, SourceDir("//")).value());
    418 
    419   EXPECT_EQ("//out/Debug/obj/foo/bar/",
    420             GetOutputDirForSourceDir(
    421                 &default_settings, SourceDir("//foo/bar/")).value());
    422   EXPECT_EQ("obj/foo/bar/",
    423             GetOutputDirForSourceDirAsOutputFile(
    424                 &default_settings, SourceDir("//foo/bar/")).value());
    425 
    426   // Secondary toolchain.
    427   Settings other_settings(&build_settings, "two/");
    428   EXPECT_EQ("//out/Debug/two/obj/",
    429             GetOutputDirForSourceDir(
    430                 &other_settings, SourceDir("//")).value());
    431   EXPECT_EQ("two/obj/",
    432             GetOutputDirForSourceDirAsOutputFile(
    433                 &other_settings, SourceDir("//")).value());
    434 
    435   EXPECT_EQ("//out/Debug/two/obj/foo/bar/",
    436             GetOutputDirForSourceDir(&other_settings,
    437                                      SourceDir("//foo/bar/")).value());
    438   EXPECT_EQ("two/obj/foo/bar/",
    439             GetOutputDirForSourceDirAsOutputFile(
    440                 &other_settings, SourceDir("//foo/bar/")).value());
    441 }
    442 
    443 TEST(FilesystemUtils, GetGenDirForSourceDir) {
    444   BuildSettings build_settings;
    445   build_settings.SetBuildDir(SourceDir("//out/Debug/"));
    446 
    447   // Test the default toolchain.
    448   Settings default_settings(&build_settings, "");
    449   EXPECT_EQ("//out/Debug/gen/",
    450             GetGenDirForSourceDir(
    451                 &default_settings, SourceDir("//")).value());
    452   EXPECT_EQ("gen/",
    453             GetGenDirForSourceDirAsOutputFile(
    454                 &default_settings, SourceDir("//")).value());
    455 
    456   EXPECT_EQ("//out/Debug/gen/foo/bar/",
    457             GetGenDirForSourceDir(
    458                 &default_settings, SourceDir("//foo/bar/")).value());
    459   EXPECT_EQ("gen/foo/bar/",
    460             GetGenDirForSourceDirAsOutputFile(
    461                 &default_settings, SourceDir("//foo/bar/")).value());
    462 
    463   // Secondary toolchain.
    464   Settings other_settings(&build_settings, "two/");
    465   EXPECT_EQ("//out/Debug/two/gen/",
    466             GetGenDirForSourceDir(
    467                 &other_settings, SourceDir("//")).value());
    468   EXPECT_EQ("two/gen/",
    469             GetGenDirForSourceDirAsOutputFile(
    470                 &other_settings, SourceDir("//")).value());
    471 
    472   EXPECT_EQ("//out/Debug/two/gen/foo/bar/",
    473             GetGenDirForSourceDir(
    474                 &other_settings, SourceDir("//foo/bar/")).value());
    475   EXPECT_EQ("two/gen/foo/bar/",
    476             GetGenDirForSourceDirAsOutputFile(
    477                 &other_settings, SourceDir("//foo/bar/")).value());
    478 }
    479 
    480 TEST(FilesystemUtils, GetTargetDirs) {
    481   BuildSettings build_settings;
    482   build_settings.SetBuildDir(SourceDir("//out/Debug/"));
    483   Settings settings(&build_settings, "");
    484 
    485   Target a(&settings, Label(SourceDir("//foo/bar/"), "baz"));
    486   EXPECT_EQ("//out/Debug/obj/foo/bar/", GetTargetOutputDir(&a).value());
    487   EXPECT_EQ("obj/foo/bar/", GetTargetOutputDirAsOutputFile(&a).value());
    488   EXPECT_EQ("//out/Debug/gen/foo/bar/", GetTargetGenDir(&a).value());
    489   EXPECT_EQ("gen/foo/bar/", GetTargetGenDirAsOutputFile(&a).value());
    490 }
    491 
    492 // Tests handling of output dirs when build dir is the same as the root.
    493 TEST(FilesystemUtils, GetDirForEmptyBuildDir) {
    494   BuildSettings build_settings;
    495   build_settings.SetBuildDir(SourceDir("//"));
    496   Settings settings(&build_settings, "");
    497 
    498   EXPECT_EQ("//", GetToolchainOutputDir(&settings).value());
    499   EXPECT_EQ("//gen/", GetToolchainGenDir(&settings).value());
    500   EXPECT_EQ("gen/", GetToolchainGenDirAsOutputFile(&settings).value());
    501   EXPECT_EQ("//obj/",
    502             GetOutputDirForSourceDir(&settings, SourceDir("//")).value());
    503   EXPECT_EQ("obj/",
    504             GetOutputDirForSourceDirAsOutputFile(
    505                 &settings, SourceDir("//")).value());
    506   EXPECT_EQ("gen/",
    507             GetGenDirForSourceDirAsOutputFile(
    508                 &settings, SourceDir("//")).value());
    509 }
    510