blob: c9e9a652f67eea3e9a53a42da668f27950485043 [file] [log] [blame]
Ulf Adams89f012d2015-02-26 13:39:28 +00001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.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;
23import com.google.common.collect.ImmutableSet;
24import com.google.devtools.build.lib.actions.Artifact;
25import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
26import com.google.devtools.build.lib.analysis.FileConfiguredTarget;
27import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
28import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
29import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Ulf Adams89f012d2015-02-26 13:39:28 +000030import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject;
Florian Weikert28da3652015-07-01 14:52:30 +000031import com.google.devtools.build.lib.testutil.TestMode;
Ulf Adams89f012d2015-02-26 13:39:28 +000032
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000033import org.junit.Test;
34import org.junit.runner.RunWith;
35import org.junit.runners.JUnit4;
36
Ulf Adams89f012d2015-02-26 13:39:28 +000037/**
38 * Evaluation tests with Skylark Environment.
39 */
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000040@RunWith(JUnit4.class)
Ulf Adams89f012d2015-02-26 13:39:28 +000041public class SkylarkEvaluationTest extends EvaluationTest {
Florian Weikert28da3652015-07-01 14:52:30 +000042 public SkylarkEvaluationTest() throws Exception {
43 setMode(TestMode.SKYLARK);
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000044 }
45
Florian Weikert28da3652015-07-01 14:52:30 +000046 /**
47 * Creates an instance of {@code SkylarkTest} in order to run the tests from the base class in a
48 * Skylark context
49 */
50 @Override
51 protected ModalTestCase newTest() {
52 return new SkylarkTest();
53 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +000054
Ulf Adams89f012d2015-02-26 13:39:28 +000055 @SkylarkModule(name = "Mock", doc = "")
56 static class Mock {
57 @SkylarkCallable(doc = "")
58 public static Integer valueOf(String str) {
59 return Integer.valueOf(str);
60 }
61 @SkylarkCallable(doc = "")
62 public Boolean isEmpty(String str) {
63 return str.isEmpty();
64 }
65 public void value() {}
66 @SkylarkCallable(doc = "")
67 public Mock returnMutable() {
68 return new Mock();
69 }
70 @SkylarkCallable(name = "struct_field", doc = "", structField = true)
71 public String structField() {
72 return "a";
73 }
74 @SkylarkCallable(name = "function", doc = "", structField = false)
75 public String function() {
76 return "a";
77 }
78 @SuppressWarnings("unused")
79 @SkylarkCallable(name = "nullfunc_failing", doc = "", allowReturnNones = false)
80 public Object nullfuncFailing(String p1, Integer p2) {
81 return null;
82 }
83 @SkylarkCallable(name = "nullfunc_working", doc = "", allowReturnNones = true)
84 public Object nullfuncWorking() {
85 return null;
86 }
87 @SkylarkCallable(name = "voidfunc", doc = "")
88 public void voidfunc() {}
89 @SkylarkCallable(name = "string_list", doc = "")
90 public ImmutableList<String> stringList() {
91 return ImmutableList.<String>of("a", "b");
92 }
93 @SkylarkCallable(name = "string", doc = "")
94 public String string() {
95 return "a";
96 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +000097 @Override
98 public String toString() {
99 return "<mock>";
100 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000101 }
102
103 @SkylarkModule(name = "MockInterface", doc = "")
104 static interface MockInterface {
105 @SkylarkCallable(doc = "")
106 public Boolean isEmptyInterface(String str);
107 }
108
109 static final class MockSubClass extends Mock implements MockInterface {
110 @Override
111 public Boolean isEmpty(String str) {
112 return str.isEmpty();
113 }
114 @Override
115 public Boolean isEmptyInterface(String str) {
116 return str.isEmpty();
117 }
118 @SkylarkCallable(doc = "")
119 public Boolean isEmptyClassNotAnnotated(String str) {
120 return str.isEmpty();
121 }
122 }
123
124 static final class MockClassObject implements ClassObject {
125 @Override
126 public Object getValue(String name) {
127 switch (name) {
128 case "field": return "a";
129 case "nset": return NestedSetBuilder.stableOrder().build();
130 }
131 throw new IllegalStateException();
132 }
133
134 @Override
135 public ImmutableCollection<String> getKeys() {
136 return ImmutableList.of("field", "nset");
137 }
138
139 @Override
140 public String errorMessage(String name) {
141 return null;
142 }
143 }
144
145 @SkylarkModule(name = "MockMultipleMethodClass", doc = "")
146 static final class MockMultipleMethodClass {
147 @SuppressWarnings("unused")
148 @SkylarkCallable(doc = "")
149 public void method(Object o) {}
150 @SuppressWarnings("unused")
151 @SkylarkCallable(doc = "")
152 public void method(String i) {}
153 }
154
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000155 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000156 public void testSimpleIf() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000157 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000158 " a = 0",
159 " x = 0",
160 " if x: a = 5",
161 " return a",
Florian Weikert28da3652015-07-01 14:52:30 +0000162 "a = foo()").testLookup("a", 0);
Ulf Adams89f012d2015-02-26 13:39:28 +0000163 }
164
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000165 @Test
Laurent Le Brun0942ee92015-03-17 20:22:16 +0000166 public void testIfPass() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000167 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000168 " a = 1",
169 " x = True",
170 " if x: pass",
171 " return a",
Florian Weikert28da3652015-07-01 14:52:30 +0000172 "a = foo()").testLookup("a", 1);
Laurent Le Brun0942ee92015-03-17 20:22:16 +0000173 }
174
175 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000176 public void testNestedIf() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000177 executeNestedIf(0, 0, 0);
178 executeNestedIf(1, 0, 3);
179 executeNestedIf(1, 1, 5);
Ulf Adams89f012d2015-02-26 13:39:28 +0000180 }
181
Florian Weikert28da3652015-07-01 14:52:30 +0000182 private void executeNestedIf(int x, int y, int expected) throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000183 String fun = String.format("foo%s%s", x, y);
Florian Weikert28da3652015-07-01 14:52:30 +0000184 new SkylarkTest().setUp("def " + fun + "():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000185 " x = " + x,
186 " y = " + y,
187 " a = 0",
188 " b = 0",
189 " if x:",
190 " if y:",
191 " a = 2",
192 " b = 3",
193 " return a + b",
Florian Weikert28da3652015-07-01 14:52:30 +0000194 "x = " + fun + "()").testLookup("x", expected);
Ulf Adams89f012d2015-02-26 13:39:28 +0000195 }
196
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000197 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000198 public void testIfElse() throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000199 executeIfElse("foo", "something", 2);
200 executeIfElse("bar", "", 3);
Ulf Adams89f012d2015-02-26 13:39:28 +0000201 }
202
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000203 private void executeIfElse(String fun, String y, int expected) throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000204 new SkylarkTest().setUp("def " + fun + "():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000205 " y = '" + y + "'",
206 " x = 5",
207 " if x:",
208 " if y: a = 2",
209 " else: a = 3",
Florian Weikert28da3652015-07-01 14:52:30 +0000210 " return a",
211 "z = " + fun + "()").testLookup("z", expected);
Ulf Adams89f012d2015-02-26 13:39:28 +0000212 }
213
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000214 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000215 public void testIfElifElse_IfExecutes() throws Exception {
216 execIfElifElse(1, 0, 1);
217 }
218
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000219 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000220 public void testIfElifElse_ElifExecutes() throws Exception {
221 execIfElifElse(0, 1, 2);
222 }
223
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000224 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000225 public void testIfElifElse_ElseExecutes() throws Exception {
226 execIfElifElse(0, 0, 3);
227 }
228
229 private void execIfElifElse(int x, int y, int v) throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000230 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000231 " x = " + x + "",
232 " y = " + y + "",
233 " if x:",
234 " return 1",
235 " elif y:",
236 " return 2",
237 " else:",
238 " return 3",
Florian Weikert28da3652015-07-01 14:52:30 +0000239 "v = foo()").testLookup("v", v);
Ulf Adams89f012d2015-02-26 13:39:28 +0000240 }
241
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000242 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000243 public void testForOnList() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000244 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000245 " s = ''",
246 " for i in ['hello', ' ', 'world']:",
247 " s = s + i",
248 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000249 "s = foo()").testLookup("s", "hello world");
Ulf Adams89f012d2015-02-26 13:39:28 +0000250 }
251
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000252 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000253 public void testForOnString() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000254 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000255 " s = []",
256 " for i in 'abc':",
257 " s = s + [i]",
258 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000259 "s = foo()").testExactOrder("s", "a", "b", "c");
Ulf Adams89f012d2015-02-26 13:39:28 +0000260 }
261
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000262 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000263 public void testForAssignmentList() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000264 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000265 " d = ['a', 'b', 'c']",
266 " s = ''",
267 " for i in d:",
268 " s = s + i",
Florian Weikert28da3652015-07-01 14:52:30 +0000269 " d = ['d', 'e', 'f']", // check that we use the old list
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000270 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000271 "s = foo()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000272 }
273
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000274 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000275 public void testForAssignmentDict() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000276 new SkylarkTest().setUp("def func():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000277 " d = {'a' : 1, 'b' : 2, 'c' : 3}",
278 " s = ''",
279 " for i in d:",
280 " s = s + i",
281 " d = {'d' : 1, 'e' : 2, 'f' : 3}",
282 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000283 "s = func()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000284 }
285
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000286 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000287 public void testForNotIterable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000288 new SkylarkTest()
289 .update("mock", new Mock())
Florian Weikertc1d54ec2015-08-26 14:06:58 +0000290 .testIfErrorContains(
291 "type 'int' is not iterable",
292 "def func():",
293 " for i in mock.value_of('1'): a = i",
294 "func()\n");
Ulf Adams89f012d2015-02-26 13:39:28 +0000295 }
296
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000297 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000298 public void testForOnDictionary() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000299 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000300 " d = {1: 'a', 2: 'b', 3: 'c'}",
301 " s = ''",
302 " for i in d: s = s + d[i]",
303 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000304 "s = foo()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000305 }
306
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000307 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000308 public void testForLoopReuseVariable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000309 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000310 " s = ''",
311 " for i in ['a', 'b']:",
312 " for i in ['c', 'd']: s = s + i",
313 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000314 "s = foo()").testLookup("s", "cdcd");
Ulf Adams89f012d2015-02-26 13:39:28 +0000315 }
316
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000317 @Test
Laurent Le Brun741824b2015-03-20 15:10:19 +0000318 public void testForLoopMultipleVariables() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000319 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000320 " s = ''",
321 " for [i, j] in [[1, 2], [3, 4]]:",
322 " s = s + str(i) + str(j) + '.'",
323 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000324 "s = foo()").testLookup("s", "12.34.");
Laurent Le Brun741824b2015-03-20 15:10:19 +0000325 }
326
327 @Test
Florian Weikert917ceaa2015-06-10 13:54:26 +0000328 public void testForLoopBreak() throws Exception {
329 simpleFlowTest("break", 1);
330 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000331
Florian Weikert917ceaa2015-06-10 13:54:26 +0000332 @Test
333 public void testForLoopContinue() throws Exception {
334 simpleFlowTest("continue", 10);
335 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000336
Florian Weikert917ceaa2015-06-10 13:54:26 +0000337 @SuppressWarnings("unchecked")
338 private void simpleFlowTest(String statement, int expected) throws Exception {
339 eval("def foo():",
340 " s = 0",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000341 " hit = 0",
342 " for i in range(0, 10):",
343 " s = s + 1",
344 " " + statement + "",
345 " hit = 1",
346 " return [s, hit]",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000347 "x = foo()");
348 assertThat((Iterable<Object>) lookup("x")).containsExactly(expected, 0).inOrder();
349 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000350
351 @Test
Florian Weikert917ceaa2015-06-10 13:54:26 +0000352 public void testForLoopBreakFromDeeperBlock() throws Exception {
353 flowFromDeeperBlock("break", 1);
354 flowFromNestedBlocks("break", 29);
355 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000356
357 @Test
Florian Weikert917ceaa2015-06-10 13:54:26 +0000358 public void testForLoopContinueFromDeeperBlock() throws Exception {
359 flowFromDeeperBlock("continue", 5);
360 flowFromNestedBlocks("continue", 39);
361 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000362
Florian Weikert917ceaa2015-06-10 13:54:26 +0000363 private void flowFromDeeperBlock(String statement, int expected) throws Exception {
364 eval("def foo():",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000365 " s = 0",
366 " for i in range(0, 10):",
367 " if i % 2 != 0:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000368 " " + statement + "",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000369 " s = s + 1",
370 " return s",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000371 "x = foo()");
372 assertThat(lookup("x")).isEqualTo(expected);
373 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000374
Florian Weikert917ceaa2015-06-10 13:54:26 +0000375 private void flowFromNestedBlocks(String statement, int expected) throws Exception {
376 eval("def foo2():",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000377 " s = 0",
378 " for i in range(1, 41):",
379 " if i % 2 == 0:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000380 " if i % 3 == 0:",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000381 " if i % 5 == 0:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000382 " " + statement + "",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000383 " s = s + 1",
384 " return s",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000385 "y = foo2()");
386 assertThat(lookup("y")).isEqualTo(expected);
387 }
388
389 @Test
390 public void testNestedForLoopsMultipleBreaks() throws Exception {
391 nestedLoopsTest("break", 2, 6, 6);
392 }
393
394 @Test
395 public void testNestedForLoopsMultipleContinues() throws Exception {
396 nestedLoopsTest("continue", 4, 20, 20);
397 }
398
399 @SuppressWarnings("unchecked")
400 private void nestedLoopsTest(String statement, Integer outerExpected, int firstExpected,
401 int secondExpected) throws Exception {
402 eval("def foo():",
403 " outer = 0",
404 " first = 0",
405 " second = 0",
406 " for i in range(0, 5):",
407 " for j in range(0, 5):",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000408 " if j == 2:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000409 " " + statement + "",
410 " first = first + 1",
411 " for k in range(0, 5):",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000412 " if k == 2:",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000413 " " + statement + "",
414 " second = second + 1",
415 " if i == 2:",
416 " " + statement + "",
417 " outer = outer + 1",
418 " return [outer, first, second]",
419 "x = foo()");
420 assertThat((Iterable<Object>) lookup("x"))
421 .containsExactly(outerExpected, firstExpected, secondExpected).inOrder();
422 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000423
Florian Weikert917ceaa2015-06-10 13:54:26 +0000424 @Test
425 public void testForLoopBreakError() throws Exception {
426 flowStatementInsideFunction("break");
427 flowStatementAfterLoop("break");
428 }
429
430 @Test
431 public void testForLoopContinueError() throws Exception {
432 flowStatementInsideFunction("continue");
433 flowStatementAfterLoop("continue");
434 }
435
436 private void flowStatementInsideFunction(String statement) throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000437 checkEvalErrorContains(statement + " statement must be inside a for loop",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000438 "def foo():",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000439 " " + statement + "",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000440 "x = foo()");
441 }
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000442
Florian Weikert917ceaa2015-06-10 13:54:26 +0000443 private void flowStatementAfterLoop(String statement) throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000444 checkEvalErrorContains(statement + " statement must be inside a for loop",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000445 "def foo2():",
446 " for i in range(0, 3):",
447 " pass",
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000448 " " + statement + "",
Florian Weikert917ceaa2015-06-10 13:54:26 +0000449 "y = foo2()");
450 }
Florian Weikert28da3652015-07-01 14:52:30 +0000451
Florian Weikert917ceaa2015-06-10 13:54:26 +0000452 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000453 public void testNoneAssignment() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000454 new SkylarkTest()
455 .setUp("def foo(x=None):", " x = 1", " x = None", " return 2", "s = foo()")
456 .testLookup("s", 2);
Ulf Adams89f012d2015-02-26 13:39:28 +0000457 }
458
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000459 @Test
Laurent Le Brun88014fe2015-06-17 16:02:16 +0000460 public void testReassignment() throws Exception {
461 eval("def foo(x=None):",
462 " x = 1",
463 " x = [1, 2]",
464 " x = 'str'",
465 " return x",
466 "s = foo()");
467 assertThat(lookup("s")).isEqualTo("str");
468 }
469
470 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000471 public void testJavaCalls() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000472 new SkylarkTest()
473 .update("mock", new Mock())
474 .setUp("b = mock.is_empty('a')")
475 .testLookup("b", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000476 }
477
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000478 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000479 public void testJavaCallsOnSubClass() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000480 new SkylarkTest()
481 .update("mock", new MockSubClass())
482 .setUp("b = mock.is_empty('a')")
483 .testLookup("b", Boolean.FALSE);
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 testJavaCallsOnInterface() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000488 new SkylarkTest()
489 .update("mock", new MockSubClass())
490 .setUp("b = mock.is_empty_interface('a')")
491 .testLookup("b", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000492 }
493
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000494 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000495 public void testJavaCallsNotSkylarkCallable() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000496 new SkylarkTest()
497 .update("mock", new Mock())
498 .testIfExactError("No matching method found for value() in Mock", "mock.value()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000499 }
500
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000501 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000502 public void testJavaCallsNoMethod() throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000503 new SkylarkTest()
504 .update("mock", new Mock())
505 .testIfExactError("No matching method found for bad() in Mock", "mock.bad()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000506 }
507
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000508 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000509 public void testJavaCallsNoMethodErrorMsg() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000510 new SkylarkTest().testIfExactError(
511 "No matching method found for bad(string, string, string) in int",
Ulf Adams89f012d2015-02-26 13:39:28 +0000512 "s = 3.bad('a', 'b', 'c')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000513 }
514
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000515 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000516 public void testJavaCallsMultipleMethod() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000517 new SkylarkTest()
518 .update("mock", new MockMultipleMethodClass())
519 .testIfExactError(
520 "Multiple matching methods for method(string) in MockMultipleMethodClass",
521 "s = mock.method('string')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000522 }
523
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000524 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000525 public void testJavaCallWithKwargs() throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000526 new SkylarkTest()
527 .update("mock", new Mock())
528 .testIfExactError("Keyword arguments are not allowed when calling a java method"
529 + "\nwhile calling method 'string' on object of type Mock",
530 "mock.string(key=True)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000531 }
532
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000533 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000534 public void testNoJavaCallsWithoutSkylark() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000535 new SkylarkTest().testIfExactError(
536 "No matching method found for to_string() in int", "s = 3.to_string()");
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000537 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000538
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000539 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000540 public void testNoJavaCallsIfClassNotAnnotated() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000541 new SkylarkTest()
542 .update("mock", new MockSubClass())
543 .testIfExactError(
544 "No matching method found for is_empty_class_not_annotated(string) in MockSubClass",
545 "b = mock.is_empty_class_not_annotated('a')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000546 }
547
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000548 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000549 public void testStructAccess() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000550 new SkylarkTest()
551 .update("mock", new Mock())
552 .setUp("v = mock.struct_field")
553 .testLookup("v", "a");
Ulf Adams89f012d2015-02-26 13:39:28 +0000554 }
555
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000556 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000557 public void testStructAccessAsFuncall() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000558 new SkylarkTest()
559 .update("mock", new Mock())
560 .testIfExactError(
561 "No matching method found for struct_field() in Mock", "v = mock.struct_field()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000562 }
563
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000564 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000565 public void testStructAccessOfMethod() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000566 new SkylarkTest()
567 .update("mock", new Mock())
568 .testIfExactError("Object of type 'Mock' has no field \"function\"", "v = mock.function");
Ulf Adams89f012d2015-02-26 13:39:28 +0000569 }
570
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000571 @Test
Laurent Le Brune314e2502015-03-13 15:02:46 +0000572 public void testConditionalStructConcatenation() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000573 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000574 eval("def func():",
575 " x = struct(a = 1, b = 2)",
576 " if True:",
577 " x += struct(c = 1, d = 2)",
578 " return x",
Florian Weikert28da3652015-07-01 14:52:30 +0000579 "x = func()");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000580 SkylarkClassObject x = (SkylarkClassObject) lookup("x");
Laurent Le Brune314e2502015-03-13 15:02:46 +0000581 assertEquals(1, x.getValue("a"));
582 assertEquals(2, x.getValue("b"));
583 assertEquals(1, x.getValue("c"));
584 assertEquals(2, x.getValue("d"));
585 }
586
587 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000588 public void testJavaFunctionReturnsMutableObject() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000589 new SkylarkTest()
590 .update("mock", new Mock())
591 .testIfExactError(
592 "Method 'return_mutable' returns a mutable object (type of Mock)",
593 "mock.return_mutable()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000594 }
595
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000596 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000597 public void testJavaFunctionReturnsNullFails() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000598 new SkylarkTest()
599 .update("mock", new Mock())
600 .testIfExactError(
601 "Method invocation returned None,"
602 + " please contact Skylark developers: nullfunc_failing(\"abc\", 1)",
603 "mock.nullfunc_failing('abc', 1)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000604 }
605
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000606 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000607 public void testClassObjectAccess() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000608 new SkylarkTest()
609 .update("mock", new MockClassObject())
610 .setUp("v = mock.field")
611 .testLookup("v", "a");
Ulf Adams89f012d2015-02-26 13:39:28 +0000612 }
613
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000614 @Test
Laurent Le Brunab0ca1a2015-03-31 17:13:25 +0000615 public void testInSet() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000616 new SkylarkTest().testStatement("'b' in set(['a', 'b'])", Boolean.TRUE)
617 .testStatement("'c' in set(['a', 'b'])", Boolean.FALSE)
618 .testStatement("1 in set(['a', 'b'])", Boolean.FALSE);
Laurent Le Brunab0ca1a2015-03-31 17:13:25 +0000619 }
620
621 @Test
Laurent Le Brun092f13b2015-08-24 14:50:00 +0000622 public void testUnionSet() throws Exception {
623 new SkylarkTest()
624 .testStatement("str(set([1, 3]) | set([1, 2]))", "set([1, 2, 3])")
625 .testStatement("str(set([1, 2]) | [1, 3])", "set([1, 2, 3])")
626 .testIfExactError("unsupported operand type(s) for |: 'int' and 'int'", "2 | 4");
627 }
628
629 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000630 public void testClassObjectCannotAccessNestedSet() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000631 new SkylarkTest()
632 .update("mock", new MockClassObject())
633 .testIfExactError("Type is not allowed in Skylark: EmptyNestedSet", "v = mock.nset");
Ulf Adams89f012d2015-02-26 13:39:28 +0000634 }
635
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000636 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000637 public void testJavaFunctionReturnsNone() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000638 new SkylarkTest()
639 .update("mock", new Mock())
640 .setUp("v = mock.nullfunc_working()")
641 .testLookup("v", Environment.NONE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000642 }
643
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000644 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000645 public void testVoidJavaFunctionReturnsNone() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000646 new SkylarkTest()
647 .update("mock", new Mock())
648 .setUp("v = mock.voidfunc()")
649 .testLookup("v", Environment.NONE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000650 }
651
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000652 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000653 public void testAugmentedAssignment() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000654 new SkylarkTest().setUp("def f1(x):",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000655 " x += 1",
656 " return x",
657 "",
Florian Weikert28da3652015-07-01 14:52:30 +0000658 "foo = f1(41)").testLookup("foo", 42);
Ulf Adams89f012d2015-02-26 13:39:28 +0000659 }
660
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000661 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000662 public void testStaticDirectJavaCall() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000663 new SkylarkTest().update("Mock", Mock.class).setUp("val = Mock.value_of('8')")
664 .testLookup("val", 8);
Ulf Adams89f012d2015-02-26 13:39:28 +0000665 }
666
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000667 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000668 public void testStaticDirectJavaCallMethodIsNonStatic() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000669 new SkylarkTest().update("Mock", Mock.class).testIfExactError("Method 'is_empty' is not static",
670 "val = Mock.is_empty('a')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000671 }
672
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000673 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000674 public void testDictComprehensions_IterationOrder() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000675 new SkylarkTest().setUp("def foo():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000676 " d = {x : x for x in ['c', 'a', 'b']}",
677 " s = ''",
678 " for a in d:",
679 " s += a",
680 " return s",
Florian Weikert28da3652015-07-01 14:52:30 +0000681 "s = foo()").testLookup("s", "abc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000682 }
683
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000684 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000685 public void testStructCreation() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000686 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000687 eval("x = struct(a = 1, b = 2)");
688 assertThat(lookup("x")).isInstanceOf(ClassObject.class);
Ulf Adams89f012d2015-02-26 13:39:28 +0000689 }
690
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000691 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000692 public void testStructFields() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000693 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000694 eval("x = struct(a = 1, b = 2)");
695 ClassObject x = (ClassObject) lookup("x");
Ulf Adams89f012d2015-02-26 13:39:28 +0000696 assertEquals(1, x.getValue("a"));
697 assertEquals(2, x.getValue("b"));
698 }
699
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000700 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000701 public void testStructAccessingFieldsFromSkylark() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000702 new SkylarkTest()
703 .setUp("x = struct(a = 1, b = 2)", "x1 = x.a", "x2 = x.b")
704 .testLookup("x1", 1)
705 .testLookup("x2", 2);
Ulf Adams89f012d2015-02-26 13:39:28 +0000706 }
707
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000708 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000709 public void testStructAccessingUnknownField() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000710 new SkylarkTest().testIfExactError(
711 "Object of type 'struct' has no field \"c\"", "x = struct(a = 1, b = 2)", "y = x.c");
Ulf Adams89f012d2015-02-26 13:39:28 +0000712 }
713
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000714 @Test
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000715 public void testStructAccessingUnknownFieldWithArgs() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000716 new SkylarkTest().testIfExactError(
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000717 "struct has no method 'c'", "x = struct(a = 1, b = 2)", "y = x.c()");
718 }
719
720 @Test
721 public void testStructAccessingNonFunctionFieldWithArgs() throws Exception {
722 new SkylarkTest().testIfExactError(
723 "struct field 'a' is not a function", "x = struct(a = 1, b = 2)", "x1 = x.a(1)");
724 }
725
726 @Test
727 public void testStructAccessingFunctionFieldWithArgs() throws Exception {
728 new SkylarkTest()
729 .setUp("def f(x): return x+5", "x = struct(a = f, b = 2)", "x1 = x.a(1)")
730 .testLookup("x1", 6);
Ulf Adams89f012d2015-02-26 13:39:28 +0000731 }
732
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000733 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000734 public void testStructPosArgs() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000735 new SkylarkTest().testIfExactError(
736 "struct(**kwargs) does not accept positional arguments, but got 1", "x = struct(1, b = 2)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000737 }
738
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000739 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000740 public void testStructConcatenationFieldNames() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000741 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000742 eval("x = struct(a = 1, b = 2)",
743 "y = struct(c = 1, d = 2)",
744 "z = x + y\n");
745 SkylarkClassObject z = (SkylarkClassObject) lookup("z");
Ulf Adams89f012d2015-02-26 13:39:28 +0000746 assertEquals(ImmutableSet.of("a", "b", "c", "d"), z.getKeys());
747 }
748
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000749 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000750 public void testStructConcatenationFieldValues() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000751 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000752 eval("x = struct(a = 1, b = 2)",
753 "y = struct(c = 1, d = 2)",
754 "z = x + y\n");
755 SkylarkClassObject z = (SkylarkClassObject) lookup("z");
Ulf Adams89f012d2015-02-26 13:39:28 +0000756 assertEquals(1, z.getValue("a"));
757 assertEquals(2, z.getValue("b"));
758 assertEquals(1, z.getValue("c"));
759 assertEquals(2, z.getValue("d"));
760 }
761
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000762 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000763 public void testStructConcatenationCommonFields() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000764 new SkylarkTest().testIfExactError("Cannot concat structs with common field(s): a",
765 "x = struct(a = 1, b = 2)", "y = struct(c = 1, a = 2)", "z = x + y\n");
Ulf Adams89f012d2015-02-26 13:39:28 +0000766 }
767
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000768 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000769 public void testDotExpressionOnNonStructObject() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000770 new SkylarkTest().testIfExactError("Object of type 'string' has no field \"field\"",
771 "x = 'a'.field");
Ulf Adams89f012d2015-02-26 13:39:28 +0000772 }
773
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000774 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000775 public void testPlusEqualsOnDict() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000776 new SkylarkTest().setUp("def func():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000777 " d = {'a' : 1}",
778 " d += {'b' : 2}",
779 " return d",
Florian Weikert28da3652015-07-01 14:52:30 +0000780 "d = func()")
781 .testLookup("d", ImmutableMap.of("a", 1, "b", 2));
Ulf Adams89f012d2015-02-26 13:39:28 +0000782 }
783
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000784 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000785 public void testDictAssignmentAsLValue() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000786 new SkylarkTest().setUp("def func():",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000787 " d = {'a' : 1}",
788 " d['b'] = 2",
789 " return d",
Florian Weikert28da3652015-07-01 14:52:30 +0000790 "d = func()").testLookup("d", ImmutableMap.of("a", 1, "b", 2));
Ulf Adams89f012d2015-02-26 13:39:28 +0000791 }
792
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000793 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000794 public void testDictAssignmentAsLValueNoSideEffects() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000795 new SkylarkTest().setUp("def func(d):",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000796 " d['b'] = 2",
797 "d = {'a' : 1}",
Florian Weikert28da3652015-07-01 14:52:30 +0000798 "func(d)").testLookup("d", ImmutableMap.of("a", 1));
Ulf Adams89f012d2015-02-26 13:39:28 +0000799 }
800
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000801 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000802 public void testListIndexAsLValueAsLValue() throws Exception {
Florian Weikertc1d54ec2015-08-26 14:06:58 +0000803 new SkylarkTest()
804 .testIfErrorContains(
805 "unsupported operand type(s) for +: 'list' and 'dict'",
806 "def id(l):",
807 " return l",
808 "def func():",
809 " l = id([1])",
810 " l[0] = 2",
811 " return l",
812 "l = func()");
Ulf Adams89f012d2015-02-26 13:39:28 +0000813 }
814
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000815 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000816 public void testTopLevelDict() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000817 new SkylarkTest().setUp("if 1:",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000818 " v = 'a'",
819 "else:",
Florian Weikert28da3652015-07-01 14:52:30 +0000820 " v = 'b'").testLookup("v", "a");
Ulf Adams89f012d2015-02-26 13:39:28 +0000821 }
822
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000823 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000824 public void testUserFunctionKeywordArgs() throws Exception {
Francois-Rene Rideau676905a2015-08-31 15:39:09 +0000825 new SkylarkTest().setUp("def foo(a, b, c):",
Florian Weikert28da3652015-07-01 14:52:30 +0000826 " return a + b + c", "s = foo(1, c=2, b=3)")
827 .testLookup("s", 6);
Ulf Adams89f012d2015-02-26 13:39:28 +0000828 }
829
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000830 @Test
Laurent Le Brun68743162015-05-13 13:18:09 +0000831 public void testFunctionCallOrdering() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000832 new SkylarkTest().setUp("def func(): return foo() * 2",
Laurent Le Brun68743162015-05-13 13:18:09 +0000833 "def foo(): return 2",
Florian Weikert28da3652015-07-01 14:52:30 +0000834 "x = func()")
835 .testLookup("x", 4);
Laurent Le Brun68743162015-05-13 13:18:09 +0000836 }
837
838 @Test
839 public void testFunctionCallBadOrdering() throws Exception {
Florian Weikert3f610e82015-08-18 14:37:46 +0000840 new SkylarkTest().testIfErrorContains("name 'foo' is not defined",
Laurent Le Brun68743162015-05-13 13:18:09 +0000841 "def func(): return foo() * 2",
842 "x = func()",
843 "def foo(): return 2");
844 }
845
846 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000847 public void testNoneTrueFalseInSkylark() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000848 new SkylarkTest().setUp("a = None",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000849 "b = True",
Florian Weikert28da3652015-07-01 14:52:30 +0000850 "c = False")
851 .testLookup("a", Environment.NONE)
852 .testLookup("b", Boolean.TRUE)
853 .testLookup("c", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000854 }
855
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000856 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000857 public void testHasattr() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000858 new SkylarkTest().setUp("s = struct(a=1)",
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000859 "x = hasattr(s, 'a')",
Florian Weikert28da3652015-07-01 14:52:30 +0000860 "y = hasattr(s, 'b')\n")
861 .testLookup("x", Boolean.TRUE)
862 .testLookup("y", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000863 }
864
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000865 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000866 public void testHasattrMethods() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000867 new SkylarkTest()
868 .update("mock", new Mock())
869 .setUp("a = hasattr(mock, 'struct_field')", "b = hasattr(mock, 'function')",
870 "c = hasattr(mock, 'is_empty')", "d = hasattr('str', 'replace')",
871 "e = hasattr(mock, 'other')\n")
872 .testLookup("a", Boolean.TRUE)
873 .testLookup("b", Boolean.TRUE)
874 .testLookup("c", Boolean.TRUE)
875 .testLookup("d", Boolean.TRUE)
876 .testLookup("e", Boolean.FALSE);
Ulf Adams89f012d2015-02-26 13:39:28 +0000877 }
878
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000879 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000880 public void testGetattr() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000881 new SkylarkTest()
882 .setUp("s = struct(a='val')", "x = getattr(s, 'a')", "y = getattr(s, 'b', 'def')",
883 "z = getattr(s, 'b', default = 'def')", "w = getattr(s, 'a', default='ignored')")
884 .testLookup("x", "val")
885 .testLookup("y", "def")
886 .testLookup("z", "def")
887 .testLookup("w", "val");
Ulf Adams89f012d2015-02-26 13:39:28 +0000888 }
889
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000890 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000891 public void testGetattrNoAttr() throws Exception {
Laurent Le Brunfaf78412015-07-28 16:13:00 +0000892 new SkylarkTest().testIfExactError("Object of type 'struct' has no attribute \"b\"",
Florian Weikert28da3652015-07-01 14:52:30 +0000893 "s = struct(a='val')", "getattr(s, 'b')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000894 }
895
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000896 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000897 public void testListAnTupleConcatenationDoesNotWorkInSkylark() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000898 new SkylarkTest().testIfExactError("cannot concatenate lists and tuples", "[1, 2] + (3, 4)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000899 }
900
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000901 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000902 public void testCannotCreateMixedListInSkylark() throws Exception {
Laurent Le Brune083a912015-08-10 15:13:34 +0000903 new SkylarkTest().testExactOrder("['a', 'b', 1, 2]", "a", "b", 1, 2);
Ulf Adams89f012d2015-02-26 13:39:28 +0000904 }
905
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000906 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000907 public void testCannotConcatListInSkylarkWithDifferentGenericTypes() throws Exception {
Laurent Le Brune083a912015-08-10 15:13:34 +0000908 new SkylarkTest().testExactOrder("[1, 2] + ['a', 'b']", 1, 2, "a", "b");
Ulf Adams89f012d2015-02-26 13:39:28 +0000909 }
910
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000911 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000912 public void testConcatEmptyListWithNonEmptyWorks() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000913 new SkylarkTest().testExactOrder("[] + ['a', 'b']", "a", "b");
Ulf Adams89f012d2015-02-26 13:39:28 +0000914 }
915
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000916 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000917 public void testFormatStringWithTuple() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000918 new SkylarkTest().setUp("v = '%s%s' % ('a', 1)").testLookup("v", "a1");
Ulf Adams89f012d2015-02-26 13:39:28 +0000919 }
920
Francois-Rene Rideaue8cfead2015-03-17 16:01:47 +0000921 @Test
922 public void testSingletonTuple() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000923 new SkylarkTest().testExactOrder("(1,)", 1);
Francois-Rene Rideaue8cfead2015-03-17 16:01:47 +0000924 }
925
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000926 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000927 public void testDirFindsClassObjectFields() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000928 new SkylarkTest().update("mock", new MockClassObject()).setUp()
929 .testExactOrder("dir(mock)", "field", "nset");
Ulf Adams89f012d2015-02-26 13:39:28 +0000930 }
931
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000932 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000933 public void testDirFindsJavaObjectStructFieldsAndMethods() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000934 new SkylarkTest().update("mock", new Mock()).testExactOrder("dir(mock)",
935 "function",
936 "is_empty",
937 "nullfunc_failing",
938 "nullfunc_working",
939 "return_mutable",
940 "string",
941 "string_list",
942 "struct_field",
943 "value_of",
944 "voidfunc");
Ulf Adams89f012d2015-02-26 13:39:28 +0000945 }
946
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000947 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000948 public void testPrint() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000949 // TODO(fwe): cannot be handled by current testing suite
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000950 setFailFast(false);
951 eval("print('hello')");
952 assertContainsEvent("hello");
953 eval("print('a', 'b')");
954 assertContainsEvent("a b");
955 eval("print('a', 'b', sep='x')");
956 assertContainsEvent("axb");
Ulf Adams89f012d2015-02-26 13:39:28 +0000957 }
958
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000959 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000960 public void testPrintBadKwargs() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000961 new SkylarkTest().testIfExactError(
Francois-Rene Rideau537a90b2015-04-22 06:47:31 +0000962 "unexpected keywords 'end', 'other' in call to print(*args, sep: string = \" \")",
963 "print(end='x', other='y')");
Ulf Adams89f012d2015-02-26 13:39:28 +0000964 }
965
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000966 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000967 public void testSkylarkTypes() {
968 assertEquals(TransitiveInfoCollection.class,
969 EvalUtils.getSkylarkType(FileConfiguredTarget.class));
970 assertEquals(TransitiveInfoCollection.class,
971 EvalUtils.getSkylarkType(RuleConfiguredTarget.class));
972 assertEquals(Artifact.class, EvalUtils.getSkylarkType(SpecialArtifact.class));
973 }
974
975 // Override tests in EvaluationTest incompatible with Skylark
976
977 @SuppressWarnings("unchecked")
978 @Override
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000979 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000980 public void testConcatLists() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +0000981 new SkylarkTest().testExactOrder("[1,2] + [3,4]", 1, 2, 3, 4).testExactOrder("(1,2)", 1, 2)
982 .testExactOrder("(1,2) + (3,4)", 1, 2, 3, 4);
983
984 // TODO(fwe): cannot be handled by current testing suite
Ulf Adams89f012d2015-02-26 13:39:28 +0000985 // list
986 Object x = eval("[1,2] + [3,4]");
987 assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
Ulf Adams89f012d2015-02-26 13:39:28 +0000988
989 // tuple
990 x = eval("(1,2)");
991 assertThat((Iterable<Object>) x).containsExactly(1, 2).inOrder();
992 assertTrue(((SkylarkList) x).isTuple());
993
994 x = eval("(1,2) + (3,4)");
995 assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
996 assertTrue(((SkylarkList) x).isTuple());
997 }
998
Ulf Adams89f012d2015-02-26 13:39:28 +0000999 @Override
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001000 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +00001001 public void testListConcatenation() throws Exception {}
1002
Florian Weikertf07e5442015-07-01 13:08:43 +00001003 @Override
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001004 @Test
1005 public void testInFail() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001006 new SkylarkTest().testIfExactError(
1007 "in operator only works on strings if the left operand is also a string", "1 in '123'");
1008 new SkylarkTest().testIfExactError(
1009 "in operator only works on lists, tuples, sets, dicts and strings", "'a' in 1");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001010 }
1011
Ulf Adams89f012d2015-02-26 13:39:28 +00001012 @Override
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +00001013 @Test
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001014 public void testListComprehensionsMultipleVariablesFail() throws Exception {
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001015 new SkylarkTest()
1016 .testIfErrorContains(
1017 "lvalue has length 3, but rvalue has has length 2",
1018 "def foo (): return [x + y for x, y, z in [(1, 2), (3, 4)]]",
1019 "foo()");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001020
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001021 new SkylarkTest()
1022 .testIfErrorContains(
1023 "type 'int' is not a collection",
1024 "def bar (): return [x + y for x, y in (1, 2)]",
1025 "bar()");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001026
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001027 new SkylarkTest()
1028 .testIfErrorContains(
1029 "lvalue has length 3, but rvalue has has length 2",
1030 "[x + y for x, y, z in [(1, 2), (3, 4)]]");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001031
1032 // can't reuse the same local variable twice(!)
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001033 new SkylarkTest()
1034 .testIfErrorContains(
1035 "ERROR 2:1: Variable x is read only",
1036 "[x + y for x, y in (1, 2)]",
1037 "[x + y for x, y in (1, 2)]");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001038
Florian Weikertc1d54ec2015-08-26 14:06:58 +00001039 new SkylarkTest()
1040 .testIfErrorContains("type 'int' is not a collection", "[x2 + y2 for x2, y2 in (1, 2)]");
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001041 }
1042
1043 @Override
1044 @Test
1045 public void testNotCallInt() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001046 new SkylarkTest().setUp("sum = 123456").testLookup("sum", 123456)
1047 .testIfExactError("'int' object is not callable", "sum(1, 2, 3, 4, 5, 6)")
1048 .testStatement("sum", 123456);
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +00001049 }
Francois-Rene Rideau6fc5ee72015-03-12 20:55:17 +00001050
1051 @Test
1052 public void testConditionalExpressionAtToplevel() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001053 new SkylarkTest().setUp("x = 1 if 2 else 3").testLookup("x", 1);
Francois-Rene Rideau6fc5ee72015-03-12 20:55:17 +00001054 }
1055
1056 @Test
1057 public void testConditionalExpressionInFunction() throws Exception {
Florian Weikert28da3652015-07-01 14:52:30 +00001058 new SkylarkTest().setUp("def foo(a, b, c): return a+b if c else a-b\n").testStatement(
1059 "foo(23, 5, 0)", 18);
Francois-Rene Rideau6fc5ee72015-03-12 20:55:17 +00001060 }
Ulf Adams89f012d2015-02-26 13:39:28 +00001061}