blob: e085738bfb3ee7c8c525759d2a3bee41846a3a98 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2015 The Bazel Authors. All rights reserved.
Ulf Adams89f012d2015-02-26 13:39:28 +00002//
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.syntax;
15
Ulf Adams795895a2015-03-06 15:58:35 +000016import static com.google.common.truth.Truth.assertThat;
dslomov2317ef82017-09-28 11:19:54 -040017import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000018
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +000019import com.google.common.collect.ImmutableList;
Ulf Adams89f012d2015-02-26 13:39:28 +000020import com.google.devtools.build.lib.collect.nestedset.Order;
Jon Brandveinb3d0bdd2017-01-13 17:46:29 +000021import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
Francois-Rene Rideau4e994102015-09-17 22:41:28 +000022import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
Han-Wen Nienhuysceae8c52015-09-22 16:24:45 +000023import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +000024import java.util.Arrays;
25import java.util.HashMap;
26import java.util.List;
27import java.util.Map;
Dmitry Lomovcdb6ef52016-08-05 08:38:26 +000028import org.junit.Test;
29import org.junit.runner.RunWith;
30import org.junit.runners.JUnit4;
Florian Weikertb914f3c2015-07-29 13:35:19 +000031
Ulf Adams89f012d2015-02-26 13:39:28 +000032/**
33 * Tests for SkylarkNestedSet.
34 */
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000035@RunWith(JUnit4.class)
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000036public class SkylarkNestedSetTest extends EvaluationTestCase {
Ulf Adams89f012d2015-02-26 13:39:28 +000037
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000038 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +000039 public void testConstructor() throws Exception {
Jon Brandvein052f9ce2017-01-19 21:50:34 +000040 eval("s = depset(order='default')");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +000041 assertThat(lookup("s")).isInstanceOf(SkylarkNestedSet.class);
Ulf Adams89f012d2015-02-26 13:39:28 +000042 }
43
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000044 @Test
cparsonsa5b764f2018-12-06 15:07:58 -080045 public void testTuplePairs() throws Exception {
46 eval(
47 // Depsets with tuple-pairs
48 "s_one = depset([('1', '2'), ('3', '4')])",
49 "s_two = depset(direct = [('1', '2'), ('3', '4'), ('5', '6')])",
50 "s_three = depset(transitive = [s_one, s_two])",
51 "s_four = depset(direct = [('1', '3')], transitive = [s_one, s_two])",
52 // Depsets with tuple-pairs and non-pair tuples are considered just tuple depsets.
cparsonse210bec2019-01-03 14:33:38 -080053 "s_five = depset(direct = [('1', '3', '5')], transitive = [s_one, s_two])",
cparsonsa5b764f2018-12-06 15:07:58 -080054 "s_six = depset(transitive = [s_one, s_five])",
55 "s_seven = depset(direct = [('1', '3')], transitive = [s_one, s_five])",
56 "s_eight = depset(direct = [(1, 3)], transitive = [s_one, s_two])");
57 assertThat(get("s_one").getContentType()).isEqualTo(SkylarkType.STRING_PAIR);
58 assertThat(get("s_two").getContentType()).isEqualTo(SkylarkType.STRING_PAIR);
59 assertThat(get("s_three").getContentType()).isEqualTo(SkylarkType.STRING_PAIR);
60 assertThat(get("s_four").getContentType()).isEqualTo(SkylarkType.STRING_PAIR);
61
62 assertThat(get("s_five").getContentType()).isEqualTo(SkylarkType.TUPLE);
63 assertThat(get("s_six").getContentType()).isEqualTo(SkylarkType.TUPLE);
64 assertThat(get("s_seven").getContentType()).isEqualTo(SkylarkType.TUPLE);
65 assertThat(get("s_eight").getContentType()).isEqualTo(SkylarkType.TUPLE);
cparsonse210bec2019-01-03 14:33:38 -080066
67 assertThat(get("s_four").getSet(Tuple.class))
68 .containsExactly(
69 Tuple.of("1", "3"), Tuple.of("1", "2"), Tuple.of("3", "4"), Tuple.of("5", "6"));
70 assertThat(get("s_five").getSet(Tuple.class))
71 .containsExactly(
72 Tuple.of("1", "3", "5"), Tuple.of("1", "2"), Tuple.of("3", "4"), Tuple.of("5", "6"));
73 assertThat(get("s_eight").getSet(Tuple.class))
74 .containsExactly(
75 Tuple.of(1, 3), Tuple.of("1", "2"), Tuple.of("3", "4"), Tuple.of("5", "6"));
cparsonsa5b764f2018-12-06 15:07:58 -080076 }
77
78 @Test
Jon Brandveinb3d0bdd2017-01-13 17:46:29 +000079 public void testGetSet() throws Exception {
80 eval("s = depset(['a', 'b'])");
81 assertThat(get("s").getSet(String.class)).containsExactly("a", "b").inOrder();
82 assertThat(get("s").getSet(Object.class)).containsExactly("a", "b").inOrder();
dslomov2317ef82017-09-28 11:19:54 -040083 assertThrows(
84 IllegalArgumentException.class,
85 () -> get("s").getSet(Integer.class)
86 );
Jon Brandveinb3d0bdd2017-01-13 17:46:29 +000087 }
88
89 @Test
dslomov2317ef82017-09-28 11:19:54 -040090 public void testGetSetDirect() throws Exception {
91 eval("s = depset(direct = ['a', 'b'])");
92 assertThat(get("s").getSet(String.class)).containsExactly("a", "b").inOrder();
93 assertThat(get("s").getSet(Object.class)).containsExactly("a", "b").inOrder();
94 assertThrows(
95 IllegalArgumentException.class,
96 () -> get("s").getSet(Integer.class)
97 );
98 }
99
100 @Test
101 public void testGetSetItems() throws Exception {
102 eval("s = depset(items = ['a', 'b'])");
103 assertThat(get("s").getSet(String.class)).containsExactly("a", "b").inOrder();
104 assertThat(get("s").getSet(Object.class)).containsExactly("a", "b").inOrder();
105 assertThrows(
106 IllegalArgumentException.class,
107 () -> get("s").getSet(Integer.class)
108 );
109 }
110
111
112 @Test
Jon Brandvein3cfeeec2017-01-20 04:23:37 +0000113 public void testToCollection() throws Exception {
114 eval("s = depset(['a', 'b'])");
115 assertThat(get("s").toCollection(String.class)).containsExactly("a", "b").inOrder();
116 assertThat(get("s").toCollection(Object.class)).containsExactly("a", "b").inOrder();
117 assertThat(get("s").toCollection()).containsExactly("a", "b").inOrder();
dslomov2317ef82017-09-28 11:19:54 -0400118 assertThrows(
119 IllegalArgumentException.class,
120 () -> get("s").toCollection(Integer.class)
121 );
122 }
123
124 @Test
125 public void testToCollectionDirect() throws Exception {
126 eval("s = depset(direct = ['a', 'b'])");
127 assertThat(get("s").toCollection(String.class)).containsExactly("a", "b").inOrder();
128 assertThat(get("s").toCollection(Object.class)).containsExactly("a", "b").inOrder();
129 assertThat(get("s").toCollection()).containsExactly("a", "b").inOrder();
130 assertThrows(
131 IllegalArgumentException.class,
132 () -> get("s").toCollection(Integer.class)
133 );
134 }
135
136 @Test
137 public void testToCollectionItems() throws Exception {
138 eval("s = depset(items = ['a', 'b'])");
139 assertThat(get("s").toCollection(String.class)).containsExactly("a", "b").inOrder();
140 assertThat(get("s").toCollection(Object.class)).containsExactly("a", "b").inOrder();
141 assertThat(get("s").toCollection()).containsExactly("a", "b").inOrder();
142 assertThrows(
143 IllegalArgumentException.class,
144 () -> get("s").toCollection(Integer.class)
145 );
Jon Brandvein3cfeeec2017-01-20 04:23:37 +0000146 }
147
148 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000149 public void testOrder() throws Exception {
Jon Brandvein052f9ce2017-01-19 21:50:34 +0000150 eval("s = depset(['a', 'b'], order='postorder')");
151 assertThat(get("s").getSet(String.class).getOrder()).isEqualTo(Order.COMPILE_ORDER);
152 }
153
154 @Test
dslomov2317ef82017-09-28 11:19:54 -0400155 public void testOrderDirect() throws Exception {
156 eval("s = depset(direct = ['a', 'b'], order='postorder')");
157 assertThat(get("s").getSet(String.class).getOrder()).isEqualTo(Order.COMPILE_ORDER);
158 }
159
160 @Test
161 public void testOrderItems() throws Exception {
162 eval("s = depset(items = ['a', 'b'], order='postorder')");
163 assertThat(get("s").getSet(String.class).getOrder()).isEqualTo(Order.COMPILE_ORDER);
164 }
165
166 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000167 public void testBadOrder() throws Exception {
168 new BothModesTest().testIfExactError(
169 "Invalid order: non_existing",
170 "depset(['a'], order='non_existing')");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000171 }
172
173 @Test
dslomov2317ef82017-09-28 11:19:54 -0400174 public void testBadOrderDirect() throws Exception {
175 new BothModesTest().testIfExactError(
176 "Invalid order: non_existing",
177 "depset(direct = ['a'], order='non_existing')");
178 }
179
180 @Test
181 public void testBadOrderItems() throws Exception {
182 new BothModesTest().testIfExactError(
183 "Invalid order: non_existing",
184 "depset(items = ['a'], order='non_existing')");
185 }
186
187 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000188 public void testEmptyGenericType() throws Exception {
189 eval("s = depset()");
190 assertThat(get("s").getContentType()).isEqualTo(SkylarkType.TOP);
Jon Brandveinb3d0bdd2017-01-13 17:46:29 +0000191 }
192
193 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000194 public void testHomogeneousGenericType() throws Exception {
195 eval("s = depset(['a', 'b', 'c'])");
196 assertThat(get("s").getContentType()).isEqualTo(SkylarkType.of(String.class));
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000197 }
198
199 @Test
dslomov2317ef82017-09-28 11:19:54 -0400200 public void testHomogeneousGenericTypeDirect() throws Exception {
201 eval("s = depset(['a', 'b', 'c'], transitive = [])");
202 assertThat(get("s").getContentType()).isEqualTo(SkylarkType.of(String.class));
203 }
204
205 @Test
206 public void testHomogeneousGenericTypeItems() throws Exception {
207 eval("s = depset(items = ['a', 'b', 'c'], transitive = [])");
208 assertThat(get("s").getContentType()).isEqualTo(SkylarkType.of(String.class));
209 }
210
211 @Test
212 public void testHomogeneousGenericTypeTransitive() throws Exception {
213 eval("s = depset(['a', 'b', 'c'], transitive = [depset(['x'])])");
214 assertThat(get("s").getContentType()).isEqualTo(SkylarkType.of(String.class));
215 }
216
217 @Test
218 public void testTransitiveIncompatibleOrder() throws Exception {
219 checkEvalError(
220 "Order 'postorder' is incompatible with order 'topological'",
221 "depset(['a', 'b'], order='postorder',",
222 " transitive = [depset(['c', 'd'], order='topological')])");
223 }
224
225 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000226 public void testBadGenericType() throws Exception {
Jon Brandvein3cfeeec2017-01-20 04:23:37 +0000227 new BothModesTest().testIfExactError(
228 "cannot add an item of type 'int' to a depset of 'string'",
229 "depset(['a', 5])");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000230 }
231
232 @Test
dslomov2317ef82017-09-28 11:19:54 -0400233 public void testBadGenericTypeDirect() throws Exception {
234 new BothModesTest().testIfExactError(
235 "cannot add an item of type 'int' to a depset of 'string'",
236 "depset(direct = ['a', 5])");
237 }
238
239 @Test
240 public void testBadGenericTypeItems() throws Exception {
241 new BothModesTest().testIfExactError(
242 "cannot add an item of type 'int' to a depset of 'string'",
243 "depset(items = ['a', 5])");
244 }
245
246 @Test
247 public void testBadGenericTypeTransitive() throws Exception {
248 new BothModesTest().testIfExactError(
249 "cannot add an item of type 'int' to a depset of 'string'",
250 "depset(['a', 'b'], transitive=[depset([1])])");
251 }
252
253 @Test
254 public void testLegacyAndNewApi() throws Exception {
255 new BothModesTest().testIfExactError(
256 "Do not pass both 'direct' and 'items' argument to depset constructor.",
257 "depset(['a', 'b'], direct = ['c', 'd'])");
258 }
259
260 @Test
261 public void testItemsAndTransitive() throws Exception {
262 new BothModesTest().testIfExactError(
263 "expected type 'sequence' for items but got type 'depset' instead",
264 "depset(items = depset(), transitive = [depset()])");
265 }
266
267 @Test
268 public void testTooManyPositionals() throws Exception {
cparsons7ac265d2019-04-16 15:31:17 -0700269 new BothModesTest()
270 .testIfErrorContains(
cparsonsf0cf2b42019-08-15 10:56:40 -0700271 "expected no more than 2 positional arguments, but got 3", "depset([], 'default', [])");
dslomov2317ef82017-09-28 11:19:54 -0400272 }
273
274
275 @Test
276 public void testTransitiveOrder() throws Exception {
277 assertContainsInOrder("depset([], transitive=[depset(['a', 'b', 'c'])])", "a", "b", "c");
278 assertContainsInOrder("depset(['a'], transitive = [depset(['b', 'c'])])", "b", "c", "a");
279 assertContainsInOrder("depset(['a', 'b'], transitive = [depset(['c'])])", "c", "a", "b");
280 assertContainsInOrder("depset(['a', 'b', 'c'], transitive = [depset([])])", "a", "b", "c");
281 }
282
283 @Test
284 public void testTransitiveOrderItems() throws Exception {
285 assertContainsInOrder("depset(items=[], transitive=[depset(['a', 'b', 'c'])])", "a", "b", "c");
286 assertContainsInOrder("depset(items=['a'], transitive = [depset(['b', 'c'])])", "b", "c", "a");
287 assertContainsInOrder("depset(items=['a', 'b'], transitive = [depset(['c'])])", "c", "a", "b");
288 assertContainsInOrder("depset(items=['a', 'b', 'c'], transitive = [depset([])])",
289 "a", "b", "c");
290 }
291
292 @Test
293 public void testTransitiveOrderDirect() throws Exception {
294 assertContainsInOrder("depset(direct=[], transitive=[depset(['a', 'b', 'c'])])", "a", "b", "c");
295 assertContainsInOrder("depset(direct=['a'], transitive = [depset(['b', 'c'])])", "b", "c", "a");
296 assertContainsInOrder("depset(direct=['a', 'b'], transitive = [depset(['c'])])", "c", "a", "b");
297 assertContainsInOrder("depset(direct=['a', 'b', 'c'], transitive = [depset([])])",
298 "a", "b", "c");
299 }
300
301 @Test
laurentlb2bbda4a2017-12-07 10:38:46 -0800302 public void testIncompatibleUnion() throws Exception {
303 new BothModesTest("--incompatible_depset_union=true")
304 .testIfErrorContains(
305 "depset method `.union` has been removed", "depset([]).union(['a', 'b', 'c'])");
306
307 new BothModesTest("--incompatible_depset_union=true")
308 .testIfErrorContains("`+` operator on a depset is forbidden", "depset([]) + ['a']");
309
310 new BothModesTest("--incompatible_depset_union=true")
311 .testIfErrorContains("`|` operator on a depset is forbidden", "depset([]) | ['a']");
312 }
313
314 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000315 public void testUnionWithList() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800316 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000317 assertContainsInOrder("depset([]).union(['a', 'b', 'c'])", "a", "b", "c");
318 assertContainsInOrder("depset(['a']).union(['b', 'c'])", "a", "b", "c");
319 assertContainsInOrder("depset(['a', 'b']).union(['c'])", "a", "b", "c");
320 assertContainsInOrder("depset(['a', 'b', 'c']).union([])", "a", "b", "c");
321 }
322
323 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000324 public void testUnionWithDepset() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800325 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000326 assertContainsInOrder("depset([]).union(depset(['a', 'b', 'c']))", "a", "b", "c");
dslomov2317ef82017-09-28 11:19:54 -0400327 assertContainsInOrder("depset(['a']).union(depset(['b', 'c']))", "b", "c", "a");
328 assertContainsInOrder("depset(['a', 'b']).union(depset(['c']))", "c", "a", "b");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000329 assertContainsInOrder("depset(['a', 'b', 'c']).union(depset([]))", "a", "b", "c");
330 }
331
332 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000333 public void testUnionDuplicates() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800334 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000335 assertContainsInOrder("depset(['a', 'b', 'c']).union(['a', 'b', 'c'])", "a", "b", "c");
336 assertContainsInOrder("depset(['a', 'a', 'a']).union(['a', 'a'])", "a");
337
338 assertContainsInOrder("depset(['a', 'b', 'c']).union(depset(['a', 'b', 'c']))", "a", "b", "c");
339 assertContainsInOrder("depset(['a', 'a', 'a']).union(depset(['a', 'a']))", "a");
340 }
341
dslomov2317ef82017-09-28 11:19:54 -0400342
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000343 private void assertContainsInOrder(String statement, Object... expectedElements)
344 throws Exception {
Jon Brandvein3cfeeec2017-01-20 04:23:37 +0000345 assertThat(((SkylarkNestedSet) eval(statement)).toCollection())
dslomov2317ef82017-09-28 11:19:54 -0400346 .containsExactly(expectedElements)
347 .inOrder();
Ulf Adams89f012d2015-02-26 13:39:28 +0000348 }
349
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000350 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000351 public void testUnionOrder() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800352 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000353 eval(
354 "def func():",
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000355 " s1 = depset()",
356 " s2 = depset()",
357 " s1 += ['a']",
358 " s2 += ['b']",
359 " s1 += s2",
360 " return s1",
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000361 "s = func()");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000362 assertThat(get("s").toCollection()).containsExactly("b", "a").inOrder();
Ulf Adams89f012d2015-02-26 13:39:28 +0000363 }
364
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000365 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000366 public void testUnionIncompatibleOrder() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700367 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Vladimir Moskvad200daf2016-12-23 16:35:37 +0000368 checkEvalError(
Jon Brandvein052f9ce2017-01-19 21:50:34 +0000369 "Order mismatch: topological != postorder",
370 "depset(['a', 'b'], order='postorder') + depset(['c', 'd'], order='topological')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000371 }
372
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000373 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000374 public void testUnionWithNonsequence() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700375 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
376 checkEvalError("cannot union value of type 'int' to a depset", "depset([]).union(5)");
377 checkEvalError("cannot union value of type 'string' to a depset", "depset(['a']).union('b')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000378 }
379
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000380 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000381 public void testUnionWrongNumArgs() throws Exception {
cparsons03035142019-01-15 13:35:22 -0800382 new BothModesTest()
383 .testIfErrorContains(
384 "parameter 'new_elements' has no default value, "
385 + "for call to method union(new_elements) of 'depset'",
386 "depset(['a']).union()");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000387 }
388
389 @Test
390 public void testUnionNoSideEffects() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700391 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Vladimir Moskvad200daf2016-12-23 16:35:37 +0000392 eval(
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000393 "def func():",
394 " s1 = depset(['a'])",
395 " s2 = s1.union(['b'])",
396 " return s1",
397 "s = func()");
398 assertThat(((SkylarkNestedSet) lookup("s")).toCollection()).isEqualTo(ImmutableList.of("a"));
399 }
400
401 @Test
402 public void testFunctionReturnsDepset() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700403 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000404 eval(
405 "def func():",
406 " t = depset()",
407 " t += ['a']",
408 " return t",
409 "s = func()");
410 assertThat(get("s")).isInstanceOf(SkylarkNestedSet.class);
411 assertThat(get("s").toCollection()).containsExactly("a");
412 }
413
414 @Test
415 public void testPlusEqualsWithList() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700416 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000417 eval(
418 "def func():",
419 " t = depset()",
420 " t += ['a', 'b']",
421 " return t",
422 "s = func()");
423 assertThat(get("s").toCollection()).containsExactly("a", "b").inOrder();
424 }
425
426 @Test
427 public void testPlusEqualsNoSideEffects() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700428 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000429 eval(
430 "def func():",
431 " s1 = depset()",
432 " s1 += ['a']",
433 " s2 = s1",
434 " s2 += ['b']",
435 " return s1",
436 "s = func()");
437 assertThat(get("s").toCollection()).containsExactly("a");
438 }
439
440 @Test
441 public void testFuncParamNoSideEffects() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700442 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000443 eval(
444 "def func1(t):",
445 " t += ['b']",
Ulf Adams89f012d2015-02-26 13:39:28 +0000446 "def func2():",
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000447 " u = depset()",
448 " u += ['a']",
449 " func1(u)",
450 " return u",
451 "s = func2()");
452 assertThat(get("s").toCollection()).containsExactly("a");
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000453 }
454
455 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000456 public void testTransitiveOrdering() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700457 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000458 eval(
459 "def func():",
vladmosdcf36832017-08-09 17:44:10 +0200460 " sa = depset(['a'], order='postorder')",
461 " sb = depset(['b'], order='postorder')",
462 " sc = depset(['c'], order='postorder') + sa",
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000463 " return depset() + sb + sc",
464 "s = func()");
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000465 // The iterator lists the Transitive sets first
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000466 assertThat(get("s").toCollection()).containsExactly("b", "a", "c").inOrder();
Ulf Adams89f012d2015-02-26 13:39:28 +0000467 }
468
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000469 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000470 public void testLeftRightDirectOrdering() throws Exception {
laurentlb63c7ea62019-04-25 08:45:21 -0700471 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Vladimir Moskvad200daf2016-12-23 16:35:37 +0000472 eval(
473 "def func():",
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000474 " t = depset()",
475 " t += [4]",
476 " t += [2, 4]",
477 " t += [3, 4, 5]",
478 " return t",
479 "s = func()");
480 // All elements are direct. The iterator lists them left-to-right.
481 assertThat(get("s").toCollection()).containsExactly(4, 2, 3, 5).inOrder();
Ulf Adams89f012d2015-02-26 13:39:28 +0000482 }
483
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000484 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000485 public void testToString() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800486 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000487 eval(
488 "s = depset() + [2, 4, 6] + [3, 4, 5]",
489 "x = str(s)");
Vladimir Moskvaba4f0bb2017-01-30 15:45:49 +0000490 assertThat(lookup("x")).isEqualTo("depset([2, 4, 6, 3, 5])");
Ulf Adams89f012d2015-02-26 13:39:28 +0000491 }
492
Laurent Le Brunc7a6e362015-03-09 20:55:40 +0000493 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000494 public void testToStringWithOrder() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800495 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000496 eval(
Jon Brandvein052f9ce2017-01-19 21:50:34 +0000497 "s = depset(order = 'topological') + [2, 4, 6] + [3, 4, 5]",
Jon Brandvein5b792dc2017-01-12 20:22:07 +0000498 "x = str(s)");
Vladimir Moskvaba4f0bb2017-01-30 15:45:49 +0000499 assertThat(lookup("x")).isEqualTo("depset([2, 4, 6, 3, 5], order = \"topological\")");
Laurent Le Brunc7a6e362015-03-09 20:55:40 +0000500 }
501
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000502 @SuppressWarnings("unchecked")
503 private SkylarkNestedSet get(String varname) throws Exception {
504 return (SkylarkNestedSet) lookup(varname);
Ulf Adams89f012d2015-02-26 13:39:28 +0000505 }
Han-Wen Nienhuysceae8c52015-09-22 16:24:45 +0000506
Florian Weikertb914f3c2015-07-29 13:35:19 +0000507 @Test
Jon Brandveinb3d0bdd2017-01-13 17:46:29 +0000508 public void testToList() throws Exception {
laurentlb2bbda4a2017-12-07 10:38:46 -0800509 env = newEnvironmentWithSkylarkOptions("--incompatible_depset_union=false");
Jon Brandveinb3d0bdd2017-01-13 17:46:29 +0000510 eval(
511 "s = depset() + [2, 4, 6] + [3, 4, 5]",
512 "x = s.to_list()");
513 Object value = lookup("x");
514 assertThat(value).isInstanceOf(MutableList.class);
515 assertThat((Iterable<?>) value).containsExactly(2, 4, 6, 3, 5).inOrder();
516 }
517
518 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000519 public void testOrderCompatibility() throws Exception {
Florian Weikertb914f3c2015-07-29 13:35:19 +0000520 // Two sets are compatible if
521 // (a) both have the same order or
Jon Brandvein052f9ce2017-01-19 21:50:34 +0000522 // (b) at least one order is "default"
Florian Weikertb914f3c2015-07-29 13:35:19 +0000523
524 for (Order first : Order.values()) {
janakr889f5622018-03-16 17:49:11 -0700525 SkylarkNestedSet s1 = SkylarkNestedSet.of(first, Tuple.of("1", "11"), null);
Florian Weikertb914f3c2015-07-29 13:35:19 +0000526
527 for (Order second : Order.values()) {
janakr889f5622018-03-16 17:49:11 -0700528 SkylarkNestedSet s2 = SkylarkNestedSet.of(second, Tuple.of("2", "22"), null);
Florian Weikertb914f3c2015-07-29 13:35:19 +0000529
530 boolean compatible = true;
531
532 try {
janakr889f5622018-03-16 17:49:11 -0700533 SkylarkNestedSet.of(s1, s2, null);
Florian Weikertb914f3c2015-07-29 13:35:19 +0000534 } catch (Exception ex) {
535 compatible = false;
536 }
537
538 assertThat(compatible).isEqualTo(areOrdersCompatible(first, second));
539 }
540 }
541 }
542
543 private boolean areOrdersCompatible(Order first, Order second) {
544 return first == Order.STABLE_ORDER || second == Order.STABLE_ORDER || first == second;
545 }
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000546
547 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000548 public void testOrderComplexUnion() throws Exception {
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000549 // {1, 11, {2, 22}, {3, 33}, {4, 44}}
550 List<String> preOrder = Arrays.asList("1", "11", "2", "22", "3", "33", "4", "44");
551 List<String> postOrder = Arrays.asList("2", "22", "3", "33", "4", "44", "1", "11");
552
janakr889f5622018-03-16 17:49:11 -0700553 MergeStrategy strategy =
554 new MergeStrategy() {
555 @Override
556 public SkylarkNestedSet merge(SkylarkNestedSet[] sets) throws Exception {
557 SkylarkNestedSet union = SkylarkNestedSet.of(sets[0], sets[1], null);
558 union = SkylarkNestedSet.of(union, sets[2], null);
559 union = SkylarkNestedSet.of(union, sets[3], null);
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000560
janakr889f5622018-03-16 17:49:11 -0700561 return union;
562 }
563 };
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000564
565 runComplexOrderTest(strategy, preOrder, postOrder);
566 }
567
568 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000569 public void testOrderBalancedTree() throws Exception {
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000570 // {{1, 11, {2, 22}}, {3, 33, {4, 44}}}
571 List<String> preOrder = Arrays.asList("1", "11", "2", "22", "3", "33", "4", "44");
572 List<String> postOrder = Arrays.asList("2", "22", "4", "44", "3", "33", "1", "11");
573
janakr889f5622018-03-16 17:49:11 -0700574 MergeStrategy strategy =
575 new MergeStrategy() {
576 @Override
577 public SkylarkNestedSet merge(SkylarkNestedSet[] sets) throws Exception {
578 SkylarkNestedSet leftUnion = SkylarkNestedSet.of(sets[0], sets[1], null);
579 SkylarkNestedSet rightUnion = SkylarkNestedSet.of(sets[2], sets[3], null);
580 SkylarkNestedSet union = SkylarkNestedSet.of(leftUnion, rightUnion, null);
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000581
janakr889f5622018-03-16 17:49:11 -0700582 return union;
583 }
584 };
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000585
586 runComplexOrderTest(strategy, preOrder, postOrder);
587 }
588
589 @Test
Jon Brandveinc8e1cfb2017-01-19 18:43:37 +0000590 public void testOrderManyLevelsOfNesting() throws Exception {
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000591 // {1, 11, {2, 22, {3, 33, {4, 44}}}}
592 List<String> preOrder = Arrays.asList("1", "11", "2", "22", "3", "33", "4", "44");
593 List<String> postOrder = Arrays.asList("4", "44", "3", "33", "2", "22", "1", "11");
594
janakr889f5622018-03-16 17:49:11 -0700595 MergeStrategy strategy =
596 new MergeStrategy() {
597 @Override
598 public SkylarkNestedSet merge(SkylarkNestedSet[] sets) throws Exception {
599 SkylarkNestedSet union = SkylarkNestedSet.of(sets[2], sets[3], null);
600 union = SkylarkNestedSet.of(sets[1], union, null);
601 union = SkylarkNestedSet.of(sets[0], union, null);
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000602
janakr889f5622018-03-16 17:49:11 -0700603 return union;
604 }
605 };
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000606
607 runComplexOrderTest(strategy, preOrder, postOrder);
608 }
609
610 private interface MergeStrategy {
611 SkylarkNestedSet merge(SkylarkNestedSet[] sets) throws Exception;
612 }
613
614 private void runComplexOrderTest(
615 MergeStrategy strategy, List<String> preOrder, List<String> postOrder) throws Exception {
616 Map<Order, List<String>> expected = createExpectedMap(preOrder, postOrder);
617 for (Order order : Order.values()) {
618 SkylarkNestedSet union = strategy.merge(makeFourSets(order));
619 assertThat(union.toCollection()).containsExactlyElementsIn(expected.get(order)).inOrder();
620 }
621 }
622
623 private Map<Order, List<String>> createExpectedMap(
624 List<String> preOrder, List<String> postOrder) {
625 Map<Order, List<String>> expected = new HashMap<>();
626
627 for (Order order : Order.values()) {
628 expected.put(order, isPostOrder(order) ? postOrder : preOrder);
629 }
630
631 return expected;
632 }
633
634 private boolean isPostOrder(Order order) {
635 return order == Order.STABLE_ORDER || order == Order.COMPILE_ORDER;
636 }
637
638 private SkylarkNestedSet[] makeFourSets(Order order) throws Exception {
639 return new SkylarkNestedSet[] {
janakr889f5622018-03-16 17:49:11 -0700640 SkylarkNestedSet.of(order, Tuple.of("1", "11"), null),
641 SkylarkNestedSet.of(order, Tuple.of("2", "22"), null),
642 SkylarkNestedSet.of(order, Tuple.of("3", "33"), null),
643 SkylarkNestedSet.of(order, Tuple.of("4", "44"), null)
644 };
Pedro Liberal Fernandez45bddab2017-01-11 13:31:14 +0000645 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000646}