blob: 6353c1270e6aa232745be410e1107b63b3f716ec [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
16import static com.google.common.truth.Truth.assertThat;
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000017import static org.junit.Assert.assertEquals;
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000018import static org.junit.Assert.assertTrue;
Ulf Adams89f012d2015-02-26 13:39:28 +000019
20import com.google.common.collect.ImmutableCollection;
21import com.google.common.collect.ImmutableList;
22import com.google.common.collect.ImmutableMap;
Ulf Adams89f012d2015-02-26 13:39:28 +000023import com.google.devtools.build.lib.actions.Artifact;
24import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
25import com.google.devtools.build.lib.analysis.FileConfiguredTarget;
26import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
27import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
28import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +000029import com.google.devtools.build.lib.skylarkinterface.Param;
John Field585d1a02015-12-16 16:03:52 +000030import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
31import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
Vladimir Moskvaa5b16742016-10-31 14:09:41 +000032import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
Francois-Rene Rideauef7a8a52016-01-29 17:37:48 +000033import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
Florian Weikert28da3652015-07-01 14:52:30 +000034import com.google.devtools.build.lib.testutil.TestMode;
Han-Wen Nienhuys33ce2112015-09-25 14:25:38 +000035import org.junit.Before;
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000036import org.junit.Test;
37import org.junit.runner.RunWith;
38import org.junit.runners.JUnit4;
39
Ulf Adams89f012d2015-02-26 13:39:28 +000040/**
41 * Evaluation tests with Skylark Environment.
42 */
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000043@RunWith(JUnit4.class)
Ulf Adams89f012d2015-02-26 13:39:28 +000044public class SkylarkEvaluationTest extends EvaluationTest {
Florian Weikertb4c59042015-12-01 10:47:18 +000045
Han-Wen Nienhuys33ce2112015-09-25 14:25:38 +000046 @Before
Florian Weikertb4c59042015-12-01 10:47:18 +000047 public final void setup() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +000048 setMode(TestMode.SKYLARK);
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000049 }
50
Florian Weikert28da3652015-07-01 14:52:30 +000051 /**
52 * Creates an instance of {@code SkylarkTest} in order to run the tests from the base class in a
53 * Skylark context
54 */
55 @Override
56 protected ModalTestCase newTest() {
57 return new SkylarkTest();
58 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +000059
Francois-Rene Rideau6c10eac2015-09-17 19:17:20 +000060 static class Bad {
61 Bad () {
62 }
63 }
64
Vladimir Moskvaa5b16742016-10-31 14:09:41 +000065 @SkylarkSignature(name = "foobar", returnType = String.class, documented = false)
66 static BuiltinFunction foobar = new BuiltinFunction("foobar") {
67 public String invoke() throws EvalException {
68 return "foobar";
69 }
70 };
71
Ulf Adams89f012d2015-02-26 13:39:28 +000072 @SkylarkModule(name = "Mock", doc = "")
73 static class Mock {
74 @SkylarkCallable(doc = "")
75 public static Integer valueOf(String str) {
76 return Integer.valueOf(str);
77 }
78 @SkylarkCallable(doc = "")
79 public Boolean isEmpty(String str) {
80 return str.isEmpty();
81 }
82 public void value() {}
83 @SkylarkCallable(doc = "")
Francois-Rene Rideau6c10eac2015-09-17 19:17:20 +000084 public Bad returnBad() {
85 return new Bad();
Ulf Adams89f012d2015-02-26 13:39:28 +000086 }
87 @SkylarkCallable(name = "struct_field", doc = "", structField = true)
88 public String structField() {
89 return "a";
90 }
Vladimir Moskvaa5b16742016-10-31 14:09:41 +000091 @SkylarkCallable(name = "struct_field_callable", doc = "", structField = true)
92 public BuiltinFunction structFieldCallable() {
93 return foobar;
94 }
Ulf Adams89f012d2015-02-26 13:39:28 +000095 @SkylarkCallable(name = "function", doc = "", structField = false)
96 public String function() {
97 return "a";
98 }
99 @SuppressWarnings("unused")
100 @SkylarkCallable(name = "nullfunc_failing", doc = "", allowReturnNones = false)
101 public Object nullfuncFailing(String p1, Integer p2) {
102 return null;
103 }
104 @SkylarkCallable(name = "nullfunc_working", doc = "", allowReturnNones = true)
105 public Object nullfuncWorking() {
106 return null;
107 }
108 @SkylarkCallable(name = "voidfunc", doc = "")
109 public void voidfunc() {}
110 @SkylarkCallable(name = "string_list", doc = "")
111 public ImmutableList<String> stringList() {
112 return ImmutableList.<String>of("a", "b");
113 }
114 @SkylarkCallable(name = "string", doc = "")
115 public String string() {
116 return "a";
117 }
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000118
119 @SkylarkCallable(
120 name = "with_params",
121 doc = "",
122 mandatoryPositionals = 1,
123 parameters = {
124 @Param(name = "pos2", defaultValue = "False", type = Boolean.class),
125 @Param(
126 name = "posOrNamed",
127 defaultValue = "False",
128 type = Boolean.class,
129 positional = true,
130 named = true
131 ),
132 @Param(name = "named", type = Boolean.class, positional = false, named = true),
133 @Param(
134 name = "optionalNamed",
135 type = Boolean.class,
136 defaultValue = "False",
137 positional = false,
138 named = true
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000139 ),
140 @Param(
141 name = "nonNoneable",
142 type = Object.class,
143 defaultValue = "\"a\"",
144 positional = false,
145 named = true
146 ),
147 @Param(
148 name = "noneable",
Googlere5da53c2016-09-21 12:34:44 +0000149 type = Integer.class,
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000150 defaultValue = "None",
151 noneable = true,
152 positional = false,
153 named = true
154 ),
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000155 }
156 )
157 public String withParams(
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000158 Integer pos1,
159 boolean pos2,
160 boolean posOrNamed,
161 boolean named,
162 boolean optionalNamed,
163 Object nonNoneable,
164 Object noneable) {
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000165 return "with_params("
166 + pos1
167 + ", "
168 + pos2
169 + ", "
170 + posOrNamed
171 + ", "
172 + named
173 + ", "
174 + optionalNamed
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000175 + ", "
176 + nonNoneable.toString()
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000177 + ")";
178 }
179
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000180 @Override
181 public String toString() {
182 return "<mock>";
183 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000184 }
185
186 @SkylarkModule(name = "MockInterface", doc = "")
187 static interface MockInterface {
188 @SkylarkCallable(doc = "")
189 public Boolean isEmptyInterface(String str);
190 }
191
192 static final class MockSubClass extends Mock implements MockInterface {
193 @Override
194 public Boolean isEmpty(String str) {
195 return str.isEmpty();
196 }
197 @Override
198 public Boolean isEmptyInterface(String str) {
199 return str.isEmpty();
200 }
201 @SkylarkCallable(doc = "")
202 public Boolean isEmptyClassNotAnnotated(String str) {
203 return str.isEmpty();
204 }
205 }
206
Francois-Rene Rideauab049e02016-02-17 16:13:46 +0000207 @SkylarkModule(name = "MockClassObject", doc = "", documented = false)
Ulf Adams89f012d2015-02-26 13:39:28 +0000208 static final class MockClassObject implements ClassObject {
209 @Override
210 public Object getValue(String name) {
211 switch (name) {
212 case "field": return "a";
213 case "nset": return NestedSetBuilder.stableOrder().build();
214 }
Laurent Le Brun57badf42017-01-02 15:12:24 +0000215 return null;
Ulf Adams89f012d2015-02-26 13:39:28 +0000216 }
217
218 @Override
219 public ImmutableCollection<String> getKeys() {
220 return ImmutableList.of("field", "nset");
221 }
222
223 @Override
224 public String errorMessage(String name) {
225 return null;
226 }
227 }
228
229 @SkylarkModule(name = "MockMultipleMethodClass", doc = "")
230 static final class MockMultipleMethodClass {
231 @SuppressWarnings("unused")
232 @SkylarkCallable(doc = "")
233 public void method(Object o) {}
234 @SuppressWarnings("unused")
235 @SkylarkCallable(doc = "")
236 public void method(String i) {}
237 }
238
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000239 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000240 public void testSimpleIf() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000241 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000242 " a = 0",
243 " x = 0",
244 " if x: a = 5",
245 " return a",
Florian Weikert28da3652015-07-01 14:52:30 +0000246 "a = foo()").testLookup("a", 0);
Ulf Adams89f012d2015-02-26 13:39:28 +0000247 }
248
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000249 @Test
Laurent Le Brun0942ee92015-03-17 20:22:16 +0000250 public void testIfPass() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000251 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000252 " a = 1",
253 " x = True",
254 " if x: pass",
255 " return a",
Florian Weikert28da3652015-07-01 14:52:30 +0000256 "a = foo()").testLookup("a", 1);
Laurent Le Brun0942ee92015-03-17 20:22:16 +0000257 }
258
259 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000260 public void testNestedIf() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000261 executeNestedIf(0, 0, 0);
262 executeNestedIf(1, 0, 3);
263 executeNestedIf(1, 1, 5);
Ulf Adams89f012d2015-02-26 13:39:28 +0000264 }
265
Florian Weikert28da3652015-07-01 14:52:30 +0000266 private void executeNestedIf(int x, int y, int expected) throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000267 String fun = String.format("foo%s%s", x, y);
Florian Weikert28da3652015-07-01 14:52:30 +0000268 new SkylarkTest().setUp("def " + fun + "():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000269 " x = " + x,
270 " y = " + y,
271 " a = 0",
272 " b = 0",
273 " if x:",
274 " if y:",
275 " a = 2",
276 " b = 3",
277 " return a + b",
Florian Weikert28da3652015-07-01 14:52:30 +0000278 "x = " + fun + "()").testLookup("x", expected);
Ulf Adams89f012d2015-02-26 13:39:28 +0000279 }
280
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000281 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000282 public void testIfElse() throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000283 executeIfElse("foo", "something", 2);
284 executeIfElse("bar", "", 3);
Ulf Adams89f012d2015-02-26 13:39:28 +0000285 }
286
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000287 private void executeIfElse(String fun, String y, int expected) throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000288 new SkylarkTest().setUp("def " + fun + "():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000289 " y = '" + y + "'",
290 " x = 5",
291 " if x:",
292 " if y: a = 2",
293 " else: a = 3",
Florian Weikert28da3652015-07-01 14:52:30 +0000294 " return a",
295 "z = " + fun + "()").testLookup("z", expected);
Ulf Adams89f012d2015-02-26 13:39:28 +0000296 }
297
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000298 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000299 public void testIfElifElse_IfExecutes() throws Exception {
300 execIfElifElse(1, 0, 1);
301 }
302
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000303 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000304 public void testIfElifElse_ElifExecutes() throws Exception {
305 execIfElifElse(0, 1, 2);
306 }
307
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000308 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000309 public void testIfElifElse_ElseExecutes() throws Exception {
310 execIfElifElse(0, 0, 3);
311 }
312
313 private void execIfElifElse(int x, int y, int v) throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000314 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000315 " x = " + x + "",
316 " y = " + y + "",
317 " if x:",
318 " return 1",
319 " elif y:",
320 " return 2",
321 " else:",
322 " return 3",
Florian Weikert28da3652015-07-01 14:52:30 +0000323 "v = foo()").testLookup("v", v);
Ulf Adams89f012d2015-02-26 13:39:28 +0000324 }
325
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000326 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000327 public void testForOnList() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000328 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000329 " s = ''",
330 " for i in ['hello', ' ', 'world']:",
331 " s = s + i",
332 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000333 "s = foo()").testLookup("s", "hello world");
Ulf Adams89f012d2015-02-26 13:39:28 +0000334 }
335
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000336 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000337 public void testForOnString() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000338 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000339 " s = []",
340 " for i in 'abc':",
341 " s = s + [i]",
342 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000343 "s = foo()").testExactOrder("s", "a", "b", "c");
Ulf Adams89f012d2015-02-26 13:39:28 +0000344 }
345
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000346 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000347 public void testForAssignmentList() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000348 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000349 " d = ['a', 'b', 'c']",
350 " s = ''",
351 " for i in d:",
352 " s = s + i",
Florian Weikert28da3652015-07-01 14:52:30 +0000353 " d = ['d', 'e', 'f']", // check that we use the old list
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000354 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000355 "s = foo()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000356 }
357
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000358 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000359 public void testForAssignmentDict() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000360 new SkylarkTest().setUp("def func():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000361 " d = {'a' : 1, 'b' : 2, 'c' : 3}",
362 " s = ''",
363 " for i in d:",
364 " s = s + i",
365 " d = {'d' : 1, 'e' : 2, 'f' : 3}",
366 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000367 "s = func()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000368 }
369
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000370 @Test
Jon Brandvein15775b22016-07-25 15:13:44 +0000371 public void testForUpdateList() throws Exception {
Jon Brandvein15775b22016-07-25 15:13:44 +0000372 new SkylarkTest().setUp("def foo():",
Jon Brandvein65e3ae62016-09-27 19:57:40 +0000373 " xs = [1, 2, 3]",
Jon Brandvein15775b22016-07-25 15:13:44 +0000374 " for x in xs:",
Jon Brandvein65e3ae62016-09-27 19:57:40 +0000375 " if x == 1:",
376 " xs.append(10)"
377 ).testIfErrorContains("trying to mutate a locked object", "foo()");
Jon Brandvein15775b22016-07-25 15:13:44 +0000378 }
379
380 @Test
381 public void testForUpdateDict() throws Exception {
Jon Brandvein15775b22016-07-25 15:13:44 +0000382 new SkylarkTest().setUp("def foo():",
383 " d = {'a': 1, 'b': 2, 'c': 3}",
Jon Brandvein15775b22016-07-25 15:13:44 +0000384 " for k in d:",
Jon Brandvein65e3ae62016-09-27 19:57:40 +0000385 " d[k] *= 2"
386 ).testIfErrorContains("trying to mutate a locked object", "foo()");
387 }
388
389 @Test
390 public void testForUnlockedAfterBreak() throws Exception {
391 new SkylarkTest().setUp("def foo():",
392 " xs = [1, 2]",
393 " for x in xs:",
394 " break",
395 " xs.append(3)",
396 " return xs"
397 ).testEval("foo()", "[1, 2, 3]");
398 }
399
400 @Test
401 public void testForNestedOnSameListStillLocked() throws Exception {
402 new SkylarkTest().setUp("def foo():",
403 " xs = [1, 2]",
404 " ys = []",
405 " for x1 in xs:",
406 " for x2 in xs:",
407 " ys.append(x1 * x2)",
408 " xs.append(4)",
409 " return ys"
410 ).testIfErrorContains("trying to mutate a locked object", "foo()");
411 }
412
413 @Test
414 public void testForNestedOnSameListErrorMessage() throws Exception {
415 new SkylarkTest().setUp("def foo():",
416 " xs = [1, 2]",
417 " ys = []",
418 " for x1 in xs:",
419 " for x2 in xs:",
420 " ys.append(x1 * x2)",
421 " xs.append(4)",
422 " return ys"
423 // No file name in message, due to how test is set up.
Carmi Grushko46bf88c2017-02-20 22:37:15 +0000424 ).testIfErrorContains("Object locked at the following location(s): :4:3, :5:5", "foo()");
Jon Brandvein65e3ae62016-09-27 19:57:40 +0000425 }
426
427 @Test
428 public void testForNestedOnSameListUnlockedAtEnd() throws Exception {
429 new SkylarkTest().setUp("def foo():",
430 " xs = [1, 2]",
431 " ys = []",
432 " for x1 in xs:",
433 " for x2 in xs:",
434 " ys.append(x1 * x2)",
435 " xs.append(4)",
436 " return ys"
437 ).testEval("foo()", "[1, 2, 2, 4]");
438 }
439
440 @Test
441 public void testForNestedWithListCompGood() throws Exception {
442 new SkylarkTest().setUp("def foo():",
443 " xs = [1, 2]",
444 " ys = []",
445 " for x in xs:",
446 " zs = [None for x in xs for y in (ys.append(x) or ys)]",
447 " return ys"
448 ).testEval("foo()", "[1, 2, 1, 2]");
449 }
450 @Test
451 public void testForNestedWithListCompBad() throws Exception {
452 new SkylarkTest().setUp("def foo():",
453 " xs = [1, 2, 3]",
454 " ys = []",
455 " for x in xs:",
456 " zs = [None for x in xs for y in (xs.append(x) or ys)]",
457 " return ys"
458 ).testIfErrorContains("trying to mutate a locked object", "foo()");
Jon Brandvein15775b22016-07-25 15:13:44 +0000459 }
460
461 @Test
462 public void testForDeepUpdate() throws Exception {
463 // Check that indirectly reachable values can still be manipulated as normal.
464 new SkylarkTest().setUp("def foo():",
465 " xs = [['a'], ['b'], ['c']]",
466 " ys = []",
467 " for x in xs:",
468 " for y in x:",
469 " ys.append(y)",
470 " xs[2].append(x[0])",
471 " return ys",
472 "ys = foo()").testLookup("ys", MutableList.of(null, "a", "b", "c", "a", "b"));
473 }
474
475 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000476 public void testForNotIterable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000477 new SkylarkTest()
478 .update("mock", new Mock())
Florian Weikertc1d54ec2015-08-26 14:06:58 +0000479 .testIfErrorContains(
480 "type 'int' is not iterable",
481 "def func():",
482 " for i in mock.value_of('1'): a = i",
483 "func()\n");
Ulf Adams89f012d2015-02-26 13:39:28 +0000484 }
485
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000486 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000487 public void testForOnDictionary() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000488 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000489 " d = {1: 'a', 2: 'b', 3: 'c'}",
490 " s = ''",
491 " for i in d: s = s + d[i]",
492 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000493 "s = foo()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000494 }
495
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000496 @Test
Francois-Rene Rideau6c10eac2015-09-17 19:17:20 +0000497 public void testBadDictKey() throws Exception {
498 new SkylarkTest().testIfErrorContains(
499 "unhashable type: 'list'",
500 "{ [1, 2]: [3, 4] }");
501 }
502
503 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000504 public void testForLoopReuseVariable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000505 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000506 " s = ''",
507 " for i in ['a', 'b']:",
508 " for i in ['c', 'd']: s = s + i",
509 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000510 "s = foo()").testLookup("s", "cdcd");
Ulf Adams89f012d2015-02-26 13:39:28 +0000511 }
512
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000513 @Test
Laurent Le Brun741824b2015-03-20 15:10:19 +0000514 public void testForLoopMultipleVariables() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000515 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000516 " s = ''",
517 " for [i, j] in [[1, 2], [3, 4]]:",
518 " s = s + str(i) + str(j) + '.'",
519 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000520 "s = foo()").testLookup("s", "12.34.");
Laurent Le Brun741824b2015-03-20 15:10:19 +0000521 }
522
523 @Test
Florian Weikert917ceaa2015-06-10 13:54:26 +0000524 public void testForLoopBreak() throws Exception {
525 simpleFlowTest("break", 1);
526 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000527
Florian Weikert917ceaa2015-06-10 13:54:26 +0000528 @Test
529 public void testForLoopContinue() throws Exception {
530 simpleFlowTest("continue", 10);
531 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000532
Florian Weikert917ceaa2015-06-10 13:54:26 +0000533 @SuppressWarnings("unchecked")
534 private void simpleFlowTest(String statement, int expected) throws Exception {
535 eval("def foo():",
536 " s = 0",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000537 " hit = 0",
538 " for i in range(0, 10):",
539 " s = s + 1",
540 " " + statement + "",
541 " hit = 1",
542 " return [s, hit]",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000543 "x = foo()");
544 assertThat((Iterable<Object>) lookup("x")).containsExactly(expected, 0).inOrder();
545 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000546
547 @Test
Florian Weikert917ceaa2015-06-10 13:54:26 +0000548 public void testForLoopBreakFromDeeperBlock() throws Exception {
549 flowFromDeeperBlock("break", 1);
550 flowFromNestedBlocks("break", 29);
551 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000552
553 @Test
Florian Weikert917ceaa2015-06-10 13:54:26 +0000554 public void testForLoopContinueFromDeeperBlock() throws Exception {
555 flowFromDeeperBlock("continue", 5);
556 flowFromNestedBlocks("continue", 39);
557 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000558
Florian Weikert917ceaa2015-06-10 13:54:26 +0000559 private void flowFromDeeperBlock(String statement, int expected) throws Exception {
560 eval("def foo():",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000561 " s = 0",
562 " for i in range(0, 10):",
563 " if i % 2 != 0:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000564 " " + statement + "",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000565 " s = s + 1",
566 " return s",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000567 "x = foo()");
568 assertThat(lookup("x")).isEqualTo(expected);
569 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000570
Florian Weikert917ceaa2015-06-10 13:54:26 +0000571 private void flowFromNestedBlocks(String statement, int expected) throws Exception {
572 eval("def foo2():",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000573 " s = 0",
574 " for i in range(1, 41):",
575 " if i % 2 == 0:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000576 " if i % 3 == 0:",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000577 " if i % 5 == 0:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000578 " " + statement + "",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000579 " s = s + 1",
580 " return s",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000581 "y = foo2()");
582 assertThat(lookup("y")).isEqualTo(expected);
583 }
584
585 @Test
586 public void testNestedForLoopsMultipleBreaks() throws Exception {
587 nestedLoopsTest("break", 2, 6, 6);
588 }
589
590 @Test
591 public void testNestedForLoopsMultipleContinues() throws Exception {
592 nestedLoopsTest("continue", 4, 20, 20);
593 }
594
595 @SuppressWarnings("unchecked")
596 private void nestedLoopsTest(String statement, Integer outerExpected, int firstExpected,
597 int secondExpected) throws Exception {
598 eval("def foo():",
599 " outer = 0",
600 " first = 0",
601 " second = 0",
602 " for i in range(0, 5):",
603 " for j in range(0, 5):",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000604 " if j == 2:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000605 " " + statement + "",
606 " first = first + 1",
607 " for k in range(0, 5):",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000608 " if k == 2:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000609 " " + statement + "",
610 " second = second + 1",
611 " if i == 2:",
612 " " + statement + "",
613 " outer = outer + 1",
614 " return [outer, first, second]",
615 "x = foo()");
616 assertThat((Iterable<Object>) lookup("x"))
617 .containsExactly(outerExpected, firstExpected, secondExpected).inOrder();
618 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000619
Florian Weikert917ceaa2015-06-10 13:54:26 +0000620 @Test
621 public void testForLoopBreakError() throws Exception {
622 flowStatementInsideFunction("break");
623 flowStatementAfterLoop("break");
624 }
625
626 @Test
627 public void testForLoopContinueError() throws Exception {
628 flowStatementInsideFunction("continue");
629 flowStatementAfterLoop("continue");
630 }
631
632 private void flowStatementInsideFunction(String statement) throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000633 checkEvalErrorContains(statement + " statement must be inside a for loop",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000634 "def foo():",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000635 " " + statement + "",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000636 "x = foo()");
637 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000638
Florian Weikert917ceaa2015-06-10 13:54:26 +0000639 private void flowStatementAfterLoop(String statement) throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000640 checkEvalErrorContains(statement + " statement must be inside a for loop",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000641 "def foo2():",
642 " for i in range(0, 3):",
643 " pass",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000644 " " + statement + "",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000645 "y = foo2()");
646 }
Florian Weikert28da3652015-07-01 14:52:30 +0000647
Florian Weikert917ceaa2015-06-10 13:54:26 +0000648 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000649 public void testNoneAssignment() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000650 new SkylarkTest()
651 .setUp("def foo(x=None):", " x = 1", " x = None", " return 2", "s = foo()")
652 .testLookup("s", 2);
Ulf Adams89f012d2015-02-26 13:39:28 +0000653 }
654
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000655 @Test
Laurent Le Brun88014fe2015-06-17 16:02:16 +0000656 public void testReassignment() throws Exception {
657 eval("def foo(x=None):",
658 " x = 1",
659 " x = [1, 2]",
660 " x = 'str'",
661 " return x",
662 "s = foo()");
663 assertThat(lookup("s")).isEqualTo("str");
664 }
665
666 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000667 public void testJavaCalls() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000668 new SkylarkTest()
669 .update("mock", new Mock())
670 .setUp("b = mock.is_empty('a')")
671 .testLookup("b", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000672 }
673
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000674 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000675 public void testJavaCallsOnSubClass() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000676 new SkylarkTest()
677 .update("mock", new MockSubClass())
678 .setUp("b = mock.is_empty('a')")
679 .testLookup("b", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000680 }
681
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000682 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000683 public void testJavaCallsOnInterface() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000684 new SkylarkTest()
685 .update("mock", new MockSubClass())
686 .setUp("b = mock.is_empty_interface('a')")
687 .testLookup("b", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000688 }
689
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000690 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000691 public void testJavaCallsNotSkylarkCallable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000692 new SkylarkTest()
693 .update("mock", new Mock())
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000694 .testIfExactError("type 'Mock' has no method value()", "mock.value()");
Laurent Le Brun648f8f32015-09-09 19:46:29 +0000695 }
696
697 @Test
698 public void testNoOperatorIndex() throws Exception {
699 new SkylarkTest()
700 .update("mock", new Mock())
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000701 .testIfExactError("type 'Mock' has no operator [](int)", "mock[2]");
Ulf Adams89f012d2015-02-26 13:39:28 +0000702 }
703
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000704 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000705 public void testJavaCallsNoMethod() throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000706 new SkylarkTest()
707 .update("mock", new Mock())
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000708 .testIfExactError("type 'Mock' has no method bad()", "mock.bad()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000709 }
710
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000711 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000712 public void testJavaCallsNoMethodErrorMsg() throws Exception {
Laurent Le Brun648f8f32015-09-09 19:46:29 +0000713 new SkylarkTest()
714 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000715 "type 'int' has no method bad(string, string, string)", "s = 3.bad('a', 'b', 'c')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000716 }
717
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000718 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000719 public void testJavaCallsMultipleMethod() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000720 new SkylarkTest()
721 .update("mock", new MockMultipleMethodClass())
722 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000723 "type 'MockMultipleMethodClass' has multiple matches for function method(string)",
Florian Weikert28da3652015-07-01 14:52:30 +0000724 "s = mock.method('string')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000725 }
726
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000727 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000728 public void testJavaCallWithKwargs() throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000729 new SkylarkTest()
730 .update("mock", new Mock())
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000731 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000732 "type 'Mock' has no method isEmpty(string str)", "mock.isEmpty(str='abc')");
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000733 }
734
735
736 @Test
737 public void testJavaCallWithPositionalAndKwargs() throws Exception {
738 new SkylarkTest()
739 .update("mock", new Mock())
740 .setUp("b = mock.with_params(1, True, named=True)")
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000741 .testLookup("b", "with_params(1, true, false, true, false, a)");
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000742 new SkylarkTest()
743 .update("mock", new Mock())
744 .setUp("")
745 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000746 "parameter 'named' has no default value, in method with_params(int, bool) of 'Mock'",
Pedro Liberal Fernandez92f06a52016-09-28 07:33:42 +0000747 "mock.with_params(1, True)");
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000748 new SkylarkTest()
749 .update("mock", new Mock())
750 .setUp("")
751 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000752 "parameter 'named' has no default value, in method with_params(int, bool, bool) "
753 + "of 'Mock'",
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000754 "mock.with_params(1, True, True)");
755 new SkylarkTest()
756 .update("mock", new Mock())
757 .setUp("b = mock.with_params(1, True, True, named=True)")
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000758 .testLookup("b", "with_params(1, true, true, true, false, a)");
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000759 new SkylarkTest()
760 .update("mock", new Mock())
761 .setUp("b = mock.with_params(1, True, named=True, posOrNamed=True)")
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000762 .testLookup("b", "with_params(1, true, true, true, false, a)");
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +0000763 new SkylarkTest()
764 .update("mock", new Mock())
765 .setUp("b = mock.with_params(1, True, named=True, posOrNamed=True, optionalNamed=True)")
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000766 .testLookup("b", "with_params(1, true, true, true, true, a)");
Pedro Liberal Fernandez837dbc12016-08-18 14:13:01 +0000767 new SkylarkTest()
768 .update("mock", new Mock())
769 .setUp("")
770 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000771 "too many arguments, in method with_params(int, bool, bool named, "
772 + "bool posOrNamed, int n) of 'Mock'",
Pedro Liberal Fernandez837dbc12016-08-18 14:13:01 +0000773 "mock.with_params(1, True, named=True, posOrNamed=True, n=2)");
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000774 new SkylarkTest()
775 .update("mock", new Mock())
776 .setUp("")
777 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000778 "parameter 'nonNoneable' cannot be None, in method with_params(int, bool, bool, "
779 + "bool named, bool optionalNamed, NoneType nonNoneable) of 'Mock'",
Pedro Liberal Fernandezd0c5ff22016-08-18 18:53:46 +0000780 "mock.with_params(1, True, True, named=True, optionalNamed=False, nonNoneable=None)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000781 }
782
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000783 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000784 public void testNoJavaCallsWithoutSkylark() throws Exception {
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000785 new SkylarkTest().testIfExactError("type 'int' has no method to_string()", "s = 3.to_string()");
Laurent Le Brun648f8f32015-09-09 19:46:29 +0000786 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000787
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000788 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000789 public void testNoJavaCallsIfClassNotAnnotated() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000790 new SkylarkTest()
791 .update("mock", new MockSubClass())
792 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000793 "type 'Mock' has no method is_empty_class_not_annotated(string)",
Florian Weikert28da3652015-07-01 14:52:30 +0000794 "b = mock.is_empty_class_not_annotated('a')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000795 }
796
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000797 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000798 public void testStructAccess() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000799 new SkylarkTest()
800 .update("mock", new Mock())
801 .setUp("v = mock.struct_field")
802 .testLookup("v", "a");
Ulf Adams89f012d2015-02-26 13:39:28 +0000803 }
804
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000805 @Test
Vladimir Moskvaa5b16742016-10-31 14:09:41 +0000806 public void testStructAccessAsFuncallNonCallable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000807 new SkylarkTest()
808 .update("mock", new Mock())
Vladimir Moskvaa5b16742016-10-31 14:09:41 +0000809 .testIfExactError("'string' object is not callable", "v = mock.struct_field()");
810 }
811
812 @Test
813 public void testStructAccessAsFuncall() throws Exception {
814 foobar.configure(getClass().getDeclaredField("foobar").getAnnotation(SkylarkSignature.class));
815 new SkylarkTest()
816 .update("mock", new Mock())
817 .setUp("v = mock.struct_field_callable()")
818 .testLookup("v", "foobar");
Ulf Adams89f012d2015-02-26 13:39:28 +0000819 }
820
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000821 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000822 public void testStructAccessOfMethod() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000823 new SkylarkTest()
824 .update("mock", new Mock())
Laurent Le Brun57badf42017-01-02 15:12:24 +0000825 .testIfExactError("object of type 'Mock' has no field 'function'", "v = mock.function");
826 }
827
828 @Test
829 public void testStructAccessTypo() throws Exception {
830 new SkylarkTest()
831 .update("mock", new MockClassObject())
832 .testIfExactError(
833 "object of type 'MockClassObject' has no field 'fild' (did you mean 'field'?)",
834 "mock.fild");
Ulf Adams89f012d2015-02-26 13:39:28 +0000835 }
836
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000837 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000838 public void testJavaFunctionReturnsMutableObject() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000839 new SkylarkTest()
840 .update("mock", new Mock())
841 .testIfExactError(
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000842 "method 'return_bad' returns an object of invalid type Bad", "mock.return_bad()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000843 }
844
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000845 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000846 public void testJavaFunctionReturnsNullFails() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000847 new SkylarkTest()
848 .update("mock", new Mock())
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000849 .testIfErrorContains(
850 "method invocation returned None,"
851 + " please file a bug report: nullfunc_failing(\"abc\", 1)",
Florian Weikert28da3652015-07-01 14:52:30 +0000852 "mock.nullfunc_failing('abc', 1)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000853 }
854
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000855 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000856 public void testClassObjectAccess() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000857 new SkylarkTest()
858 .update("mock", new MockClassObject())
859 .setUp("v = mock.field")
860 .testLookup("v", "a");
Ulf Adams89f012d2015-02-26 13:39:28 +0000861 }
862
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000863 @Test
Laurent Le Brunab0ca1a2015-03-31 17:13:25 +0000864 public void testInSet() throws Exception {
Vladimir Moskvad200daf2016-12-23 16:35:37 +0000865 new SkylarkTest()
866 .testStatement("'b' in depset(['a', 'b'])", Boolean.TRUE)
867 .testStatement("'c' in depset(['a', 'b'])", Boolean.FALSE)
868 .testStatement("1 in depset(['a', 'b'])", Boolean.FALSE);
Laurent Le Brunab0ca1a2015-03-31 17:13:25 +0000869 }
870
871 @Test
Laurent Le Brun092f13b2015-08-24 14:50:00 +0000872 public void testUnionSet() throws Exception {
873 new SkylarkTest()
Vladimir Moskvaba4f0bb2017-01-30 15:45:49 +0000874 .testStatement("str(depset([1, 3]) | depset([1, 2]))", "depset([1, 2, 3])")
875 .testStatement("str(depset([1, 2]) | [1, 3])", "depset([1, 2, 3])")
Laurent Le Brun092f13b2015-08-24 14:50:00 +0000876 .testIfExactError("unsupported operand type(s) for |: 'int' and 'int'", "2 | 4");
877 }
878
879 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000880 public void testClassObjectCannotAccessNestedSet() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000881 new SkylarkTest()
882 .update("mock", new MockClassObject())
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000883 .testIfErrorContains("internal error: type 'NestedSet' is not allowed", "v = mock.nset");
Ulf Adams89f012d2015-02-26 13:39:28 +0000884 }
885
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000886 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000887 public void testJavaFunctionReturnsNone() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000888 new SkylarkTest()
889 .update("mock", new Mock())
890 .setUp("v = mock.nullfunc_working()")
Francois-Rene Rideau0f7ba342015-08-31 16:16:21 +0000891 .testLookup("v", Runtime.NONE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000892 }
893
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000894 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000895 public void testVoidJavaFunctionReturnsNone() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000896 new SkylarkTest()
897 .update("mock", new Mock())
898 .setUp("v = mock.voidfunc()")
Francois-Rene Rideau0f7ba342015-08-31 16:16:21 +0000899 .testLookup("v", Runtime.NONE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000900 }
901
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000902 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000903 public void testAugmentedAssignment() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000904 new SkylarkTest().setUp("def f1(x):",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000905 " x += 1",
906 " return x",
907 "",
Florian Weikert28da3652015-07-01 14:52:30 +0000908 "foo = f1(41)").testLookup("foo", 42);
Ulf Adams89f012d2015-02-26 13:39:28 +0000909 }
910
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000911 @Test
Vladimir Moskva23ba4a82017-02-21 15:30:54 +0000912 public void testAugmentedAssignmentHasNoSideEffects() throws Exception {
913 new SkylarkTest().setUp(
914 "counter = [0]",
915 "value = [1, 2]",
916 "",
917 "def f():",
918 " counter[0] = counter[0] + 1",
919 " return value",
920 "",
921 "f()[1] += 1") // `f()` should be called only once here
922 .testLookup("counter", MutableList.of(env, 1));
923 }
924
925 @Test
926 public void testAugmentedAssignmentNotAllowedForListLiterals() throws Exception {
927 new SkylarkTest().testIfErrorContains("Cannot perform augment assignment on a list literal",
928 "def f(a, b):",
929 " [a, b] += []",
930 "f(1, 2)");
931 }
932
933 @Test
934 public void testAssignmentEvaluationOrder() throws Exception {
935 new SkylarkTest().setUp(
936 "ordinary = []",
937 "augmented = []",
938 "value = [1, 2]",
939 "",
940 "def f(record):",
941 " record.append('f')",
942 " return value",
943 "",
944 "def g(record):",
945 " record.append('g')",
946 " return value",
947 "",
948 "f(ordinary)[0] = g(ordinary)[1]",
949 "f(augmented)[0] += g(augmented)[1]")
950 .testLookup("ordinary", MutableList.of(env, "g", "f")) // This order is consistent
951 .testLookup("augmented", MutableList.of(env, "f", "g")); // with Python
952 }
953
954 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000955 public void testStaticDirectJavaCall() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000956 new SkylarkTest().update("Mock", Mock.class).setUp("val = Mock.value_of('8')")
957 .testLookup("val", 8);
Ulf Adams89f012d2015-02-26 13:39:28 +0000958 }
959
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000960 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000961 public void testStaticDirectJavaCallMethodIsNonStatic() throws Exception {
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000962 new SkylarkTest()
963 .update("Mock", Mock.class)
964 .testIfExactError("method 'is_empty' is not static", "val = Mock.is_empty('a')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000965 }
966
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000967 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000968 public void testDictComprehensions_IterationOrder() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000969 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000970 " d = {x : x for x in ['c', 'a', 'b']}",
971 " s = ''",
972 " for a in d:",
973 " s += a",
974 " return s",
Vladimir Moskva76e31d12016-12-05 16:28:37 +0000975 "s = foo()").testLookup("s", "cab");
Ulf Adams89f012d2015-02-26 13:39:28 +0000976 }
977
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000978 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000979 public void testDotExpressionOnNonStructObject() throws Exception {
Laurent Le Brunc31f3512016-12-29 21:41:33 +0000980 new SkylarkTest()
Laurent Le Brun57badf42017-01-02 15:12:24 +0000981 .testIfExactError("object of type 'string' has no field 'field'", "x = 'a'.field");
Ulf Adams89f012d2015-02-26 13:39:28 +0000982 }
983
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000984 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000985 public void testPlusEqualsOnDict() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000986 new SkylarkTest().setUp("def func():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000987 " d = {'a' : 1}",
988 " d += {'b' : 2}",
989 " return d",
Florian Weikert28da3652015-07-01 14:52:30 +0000990 "d = func()")
991 .testLookup("d", ImmutableMap.of("a", 1, "b", 2));
Ulf Adams89f012d2015-02-26 13:39:28 +0000992 }
993
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000994 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000995 public void testDictAssignmentAsLValue() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000996 new SkylarkTest().setUp("def func():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000997 " d = {'a' : 1}",
998 " d['b'] = 2",
999 " return d",
Florian Weikert28da3652015-07-01 14:52:30 +00001000 "d = func()").testLookup("d", ImmutableMap.of("a", 1, "b", 2));
Ulf Adams89f012d2015-02-26 13:39:28 +00001001 }
1002
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001003 @Test
Vladimir Moskva10770382016-08-23 15:04:54 +00001004 public void testNestedDictAssignmentAsLValue() throws Exception {
1005 new SkylarkTest().setUp("def func():",
1006 " d = {'a' : 1}",
1007 " e = {'d': d}",
1008 " e['d']['b'] = 2",
1009 " return e",
1010 "e = func()").testLookup("e", ImmutableMap.of("d", ImmutableMap.of("a", 1, "b", 2)));
1011 }
1012
1013 @Test
1014 public void testListAssignmentAsLValue() throws Exception {
1015 new SkylarkTest().setUp("def func():",
1016 " a = [1, 2]",
1017 " a[1] = 3",
1018 " a[-2] = 4",
1019 " return a",
1020 "a = str(func())").testLookup("a", "[4, 3]");
1021 }
1022
1023 @Test
1024 public void testNestedListAssignmentAsLValue() throws Exception {
1025 new SkylarkTest().setUp("def func():",
1026 " d = [1, 2]",
1027 " e = [3, d]",
1028 " e[1][1] = 4",
1029 " return e",
1030 "e = str(func())").testLookup("e", "[3, [1, 4]]");
1031 }
1032
1033 @Test
Laurent Le Brund640bd32016-01-07 13:58:43 +00001034 public void testDictTupleAssignmentAsLValue() throws Exception {
1035 new SkylarkTest().setUp("def func():",
1036 " d = {'a' : 1}",
1037 " d['b'], d['c'] = 2, 3",
1038 " return d",
1039 "d = func()").testLookup("d", ImmutableMap.of("a", 1, "b", 2, "c", 3));
1040 }
1041
1042 @Test
1043 public void testDictItemPlusEqual() throws Exception {
1044 new SkylarkTest().setUp("def func():",
1045 " d = {'a' : 2}",
1046 " d['a'] += 3",
1047 " return d",
1048 "d = func()").testLookup("d", ImmutableMap.of("a", 5));
1049 }
1050
1051 @Test
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001052 public void testDictAssignmentAsLValueSideEffects() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001053 new SkylarkTest().setUp("def func(d):",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001054 " d['b'] = 2",
1055 "d = {'a' : 1}",
Francois-Rene Rideauab049e02016-02-17 16:13:46 +00001056 "func(d)").testLookup("d", SkylarkDict.of(null, "a", 1, "b", 2));
Ulf Adams89f012d2015-02-26 13:39:28 +00001057 }
1058
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001059 @Test
Francois-Rene Rideauef7a8a52016-01-29 17:37:48 +00001060 public void testAssignmentToListInDictSideEffect() throws Exception {
1061 new SkylarkTest().setUp(
1062 "l = [1, 2]",
1063 "d = {0: l}",
1064 "d[0].append(3)").testLookup("l", MutableList.of(null, 1, 2, 3));
1065 }
1066
1067 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001068 public void testTopLevelDict() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001069 new SkylarkTest().setUp("if 1:",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001070 " v = 'a'",
1071 "else:",
Florian Weikert28da3652015-07-01 14:52:30 +00001072 " v = 'b'").testLookup("v", "a");
Ulf Adams89f012d2015-02-26 13:39:28 +00001073 }
1074
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001075 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001076 public void testUserFunctionKeywordArgs() throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +00001077 new SkylarkTest().setUp("def foo(a, b, c):",
Florian Weikert28da3652015-07-01 14:52:30 +00001078 " return a + b + c", "s = foo(1, c=2, b=3)")
1079 .testLookup("s", 6);
Ulf Adams89f012d2015-02-26 13:39:28 +00001080 }
1081
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001082 @Test
Laurent Le Brun68743162015-05-13 13:18:09 +00001083 public void testFunctionCallOrdering() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001084 new SkylarkTest().setUp("def func(): return foo() * 2",
Laurent Le Brun68743162015-05-13 13:18:09 +00001085 "def foo(): return 2",
Florian Weikert28da3652015-07-01 14:52:30 +00001086 "x = func()")
1087 .testLookup("x", 4);
Laurent Le Brun68743162015-05-13 13:18:09 +00001088 }
1089
1090 @Test
1091 public void testFunctionCallBadOrdering() throws Exception {
Florian Weikert3f610e82015-08-18 14:37:46 +00001092 new SkylarkTest().testIfErrorContains("name 'foo' is not defined",
Laurent Le Brun68743162015-05-13 13:18:09 +00001093 "def func(): return foo() * 2",
1094 "x = func()",
1095 "def foo(): return 2");
1096 }
1097
1098 @Test
Laurent Le Brune102a2d2017-01-02 12:06:18 +00001099 public void testTypo() throws Exception {
1100 new SkylarkTest()
1101 .testIfErrorContains(
1102 "name 'my_variable' is not defined (did you mean 'myVariable'?)",
1103 "myVariable = 2",
1104 "x = my_variable + 1");
1105 }
1106
1107 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001108 public void testNoneTrueFalseInSkylark() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001109 new SkylarkTest().setUp("a = None",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001110 "b = True",
Florian Weikert28da3652015-07-01 14:52:30 +00001111 "c = False")
Francois-Rene Rideau0f7ba342015-08-31 16:16:21 +00001112 .testLookup("a", Runtime.NONE)
Florian Weikert28da3652015-07-01 14:52:30 +00001113 .testLookup("b", Boolean.TRUE)
1114 .testLookup("c", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +00001115 }
1116
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001117 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001118 public void testHasattrMethods() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001119 new SkylarkTest()
1120 .update("mock", new Mock())
1121 .setUp("a = hasattr(mock, 'struct_field')", "b = hasattr(mock, 'function')",
1122 "c = hasattr(mock, 'is_empty')", "d = hasattr('str', 'replace')",
1123 "e = hasattr(mock, 'other')\n")
1124 .testLookup("a", Boolean.TRUE)
1125 .testLookup("b", Boolean.TRUE)
1126 .testLookup("c", Boolean.TRUE)
1127 .testLookup("d", Boolean.TRUE)
1128 .testLookup("e", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +00001129 }
1130
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001131 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001132 public void testListAnTupleConcatenationDoesNotWorkInSkylark() throws Exception {
Francois-Rene Rideau93ed7f12015-10-20 15:39:33 +00001133 new SkylarkTest().testIfExactError("unsupported operand type(s) for +: 'list' and 'tuple'",
Francois-Rene Rideau4e994102015-09-17 22:41:28 +00001134 "[1, 2] + (3, 4)");
Ulf Adams89f012d2015-02-26 13:39:28 +00001135 }
1136
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001137 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001138 public void testCannotCreateMixedListInSkylark() throws Exception {
Laurent Le Brune083a912015-08-10 15:13:34 +00001139 new SkylarkTest().testExactOrder("['a', 'b', 1, 2]", "a", "b", 1, 2);
Ulf Adams89f012d2015-02-26 13:39:28 +00001140 }
1141
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001142 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001143 public void testCannotConcatListInSkylarkWithDifferentGenericTypes() throws Exception {
Laurent Le Brune083a912015-08-10 15:13:34 +00001144 new SkylarkTest().testExactOrder("[1, 2] + ['a', 'b']", 1, 2, "a", "b");
Ulf Adams89f012d2015-02-26 13:39:28 +00001145 }
1146
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001147 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001148 public void testConcatEmptyListWithNonEmptyWorks() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001149 new SkylarkTest().testExactOrder("[] + ['a', 'b']", "a", "b");
Ulf Adams89f012d2015-02-26 13:39:28 +00001150 }
1151
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001152 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001153 public void testFormatStringWithTuple() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001154 new SkylarkTest().setUp("v = '%s%s' % ('a', 1)").testLookup("v", "a1");
Ulf Adams89f012d2015-02-26 13:39:28 +00001155 }
1156
Francois-Rene Rideaue8cfead2015-03-17 16:01:47 +00001157 @Test
1158 public void testSingletonTuple() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001159 new SkylarkTest().testExactOrder("(1,)", 1);
Francois-Rene Rideaue8cfead2015-03-17 16:01:47 +00001160 }
1161
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001162 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001163 public void testDirFindsClassObjectFields() throws Exception {
Laurent Le Brun8e965b82016-08-03 11:50:24 +00001164 new SkylarkTest().update("mock", new MockClassObject())
Florian Weikert28da3652015-07-01 14:52:30 +00001165 .testExactOrder("dir(mock)", "field", "nset");
Ulf Adams89f012d2015-02-26 13:39:28 +00001166 }
1167
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001168 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001169 public void testDirFindsJavaObjectStructFieldsAndMethods() throws Exception {
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +00001170 new SkylarkTest()
1171 .update("mock", new Mock())
1172 .testExactOrder(
1173 "dir(mock)",
1174 "function",
1175 "is_empty",
1176 "nullfunc_failing",
1177 "nullfunc_working",
1178 "return_bad",
1179 "string",
1180 "string_list",
1181 "struct_field",
Vladimir Moskvaa5b16742016-10-31 14:09:41 +00001182 "struct_field_callable",
Damien Martin-Guillerez2d32c582016-08-04 14:29:18 +00001183 "value_of",
1184 "voidfunc",
1185 "with_params");
Ulf Adams89f012d2015-02-26 13:39:28 +00001186 }
1187
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001188 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001189 public void testPrint() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001190 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001191 setFailFast(false);
1192 eval("print('hello')");
Ulf Adamsc708f962015-10-22 12:02:28 +00001193 assertContainsWarning("hello");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001194 eval("print('a', 'b')");
Ulf Adamsc708f962015-10-22 12:02:28 +00001195 assertContainsWarning("a b");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001196 eval("print('a', 'b', sep='x')");
Ulf Adamsc708f962015-10-22 12:02:28 +00001197 assertContainsWarning("axb");
Ulf Adams89f012d2015-02-26 13:39:28 +00001198 }
1199
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001200 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001201 public void testPrintBadKwargs() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001202 new SkylarkTest().testIfExactError(
Francois-Rene Rideau537a90b2015-04-22 06:47:31 +00001203 "unexpected keywords 'end', 'other' in call to print(*args, sep: string = \" \")",
1204 "print(end='x', other='y')");
Ulf Adams89f012d2015-02-26 13:39:28 +00001205 }
1206
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001207 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001208 public void testSkylarkTypes() {
1209 assertEquals(TransitiveInfoCollection.class,
1210 EvalUtils.getSkylarkType(FileConfiguredTarget.class));
1211 assertEquals(TransitiveInfoCollection.class,
1212 EvalUtils.getSkylarkType(RuleConfiguredTarget.class));
1213 assertEquals(Artifact.class, EvalUtils.getSkylarkType(SpecialArtifact.class));
1214 }
1215
1216 // Override tests in EvaluationTest incompatible with Skylark
1217
1218 @SuppressWarnings("unchecked")
1219 @Override
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001220 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001221 public void testConcatLists() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001222 new SkylarkTest().testExactOrder("[1,2] + [3,4]", 1, 2, 3, 4).testExactOrder("(1,2)", 1, 2)
1223 .testExactOrder("(1,2) + (3,4)", 1, 2, 3, 4);
1224
1225 // TODO(fwe): cannot be handled by current testing suite
Ulf Adams89f012d2015-02-26 13:39:28 +00001226 // list
1227 Object x = eval("[1,2] + [3,4]");
1228 assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
Ulf Adams89f012d2015-02-26 13:39:28 +00001229
1230 // tuple
1231 x = eval("(1,2)");
1232 assertThat((Iterable<Object>) x).containsExactly(1, 2).inOrder();
1233 assertTrue(((SkylarkList) x).isTuple());
1234
1235 x = eval("(1,2) + (3,4)");
1236 assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
1237 assertTrue(((SkylarkList) x).isTuple());
1238 }
1239
Ulf Adams89f012d2015-02-26 13:39:28 +00001240 @Override
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001241 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001242 public void testListConcatenation() throws Exception {}
1243
Florian Weikertf07e5442015-07-01 13:08:43 +00001244 @Override
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001245 @Test
1246 public void testInFail() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001247 new SkylarkTest().testIfExactError(
1248 "in operator only works on strings if the left operand is also a string", "1 in '123'");
1249 new SkylarkTest().testIfExactError(
1250 "in operator only works on lists, tuples, sets, dicts and strings", "'a' in 1");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001251 }
1252
Ulf Adams89f012d2015-02-26 13:39:28 +00001253 @Override
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001254 @Test
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001255 public void testListComprehensionsMultipleVariablesFail() throws Exception {
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001256 new SkylarkTest()
1257 .testIfErrorContains(
1258 "lvalue has length 3, but rvalue has has length 2",
1259 "def foo (): return [x + y for x, y, z in [(1, 2), (3, 4)]]",
1260 "foo()");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001261
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001262 new SkylarkTest()
1263 .testIfErrorContains(
1264 "type 'int' is not a collection",
1265 "def bar (): return [x + y for x, y in (1, 2)]",
1266 "bar()");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001267
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001268 new SkylarkTest()
1269 .testIfErrorContains(
1270 "lvalue has length 3, but rvalue has has length 2",
1271 "[x + y for x, y, z in [(1, 2), (3, 4)]]");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001272
1273 // can't reuse the same local variable twice(!)
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001274 new SkylarkTest()
1275 .testIfErrorContains(
Laurent Le Brund4d7fca2017-02-14 19:12:02 +00001276 "Variable x is read only", "[x + y for x, y in (1, 2)]", "[x + y for x, y in (1, 2)]");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001277
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001278 new SkylarkTest()
1279 .testIfErrorContains("type 'int' is not a collection", "[x2 + y2 for x2, y2 in (1, 2)]");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001280 }
1281
1282 @Override
1283 @Test
1284 public void testNotCallInt() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001285 new SkylarkTest().setUp("sum = 123456").testLookup("sum", 123456)
1286 .testIfExactError("'int' object is not callable", "sum(1, 2, 3, 4, 5, 6)")
1287 .testStatement("sum", 123456);
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001288 }
Francois-Rene Rideau6fc5ee72015-03-12 20:55:17 +00001289
1290 @Test
1291 public void testConditionalExpressionAtToplevel() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001292 new SkylarkTest().setUp("x = 1 if 2 else 3").testLookup("x", 1);
Francois-Rene Rideau6fc5ee72015-03-12 20:55:17 +00001293 }
1294
1295 @Test
1296 public void testConditionalExpressionInFunction() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001297 new SkylarkTest().setUp("def foo(a, b, c): return a+b if c else a-b\n").testStatement(
1298 "foo(23, 5, 0)", 18);
Francois-Rene Rideau6fc5ee72015-03-12 20:55:17 +00001299 }
Ulf Adams89f012d2015-02-26 13:39:28 +00001300}