DCHECK if shader compilation fails that it's due to context loss.
[chromium-blink-merge.git] / tools / gn / substitution_writer_unittest.cc
blobf5dcb78ff0f256e10083e410b968193327b89cb2
1 // Copyright 2014 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.
5 #include <sstream>
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "tools/gn/err.h"
9 #include "tools/gn/escape.h"
10 #include "tools/gn/substitution_list.h"
11 #include "tools/gn/substitution_pattern.h"
12 #include "tools/gn/substitution_writer.h"
13 #include "tools/gn/target.h"
14 #include "tools/gn/test_with_scope.h"
16 TEST(SubstitutionWriter, GetListAs) {
17 TestWithScope setup;
19 SubstitutionList list = SubstitutionList::MakeForTest(
20 "//foo/bar/a.cc",
21 "//foo/bar/b.cc");
23 std::vector<SourceFile> sources;
24 SubstitutionWriter::GetListAsSourceFiles(list, &sources);
25 ASSERT_EQ(2u, sources.size());
26 EXPECT_EQ("//foo/bar/a.cc", sources[0].value());
27 EXPECT_EQ("//foo/bar/b.cc", sources[1].value());
29 std::vector<OutputFile> outputs;
30 SubstitutionWriter::GetListAsOutputFiles(setup.settings(), list, &outputs);
31 ASSERT_EQ(2u, outputs.size());
32 EXPECT_EQ("../../foo/bar/a.cc", outputs[0].value());
33 EXPECT_EQ("../../foo/bar/b.cc", outputs[1].value());
36 TEST(SubstitutionWriter, ApplyPatternToSource) {
37 TestWithScope setup;
39 SubstitutionPattern pattern;
40 Err err;
41 ASSERT_TRUE(pattern.Parse("{{source_gen_dir}}/{{source_name_part}}.tmp",
42 nullptr, &err));
44 SourceFile result = SubstitutionWriter::ApplyPatternToSource(
45 setup.settings(), pattern, SourceFile("//foo/bar/myfile.txt"));
46 ASSERT_EQ("//out/Debug/gen/foo/bar/myfile.tmp", result.value());
49 TEST(SubstitutionWriter, ApplyPatternToSourceAsOutputFile) {
50 TestWithScope setup;
52 SubstitutionPattern pattern;
53 Err err;
54 ASSERT_TRUE(pattern.Parse("{{source_gen_dir}}/{{source_name_part}}.tmp",
55 nullptr, &err));
57 OutputFile result = SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
58 setup.settings(), pattern, SourceFile("//foo/bar/myfile.txt"));
59 ASSERT_EQ("gen/foo/bar/myfile.tmp", result.value());
62 TEST(SubstitutionWriter, WriteNinjaVariablesForSource) {
63 TestWithScope setup;
65 std::vector<SubstitutionType> types;
66 types.push_back(SUBSTITUTION_SOURCE);
67 types.push_back(SUBSTITUTION_SOURCE_NAME_PART);
68 types.push_back(SUBSTITUTION_SOURCE_DIR);
70 EscapeOptions options;
71 options.mode = ESCAPE_NONE;
73 std::ostringstream out;
74 SubstitutionWriter::WriteNinjaVariablesForSource(
75 setup.settings(), SourceFile("//foo/bar/baz.txt"), types, options, out);
77 // The "source" should be skipped since that will expand to $in which is
78 // implicit.
79 EXPECT_EQ(
80 " source_name_part = baz\n"
81 " source_dir = ../../foo/bar\n",
82 out.str());
85 TEST(SubstitutionWriter, WriteWithNinjaVariables) {
86 Err err;
87 SubstitutionPattern pattern;
88 ASSERT_TRUE(pattern.Parse("-i {{source}} --out=bar\"{{source_name_part}}\".o",
89 nullptr, &err));
90 EXPECT_FALSE(err.has_error());
92 EscapeOptions options;
93 options.mode = ESCAPE_NONE;
95 std::ostringstream out;
96 SubstitutionWriter::WriteWithNinjaVariables(pattern, options, out);
98 EXPECT_EQ(
99 "-i ${in} --out=bar\"${source_name_part}\".o",
100 out.str());
103 TEST(SubstitutionWriter, SourceSubstitutions) {
104 TestWithScope setup;
106 // Call to get substitutions relative to the build dir.
107 #define GetRelSubst(str, what) \
108 SubstitutionWriter::GetSourceSubstitution( \
109 setup.settings(), \
110 SourceFile(str), \
111 what, \
112 SubstitutionWriter::OUTPUT_RELATIVE, \
113 setup.settings()->build_settings()->build_dir())
115 // Call to get absolute directory substitutions.
116 #define GetAbsSubst(str, what) \
117 SubstitutionWriter::GetSourceSubstitution( \
118 setup.settings(), \
119 SourceFile(str), \
120 what, \
121 SubstitutionWriter::OUTPUT_ABSOLUTE, \
122 SourceDir())
124 // Try all possible templates with a normal looking string.
125 EXPECT_EQ("../../foo/bar/baz.txt",
126 GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE));
127 EXPECT_EQ("//foo/bar/baz.txt",
128 GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE));
130 EXPECT_EQ("baz",
131 GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_NAME_PART));
132 EXPECT_EQ("baz",
133 GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_NAME_PART));
135 EXPECT_EQ("baz.txt",
136 GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_FILE_PART));
137 EXPECT_EQ("baz.txt",
138 GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_FILE_PART));
140 EXPECT_EQ("../../foo/bar",
141 GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_DIR));
142 EXPECT_EQ("//foo/bar",
143 GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_DIR));
145 EXPECT_EQ("foo/bar", GetRelSubst("//foo/bar/baz.txt",
146 SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR));
147 EXPECT_EQ("foo/bar", GetAbsSubst("//foo/bar/baz.txt",
148 SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR));
150 EXPECT_EQ("gen/foo/bar",
151 GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_GEN_DIR));
152 EXPECT_EQ("//out/Debug/gen/foo/bar",
153 GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_GEN_DIR));
155 EXPECT_EQ("obj/foo/bar",
156 GetRelSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_OUT_DIR));
157 EXPECT_EQ("//out/Debug/obj/foo/bar",
158 GetAbsSubst("//foo/bar/baz.txt", SUBSTITUTION_SOURCE_OUT_DIR));
160 // Operations on an absolute path.
161 EXPECT_EQ("/baz.txt", GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE));
162 EXPECT_EQ("/.", GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_DIR));
163 EXPECT_EQ("gen", GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_GEN_DIR));
164 EXPECT_EQ("obj/ABS_PATH",
165 GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_OUT_DIR));
166 #if defined(OS_WIN)
167 EXPECT_EQ("obj/ABS_PATH/C",
168 GetRelSubst("/C:/baz.txt", SUBSTITUTION_SOURCE_OUT_DIR));
169 #endif
171 EXPECT_EQ(".",
172 GetRelSubst("//baz.txt", SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR));
174 #undef GetAbsSubst
175 #undef GetRelSubst
178 TEST(SubstitutionWriter, TargetSubstitutions) {
179 TestWithScope setup;
180 Err err;
182 Target target(setup.settings(), Label(SourceDir("//foo/bar/"), "baz"));
183 target.set_output_type(Target::STATIC_LIBRARY);
184 target.SetToolchain(setup.toolchain());
185 ASSERT_TRUE(target.OnResolved(&err));
187 std::string result;
188 EXPECT_TRUE(SubstitutionWriter::GetTargetSubstitution(
189 &target, SUBSTITUTION_LABEL, &result));
190 EXPECT_EQ("//foo/bar:baz", result);
192 EXPECT_TRUE(SubstitutionWriter::GetTargetSubstitution(
193 &target, SUBSTITUTION_ROOT_GEN_DIR, &result));
194 EXPECT_EQ("gen", result);
196 EXPECT_TRUE(SubstitutionWriter::GetTargetSubstitution(
197 &target, SUBSTITUTION_ROOT_OUT_DIR, &result));
198 EXPECT_EQ(".", result);
200 EXPECT_TRUE(SubstitutionWriter::GetTargetSubstitution(
201 &target, SUBSTITUTION_TARGET_GEN_DIR, &result));
202 EXPECT_EQ("gen/foo/bar", result);
204 EXPECT_TRUE(SubstitutionWriter::GetTargetSubstitution(
205 &target, SUBSTITUTION_TARGET_OUT_DIR, &result));
206 EXPECT_EQ("obj/foo/bar", result);
208 EXPECT_TRUE(SubstitutionWriter::GetTargetSubstitution(
209 &target, SUBSTITUTION_TARGET_OUTPUT_NAME, &result));
210 EXPECT_EQ("libbaz", result);
213 TEST(SubstitutionWriter, CompilerSubstitutions) {
214 TestWithScope setup;
215 Err err;
217 Target target(setup.settings(), Label(SourceDir("//foo/bar/"), "baz"));
218 target.set_output_type(Target::STATIC_LIBRARY);
219 target.SetToolchain(setup.toolchain());
220 ASSERT_TRUE(target.OnResolved(&err));
222 // The compiler substitution is just source + target combined. So test one
223 // of each of those classes of things to make sure this is hooked up.
224 EXPECT_EQ("file",
225 SubstitutionWriter::GetCompilerSubstitution(
226 &target, SourceFile("//foo/bar/file.txt"),
227 SUBSTITUTION_SOURCE_NAME_PART));
228 EXPECT_EQ("gen/foo/bar",
229 SubstitutionWriter::GetCompilerSubstitution(
230 &target, SourceFile("//foo/bar/file.txt"),
231 SUBSTITUTION_TARGET_GEN_DIR));
234 TEST(SubstitutionWriter, LinkerSubstitutions) {
235 TestWithScope setup;
236 Err err;
238 Target target(setup.settings(), Label(SourceDir("//foo/bar/"), "baz"));
239 target.set_output_type(Target::SHARED_LIBRARY);
240 target.SetToolchain(setup.toolchain());
241 ASSERT_TRUE(target.OnResolved(&err));
243 const Tool* tool = setup.toolchain()->GetToolForTargetFinalOutput(&target);
245 // The compiler substitution is just target + OUTPUT_EXTENSION combined. So
246 // test one target one plus the output extension.
247 EXPECT_EQ(".so",
248 SubstitutionWriter::GetLinkerSubstitution(
249 &target, tool, SUBSTITUTION_OUTPUT_EXTENSION));
250 EXPECT_EQ("gen/foo/bar",
251 SubstitutionWriter::GetLinkerSubstitution(
252 &target, tool, SUBSTITUTION_TARGET_GEN_DIR));
254 // Test that we handle paths that end up in the root build dir properly
255 // (no leading "./" or "/").
256 SubstitutionPattern pattern;
257 ASSERT_TRUE(pattern.Parse("{{root_out_dir}}/{{target_output_name}}.so",
258 nullptr, &err));
260 OutputFile output = SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
261 &target, tool, pattern);
262 EXPECT_EQ("./libbaz.so", output.value());