blob: b0a3a2391ba2085da4a73971b2a33aafa80e8877 [file] [log] [blame]
Googler5da0dd52017-05-01 19:00:58 +02001// Copyright 2015 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.packages;
15
16import static com.google.common.truth.Truth.assertThat;
Googler5da0dd52017-05-01 19:00:58 +020017
tomlua155b532017-11-08 20:12:47 +010018import com.google.common.base.Preconditions;
Googler5da0dd52017-05-01 19:00:58 +020019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableMap;
21import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.AttributeValueGetter;
22import com.google.devtools.build.lib.testutil.Suite;
23import com.google.devtools.build.lib.testutil.TestSpec;
Googler5da0dd52017-05-01 19:00:58 +020024import java.util.ArrayList;
25import java.util.Arrays;
26import java.util.Collection;
27import java.util.LinkedHashSet;
28import java.util.List;
29import java.util.Map;
30import java.util.Set;
lberkiaea56b32017-05-30 12:35:33 +020031import org.junit.Test;
32import org.junit.runner.RunWith;
33import org.junit.runners.JUnit4;
Googler5da0dd52017-05-01 19:00:58 +020034
35/**
36 * Tests for {@link ImplicitOutputsFunction}.
37 */
38@TestSpec(size = Suite.SMALL_TESTS)
39@RunWith(JUnit4.class)
40public final class ImplicitOutputsFunctionTest {
41 private void assertPlaceholderCollection(
42 String template, String expectedTemplate, String... expectedPlaceholders) throws Exception {
43 List<String> actualPlaceholders = new ArrayList<>();
lberkiaea56b32017-05-30 12:35:33 +020044 assertThat(
45 ImplicitOutputsFunction.createPlaceholderSubstitutionFormatString(
46 template, actualPlaceholders))
47 .isEqualTo(expectedTemplate);
Googler5da0dd52017-05-01 19:00:58 +020048 assertThat(actualPlaceholders)
49 .containsExactlyElementsIn(Arrays.asList(expectedPlaceholders))
50 .inOrder();
51 }
52
53 @Test
54 public void testNoPlaceholder() throws Exception {
55 assertPlaceholderCollection("foo", "foo");
56 }
57
58 @Test
59 public void testJustPlaceholder() throws Exception {
60 assertPlaceholderCollection("%{foo}", "%s", "foo");
61 }
62
63 @Test
64 public void testPrefixedPlaceholder() throws Exception {
65 assertPlaceholderCollection("foo%{bar}", "foo%s", "bar");
66 }
67
68 @Test
69 public void testSuffixedPlaceholder() throws Exception {
70 assertPlaceholderCollection("%{foo}bar", "%sbar", "foo");
71 }
72
73 @Test
74 public void testMultiplePlaceholdersPrefixed() throws Exception {
75 assertPlaceholderCollection("foo%{bar}baz%{qux}", "foo%sbaz%s", "bar", "qux");
76 }
77
78 @Test
79 public void testMultiplePlaceholdersSuffixed() throws Exception {
80 assertPlaceholderCollection("%{foo}bar%{baz}qux", "%sbar%squx", "foo", "baz");
81 }
82
83 @Test
84 public void testTightlyPackedPlaceholders() throws Exception {
85 assertPlaceholderCollection("%{foo}%{bar}%{baz}", "%s%s%s", "foo", "bar", "baz");
86 }
87
88 @Test
89 public void testIncompletePlaceholder() throws Exception {
Han-Wen Nienhuys3428dc92015-10-21 15:03:34 +000090 assertPlaceholderCollection("%{foo", "%%{foo");
91 }
92
93 @Test
94 public void testCompleteAndIncompletePlaceholder() throws Exception {
95 assertPlaceholderCollection("%{foo}%{bar", "%s%%{bar", "foo");
96 }
97
98 @Test
99 public void testPlaceholderLooksLikeNestedIncompletePlaceholder() throws Exception {
100 assertPlaceholderCollection("%{%{foo", "%%{%%{foo");
101 }
102
103 @Test
104 public void testPlaceholderLooksLikeNestedPlaceholder() throws Exception {
105 assertPlaceholderCollection("%{%{foo}", "%s", "%{foo");
106 }
107
108 @Test
109 public void testEscapesJustPercentSign() throws Exception {
110 assertPlaceholderCollection("%", "%%");
111 }
112
113 @Test
114 public void testEscapesPrintfPlaceholder() throws Exception {
115 assertPlaceholderCollection("%{x}%s%{y}", "%s%%s%s", "x", "y");
116 }
117
118 @Test
119 public void testEscapesPercentSign() throws Exception {
120 assertPlaceholderCollection("foo%{bar}%baz", "foo%s%%baz", "bar");
121 }
122
123 private static AttributeValueGetter attrs(
124 final Map<String, ? extends Collection<String>> values) {
125 return new AttributeValueGetter() {
126 @Override
127 public Set<String> get(AttributeMap ignored, String attr) {
128 return new LinkedHashSet<>(Preconditions.checkNotNull(values.get(attr)));
129 }
130 };
131 }
132
133 private void assertPlaceholderSubtitution(
134 String template,
135 AttributeValueGetter attrValues,
136 String[] expectedSubstitutions,
137 String[] expectedFoundPlaceholders)
138 throws Exception {
jcater17cb02d2017-11-16 10:09:13 -0800139 // Directly call into ParsedTemplate in order to access the attribute names.
140 ImplicitOutputsFunction.ParsedTemplate parsedTemplate =
141 ImplicitOutputsFunction.ParsedTemplate.parse(template);
142
143 assertThat(parsedTemplate.attributeNames())
Han-Wen Nienhuys3428dc92015-10-21 15:03:34 +0000144 .containsExactlyElementsIn(Arrays.asList(expectedFoundPlaceholders))
145 .inOrder();
jcater17cb02d2017-11-16 10:09:13 -0800146
147 // Test the actual substitution code.
148 List<String> substitutions =
149 ImplicitOutputsFunction.substitutePlaceholderIntoTemplate(template, null, attrValues);
lberkiaea56b32017-05-30 12:35:33 +0200150 assertThat(substitutions)
151 .containsExactlyElementsIn(Arrays.asList(expectedSubstitutions));
Han-Wen Nienhuys3428dc92015-10-21 15:03:34 +0000152 }
153
154 @Test
155 public void testSingleScalarElementSubstitution() throws Exception {
156 assertPlaceholderSubtitution(
157 "%{x}",
158 attrs(ImmutableMap.of("x", ImmutableList.of("a"))),
159 new String[] {"a"},
160 new String[] {"x"});
161 }
162
163 @Test
164 public void testSingleVectorElementSubstitution() throws Exception {
165 assertPlaceholderSubtitution(
166 "%{x}",
167 attrs(ImmutableMap.of("x", ImmutableList.of("a", "b", "c"))),
168 new String[] {"a", "b", "c"},
169 new String[] {"x"});
170 }
171
172 @Test
173 public void testMultipleElementsSubstitution() throws Exception {
174 assertPlaceholderSubtitution(
175 "%{x}-%{y}-%{z}",
176 attrs(
177 ImmutableMap.of(
178 "x", ImmutableList.of("foo", "bar", "baz"),
179 "y", ImmutableList.of("meow"),
180 "z", ImmutableList.of("1", "2"))),
181 new String[] {
182 "foo-meow-1", "foo-meow-2", "bar-meow-1", "bar-meow-2", "baz-meow-1", "baz-meow-2"
183 },
184 new String[] {"x", "y", "z"});
185 }
186
187 @Test
188 public void testEmptyElementSubstitution() throws Exception {
189 assertPlaceholderSubtitution(
190 "a-%{x}",
191 attrs(ImmutableMap.of("x", ImmutableList.<String>of())),
192 new String[0],
193 new String[] {"x"});
194 }
195
196 @Test
197 public void testSamePlaceholderMultipleTimes() throws Exception {
198 assertPlaceholderSubtitution(
199 "%{x}-%{y}-%{x}",
200 attrs(ImmutableMap.of("x", ImmutableList.of("a", "b"), "y", ImmutableList.of("1", "2"))),
201 new String[] {"a-1-a", "a-1-b", "a-2-a", "a-2-b", "b-1-a", "b-1-b", "b-2-a", "b-2-b"},
202 new String[] {"x", "y", "x"});
203 }
204
205 @Test
206 public void testRepeatingPlaceholderValue() throws Exception {
207 assertPlaceholderSubtitution(
208 "%{x}",
209 attrs(ImmutableMap.of("x", ImmutableList.of("a", "a"))),
210 new String[] {"a"},
211 new String[] {"x"});
212 }
213
214 @Test
215 public void testIncompletePlaceholderTreatedAsText() throws Exception {
216 assertPlaceholderSubtitution(
217 "%{x}-%{y-%{z",
218 attrs(ImmutableMap.of("x", ImmutableList.of("a", "b"))),
219 new String[] {"a-%{y-%{z", "b-%{y-%{z"},
220 new String[] {"x"});
221 }
222}