aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java
diff options
context:
space:
mode:
authorGravatar Han-Wen Nienhuys <hanwen@google.com>2015-02-27 15:53:24 +0000
committerGravatar Ulf Adams <ulfjack@google.com>2015-03-05 14:15:34 +0000
commitccf19eaa0045a26f2654311966b9ece51354ede1 (patch)
tree1d53337658d6ba82d789605406a2a4afd4900a78 /src/test/java
parent22513330de1212d05c2342d4290a057b214a9b96 (diff)
Convert rest of syntax tests to JUnit4.
-- MOS_MIGRATED_REVID=87342725
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java4
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java17
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java62
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java45
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java10
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java93
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java81
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java26
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java31
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java89
10 files changed, 444 insertions, 14 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java
index ba59864ffe..cba1bd61ed 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/AbstractParserTestCase.java
@@ -20,14 +20,12 @@ import com.google.devtools.build.lib.rules.SkylarkModules;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.util.FsApparatus;
-import junit.framework.TestCase;
-
import java.util.List;
/**
* Base class for test cases that use parsing services.
*/
-public abstract class AbstractParserTestCase extends TestCase {
+public abstract class AbstractParserTestCase {
public static final class EmptyPackageLocator implements CachingPackageLocator {
@Override
public Path getBuildFileForPackage(String packageName) {
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
index 045291364c..daa849b3ee 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
@@ -14,14 +14,23 @@
package com.google.devtools.build.lib.syntax;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import com.google.common.collect.Sets;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
/**
* Tests of Environment.
*/
+@RunWith(JUnit4.class)
public class EnvironmentTest extends AbstractEvaluationTestCase {
// Test the API directly
+ @Test
public void testLookupAndUpdate() throws Exception {
Environment env = new Environment();
@@ -37,6 +46,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
assertEquals("bar", env.lookup("foo"));
}
+ @Test
public void testLookupWithDefault() throws Exception {
Environment env = new Environment();
assertEquals(21, env.lookup("VERSION", 21));
@@ -44,6 +54,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
assertEquals(42, env.lookup("VERSION", 21));
}
+ @Test
public void testDoubleUpdateSucceeds() throws Exception {
Environment env = new Environment();
env.update("VERSION", 42);
@@ -53,6 +64,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
}
// Test assign through interpreter, lookup through API:
+ @Test
public void testAssign() throws Exception {
Environment env = new Environment();
@@ -69,6 +81,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
}
// Test update through API, reference through interpreter:
+ @Test
public void testReference() throws Exception {
Environment env = new Environment();
@@ -85,6 +98,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
}
// Test assign and reference through interpreter:
+ @Test
public void testAssignAndReference() throws Exception {
Environment env = new Environment();
@@ -100,6 +114,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
assertEquals("bar", eval(parseExpr("foo"), env));
}
+ @Test
public void testGetVariableNames() throws Exception {
Environment env = new Environment();
env.update("foo", "bar");
@@ -114,6 +129,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
nestedEnv.getVariableNames());
}
+ @Test
public void testToString() throws Exception {
Environment env = new Environment();
env.update("subject", new StringLiteral("Hello, 'world'.", '\''));
@@ -122,6 +138,7 @@ public class EnvironmentTest extends AbstractEvaluationTestCase {
+ "subject -> 'Hello, \\'world\\'.', }", env.toString());
}
+ @Test
public void testBindToNullThrowsException() throws Exception {
try {
new Environment().update("some_name", null);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
index f7ed359dab..f33b500c32 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
@@ -14,6 +14,10 @@
package com.google.devtools.build.lib.syntax;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -22,6 +26,11 @@ import com.google.common.collect.Lists;
import com.google.devtools.build.lib.packages.PackageFactory;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -31,13 +40,14 @@ import java.util.Map;
/**
* Test of evaluation behavior. (Implicitly uses lexer + parser.)
*/
+@RunWith(JUnit4.class)
public class EvaluationTest extends AbstractEvaluationTestCase {
protected Environment env;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
+
PackageFactory factory = new PackageFactory(TestRuleClassProvider.getRuleClassProvider());
env = factory.getEnvironment();
}
@@ -53,6 +63,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
return eval(parseExpr(input), env);
}
+ @Test
public void testExprs() throws Exception {
assertEquals("fooxbar",
eval("'%sx' % 'foo' + 'bar'"));
@@ -70,6 +81,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
checkEvalError("3 % 'foo'", "unsupported operand type(s) for %: 'int' and 'string'");
}
+ @Test
public void testListExprs() throws Exception {
assertEquals(Arrays.asList(1, 2, 3),
eval("[1, 2, 3]"));
@@ -77,10 +89,12 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
eval("(1, 2, 3)"));
}
+ @Test
public void testStringFormatMultipleArgs() throws Exception {
assertEquals("XYZ", eval("'%sY%s' % ('X', 'Z')"));
}
+ @Test
public void testAndOr() throws Exception {
assertEquals(8, eval("8 or 9"));
assertEquals(8, eval("8 or foo")); // check that 'foo' is not evaluated
@@ -104,11 +118,13 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(Environment.NONE, eval("None and 1"));
}
+ @Test
public void testNot() throws Exception {
assertEquals(false, eval("not 1"));
assertEquals(true, eval("not ''"));
}
+ @Test
public void testNotWithLogicOperators() throws Exception {
assertEquals(0, eval("0 and not 0"));
assertEquals(0, eval("not 0 and 0"));
@@ -123,16 +139,19 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(false, eval("not (1 or 0)"));
}
+ @Test
public void testNotWithArithmeticOperators() throws Exception {
assertEquals(true, eval("not 0 + 0"));
assertEquals(false, eval("not 2 - 1"));
}
+ @Test
public void testNotWithCollections() throws Exception {
assertEquals(true, eval("not []"));
assertEquals(false, eval("not {'a' : 1}"));
}
+ @Test
public void testEquality() throws Exception {
assertEquals(true, eval("1 == 1"));
assertEquals(false, eval("1 == 2"));
@@ -143,6 +162,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(true, eval("None == None"));
}
+ @Test
public void testInequality() throws Exception {
assertEquals(false, eval("1 != 1"));
assertEquals(true, eval("1 != 2"));
@@ -152,6 +172,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(true, eval("[1, 2] != [2, 1]"));
}
+ @Test
public void testEqualityPrecedence() throws Exception {
assertEquals(true, eval("1 + 3 == 2 + 2"));
assertEquals(true, eval("not 1 == 2"));
@@ -160,6 +181,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(2, eval("2 or 3 == 3 and 1"));
}
+ @Test
public void testLessThan() throws Exception {
assertEquals(true, eval("1 <= 1"));
assertEquals(false, eval("1 < 1"));
@@ -167,6 +189,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(false, eval("'c' < 'a'"));
}
+ @Test
public void testGreaterThan() throws Exception {
assertEquals(true, eval("1 >= 1"));
assertEquals(false, eval("1 > 1"));
@@ -174,14 +197,17 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(true, eval("'c' > 'a'"));
}
+ @Test
public void testCompareStringInt() throws Exception {
checkEvalError("'a' >= 1", "Cannot compare string with int");
}
+ @Test
public void testNotComparable() throws Exception {
checkEvalError("[1, 2] < [1, 3]", "[1, 2] is not comparable");
}
+ @Test
public void testSumFunction() throws Exception {
Function sum = new AbstractFunction("sum") {
@Override
@@ -216,6 +242,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(123456, eval("sum", env));
}
+ @Test
public void testKeywordArgs() throws Exception {
// This function returns the list of keyword-argument keys or values,
@@ -248,6 +275,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
eval("keyval(1, foo=1, bar='bar', wiz=[1,2,3])", env));
}
+ @Test
public void testMult() throws Exception {
assertEquals(42, eval("6 * 7"));
@@ -256,10 +284,12 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals("100000", eval("'1' + '0' * 5"));
}
+ @Test
public void testConcatStrings() throws Exception {
assertEquals("foobar", eval("'foo' + 'bar'"));
}
+ @Test
public void testConcatLists() throws Exception {
// list
Object x = eval("[1,2] + [3,4]");
@@ -276,6 +306,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
}
@SuppressWarnings("unchecked")
+ @Test
public void testListComprehensions() throws Exception {
Iterable<Object> eval = (Iterable<Object>) eval(
"['foo/%s.java' % x for x in []]");
@@ -311,6 +342,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
// TODO(bazel-team): should this test work in Skylark?
@SuppressWarnings("unchecked")
+ @Test
public void testListComprehensionModifiesGlobalEnv() throws Exception {
Environment env = singletonEnv("x", 42);
assertThat((Iterable<Object>) eval(parseExpr("[x + 1 for x in [1,2,3]]"), env))
@@ -318,6 +350,7 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals(3, env.lookup("x")); // (x is global)
}
+ @Test
public void testDictComprehensions() throws Exception {
assertEquals(Collections.emptyMap(), eval("{x : x for x in []}"));
assertEquals(ImmutableMap.of(1, 1, 2, 2), eval("{x : x for x in [1, 2]}"));
@@ -329,18 +362,21 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
eval("{'k_' + x : 'v_' + x for x in ['a', 'b']}"));
}
+ @Test
public void testDictComprehensions_MultipleKey() throws Exception {
assertEquals(ImmutableMap.of(1, 1, 2, 2), eval("{x : x for x in [1, 2, 1]}"));
assertEquals(ImmutableMap.of("ab", "ab", "c", "c"),
eval("{x : x for x in ['ab', 'c', 'a' + 'b']}"));
}
+ @Test
public void testDictComprehensions_ToString() throws Exception {
assertEquals("{x: x for x in [1, 2]}", parseExpr("{x : x for x in [1, 2]}").toString());
assertEquals("{x + 'a': x for x in [1, 2]}",
parseExpr("{x + 'a' : x for x in [1, 2]}").toString());
}
+ @Test
public void testListConcatenation() throws Exception {
assertEquals(Arrays.asList(1, 2, 3, 4), eval("[1, 2] + [3, 4]", env));
assertEquals(ImmutableList.of(1, 2, 3, 4), eval("(1, 2) + (3, 4)", env));
@@ -348,21 +384,25 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
checkEvalError("(1, 2) + [3, 4]", "can only concatenate list (not \"tuple\") to list");
}
+ @Test
public void testListComprehensionFailsOnNonSequence() throws Exception {
checkEvalError("[x + 1 for x in 123]", "type 'int' is not an iterable");
}
@SuppressWarnings("unchecked")
+ @Test
public void testListComprehensionOnString() throws Exception {
assertThat((Iterable<Object>) eval("[x for x in 'abc']")).containsExactly("a", "b", "c")
.inOrder();
}
+ @Test
public void testInvalidAssignment() throws Exception {
Environment env = singletonEnv("x", 1);
checkEvalError(parseStmt("x + 1 = 2"), env, "can only assign to variables, not to 'x + 1'");
}
+ @Test
public void testListComprehensionOnDictionary() throws Exception {
List<Statement> input = parseFile("val = ['var_' + n for n in {'a':1,'b':2}]");
exec(input, env);
@@ -372,58 +412,71 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
assertEquals("var_b", Iterables.get(result, 1));
}
+ @Test
public void testListComprehensionOnDictionaryCompositeExpression() throws Exception {
exec(parseFile("d = {1:'a',2:'b'}\n"
+ "l = [d[x] for x in d]"), env);
assertEquals("[a, b]", env.lookup("l").toString());
}
+ @Test
public void testInOnListContains() throws Exception {
assertEquals(Boolean.TRUE, eval("'b' in ['a', 'b']"));
}
+ @Test
public void testInOnListDoesNotContain() throws Exception {
assertEquals(Boolean.FALSE, eval("'c' in ['a', 'b']"));
}
+ @Test
public void testInOnTupleContains() throws Exception {
assertEquals(Boolean.TRUE, eval("'b' in ('a', 'b')"));
}
+ @Test
public void testInOnTupleDoesNotContain() throws Exception {
assertEquals(Boolean.FALSE, eval("'c' in ('a', 'b')"));
}
+ @Test
public void testInOnDictContains() throws Exception {
assertEquals(Boolean.TRUE, eval("'b' in {'a' : 1, 'b' : 2}"));
}
+ @Test
public void testInOnDictDoesNotContainKey() throws Exception {
assertEquals(Boolean.FALSE, eval("'c' in {'a' : 1, 'b' : 2}"));
}
+ @Test
public void testInOnDictDoesNotContainVal() throws Exception {
assertEquals(Boolean.FALSE, eval("1 in {'a' : 1, 'b' : 2}"));
}
+ @Test
public void testInOnStringContains() throws Exception {
assertEquals(Boolean.TRUE, eval("'b' in 'abc'"));
}
+ @Test
public void testInOnStringDoesNotContain() throws Exception {
assertEquals(Boolean.FALSE, eval("'d' in 'abc'"));
}
+ @Test
public void testInOnStringLeftNotString() throws Exception {
checkEvalError("1 in '123'",
"in operator only works on strings if the left operand is also a string");
}
+ @Test
public void testInFailsOnNonIterable() throws Exception {
checkEvalError("'a' in 1",
"in operator only works on lists, tuples, dictionaries and strings");
}
+ @Test
public void testInCompositeForPrecedence() throws Exception {
assertEquals(0, eval("not 'a' in ['a'] or 0"));
}
@@ -437,27 +490,32 @@ public class EvaluationTest extends AbstractEvaluationTestCase {
};
}
+ @Test
public void testPercOnObject() throws Exception {
env.update("obj", createObjWithStr());
assertEquals("str marker", eval("'%s' % obj", env));
}
+ @Test
public void testPercOnObjectList() throws Exception {
env.update("obj", createObjWithStr());
assertEquals("str marker str marker", eval("'%s %s' % (obj, obj)", env));
}
+ @Test
public void testPercOnObjectInvalidFormat() throws Exception {
env.update("obj", createObjWithStr());
checkEvalError("'%d' % obj", env, "invalid arguments for format string");
}
@SuppressWarnings("unchecked")
+ @Test
public void testDictKeys() throws Exception {
exec("v = {'a': 1}.keys() + ['b', 'c']", env);
assertThat((Iterable<Object>) env.lookup("v")).containsExactly("a", "b", "c").inOrder();
}
+ @Test
public void testDictKeysTooManyArgs() throws Exception {
checkEvalError("{'a': 1}.keys('abc')", env, "Invalid number of arguments (expected 0)");
checkEvalError("{'a': 1}.keys(arg='abc')", env, "Invalid number of arguments (expected 0)");
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java b/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
index fc14922e2e..eaefb6918e 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/FunctionTest.java
@@ -14,12 +14,20 @@
package com.google.devtools.build.lib.syntax;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.packages.MethodLibrary;
import com.google.devtools.build.lib.syntax.SkylarkType.SkylarkFunctionType;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -27,6 +35,7 @@ import java.util.Map;
/**
* A test class for functions and scoping.
*/
+@RunWith(JUnit4.class)
public class FunctionTest extends AbstractEvaluationTestCase {
private Environment env;
@@ -35,12 +44,13 @@ public class FunctionTest extends AbstractEvaluationTestCase {
ImmutableMap.<String, SkylarkType>of(
"outer_func", SkylarkFunctionType.of("outer_func", SkylarkType.NONE));
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
+
env = new SkylarkEnvironment(syntaxEvents.collector());
}
+ @Test
public void testFunctionDef() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func(a,b,c):\n"
@@ -55,6 +65,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertThat(stmt.getStatements()).hasSize(2);
}
+ @Test
public void testFunctionDefDuplicateArguments() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark(
@@ -63,6 +74,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
syntaxEvents.assertContainsEvent("duplicate parameter name in function definition");
}
+ @Test
public void testFunctionDefCallOuterFunc() throws Exception {
final List<Object> params = new ArrayList<>();
List<Statement> input = parseFileForSkylark(
@@ -89,6 +101,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
env.update("outer_func", outerFunc);
}
+ @Test
public void testFunctionDefNoEffectOutsideScope() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func():\n"
@@ -99,6 +112,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(1, env.lookup("a"));
}
+ @Test
public void testFunctionDefGlobalVaribleReadInFunction() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = 1\n"
@@ -110,6 +124,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(1, env.lookup("c"));
}
+ @Test
public void testFunctionDefLocalGlobalScope() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = 1\n"
@@ -122,6 +137,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(2, env.lookup("c"));
}
+ @Test
public void testFunctionDefLocalVariableReferencedBeforeAssignment() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = 1\n"
@@ -138,6 +154,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
}
}
+ @Test
public void testFunctionDefLocalVariableReferencedAfterAssignment() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = 1\n"
@@ -152,6 +169,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
}
@SuppressWarnings("unchecked")
+ @Test
public void testSkylarkGlobalComprehensionIsAllowed() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = [i for i in [1, 2, 3]]\n");
@@ -159,6 +177,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertThat((Iterable<Object>) env.lookup("a")).containsExactly(1, 2, 3).inOrder();
}
+ @Test
public void testFunctionReturn() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func():\n"
@@ -168,6 +187,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(2, env.lookup("b"));
}
+ @Test
public void testFunctionReturnFromALoop() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func():\n"
@@ -178,6 +198,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(1, env.lookup("b"));
}
+ @Test
public void testFunctionExecutesProperly() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func(a):\n"
@@ -192,6 +213,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(2, env.lookup("d"));
}
+ @Test
public void testFunctionCallFromFunction() throws Exception {
final List<Object> params = new ArrayList<>();
List<Statement> input = parseFileForSkylark(
@@ -207,6 +229,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertThat(params).containsExactly(1, 2).inOrder();
}
+ @Test
public void testFunctionCallFromFunctionReadGlobalVar() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = 1\n"
@@ -219,6 +242,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(1, env.lookup("b"));
}
+ @Test
public void testSingleLineFunction() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func(): return 'a'\n"
@@ -227,6 +251,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals("a", env.lookup("s"));
}
+ @Test
public void testFunctionReturnsDictionary() throws Exception {
MethodLibrary.setupMethodEnvironment(env);
List<Statement> input = parseFileForSkylark(
@@ -237,6 +262,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(1, env.lookup("a"));
}
+ @Test
public void testFunctionReturnsList() throws Exception {
MethodLibrary.setupMethodEnvironment(env);
List<Statement> input = parseFileForSkylark(
@@ -248,6 +274,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
}
@SuppressWarnings("unchecked")
+ @Test
public void testFunctionListArgumentsAreImmutable() throws Exception {
MethodLibrary.setupMethodEnvironment(env);
List<Statement> input = parseFileForSkylark(
@@ -259,6 +286,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertThat((Iterable<Object>) env.lookup("l")).containsExactly(1);
}
+ @Test
public void testFunctionDictArgumentsAreImmutable() throws Exception {
MethodLibrary.setupMethodEnvironment(env);
List<Statement> input = parseFileForSkylark(
@@ -270,6 +298,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableMap.of("a", 1), env.lookup("d"));
}
+ @Test
public void testFunctionNameAliasing() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func(a):\n"
@@ -280,6 +309,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(2, env.lookup("r"));
}
+ @Test
public void testCallingFunctionsWithMixedModeArgs() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func(a, b, c):\n"
@@ -299,6 +329,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
+ " return r\n";
}
+ @Test
public void testWhichOptionalArgsAreDefinedForFunctions() throws Exception {
List<Statement> input = parseFileForSkylark(
functionWithOptionalArgs()
@@ -313,6 +344,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals("4ac", env.lookup("v4"));
}
+ @Test
public void testDefaultArguments() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func(a, b = 'b', c = 'c'):\n"
@@ -328,6 +360,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals("aby", env.lookup("v4"));
}
+ @Test
public void testDefaultArgumentsInsufficientArgNum() throws Exception {
checkError("func(a, b = null, c = null) received insufficient arguments",
"def func(a, b = 'b', c = 'c'):",
@@ -335,6 +368,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
"func()");
}
+ @Test
public void testKwargs() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo(a, b = 'b', c = 'c'):\n"
@@ -349,6 +383,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals("xyz", env.lookup("v3"));
}
+ @Test
public void testKwargsBadKey() throws Exception {
checkError("Keywords must be strings, not int",
"def func(a, b):",
@@ -356,6 +391,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
"func('a', **{3: 1})");
}
+ @Test
public void testKwargsIsNotDict() throws Exception {
checkError("Argument after ** must be a dictionary, not int",
"def func(a, b):",
@@ -363,6 +399,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
"func('a', **42)");
}
+ @Test
public void testKwargsCollision() throws Exception {
checkError("func(a, b) got multiple values for keyword argument 'b'",
"def func(a, b):",
@@ -370,6 +407,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
"func('a', 'b', **{'b': 'foo'})");
}
+ @Test
public void testKwargsCollisionWithNamed() throws Exception {
checkError("duplicate keyword 'b' in call to func",
"def func(a, b):",
@@ -377,6 +415,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
"func('a', b = 'b', **{'b': 'foo'})");
}
+ @Test
public void testDefaultArguments2() throws Exception {
List<Statement> input = parseFileForSkylark(
"a = 2\n"
@@ -389,6 +428,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals(2, env.lookup("v"));
}
+ @Test
public void testMixingPositionalOptional() throws Exception {
List<Statement> input = parseFileForSkylark(
"def f(name, value = '', optional = ''): return value\n"
@@ -397,6 +437,7 @@ public class FunctionTest extends AbstractEvaluationTestCase {
assertEquals("value", env.lookup("v"));
}
+ @Test
public void testStarArg() throws Exception {
List<Statement> input = parseFileForSkylark(
"def f(name, value = '1', optional = '2'): return name + value + optional\n"
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
index c7c2c40134..cb879f8c41 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
@@ -13,13 +13,21 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
import java.util.Arrays;
/**
* Tests for {@link MixedModeFunction}.
*/
+@RunWith(JUnit4.class)
public class MixedModeFunctionTest extends AbstractEvaluationTestCase {
private Environment singletonEnv(String id, Object value) {
@@ -91,6 +99,7 @@ public class MixedModeFunctionTest extends AbstractEvaluationTestCase {
}
}
+ @Test
public void testNoSurplusArguments() throws Exception {
checkMixedModeFunctions(false,
"mixed(foo, bar = null)",
@@ -110,6 +119,7 @@ public class MixedModeFunctionTest extends AbstractEvaluationTestCase {
});
}
+ @Test
public void testOnlyNamedArguments() throws Exception {
checkMixedModeFunctions(true,
"mixed(foo, bar = null)",
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
index e698728553..a4fa5d1f9a 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -15,16 +15,24 @@ package com.google.devtools.build.lib.syntax;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.syntax.DictionaryLiteral.DictionaryEntryLiteral;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
import java.util.List;
/**
* Tests of parser behaviour.
- *
*/
+@RunWith(JUnit4.class)
public class ParserTest extends AbstractParserTestCase {
private static String getText(String text, ASTNode node) {
@@ -57,6 +65,7 @@ public class ParserTest extends AbstractParserTestCase {
return f.getArguments().get(index).getValue();
}
+ @Test
public void testPrecedence1() throws Exception {
BinaryOperatorExpression e =
(BinaryOperatorExpression) parseExpr("'%sx' % 'foo' + 'bar'");
@@ -64,24 +73,28 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(Operator.PLUS, e.getOperator());
}
+ @Test
public void testPrecedence2() throws Exception {
BinaryOperatorExpression e =
(BinaryOperatorExpression) parseExpr("('%sx' % 'foo') + 'bar'");
assertEquals(Operator.PLUS, e.getOperator());
}
+ @Test
public void testPrecedence3() throws Exception {
BinaryOperatorExpression e =
(BinaryOperatorExpression) parseExpr("'%sx' % ('foo' + 'bar')");
assertEquals(Operator.PERCENT, e.getOperator());
}
+ @Test
public void testPrecedence4() throws Exception {
BinaryOperatorExpression e =
(BinaryOperatorExpression) parseExpr("1 + - (2 - 3)");
assertEquals(Operator.PLUS, e.getOperator());
}
+ @Test
public void testUnaryMinusExpr() throws Exception {
FuncallExpression e = (FuncallExpression) parseExpr("-5");
FuncallExpression e2 = (FuncallExpression) parseExpr("- 5");
@@ -96,6 +109,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(5, (int) arg0.getValue());
}
+ @Test
public void testFuncallExpr() throws Exception {
FuncallExpression e = (FuncallExpression) parseExpr("foo(1, 2, bar=wiz)");
@@ -117,6 +131,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("wiz", arg2val.getName());
}
+ @Test
public void testMethCallExpr() throws Exception {
FuncallExpression e =
(FuncallExpression) parseExpr("foo.foo(1, 2, bar=wiz)");
@@ -139,6 +154,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("wiz", arg2val.getName());
}
+ @Test
public void testChainedMethCallExpr() throws Exception {
FuncallExpression e =
(FuncallExpression) parseExpr("foo.replace().split(1)");
@@ -153,6 +169,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(1, (int) arg0.getValue());
}
+ @Test
public void testPropRefExpr() throws Exception {
DotExpression e = (DotExpression) parseExpr("foo.foo");
@@ -160,6 +177,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("foo", ident.getName());
}
+ @Test
public void testStringMethExpr() throws Exception {
FuncallExpression e = (FuncallExpression) parseExpr("'foo'.foo()");
@@ -169,26 +187,31 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(e.getArguments()).isEmpty();
}
+ @Test
public void testStringLiteralOptimizationValue() throws Exception {
StringLiteral l = (StringLiteral) parseExpr("'abc' + 'def'");
assertEquals("abcdef", l.value);
}
+ @Test
public void testStringLiteralOptimizationToString() throws Exception {
StringLiteral l = (StringLiteral) parseExpr("'abc' + 'def'");
assertEquals("'abcdef'", l.toString());
}
+ @Test
public void testStringLiteralOptimizationLocation() throws Exception {
StringLiteral l = (StringLiteral) parseExpr("'abc' + 'def'");
assertEquals(0, l.getLocation().getStartOffset());
assertEquals(13, l.getLocation().getEndOffset());
}
+ @Test
public void testStringLiteralOptimizationDifferentQuote() throws Exception {
assertThat(parseExpr("'abc' + \"def\"")).isInstanceOf(BinaryOperatorExpression.class);
}
+ @Test
public void testSubstring() throws Exception {
FuncallExpression e = (FuncallExpression) parseExpr("'FOO.CC'[:].lower()[1:]");
assertEquals("$substring", e.getFunction().getName());
@@ -214,6 +237,7 @@ public class ParserTest extends AbstractParserTestCase {
}
}
+ @Test
public void testErrorRecovery() throws Exception {
syntaxEvents.setFailFast(false);
@@ -245,6 +269,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(3, (int) arg2.getValue());
}
+ @Test
public void testDoesntGetStuck() throws Exception {
syntaxEvents.setFailFast(false);
@@ -262,6 +287,7 @@ public class ParserTest extends AbstractParserTestCase {
// i.e. there were some events
}
+ @Test
public void testSecondaryLocation() {
String expr = "f(1 % 2)";
FuncallExpression call = (FuncallExpression) parseExpr(expr);
@@ -269,6 +295,7 @@ public class ParserTest extends AbstractParserTestCase {
assertTrue(arg.getLocation().getEndOffset() < call.getLocation().getEndOffset());
}
+ @Test
public void testPrimaryLocation() {
String expr = "f(1 + 2)";
FuncallExpression call = (FuncallExpression) parseExpr(expr);
@@ -276,6 +303,7 @@ public class ParserTest extends AbstractParserTestCase {
assertTrue(arg.getLocation().getEndOffset() < call.getLocation().getEndOffset());
}
+ @Test
public void testAssignLocation() {
String expr = "a = b;c = d\n";
List<Statement> statements = parseFile(expr);
@@ -283,12 +311,14 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(5, statement.getLocation().getEndOffset());
}
+ @Test
public void testAssign() {
String expr = "list[0] = 5; dict['key'] = value\n";
List<Statement> statements = parseFile(expr);
assertThat(statements).hasSize(2);
}
+ @Test
public void testInvalidAssign() {
syntaxEvents.setFailFast(false);
parseExpr("1 + (b = c)");
@@ -296,10 +326,12 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.collector().clear();
}
+ @Test
public void testAugmentedAssign() throws Exception {
assertEquals("[x = x + 1\n]", parseFile("x += 1").toString());
}
+ @Test
public void testPrettyPrintFunctions() throws Exception {
assertEquals("[x[1:3]\n]", parseFile("x[1:3]").toString());
assertEquals("[str[42]\n]", parseFile("str[42]").toString());
@@ -307,6 +339,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("[new_file(['hello'])\n]", parseFile("new_file('hello')").toString());
}
+ @Test
public void testFuncallLocation() {
String expr = "a(b);c = d\n";
List<Statement> statements = parseFile(expr);
@@ -314,6 +347,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(4, statement.getLocation().getEndOffset());
}
+ @Test
public void testSpecialFuncallLocation() throws Exception {
List<Statement> statements = parseFile("-x\n");
assertLocation(0, 3, statements.get(0).getLocation());
@@ -325,6 +359,7 @@ public class ParserTest extends AbstractParserTestCase {
assertLocation(0, 10, statements.get(0).getLocation());
}
+ @Test
public void testListPositions() throws Exception {
String expr = "[0,f(1),2]";
ListLiteral list = (ListLiteral) parseExpr(expr);
@@ -334,6 +369,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("2", getText(expr, getElem(list, 2)));
}
+ @Test
public void testDictPositions() throws Exception {
String expr = "{1:2,2:f(1),3:4}";
DictionaryLiteral list = (DictionaryLiteral) parseExpr(expr);
@@ -343,6 +379,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("3:4", getText(expr, getElem(list, 2)));
}
+ @Test
public void testArgumentPositions() throws Exception {
String stmt = "f(0,g(1,2),2)";
FuncallExpression f = (FuncallExpression) parseExpr(stmt);
@@ -352,6 +389,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals("2", getText(stmt, getArg(f, 2)));
}
+ @Test
public void testListLiterals1() throws Exception {
ListLiteral list = (ListLiteral) parseExpr("[0,1,2]");
assertFalse(list.isTuple());
@@ -362,6 +400,7 @@ public class ParserTest extends AbstractParserTestCase {
}
}
+ @Test
public void testTupleLiterals2() throws Exception {
ListLiteral tuple = (ListLiteral) parseExpr("(0,1,2)");
assertTrue(tuple.isTuple());
@@ -372,12 +411,14 @@ public class ParserTest extends AbstractParserTestCase {
}
}
+ @Test
public void testTupleLiterals3() throws Exception {
ListLiteral emptyTuple = (ListLiteral) parseExpr("()");
assertTrue(emptyTuple.isTuple());
assertThat(emptyTuple.getElements()).isEmpty();
}
+ @Test
public void testTupleLiterals4() throws Exception {
ListLiteral singletonTuple = (ListLiteral) parseExpr("(42,)");
assertTrue(singletonTuple.isTuple());
@@ -385,17 +426,20 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(42, getIntElem(singletonTuple, 0));
}
+ @Test
public void testTupleLiterals5() throws Exception {
IntegerLiteral intLit = (IntegerLiteral) parseExpr("(42)"); // not a tuple!
assertEquals(42, (int) intLit.getValue());
}
+ @Test
public void testListLiterals6() throws Exception {
ListLiteral emptyList = (ListLiteral) parseExpr("[]");
assertFalse(emptyList.isTuple());
assertThat(emptyList.getElements()).isEmpty();
}
+ @Test
public void testListLiterals7() throws Exception {
ListLiteral singletonList = (ListLiteral) parseExpr("[42,]");
assertFalse(singletonList.isTuple());
@@ -403,6 +447,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(42, getIntElem(singletonList, 0));
}
+ @Test
public void testListLiterals8() throws Exception {
ListLiteral singletonList = (ListLiteral) parseExpr("[42]"); // a singleton
assertFalse(singletonList.isTuple());
@@ -410,6 +455,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(42, getIntElem(singletonList, 0));
}
+ @Test
public void testDictionaryLiterals() throws Exception {
DictionaryLiteral dictionaryList =
(DictionaryLiteral) parseExpr("{1:42}"); // a singleton dictionary
@@ -419,12 +465,14 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(42, getIntElem(tuple, false));
}
+ @Test
public void testDictionaryLiterals1() throws Exception {
DictionaryLiteral dictionaryList =
(DictionaryLiteral) parseExpr("{}"); // an empty dictionary
assertThat(dictionaryList.getEntries()).isEmpty();
}
+ @Test
public void testDictionaryLiterals2() throws Exception {
DictionaryLiteral dictionaryList =
(DictionaryLiteral) parseExpr("{1:42,}"); // a singleton dictionary
@@ -434,6 +482,7 @@ public class ParserTest extends AbstractParserTestCase {
assertEquals(42, getIntElem(tuple, false));
}
+ @Test
public void testDictionaryLiterals3() throws Exception {
DictionaryLiteral dictionaryList = (DictionaryLiteral) parseExpr("{1:42,2:43,3:44}");
assertThat(dictionaryList.getEntries()).hasSize(3);
@@ -444,6 +493,7 @@ public class ParserTest extends AbstractParserTestCase {
}
}
+ @Test
public void testListLiterals9() throws Exception {
ListLiteral singletonList =
(ListLiteral) parseExpr("[ abi + opt_level + \'/include\' ]");
@@ -451,6 +501,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(singletonList.getElements()).hasSize(1);
}
+ @Test
public void testListComprehensionSyntax() throws Exception {
syntaxEvents.setFailFast(false);
@@ -475,6 +526,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.collector().clear();
}
+ @Test
public void testListComprehension() throws Exception {
ListComprehension list =
(ListComprehension) parseExpr(
@@ -491,22 +543,26 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(list.getLists()).hasSize(2);
}
+ @Test
public void testParserContainsErrorsIfSyntaxException() throws Exception {
syntaxEvents.setFailFast(false);
parseExpr("'foo' %%");
syntaxEvents.assertContainsEvent("syntax error at '%'");
}
+ @Test
public void testParserDoesNotContainErrorsIfSuccess() throws Exception {
parseExpr("'foo'");
}
+ @Test
public void testParserContainsErrors() throws Exception {
syntaxEvents.setFailFast(false);
parseStmt("+");
syntaxEvents.assertContainsEvent("syntax error at '+'");
}
+ @Test
public void testSemicolonAndNewline() throws Exception {
List<Statement> stmts = parseFile(
"foo='bar'; foo(bar)" + '\n'
@@ -516,6 +572,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(4);
}
+ @Test
public void testSemicolonAndNewline2() throws Exception {
syntaxEvents.setFailFast(false);
List<Statement> stmts = parseFile(
@@ -526,6 +583,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(2);
}
+ @Test
public void testExprAsStatement() throws Exception {
List<Statement> stmts = parseFile(
"li = []\n"
@@ -536,6 +594,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(4);
}
+ @Test
public void testParseBuildFileWithSingeRule() throws Exception {
List<Statement> stmts = parseFile(
"genrule(name = 'foo'," + '\n'
@@ -547,6 +606,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(1);
}
+ @Test
public void testParseBuildFileWithMultipleRules() throws Exception {
List<Statement> stmts = parseFile(
"genrule(name = 'foo'," + '\n'
@@ -563,6 +623,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(2);
}
+ @Test
public void testParseBuildFileWithComments() throws Exception {
Parser.ParseResult result = parseFileWithComments(
"# Test BUILD file" + '\n'
@@ -578,6 +639,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(result.comments).hasSize(2);
}
+ @Test
public void testParseBuildFileWithManyComments() throws Exception {
Parser.ParseResult result = parseFileWithComments(
"# 1" + '\n'
@@ -614,6 +676,7 @@ public class ParserTest extends AbstractParserTestCase {
.that(result.comments.size()).isEqualTo(10); // One per '#'
}
+ @Test
public void testMissingComma() throws Exception {
syntaxEvents.setFailFast(false);
// Regression test.
@@ -623,6 +686,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("syntax error at 'srcs'");
}
+ @Test
public void testDoubleSemicolon() throws Exception {
syntaxEvents.setFailFast(false);
// Regression test.
@@ -630,6 +694,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("syntax error at ';'");
}
+ @Test
public void testFunctionDefinitionErrorRecovery() throws Exception {
// Parser skips over entire function definitions, and reports a meaningful
// error.
@@ -645,6 +710,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(2);
}
+ @Test
public void testFunctionDefinitionIgnored() throws Exception {
// Parser skips over entire function definitions without reporting error,
// when parsePython is set to true.
@@ -666,6 +732,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(2);
}
+ @Test
public void testMissingBlock() throws Exception {
syntaxEvents.setFailFast(false);
List<Statement> stmts = parseFile(
@@ -677,6 +744,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("expected an indented block");
}
+ @Test
public void testInvalidDef() throws Exception {
syntaxEvents.setFailFast(false);
parseFile(
@@ -687,6 +755,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("syntax error at 'EOF'");
}
+ @Test
public void testSkipIfBlock() throws Exception {
// Skip over 'if' blocks, when parsePython is set
List<Statement> stmts = parseFile(
@@ -700,6 +769,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts).hasSize(2);
}
+ @Test
public void testSkipIfBlockFail() throws Exception {
// Do not parse 'if' blocks, when parsePython is not set
syntaxEvents.setFailFast(false);
@@ -713,6 +783,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("This Python-style construct is not supported");
}
+ @Test
public void testForLoopMultipleVariablesFail() throws Exception {
// For loops with multiple variables are not allowed, when parsePython is not set
syntaxEvents.setFailFast(false);
@@ -723,6 +794,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("For loops with multiple variables are not yet supported.");
}
+ @Test
public void testForLoopMultipleVariables() throws Exception {
// For loops with multiple variables is ok, when parsePython is set
List<Statement> stmts1 = parseFile(
@@ -741,6 +813,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmts3).hasSize(1);
}
+ @Test
public void testForLoopBadSyntax() throws Exception {
syntaxEvents.setFailFast(false);
parseFile(
@@ -749,6 +822,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("syntax error");
}
+ @Test
public void testForLoopBadSyntax2() throws Exception {
syntaxEvents.setFailFast(false);
parseFile(
@@ -757,18 +831,21 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("syntax error");
}
+ @Test
public void testFunCallBadSyntax() throws Exception {
syntaxEvents.setFailFast(false);
parseFile("f(1,\n");
syntaxEvents.assertContainsEvent("syntax error");
}
+ @Test
public void testFunCallBadSyntax2() throws Exception {
syntaxEvents.setFailFast(false);
parseFile("f(1, 5, ,)\n");
syntaxEvents.assertContainsEvent("syntax error");
}
+ @Test
public void testLoadOneSymbol() throws Exception {
List<Statement> statements = parseFileForSkylark(
"load('/foo/bar/file', 'fun_test')\n");
@@ -777,6 +854,7 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmt.getSymbols()).hasSize(1);
}
+ @Test
public void testLoadMultipleSymbols() throws Exception {
List<Statement> statements = parseFileForSkylark(
"load('file', 'foo', 'bar')\n");
@@ -785,36 +863,42 @@ public class ParserTest extends AbstractParserTestCase {
assertThat(stmt.getSymbols()).hasSize(2);
}
+ @Test
public void testLoadSyntaxError() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark("load(non_quoted, 'a')\n");
syntaxEvents.assertContainsEvent("syntax error");
}
+ @Test
public void testLoadSyntaxError2() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark("load('non_quoted', a)\n");
syntaxEvents.assertContainsEvent("syntax error");
}
+ @Test
public void testLoadNotAtTopLevel() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark("if 1: load(8)\n");
syntaxEvents.assertContainsEvent("function 'load' does not exist");
}
+ @Test
public void testParseErrorNotComparison() throws Exception {
syntaxEvents.setFailFast(false);
parseFile("2 < not 3");
syntaxEvents.assertContainsEvent("syntax error at 'not'");
}
+ @Test
public void testNotWithArithmeticOperatorsBadSyntax() throws Exception {
syntaxEvents.setFailFast(false);
parseFile("0 + not 0");
syntaxEvents.assertContainsEvent("syntax error at 'not'");
}
+ @Test
public void testOptionalArgBeforeMandatoryArgInFuncDef() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark("def func(a, b = 'a', c):\n return 0\n");
@@ -822,6 +906,7 @@ public class ParserTest extends AbstractParserTestCase {
"a mandatory positional parameter must not follow an optional parameter");
}
+ @Test
public void testKwargBeforePositionalArg() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark(
@@ -830,6 +915,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("unexpected tokens after kwarg");
}
+ @Test
public void testDuplicateKwarg() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark(
@@ -838,6 +924,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("unexpected tokens after kwarg");
}
+ @Test
public void testUnnamedStar() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark(
@@ -845,6 +932,7 @@ public class ParserTest extends AbstractParserTestCase {
syntaxEvents.assertContainsEvent("no star, star-star or named-only parameters (for now)");
}
+ @Test
public void testTopLevelForFails() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark("for i in []: 0\n");
@@ -852,6 +940,7 @@ public class ParserTest extends AbstractParserTestCase {
"for loops are not allowed on top-level. Put it into a function");
}
+ @Test
public void testNestedFunctionFails() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark(
@@ -862,12 +951,14 @@ public class ParserTest extends AbstractParserTestCase {
"nested functions are not allowed. Move the function to top-level");
}
+ @Test
public void testIncludeFailureSkylark() throws Exception {
syntaxEvents.setFailFast(false);
parseFileForSkylark("include('//foo:bar')");
syntaxEvents.assertContainsEvent("function 'include' does not exist");
}
+ @Test
public void testIncludeFailure() throws Exception {
syntaxEvents.setFailFast(false);
parseFile("include('nonexistent')\n");
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index ff3c700760..3e0b0f3285 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -14,6 +14,10 @@
package com.google.devtools.build.lib.syntax;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -31,11 +35,16 @@ import com.google.devtools.build.lib.packages.MethodLibrary;
import com.google.devtools.build.lib.rules.SkylarkModules;
import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
import java.util.List;
/**
* Evaluation tests with Skylark Environment.
*/
+@RunWith(JUnit4.class)
public class SkylarkEvaluationTest extends EvaluationTest {
@SkylarkModule(name = "Mock", doc = "")
@@ -152,6 +161,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
return env;
}
+ @Test
public void testSimpleIf() throws Exception {
exec(parseFileForSkylark(
"def foo():\n"
@@ -163,6 +173,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(0, env.lookup("a"));
}
+ @Test
public void testNestedIf() throws Exception {
executeNestedIf(0, 0, env);
assertEquals(0, env.lookup("x"));
@@ -190,6 +201,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
exec(input, env);
}
+ @Test
public void testIfElse() throws Exception {
executeIfElse("something", 2);
executeIfElse("", 3);
@@ -210,14 +222,17 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(expectedA, env.lookup("a"));
}
+ @Test
public void testIfElifElse_IfExecutes() throws Exception {
execIfElifElse(1, 0, 1);
}
+ @Test
public void testIfElifElse_ElifExecutes() throws Exception {
execIfElifElse(0, 1, 2);
}
+ @Test
public void testIfElifElse_ElseExecutes() throws Exception {
execIfElifElse(0, 0, 3);
}
@@ -238,6 +253,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(v, env.lookup("v"));
}
+ @Test
public void testForOnList() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo():\n"
@@ -252,6 +268,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
}
@SuppressWarnings("unchecked")
+ @Test
public void testForOnString() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo():\n"
@@ -265,6 +282,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertThat((Iterable<Object>) env.lookup("s")).containsExactly("a", "b", "c").inOrder();
}
+ @Test
public void testForAssignmentList() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo():\n"
@@ -280,6 +298,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("abc", env.lookup("s"));
}
+ @Test
public void testForAssignmentDict() throws Exception {
List<Statement> input = parseFileForSkylark(
"def func():\n"
@@ -295,6 +314,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("abc", env.lookup("s"));
}
+ @Test
public void testForNotIterable() throws Exception {
env.update("mock", new Mock());
List<Statement> input = parseFileForSkylark(
@@ -304,6 +324,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
checkEvalError(input, env, "type 'int' is not an iterable");
}
+ @Test
public void testForOnDictionary() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo():\n"
@@ -317,6 +338,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("abc", env.lookup("s"));
}
+ @Test
public void testForLoopReuseVariable() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo():\n"
@@ -330,6 +352,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("cdcd", env.lookup("s"));
}
+ @Test
public void testNoneAssignment() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo(x=None):\n"
@@ -342,6 +365,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(2, env.lookup("s"));
}
+ @Test
public void testJavaCalls() throws Exception {
env.update("mock", new Mock());
List<Statement> input = parseFileForSkylark(
@@ -350,6 +374,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(Boolean.FALSE, env.lookup("b"));
}
+ @Test
public void testJavaCallsOnSubClass() throws Exception {
env.update("mock", new MockSubClass());
List<Statement> input = parseFileForSkylark(
@@ -358,6 +383,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(Boolean.FALSE, env.lookup("b"));
}
+ @Test
public void testJavaCallsOnInterface() throws Exception {
env.update("mock", new MockSubClass());
List<Statement> input = parseFileForSkylark(
@@ -366,18 +392,21 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(Boolean.FALSE, env.lookup("b"));
}
+ @Test
public void testJavaCallsNotSkylarkCallable() throws Exception {
env.update("mock", new Mock());
List<Statement> input = parseFileForSkylark("mock.value()", MOCK_TYPES);
checkEvalError(input, env, "No matching method found for value() in Mock");
}
+ @Test
public void testJavaCallsNoMethod() throws Exception {
List<Statement> input = parseFileForSkylark(
"s = 3.bad()");
checkEvalError(input, env, "No matching method found for bad() in int");
}
+ @Test
public void testJavaCallsNoMethodErrorMsg() throws Exception {
List<Statement> input = parseFileForSkylark(
"s = 3.bad('a', 'b', 'c')");
@@ -385,6 +414,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
"No matching method found for bad(string, string, string) in int");
}
+ @Test
public void testJavaCallsMultipleMethod() throws Exception {
env.update("mock", new MockMultipleMethodClass());
List<Statement> input = parseFileForSkylark(
@@ -393,17 +423,20 @@ public class SkylarkEvaluationTest extends EvaluationTest {
"Multiple matching methods for method(string) in MockMultipleMethodClass");
}
+ @Test
public void testJavaCallWithKwargs() throws Exception {
List<Statement> input = parseFileForSkylark("comp = 3.compare_to(x = 4)");
checkEvalError(input, env, "Keyword arguments are not allowed when calling a java method"
+ "\nwhile calling method 'compare_to' on object 3 of type int");
}
+ @Test
public void testNoJavaCallsWithoutSkylark() throws Exception {
List<Statement> input = parseFileForSkylark("s = 3.to_string()\n");
checkEvalError(input, env, "No matching method found for to_string() in int");
}
+ @Test
public void testNoJavaCallsIfClassNotAnnotated() throws Exception {
env.update("mock", new MockSubClass());
List<Statement> input = parseFileForSkylark(
@@ -412,6 +445,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
"No matching method found for is_empty_class_not_annotated(string) in MockSubClass");
}
+ @Test
public void testStructAccess() throws Exception {
env.update("mock", new Mock());
List<Statement> input = parseFileForSkylark(
@@ -420,24 +454,28 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("a", env.lookup("v"));
}
+ @Test
public void testStructAccessAsFuncall() throws Exception {
env.update("mock", new Mock());
checkEvalError(parseFileForSkylark("v = mock.struct_field()", MOCK_TYPES), env,
"No matching method found for struct_field() in Mock");
}
+ @Test
public void testStructAccessOfMethod() throws Exception {
env.update("mock", new Mock());
checkEvalError(parseFileForSkylark(
"v = mock.function", MOCK_TYPES), env, "Object of type 'Mock' has no field 'function'");
}
+ @Test
public void testJavaFunctionReturnsMutableObject() throws Exception {
env.update("mock", new Mock());
List<Statement> input = parseFileForSkylark("mock.return_mutable()", MOCK_TYPES);
checkEvalError(input, env, "Method 'return_mutable' returns a mutable object (type of Mock)");
}
+ @Test
public void testJavaFunctionReturnsNullFails() throws Exception {
env.update("mock", new Mock());
List<Statement> input = parseFileForSkylark("mock.nullfunc_failing('abc', 1)", MOCK_TYPES);
@@ -445,30 +483,35 @@ public class SkylarkEvaluationTest extends EvaluationTest {
+ " please contact Skylark developers: nullfunc_failing(\"abc\", 1)");
}
+ @Test
public void testClassObjectAccess() throws Exception {
env.update("mock", new MockClassObject());
exec(parseFileForSkylark("v = mock.field", MOCK_TYPES), env);
assertEquals("a", env.lookup("v"));
}
+ @Test
public void testClassObjectCannotAccessNestedSet() throws Exception {
env.update("mock", new MockClassObject());
checkEvalError(parseFileForSkylark("v = mock.nset", MOCK_TYPES), env,
"Type is not allowed in Skylark: EmptyNestedSet");
}
+ @Test
public void testJavaFunctionReturnsNone() throws Exception {
env.update("mock", new Mock());
exec(parseFileForSkylark("v = mock.nullfunc_working()", MOCK_TYPES), env);
assertSame(Environment.NONE, env.lookup("v"));
}
+ @Test
public void testVoidJavaFunctionReturnsNone() throws Exception {
env.update("mock", new Mock());
exec(parseFileForSkylark("v = mock.voidfunc()", MOCK_TYPES), env);
assertSame(Environment.NONE, env.lookup("v"));
}
+ @Test
public void testAugmentedAssignment() throws Exception {
exec(parseFileForSkylark(
"def f1(x):\n"
@@ -479,6 +522,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(42, env.lookup("foo"));
}
+ @Test
public void testStaticDirectJavaCall() throws Exception {
List<Statement> input = parseFileForSkylark(
"val = Mock.value_of('8')", MOCK_TYPES);
@@ -488,6 +532,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(8, env.lookup("val"));
}
+ @Test
public void testStaticDirectJavaCallMethodIsNonStatic() throws Exception {
List<Statement> input = parseFileForSkylark(
"val = Mock.is_empty('a')", MOCK_TYPES);
@@ -496,6 +541,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
checkEvalError(input, env, "Method 'is_empty' is not static");
}
+ @Test
public void testDictComprehensions_IterationOrder() throws Exception {
List<Statement> input = parseFileForSkylark(
"def foo():\n"
@@ -509,11 +555,13 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("cab", env.lookup("s"));
}
+ @Test
public void testStructCreation() throws Exception {
exec(parseFileForSkylark("x = struct(a = 1, b = 2)"), env);
assertThat(env.lookup("x")).isInstanceOf(ClassObject.class);
}
+ @Test
public void testStructFields() throws Exception {
exec(parseFileForSkylark("x = struct(a = 1, b = 2)"), env);
ClassObject x = (ClassObject) env.lookup("x");
@@ -521,6 +569,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(2, x.getValue("b"));
}
+ @Test
public void testStructAccessingFieldsFromSkylark() throws Exception {
exec(parseFileForSkylark(
"x = struct(a = 1, b = 2)\n"
@@ -530,12 +579,14 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(2, env.lookup("x2"));
}
+ @Test
public void testStructAccessingUnknownField() throws Exception {
checkEvalError(parseFileForSkylark(
"x = struct(a = 1, b = 2)\n"
+ "y = x.c\n"), env, "Object of type 'struct' has no field 'c'");
}
+ @Test
public void testStructAccessingFieldsWithArgs() throws Exception {
checkEvalError(parseFileForSkylark(
"x = struct(a = 1, b = 2)\n"
@@ -543,12 +594,14 @@ public class SkylarkEvaluationTest extends EvaluationTest {
env, "No matching method found for a(int) in struct");
}
+ @Test
public void testStructPosArgs() throws Exception {
checkEvalError(parseFileForSkylark(
"x = struct(1, b = 2)\n"),
env, "struct only supports keyword arguments");
}
+ @Test
public void testStructConcatenationFieldNames() throws Exception {
exec(parseFileForSkylark(
"x = struct(a = 1, b = 2)\n"
@@ -558,6 +611,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(ImmutableSet.of("a", "b", "c", "d"), z.getKeys());
}
+ @Test
public void testStructConcatenationFieldValues() throws Exception {
exec(parseFileForSkylark(
"x = struct(a = 1, b = 2)\n"
@@ -570,6 +624,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(2, z.getValue("d"));
}
+ @Test
public void testStructConcatenationCommonFields() throws Exception {
checkEvalError(parseFileForSkylark(
"x = struct(a = 1, b = 2)\n"
@@ -577,11 +632,13 @@ public class SkylarkEvaluationTest extends EvaluationTest {
+ "z = x + y\n"), env, "Cannot concat structs with common field(s): a");
}
+ @Test
public void testDotExpressionOnNonStructObject() throws Exception {
checkEvalError(parseFileForSkylark(
"x = 'a'.field"), env, "Object of type 'string' has no field 'field'");
}
+ @Test
public void testPlusEqualsOnDict() throws Exception {
MethodLibrary.setupMethodEnvironment(env);
exec(parseFileForSkylark(
@@ -593,6 +650,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(ImmutableMap.of("a", 1, "b", 2), env.lookup("d"));
}
+ @Test
public void testDictAssignmentAsLValue() throws Exception {
exec(parseFileForSkylark(
"def func():\n"
@@ -603,6 +661,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(ImmutableMap.of("a", 1, "b", 2), env.lookup("d"));
}
+ @Test
public void testDictAssignmentAsLValueNoSideEffects() throws Exception {
MethodLibrary.setupMethodEnvironment(env);
exec(parseFileForSkylark(
@@ -613,6 +672,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(ImmutableMap.of("a", 1), env.lookup("d"));
}
+ @Test
public void testListIndexAsLValueAsLValue() throws Exception {
checkEvalError(parseFileForSkylark(
"def id(l):\n"
@@ -624,6 +684,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
+ "l = func()"), env, "unsupported operand type(s) for +: 'list' and 'dict'");
}
+ @Test
public void testTopLevelDict() throws Exception {
exec(parseFileForSkylark(
"if 1:\n"
@@ -633,6 +694,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("a", env.lookup("v"));
}
+ @Test
public void testUserFunctionKeywordArgs() throws Exception {
exec(parseFileForSkylark(
"def foo(a, b, c):\n"
@@ -641,6 +703,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals(6, env.lookup("s"));
}
+ @Test
public void testNoneTrueFalseInSkylark() throws Exception {
exec(parseFileForSkylark(
"a = None\n"
@@ -651,6 +714,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertFalse((Boolean) env.lookup("c"));
}
+ @Test
public void testHasattr() throws Exception {
exec(parseFileForSkylark(
"s = struct(a=1)\n"
@@ -660,6 +724,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertFalse((Boolean) env.lookup("y"));
}
+ @Test
public void testHasattrMethods() throws Exception {
env.update("mock", new Mock());
ValidationEnvironment validEnv = SkylarkModules.getValidationEnvironment();
@@ -678,6 +743,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertFalse((Boolean) env.lookup("e"));
}
+ @Test
public void testGetattr() throws Exception {
exec(parseFileForSkylark(
"s = struct(a='val')\n"
@@ -691,6 +757,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
assertEquals("val", env.lookup("w"));
}
+ @Test
public void testGetattrNoAttr() throws Exception {
checkEvalError(parseFileForSkylark(
"s = struct(a='val')\n"
@@ -699,17 +766,20 @@ public class SkylarkEvaluationTest extends EvaluationTest {
}
@SuppressWarnings("unchecked")
+ @Test
public void testListAnTupleConcatenationDoesNotWorkInSkylark() throws Exception {
checkEvalError(parseFileForSkylark("[1, 2] + (3, 4)"), env,
"cannot concatenate lists and tuples");
}
+ @Test
public void testCannotCreateMixedListInSkylark() throws Exception {
env.update("mock", new Mock());
checkEvalError(parseFileForSkylark("[mock.string(), 1, 2]", MOCK_TYPES), env,
"Incompatible types in list: found a int but the previous elements were strings");
}
+ @Test
public void testCannotConcatListInSkylarkWithDifferentGenericTypes() throws Exception {
env.update("mock", new Mock());
checkEvalError(parseFileForSkylark("mock.string_list() + [1, 2]", MOCK_TYPES), env,
@@ -717,17 +787,20 @@ public class SkylarkEvaluationTest extends EvaluationTest {
}
@SuppressWarnings("unchecked")
+ @Test
public void testConcatEmptyListWithNonEmptyWorks() throws Exception {
exec(parseFileForSkylark("l = [] + ['a', 'b']", MOCK_TYPES), env);
assertThat((Iterable<Object>) env.lookup("l")).containsExactly("a", "b").inOrder();
}
+ @Test
public void testFormatStringWithTuple() throws Exception {
exec(parseFileForSkylark("v = '%s%s' % ('a', 1)"), env);
assertEquals("a1", env.lookup("v"));
}
@SuppressWarnings("unchecked")
+ @Test
public void testDirFindsClassObjectFields() throws Exception {
env.update("mock", new MockClassObject());
exec(parseFileForSkylark("v = dir(mock)", MOCK_TYPES), env);
@@ -735,6 +808,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
}
@SuppressWarnings("unchecked")
+ @Test
public void testDirFindsJavaObjectStructFieldsAndMethods() throws Exception {
env.update("mock", new Mock());
exec(parseFileForSkylark("v = dir(mock)", MOCK_TYPES), env);
@@ -743,6 +817,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
"struct_field", "value_of", "voidfunc").inOrder();
}
+ @Test
public void testPrint() throws Exception {
exec(parseFileForSkylark("print('hello')"), env);
syntaxEvents.assertContainsEvent("hello");
@@ -752,10 +827,12 @@ public class SkylarkEvaluationTest extends EvaluationTest {
syntaxEvents.assertContainsEvent("axb");
}
+ @Test
public void testPrintBadKwargs() throws Exception {
checkEvalError("print(end='x', other='y')", "unexpected keywords: '[end, other]'");
}
+ @Test
public void testSkylarkTypes() {
assertEquals(TransitiveInfoCollection.class,
EvalUtils.getSkylarkType(FileConfiguredTarget.class));
@@ -768,6 +845,7 @@ public class SkylarkEvaluationTest extends EvaluationTest {
@SuppressWarnings("unchecked")
@Override
+ @Test
public void testConcatLists() throws Exception {
// list
Object x = eval("[1,2] + [3,4]");
@@ -786,14 +864,17 @@ public class SkylarkEvaluationTest extends EvaluationTest {
@SuppressWarnings("unchecked")
@Override
+ @Test
public void testListExprs() throws Exception {
assertThat((Iterable<Object>) eval("[1, 2, 3]")).containsExactly(1, 2, 3).inOrder();
assertThat((Iterable<Object>) eval("(1, 2, 3)")).containsExactly(1, 2, 3).inOrder();
}
@Override
+ @Test
public void testListConcatenation() throws Exception {}
@Override
+ @Test
public void testKeywordArgs() {}
}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
index 23471980f9..e3ee1e1630 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
@@ -13,16 +13,26 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.MethodLibrary;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
import java.util.Iterator;
/**
* Tests for SkylarkList.
*/
+@RunWith(JUnit4.class)
public class SkylarkListTest extends AbstractEvaluationTestCase {
@Immutable
@@ -43,31 +53,36 @@ public class SkylarkListTest extends AbstractEvaluationTestCase {
private Environment env;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
+
env = new SkylarkEnvironment(syntaxEvents.collector());
env.update("lazy", list);
MethodLibrary.setupMethodEnvironment(env);
}
+ @Test
public void testLazyListIndex() throws Exception {
checkError("Iterator requested", "a = lazy[0]");
}
+ @Test
public void testLazyListSize() throws Exception {
checkError("Iterator requested", "a = len(lazy)");
}
+ @Test
public void testLazyListEmpty() throws Exception {
checkError("Iterator requested", "if lazy:\n a = 1");
}
+ @Test
public void testLazyListConcat() throws Exception {
exec("v = [1, 2] + lazy");
assertTrue(env.lookup("v") instanceof SkylarkList);
}
+ @Test
public void testConcatListIndex() throws Exception {
exec("l = [1, 2] + [3, 4]",
"e0 = l[0]",
@@ -80,6 +95,7 @@ public class SkylarkListTest extends AbstractEvaluationTestCase {
assertEquals(4, env.lookup("e3"));
}
+ @Test
public void testConcatListHierarchicalIndex() throws Exception {
exec("l = [1] + (([2] + [3, 4]) + [5])",
"e0 = l[0]",
@@ -94,18 +110,21 @@ public class SkylarkListTest extends AbstractEvaluationTestCase {
assertEquals(5, env.lookup("e4"));
}
+ @Test
public void testConcatListSize() throws Exception {
exec("l = [1, 2] + [3, 4]",
"s = len(l)");
assertEquals(4, env.lookup("s"));
}
+ @Test
public void testConcatListToString() throws Exception {
exec("l = [1, 2] + [3, 4]",
"s = str(l)");
assertEquals("[1, 2, 3, 4]", env.lookup("s"));
}
+ @Test
public void testConcatListNotEmpty() throws Exception {
exec("l = [1, 2] + [3, 4]",
"if l:",
@@ -115,6 +134,7 @@ public class SkylarkListTest extends AbstractEvaluationTestCase {
assertEquals(1, env.lookup("v"));
}
+ @Test
public void testConcatListEmpty() throws Exception {
exec("l = [] + []",
"if l:",
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
index 622f0440a9..48a5672934 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
@@ -13,41 +13,55 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.MethodLibrary;
import com.google.devtools.build.lib.syntax.Environment.NoSuchVariableException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
/**
* Tests for SkylarkNestedSet.
*/
+@RunWith(JUnit4.class)
public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
private Environment env;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() throws Exception {
+
env = new SkylarkEnvironment(syntaxEvents.collector());
MethodLibrary.setupMethodEnvironment(env);
}
+ @Test
public void testNsetBuilder() throws Exception {
exec("n = set(order='stable')");
assertTrue(env.lookup("n") instanceof SkylarkNestedSet);
}
+ @Test
public void testNsetOrder() throws Exception {
exec("n = set(['a', 'b'], order='compile')");
assertEquals(Order.COMPILE_ORDER, get("n").getSet(String.class).getOrder());
}
+ @Test
public void testEmptyNsetGenericType() throws Exception {
exec("n = set()");
assertEquals(SkylarkType.TOP, get("n").getContentType());
}
+ @Test
public void testFunctionReturnsNset() throws Exception {
exec("def func():",
" n = set()",
@@ -57,6 +71,7 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of("a"), get("s").toCollection());
}
+ @Test
public void testNsetTwoReferences() throws Exception {
exec("def func():",
" n1 = set()",
@@ -68,6 +83,7 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of("a"), get("n").toCollection());
}
+ @Test
public void testNsetNestedItem() throws Exception {
exec("def func():",
" n1 = set()",
@@ -80,11 +96,13 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of("b", "a"), get("n").toCollection());
}
+ @Test
public void testNsetNestedItemBadOrder() throws Exception {
checkError("LINK_ORDER != COMPILE_ORDER",
"set(['a', 'b'], order='compile') + set(['c', 'd'], order='link')");
}
+ @Test
public void testNsetItemList() throws Exception {
exec("def func():",
" n = set()",
@@ -94,6 +112,7 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of("a", "b"), get("n").toCollection());
}
+ @Test
public void testNsetFuncParamNoSideEffects() throws Exception {
exec("def func1(n):",
" n += ['b']",
@@ -106,6 +125,7 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of("a"), get("n").toCollection());
}
+ @Test
public void testNsetTransitiveOrdering() throws Exception {
exec("def func():",
" na = set(['a'], order='compile')",
@@ -117,6 +137,7 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of("b", "a", "c"), get("n").toCollection());
}
+ @Test
public void testNsetOrdering() throws Exception {
exec("def func():",
" na = set()",
@@ -129,22 +150,26 @@ public class SkylarkNestedSetTest extends AbstractEvaluationTestCase {
assertEquals(ImmutableList.of(4, 2, 3, 5), get("n").toCollection());
}
+ @Test
public void testNsetBadOrder() throws Exception {
checkError("Invalid order: non_existing",
"set(order='non_existing')");
}
+ @Test
public void testNsetBadRightOperand() throws Exception {
checkError("cannot add 'string'-s to nested sets",
"l = ['a']\n",
"set() + l[0]");
}
+ @Test
public void testNsetBadCompositeItem() throws Exception {
checkError("nested set item is composite (type of struct)",
"set([struct(a='a')])");
}
+ @Test
public void testNsetToString() throws Exception {
exec("s = set() + [2, 4, 6] + [3, 4, 5]",
"x = str(s)");
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
index 49c552e83c..62b0d85425 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
@@ -15,11 +15,17 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Joiner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
/**
* Tests for the validation process of Skylark files.
*/
+@RunWith(JUnit4.class)
public class ValidationTests extends AbstractParserTestCase {
+ @Test
public void testIncompatibleLiteralTypesStringInt() {
checkError("bad variable 'a': int is incompatible with string at /some/file.txt",
"def foo():\n",
@@ -27,6 +33,7 @@ public class ValidationTests extends AbstractParserTestCase {
" a = 1");
}
+ @Test
public void testIncompatibleLiteralTypesDictString() {
checkError("bad variable 'a': int is incompatible with dict of ints at /some/file.txt:3:3",
"def foo():\n",
@@ -34,6 +41,7 @@ public class ValidationTests extends AbstractParserTestCase {
" a = 1");
}
+ @Test
public void testIncompatibleLiteralTypesInIf() {
checkError("bad variable 'a': int is incompatible with string at /some/file.txt",
"def foo():\n",
@@ -43,47 +51,56 @@ public class ValidationTests extends AbstractParserTestCase {
" a = 1");
}
+ @Test
public void testAssignmentNotValidLValue() {
checkError("can only assign to variables, not to ''a''", "'a' = 1");
}
+ @Test
public void testForNotIterable() throws Exception {
checkError("type 'int' is not iterable",
"def func():\n"
+ " for i in 5: a = i\n");
}
+ @Test
public void testForIterableWithUknownArgument() throws Exception {
parse("def func(x=None):\n"
+ " for i in x: a = i\n");
}
+ @Test
public void testForNotIterableBinaryExpression() throws Exception {
checkError("type 'int' is not iterable",
"def func():\n"
+ " for i in 1 + 1: a = i\n");
}
+ @Test
public void testOptionalArgument() throws Exception {
checkError("type 'int' is not iterable",
"def func(x=5):\n"
+ " for i in x: a = i\n");
}
+ @Test
public void testOptionalArgumentHasError() throws Exception {
checkError("unsupported operand type(s) for +: 'int' and 'string'",
"def func(x=5+'a'):\n"
+ " return 0\n");
}
+ @Test
public void testTopLevelForStatement() throws Exception {
checkError("'For' is not allowed as a top level statement", "for i in [1,2,3]: a = i\n");
}
+ @Test
public void testReturnOutsideFunction() throws Exception {
checkError("Return statements must be inside a function", "return 2\n");
}
+ @Test
public void testTwoReturnTypes() throws Exception {
checkError("bad return type of foo: string is incompatible with int at /some/file.txt:3:5",
"def foo(x):",
@@ -93,6 +110,7 @@ public class ValidationTests extends AbstractParserTestCase {
" return 'a'");
}
+ @Test
public void testTwoFunctionsWithTheSameName() throws Exception {
checkError("function foo already exists",
"def foo():",
@@ -101,6 +119,7 @@ public class ValidationTests extends AbstractParserTestCase {
" return 1");
}
+ @Test
public void testDynamicTypeCheck() throws Exception {
checkError("bad variable 'a': string is incompatible with int at /some/file.txt:2:3",
"def foo():",
@@ -108,6 +127,7 @@ public class ValidationTests extends AbstractParserTestCase {
" a = '1'");
}
+ @Test
public void testFunctionLocalVariable() throws Exception {
checkError("name 'a' is not defined",
"def func2(b):",
@@ -118,6 +138,7 @@ public class ValidationTests extends AbstractParserTestCase {
" func2(2)");
}
+ @Test
public void testFunctionLocalVariableDoesNotEffectGlobalValidationEnv() throws Exception {
checkError("name 'a' is not defined",
"def func1():",
@@ -126,6 +147,7 @@ public class ValidationTests extends AbstractParserTestCase {
" b = a");
}
+ @Test
public void testFunctionParameterDoesNotEffectGlobalValidationEnv() throws Exception {
checkError("name 'a' is not defined",
"def func1(a):",
@@ -134,6 +156,7 @@ public class ValidationTests extends AbstractParserTestCase {
" b = a");
}
+ @Test
public void testLocalValidationEnvironmentsAreSeparated() throws Exception {
parse(
"def func1():\n"
@@ -142,49 +165,59 @@ public class ValidationTests extends AbstractParserTestCase {
+ " a = 'abc'\n");
}
+ @Test
public void testListComprehensionNotIterable() throws Exception {
checkError("type 'int' is not iterable",
"[i for i in 1 for j in [2]]");
}
+ @Test
public void testListComprehensionNotIterable2() throws Exception {
checkError("type 'int' is not iterable",
"[i for i in [1] for j in 123]");
}
+ @Test
public void testListIsNotComparable() {
checkError("list of strings is not comparable", "['a'] > 1");
}
+ @Test
public void testStringCompareToInt() {
checkError("bad comparison: int is incompatible with string", "'a' > 1");
}
+ @Test
public void testInOnInt() {
checkError("operand 'in' only works on strings, dictionaries, "
+ "lists, sets or tuples, not on a(n) int", "1 in 2");
}
+ @Test
public void testUnsupportedOperator() {
checkError("unsupported operand type(s) for -: 'string' and 'int'", "'a' - 1");
}
+ @Test
public void testBuiltinSymbolsAreReadOnly() throws Exception {
checkError("Variable rule is read only", "rule = 1");
}
+ @Test
public void testSkylarkGlobalVariablesAreReadonly() throws Exception {
checkError("Variable a is read only",
"a = 1\n"
+ "a = 2");
}
+ @Test
public void testFunctionDefRecursion() throws Exception {
checkError("function 'func' does not exist",
"def func():\n"
+ " func()\n");
}
+ @Test
public void testMutualRecursion() throws Exception {
checkError("function 'bar' does not exist",
"def foo(i):\n"
@@ -194,36 +227,42 @@ public class ValidationTests extends AbstractParserTestCase {
+ "foo(4)");
}
+ @Test
public void testFunctionReturnValue() {
checkError("unsupported operand type(s) for +: 'int' and 'string'",
"def foo(): return 1\n"
+ "a = foo() + 'a'\n");
}
+ @Test
public void testFunctionReturnValueInFunctionDef() {
checkError("unsupported operand type(s) for +: 'int' and 'string'",
"def foo(): return 1\n"
+ "def bar(): a = foo() + 'a'\n");
}
+ @Test
public void testFunctionDoesNotExistInFunctionDef() {
checkError("function 'foo' does not exist",
"def bar(): a = foo() + 'a'\n"
+ "def foo(): return 1\n");
}
+ @Test
public void testStructMembersAreImmutable() {
checkError("can only assign to variables, not to 's.x'",
"s = struct(x = 'a')\n"
+ "s.x = 'b'\n");
}
+ @Test
public void testStructDictMembersAreImmutable() {
checkError("can only assign to variables, not to 's.x['b']'",
"s = struct(x = {'a' : 1})\n"
+ "s.x['b'] = 2\n");
}
+ @Test
public void testTupleAssign() throws Exception {
// TODO(bazel-team): fix our code so 'tuple' not 'list' gets printed.
checkError("unsupported operand type(s) for +: 'list' and 'dict of ints'",
@@ -231,29 +270,34 @@ public class ValidationTests extends AbstractParserTestCase {
+ "d[0] = 2\n");
}
+ @Test
public void testAssignOnNonCollection() throws Exception {
checkError("unsupported operand type(s) for +: 'string' and 'dict of ints'",
"d = 'abc'\n"
+ "d[0] = 2");
}
+ @Test
public void testNsetBadRightOperand() throws Exception {
checkError("can only concatenate nested sets with other nested sets or list of items, "
+ "not 'string'", "set() + 'a'");
}
+ @Test
public void testNsetBadItemType() throws Exception {
checkError("bad nested set: set of ints is incompatible with set of strings "
+ "at /some/file.txt:1:1",
"(set() + ['a']) + [1]");
}
+ @Test
public void testNsetBadNestedItemType() throws Exception {
checkError("bad nested set: set of ints is incompatible with set of strings "
+ "at /some/file.txt:1:1",
"(set() + ['b']) + (set() + [1])");
}
+ @Test
public void testTypeInferenceForMethodLibraryFunction() throws Exception {
checkError("bad variable 'l': string is incompatible with int at /some/file.txt:2:3",
"def foo():\n"
@@ -261,62 +305,75 @@ public class ValidationTests extends AbstractParserTestCase {
+ " l = 'a'");
}
+ @Test
public void testListLiteralBadTypes() throws Exception {
checkError("bad list literal: int is incompatible with string at /some/file.txt:1:1",
"['a', 1]");
}
+ @Test
public void testTupleLiteralWorksForDifferentTypes() throws Exception {
parse("('a', 1)");
}
+ @Test
public void testDictLiteralBadKeyTypes() throws Exception {
checkError("bad dict literal: int is incompatible with string at /some/file.txt:1:1",
"{'a': 1, 1: 2}");
}
+ @Test
public void testDictLiteralDifferentValueTypeWorks() throws Exception {
parse("{'a': 1, 'b': 'c'}");
}
+ @Test
public void testListConcatBadTypes() throws Exception {
checkError("bad list concatenation: list of ints is incompatible with list of strings"
+ " at /some/file.txt:1:1",
"['a'] + [1]");
}
+ @Test
public void testDictConcatBadKeyTypes() throws Exception {
checkError("bad dict concatenation: dict of ints is incompatible with dict of strings "
+ "at /some/file.txt:1:1",
"{'a': 1} + {1: 2}");
}
+ @Test
public void testDictLiteralBadKeyType() throws Exception {
checkError("Dict cannot contain composite type 'list of strings' as key", "{['a']: 1}");
}
+ @Test
public void testAndTypeInfer() throws Exception {
checkError("unsupported operand type(s) for +: 'string' and 'int'", "('a' and 'b') + 1");
}
+ @Test
public void testOrTypeInfer() throws Exception {
checkError("unsupported operand type(s) for +: 'string' and 'int'", "('' or 'b') + 1");
}
+ @Test
public void testAndDifferentTypes() throws Exception {
checkError("bad and operator: int is incompatible with string at /some/file.txt:1:1",
"'ab' and 3");
}
+ @Test
public void testOrDifferentTypes() throws Exception {
checkError("bad or operator: int is incompatible with string at /some/file.txt:1:1",
"'ab' or 3");
}
+ @Test
public void testOrNone() throws Exception {
parse("a = None or 3");
}
+ @Test
public void testNoneAssignment() throws Exception {
parse("def func():\n"
+ " a = None\n"
@@ -324,6 +381,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " a = None\n");
}
+ @Test
public void testNoneAssignmentError() throws Exception {
checkError("bad variable 'a': string is incompatible with int at /some/file.txt",
"def func():\n"
@@ -333,10 +391,12 @@ public class ValidationTests extends AbstractParserTestCase {
+ " a = 'b'\n");
}
+ @Test
public void testDictComprehensionNotOnList() throws Exception {
checkError("Dict comprehension elements must be a list", "{k : k for k in 'abc'}");
}
+ @Test
public void testTypeInferenceForUserDefinedFunction() throws Exception {
checkError("bad variable 'a': string is incompatible with int at /some/file.txt",
"def func():\n"
@@ -346,12 +406,14 @@ public class ValidationTests extends AbstractParserTestCase {
+ " a = func()\n");
}
+ @Test
public void testCallingNonFunction() {
checkError("a is not a function",
"a = '1':\n"
+ "a()\n");
}
+ @Test
public void testFuncallArgument() {
checkError("unsupported operand type(s) for +: 'int' and 'string'",
"def foo(x): return x\n"
@@ -360,6 +422,7 @@ public class ValidationTests extends AbstractParserTestCase {
// Skylark built-in functions specific tests
+ @Test
public void testTypeInferenceForSkylarkBuiltinGlobalFunction() throws Exception {
checkError("bad variable 'a': string is incompatible with function at /some/file.txt:3:3",
"def impl(ctx): return None\n"
@@ -368,6 +431,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " a = 'a'\n");
}
+ @Test
public void testTypeInferenceForSkylarkBuiltinObjectFunction() throws Exception {
checkError("bad variable 'a': string is incompatible with Attribute at /some/file.txt",
"def foo():\n"
@@ -375,6 +439,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " a = 'a'\n");
}
+ @Test
public void testFuncReturningDictAssignmentAsLValue() throws Exception {
checkError("can only assign to variables, not to 'dict([])['b']'",
"def dict():\n"
@@ -384,6 +449,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " return d\n");
}
+ @Test
public void testListIndexAsLValue() {
checkError("unsupported operand type(s) for +: 'list of ints' and 'dict of ints'",
"def func():\n"
@@ -392,6 +458,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " return l\n");
}
+ @Test
public void testStringIndexAsLValue() {
checkError("unsupported operand type(s) for +: 'string' and 'dict of ints'",
"def func():\n"
@@ -400,17 +467,20 @@ public class ValidationTests extends AbstractParserTestCase {
+ " return s\n");
}
+ @Test
public void testEmptyLiteralGenericIsSetInLaterConcatWorks() {
parse("def func():\n"
+ " s = {}\n"
+ " s['a'] = 'b'\n");
}
+ @Test
public void testTypeIsInferredForStructs() {
checkError("unsupported operand type(s) for +: 'struct' and 'string'",
"(struct(a = 1) + struct(b = 1)) + 'x'");
}
+ @Test
public void testReadOnlyWorksForSimpleBranching() {
parse("if 1:\n"
+ " v = 'a'\n"
@@ -418,6 +488,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 'b'");
}
+ @Test
public void testReadOnlyWorksForNestedBranching() {
parse("if 1:\n"
+ " if 0:\n"
@@ -431,6 +502,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 'd'\n");
}
+ @Test
public void testTypeCheckWorksForSimpleBranching() {
checkError("bad variable 'v': int is incompatible with string at /some/file.txt:2:3",
"if 1:\n"
@@ -439,6 +511,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 1");
}
+ @Test
public void testTypeCheckWorksForNestedBranching() {
checkError("bad variable 'v': int is incompatible with string at /some/file.txt:5:5",
"if 1:\n"
@@ -450,6 +523,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 1\n");
}
+ @Test
public void testTypeCheckWorksForDifferentLevelBranches() {
checkError("bad variable 'v': int is incompatible with string at /some/file.txt:2:3",
"if 1:\n"
@@ -459,6 +533,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 1\n");
}
+ @Test
public void testReadOnlyWorksForDifferentLevelBranches() {
checkError("Variable v is read only",
"if 1:\n"
@@ -467,6 +542,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 'b'\n");
}
+ @Test
public void testReadOnlyWorksWithinSimpleBranch() {
checkError("Variable v is read only",
"if 1:\n"
@@ -476,6 +552,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 'c'\n");
}
+ @Test
public void testReadOnlyWorksWithinNestedBranch() {
checkError("Variable v is read only",
"if 1:\n"
@@ -488,6 +565,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ " v = 'd'\n");
}
+ @Test
public void testReadOnlyWorksAfterSimpleBranch() {
checkError("Variable v is read only",
"if 1:\n"
@@ -497,6 +575,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ "v = 'b'");
}
+ @Test
public void testReadOnlyWorksAfterNestedBranch() {
checkError("Variable v is read only",
"if 1:\n"
@@ -505,6 +584,7 @@ public class ValidationTests extends AbstractParserTestCase {
+ "v = 'b'");
}
+ @Test
public void testReadOnlyWorksAfterNestedBranch2() {
checkError("Variable v is read only",
"if 1:\n"
@@ -515,29 +595,34 @@ public class ValidationTests extends AbstractParserTestCase {
+ "v = 'b'\n");
}
+ @Test
public void testModulesReadOnlyInFuncDefBody() {
checkError("Variable cmd_helper is read only",
"def func():",
" cmd_helper = set()");
}
+ @Test
public void testBuiltinGlobalFunctionsReadOnlyInFuncDefBody() {
checkError("Variable rule is read only",
"def func():",
" rule = 'abc'");
}
+ @Test
public void testBuiltinGlobalFunctionsReadOnlyAsFuncDefArg() {
checkError("Variable rule is read only",
"def func(rule):",
" return rule");
}
+ @Test
public void testFilesModulePlusStringErrorMessage() throws Exception {
checkError("unsupported operand type(s) for +: 'cmd_helper (a language module)' and 'string'",
"cmd_helper += 'a'");
}
+ @Test
public void testFunctionReturnsFunction() {
parse(
"def impl(ctx):",
@@ -549,19 +634,23 @@ public class ValidationTests extends AbstractParserTestCase {
" skylark_rule(name = name)");
}
+ @Test
public void testTypeForBooleanLiterals() {
parse("len([1, 2]) == 0 and True");
parse("len([1, 2]) == 0 and False");
}
+ @Test
public void testLoadRelativePathOneSegment() throws Exception {
parse("load('extension', 'a')\n");
}
+ @Test
public void testLoadAbsolutePathMultipleSegments() throws Exception {
parse("load('/pkg/extension', 'a')\n");
}
+ @Test
public void testLoadRelativePathMultipleSegments() throws Exception {
checkError("Path 'pkg/extension.bzl' is not valid. It should either start with "
+ "a slash or refer to a file in the current directory.",