summaryrefslogtreecommitdiff
path: root/compilationTests
diff options
context:
space:
mode:
authorYigit Boyar <yboyar@google.com>2016-02-02 11:48:47 -0800
committerYigit Boyar <yboyar@google.com>2016-02-16 14:22:34 -0800
commit6047998943beebd81e0ae1068df39c0cbee38628 (patch)
treeb20ac4ba515655202a734f851792e2d865fc2f57 /compilationTests
parentbb6f72ae4247ffd0f71e5e93a7c5082787e821ed (diff)
downloaddata-binding-6047998943beebd81e0ae1068df39c0cbee38628.tar.gz
Lambda In da house
This CL adds support for assigning callbacks to listeners using lambda expressions. These expressions can receive either 0 or N arguments where N is equal to the number of parameters in the callback function. These expressions are evaluated when the callback is invoked. In other words, they are independent from the rest of the ExprModel except the Identifier expressions. Since these are limited to 1 full expression and they don't have any invalidation flags; we use a verbose branching code generation mode where we calculate all possible execution paths, eliminate trivial ones and generate the code. This allows callbacks to be thread safe as well. See ExecutionPath class for details. It is not efficient but since these are rere occasions, should be OK. Callback expressions are still forced to be expressions that return value. To handle `void` case, I've added `void` and `Void` as acceptable symbols. Also, if the callback method returns void, the expression is free to return `void` or any other value. ¯\\_(ツ)_/¯ I've also moved kotlin to rc0. Although rc0 is unrelated to this task, it made more sense to upgrade here because most changes it will ask for were already done in this branch. Bug: 26849440 Change-Id: I805b3d470f85df9c2ce3f3ed5ca74925a08bb7a5
Diffstat (limited to 'compilationTests')
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java12
-rw-r--r--compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java46
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml31
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml31
-rw-r--r--compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml31
5 files changed, 151 insertions, 0 deletions
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java b/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
index f6d1f5ec..90fd1220 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/CompilationResult.java
@@ -18,7 +18,9 @@ package android.databinding.compilationTest;
import android.databinding.tool.processing.ScopedErrorReport;
import android.databinding.tool.processing.ScopedException;
+import android.databinding.tool.util.StringUtils;
+import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -51,6 +53,16 @@ public class CompilationResult {
return errors.get(0);
}
+ public List<String> getBindingWarnings() {
+ List<String> warnings = new ArrayList<String>();
+ for (String line : error.split(StringUtils.LINE_SEPARATOR)) {
+ if (line.startsWith("warning:")) {
+ warnings.add(line.substring("warning:".length()));
+ }
+ }
+ return warnings;
+ }
+
public List<ScopedException> getBindingExceptions() {
return ScopedException.extractErrors(error);
}
diff --git a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
index 229323ff..f38dcc4f 100644
--- a/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
+++ b/compilationTests/src/test/java/android/databinding/compilationTest/SimpleCompilationTest.java
@@ -28,6 +28,8 @@ import android.databinding.tool.processing.ScopedErrorReport;
import android.databinding.tool.processing.ScopedException;
import android.databinding.tool.store.Location;
+import com.google.common.base.Joiner;
+
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -35,6 +37,7 @@ import java.util.Collection;
import java.util.List;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -118,6 +121,21 @@ public class SimpleCompilationTest extends BaseCompilationTest {
return scopedException;
}
+ private void singleFileWarningTest(String resource, String targetFile,
+ String expectedMessage)
+ throws IOException, URISyntaxException, InterruptedException {
+ prepareProject();
+ copyResourceTo(resource, targetFile);
+ CompilationResult result = runGradle("assembleDebug");
+ assertEquals(0, result.resultCode);
+ final List<String> warnings = result.getBindingWarnings();
+ boolean found = false;
+ for (String warning : warnings) {
+ found |= warning.contains(expectedMessage);
+ }
+ assertTrue(Joiner.on("\n").join(warnings),found);
+ }
+
@Test
public void testMultipleExceptionsInDifferentFiles()
throws IOException, URISyntaxException, InterruptedException {
@@ -196,6 +214,34 @@ public class SimpleCompilationTest extends BaseCompilationTest {
}
@Test
+ public void testCallbackArgumentCountMismatch() throws Throwable {
+ singleFileErrorTest("/layout/layout_with_missing_callback_args.xml",
+ "/app/src/main/res/layout/broken.xml",
+ "(seekBar, progress) -> obj.length()",
+ String.format(ErrorMessages.CALLBACK_ARGUMENT_COUNT_MISMATCH,
+ "android.databinding.adapters.SeekBarBindingAdapter.OnProgressChanged",
+ "onProgressChanged", 3, 2));
+ }
+
+ @Test
+ public void testDuplicateCallbackArgument() throws Throwable {
+ singleFileErrorTest("/layout/layout_with_duplicate_callback_identifier.xml",
+ "/app/src/main/res/layout/broken.xml",
+ "(seekBar, progress, progress) -> obj.length()",
+ String.format(ErrorMessages.DUPLICATE_CALLBACK_ARGUMENT,
+ "progress"));
+ }
+
+ @Test
+ public void testConflictWithVariableName() throws Throwable {
+ singleFileWarningTest("/layout/layout_with_same_name_for_var_and_callback.xml",
+ "/app/src/main/res/layout/broken.xml",
+ String.format(ErrorMessages.CALLBACK_VARIABLE_NAME_CLASH,
+ "myVar", "myVar", "String"));
+
+ }
+
+ @Test
public void testRootTag() throws IOException, URISyntaxException,
InterruptedException {
prepareProject();
diff --git a/compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml b/compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml
new file mode 100644
index 00000000..3ba571e0
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_duplicate_callback_identifier.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:bind="http://schemas.android.com/apk/res-auto">
+ <data>
+ <variable name="myVar" type="String"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- undefined variable -->
+ <View android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:onProgressChanged="@{(seekBar, progress, progress) -> obj.length()}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
diff --git a/compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml b/compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml
new file mode 100644
index 00000000..7882cb6c
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_missing_callback_args.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:bind="http://schemas.android.com/apk/res-auto">
+ <data>
+ <variable name="myVar" type="String"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- undefined variable -->
+ <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:onProgressChanged="@{(seekBar, progress) -> obj.length()}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file
diff --git a/compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml b/compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml
new file mode 100644
index 00000000..379ae6ed
--- /dev/null
+++ b/compilationTests/src/test/resources/layout/layout_with_same_name_for_var_and_callback.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:bind="http://schemas.android.com/apk/res-auto">
+ <data>
+ <variable name="myVar" type="String"/>
+ </data>
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- undefined variable -->
+ <SeekBar android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:onClick="@{(myVar) -> myVar.setVisibility(1)}"/>
+ </LinearLayout>
+</layout> \ No newline at end of file