aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java119
1 files changed, 119 insertions, 0 deletions
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 a72f5e5a91..32932b6a73 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
@@ -26,6 +26,8 @@ import com.google.devtools.build.lib.analysis.FileConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
@@ -1288,4 +1290,121 @@ public class SkylarkEvaluationTest extends EvaluationTest {
new SkylarkTest().setUp("def foo(a, b, c): return a+b if c else a-b\n").testStatement(
"foo(23, 5, 0)", 18);
}
+
+ @SkylarkModule(name = "SkylarkClassObjectWithSkylarkCallables", doc = "")
+ static final class SkylarkClassObjectWithSkylarkCallables extends SkylarkClassObject {
+ private static final NativeClassObjectConstructor CONSTRUCTOR =
+ new NativeClassObjectConstructor("struct_with_skylark_callables") {};
+
+ SkylarkClassObjectWithSkylarkCallables() {
+ super(
+ CONSTRUCTOR,
+ ImmutableMap.of(
+ "values_only_field",
+ "fromValues",
+ "values_only_method",
+ new BuiltinFunction("values_only_method", FunctionSignature.of()) {
+ public String invoke() {
+ return "fromValues";
+ }
+ },
+ "collision_field",
+ "fromValues",
+ "collision_method",
+ new BuiltinFunction("collision_method", FunctionSignature.of()) {
+ public String invoke() {
+ return "fromValues";
+ }
+ }));
+ }
+
+ @SkylarkCallable(name = "callable_only_field", doc = "", structField = true)
+ public String getCallableOnlyField() {
+ return "fromSkylarkCallable";
+ }
+
+ @SkylarkCallable(name = "callable_only_method", doc = "", structField = false)
+ public String getCallableOnlyMethod() {
+ return "fromSkylarkCallable";
+ }
+
+ @SkylarkCallable(name = "collision_field", doc = "", structField = true)
+ public String getCollisionField() {
+ return "fromSkylarkCallable";
+ }
+
+ @SkylarkCallable(name = "collision_method", doc = "", structField = false)
+ public String getCollisionMethod() {
+ return "fromSkylarkCallable";
+ }
+ }
+
+ @Test
+ public void testStructFieldDefinedOnlyInValues() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .setUp("v = val.values_only_field")
+ .testLookup("v", "fromValues");
+ }
+
+ @Test
+ public void testStructMethodDefinedOnlyInValues() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .setUp("v = val.values_only_method()")
+ .testLookup("v", "fromValues");
+ }
+
+ @Test
+ public void testStructFieldDefinedOnlyInSkylarkCallable() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .setUp("v = val.callable_only_field")
+ .testLookup("v", "fromSkylarkCallable");
+ }
+
+ @Test
+ public void testStructMethodDefinedOnlyInSkylarkCallable() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .setUp("v = val.callable_only_method()")
+ .testLookup("v", "fromSkylarkCallable");
+ }
+
+ @Test
+ public void testStructFieldDefinedInValuesAndSkylarkCallable() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .setUp("v = val.collision_field")
+ .testLookup("v", "fromValues");
+ }
+
+ @Test
+ public void testStructMethodDefinedInValuesAndSkylarkCallable() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .setUp("v = val.collision_method()")
+ .testLookup("v", "fromValues");
+ }
+
+ @Test
+ public void testStructFieldNotDefined() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .testIfExactError(
+ // TODO(bazel-team): This should probably list callable_only_field/method as well.
+ "'struct_with_skylark_callables' object has no attribute 'nonexistent_field'\n"
+ + "Available attributes: collision_field, collision_method, values_only_field, "
+ + "values_only_method",
+ "v = val.nonexistent_field");
+ }
+
+ @Test
+ public void testStructMethodNotDefined() throws Exception {
+ new SkylarkTest()
+ .update("val", new SkylarkClassObjectWithSkylarkCallables())
+ .testIfExactError(
+ // TODO(bazel-team): This should probably match the error above better.
+ "struct has no method 'nonexistent_method'", "v = val.nonexistent_method()");
+ }
}