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 <sstream> 6 7#include "testing/gtest/include/gtest/gtest.h" 8#include "tools/gn/output_file.h" 9#include "tools/gn/path_output.h" 10#include "tools/gn/source_dir.h" 11#include "tools/gn/source_file.h" 12 13TEST(PathOutput, Basic) { 14 SourceDir build_dir("//out/Debug/"); 15 PathOutput writer(build_dir, ESCAPE_NONE); 16 { 17 // Normal source-root path. 18 std::ostringstream out; 19 writer.WriteFile(out, SourceFile("//foo/bar.cc")); 20 EXPECT_EQ("../../foo/bar.cc", out.str()); 21 } 22 { 23 // File in the root dir. 24 std::ostringstream out; 25 writer.WriteFile(out, SourceFile("//foo.cc")); 26 EXPECT_EQ("../../foo.cc", out.str()); 27 } 28 { 29 // Files in the output dir. 30 std::ostringstream out; 31 writer.WriteFile(out, SourceFile("//out/Debug/foo.cc")); 32 out << " "; 33 writer.WriteFile(out, SourceFile("//out/Debug/bar/baz.cc")); 34 EXPECT_EQ("foo.cc bar/baz.cc", out.str()); 35 } 36#if defined(OS_WIN) 37 { 38 // System-absolute path. 39 std::ostringstream out; 40 writer.WriteFile(out, SourceFile("/C:/foo/bar.cc")); 41 EXPECT_EQ("C:/foo/bar.cc", out.str()); 42 } 43#else 44 { 45 // System-absolute path. 46 std::ostringstream out; 47 writer.WriteFile(out, SourceFile("/foo/bar.cc")); 48 EXPECT_EQ("/foo/bar.cc", out.str()); 49 } 50#endif 51} 52 53// Same as basic but the output dir is the root. 54TEST(PathOutput, BasicInRoot) { 55 SourceDir build_dir("//"); 56 PathOutput writer(build_dir, ESCAPE_NONE); 57 { 58 // Normal source-root path. 59 std::ostringstream out; 60 writer.WriteFile(out, SourceFile("//foo/bar.cc")); 61 EXPECT_EQ("foo/bar.cc", out.str()); 62 } 63 { 64 // File in the root dir. 65 std::ostringstream out; 66 writer.WriteFile(out, SourceFile("//foo.cc")); 67 EXPECT_EQ("foo.cc", out.str()); 68 } 69} 70 71TEST(PathOutput, NinjaEscaping) { 72 SourceDir build_dir("//out/Debug/"); 73 PathOutput writer(build_dir, ESCAPE_NINJA); 74 { 75 // Spaces and $ in filenames. 76 std::ostringstream out; 77 writer.WriteFile(out, SourceFile("//foo/foo bar$.cc")); 78 EXPECT_EQ("../../foo/foo$ bar$$.cc", out.str()); 79 } 80 { 81 // Not other weird stuff 82 std::ostringstream out; 83 writer.WriteFile(out, SourceFile("//foo/\"foo\\bar\".cc")); 84 EXPECT_EQ("../../foo/\"foo\\bar\".cc", out.str()); 85 } 86} 87 88TEST(PathOutput, NinjaForkEscaping) { 89 SourceDir build_dir("//out/Debug/"); 90 PathOutput writer(build_dir, ESCAPE_NINJA_COMMAND); 91 92 // Spaces in filenames should get quoted on Windows. 93 writer.set_escape_platform(ESCAPE_PLATFORM_WIN); 94 { 95 std::ostringstream out; 96 writer.WriteFile(out, SourceFile("//foo/foo bar.cc")); 97 EXPECT_EQ("\"../../foo/foo$ bar.cc\"", out.str()); 98 } 99 100 // Spaces in filenames should get escaped on Posix. 101 writer.set_escape_platform(ESCAPE_PLATFORM_POSIX); 102 { 103 std::ostringstream out; 104 writer.WriteFile(out, SourceFile("//foo/foo bar.cc")); 105 EXPECT_EQ("../../foo/foo\\$ bar.cc", out.str()); 106 } 107 108 // Quotes should get blackslash-escaped on Windows and Posix. 109 writer.set_escape_platform(ESCAPE_PLATFORM_WIN); 110 { 111 std::ostringstream out; 112 writer.WriteFile(out, SourceFile("//foo/\"foobar\".cc")); 113 // Our Windows code currently quotes the whole thing in this case for 114 // code simplicity, even though it's strictly unnecessary. This might 115 // change in the future. 116 EXPECT_EQ("\"../../foo/\\\"foobar\\\".cc\"", out.str()); 117 } 118 writer.set_escape_platform(ESCAPE_PLATFORM_POSIX); 119 { 120 std::ostringstream out; 121 writer.WriteFile(out, SourceFile("//foo/\"foobar\".cc")); 122 EXPECT_EQ("../../foo/\\\"foobar\\\".cc", out.str()); 123 } 124 125 126 // Backslashes should get escaped on non-Windows and preserved on Windows. 127 writer.set_escape_platform(ESCAPE_PLATFORM_WIN); 128 { 129 std::ostringstream out; 130 writer.WriteFile(out, SourceFile("//foo\\bar.cc")); 131 EXPECT_EQ("../../foo\\bar.cc", out.str()); 132 } 133 writer.set_escape_platform(ESCAPE_PLATFORM_POSIX); 134 { 135 std::ostringstream out; 136 writer.WriteFile(out, SourceFile("//foo\\bar.cc")); 137 EXPECT_EQ("../../foo\\\\bar.cc", out.str()); 138 } 139} 140 141TEST(PathOutput, InhibitQuoting) { 142 SourceDir build_dir("//out/Debug/"); 143 PathOutput writer(build_dir, ESCAPE_NINJA_COMMAND); 144 writer.set_inhibit_quoting(true); 145 146 writer.set_escape_platform(ESCAPE_PLATFORM_WIN); 147 { 148 // We should get unescaped spaces in the output with no quotes. 149 std::ostringstream out; 150 writer.WriteFile(out, SourceFile("//foo/foo bar.cc")); 151 EXPECT_EQ("../../foo/foo$ bar.cc", out.str()); 152 } 153 154 writer.set_escape_platform(ESCAPE_PLATFORM_POSIX); 155 { 156 // Escapes the space. 157 std::ostringstream out; 158 writer.WriteFile(out, SourceFile("//foo/foo bar.cc")); 159 EXPECT_EQ("../../foo/foo\\$ bar.cc", out.str()); 160 } 161} 162 163TEST(PathOutput, WriteDir) { 164 { 165 SourceDir build_dir("//out/Debug/"); 166 PathOutput writer(build_dir, ESCAPE_NINJA); 167 { 168 std::ostringstream out; 169 writer.WriteDir(out, SourceDir("//foo/bar/"), 170 PathOutput::DIR_INCLUDE_LAST_SLASH); 171 EXPECT_EQ("../../foo/bar/", out.str()); 172 } 173 { 174 std::ostringstream out; 175 writer.WriteDir(out, SourceDir("//foo/bar/"), 176 PathOutput::DIR_NO_LAST_SLASH); 177 EXPECT_EQ("../../foo/bar", out.str()); 178 } 179 180 // Output source root dir. 181 { 182 std::ostringstream out; 183 writer.WriteDir(out, SourceDir("//"), 184 PathOutput::DIR_INCLUDE_LAST_SLASH); 185 EXPECT_EQ("../../", out.str()); 186 } 187 { 188 std::ostringstream out; 189 writer.WriteDir(out, SourceDir("//"), 190 PathOutput::DIR_NO_LAST_SLASH); 191 EXPECT_EQ("../..", out.str()); 192 } 193 194 // Output system root dir. 195 { 196 std::ostringstream out; 197 writer.WriteDir(out, SourceDir("/"), 198 PathOutput::DIR_INCLUDE_LAST_SLASH); 199 EXPECT_EQ("/", out.str()); 200 } 201 { 202 std::ostringstream out; 203 writer.WriteDir(out, SourceDir("/"), 204 PathOutput::DIR_INCLUDE_LAST_SLASH); 205 EXPECT_EQ("/", out.str()); 206 } 207 { 208 std::ostringstream out; 209 writer.WriteDir(out, SourceDir("/"), 210 PathOutput::DIR_NO_LAST_SLASH); 211 EXPECT_EQ("/.", out.str()); 212 } 213 214 // Output inside current dir. 215 { 216 std::ostringstream out; 217 writer.WriteDir(out, SourceDir("//out/Debug/"), 218 PathOutput::DIR_INCLUDE_LAST_SLASH); 219 EXPECT_EQ("./", out.str()); 220 } 221 { 222 std::ostringstream out; 223 writer.WriteDir(out, SourceDir("//out/Debug/"), 224 PathOutput::DIR_NO_LAST_SLASH); 225 EXPECT_EQ(".", out.str()); 226 } 227 { 228 std::ostringstream out; 229 writer.WriteDir(out, SourceDir("//out/Debug/foo/"), 230 PathOutput::DIR_INCLUDE_LAST_SLASH); 231 EXPECT_EQ("foo/", out.str()); 232 } 233 { 234 std::ostringstream out; 235 writer.WriteDir(out, SourceDir("//out/Debug/foo/"), 236 PathOutput::DIR_NO_LAST_SLASH); 237 EXPECT_EQ("foo", out.str()); 238 } 239 240 // WriteDir using an OutputFile. 241 { 242 std::ostringstream out; 243 writer.WriteDir(out, OutputFile("foo/"), 244 PathOutput::DIR_INCLUDE_LAST_SLASH); 245 EXPECT_EQ("foo/", out.str()); 246 } 247 { 248 std::ostringstream out; 249 writer.WriteDir(out, OutputFile("foo/"), 250 PathOutput::DIR_NO_LAST_SLASH); 251 EXPECT_EQ("foo", out.str()); 252 } 253 { 254 std::ostringstream out; 255 writer.WriteDir(out, OutputFile(), 256 PathOutput::DIR_INCLUDE_LAST_SLASH); 257 EXPECT_EQ("", out.str()); 258 } 259 } 260 { 261 // Empty build dir writer. 262 PathOutput root_writer(SourceDir("//"), ESCAPE_NINJA); 263 { 264 std::ostringstream out; 265 root_writer.WriteDir(out, SourceDir("//"), 266 PathOutput::DIR_INCLUDE_LAST_SLASH); 267 EXPECT_EQ("./", out.str()); 268 } 269 { 270 std::ostringstream out; 271 root_writer.WriteDir(out, SourceDir("//"), 272 PathOutput::DIR_NO_LAST_SLASH); 273 EXPECT_EQ(".", out.str()); 274 } 275 } 276} 277