Testing OnTouch Event Binding Implementation in ButterKnife
This test suite validates the OnTouch functionality in ButterKnife’s view binding system, focusing on touch event handling and listener implementations. It ensures proper generation of view bindings for touch events and verifies correct behavior of return values and multiple listener scenarios.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
jakewharton/butterknife
butterknife-runtime/src/test/java/butterknife/OnTouchTest.java
package butterknife;
import butterknife.compiler.ButterKnifeProcessor;
import com.google.testing.compile.JavaFileObjects;
import javax.tools.JavaFileObject;
import org.junit.Test;
import static com.google.common.truth.Truth.assertAbout;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
public class OnTouchTest {
@Test public void touch() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", ""
+ "package test;\n"
+ "import butterknife.OnTouch;\n"
+ "public class Test {\n"
+ " @OnTouch(1) boolean doStuff() { return false; }\n"
+ "}"
);
JavaFileObject bindingSource = JavaFileObjects.forSourceString("test/Test_ViewBinding", ""
+ "package test;\n"
+ "import android.annotation.SuppressLint;\n"
+ "import android.view.MotionEvent;\n"
+ "import android.view.View;\n"
+ "import androidx.annotation.CallSuper;\n"
+ "import androidx.annotation.UiThread;\n"
+ "import butterknife.Unbinder;\n"
+ "import butterknife.internal.Utils;\n"
+ "import java.lang.IllegalStateException;\n"
+ "import java.lang.Override;\n"
+ "public class Test_ViewBinding implements Unbinder {\n"
+ " private Test target;\n"
+ " private View view1;\n"
+ " @UiThread\n"
+ " @SuppressLint(\"ClickableViewAccessibility\")\n"
+ " public Test_ViewBinding(final Test target, View source) {\n"
+ " this.target = target;\n"
+ " View view;\n"
+ " view = Utils.findRequiredView(source, 1, \"method 'doStuff'\");\n"
+ " view1 = view;\n"
+ " view.setOnTouchListener(new View.OnTouchListener() {\n"
+ " @Override\n"
+ " public boolean onTouch(View p0, MotionEvent p1) {\n"
+ " return target.doStuff();\n"
+ " }\n"
+ " });\n"
+ " }\n"
+ " @Override\n"
+ " @CallSuper\n"
+ " public void unbind() {\n"
+ " if (target == null) throw new IllegalStateException(\"Bindings already cleared.\");\n"
+ " target = null;\n"
+ " view1.setOnTouchListener(null);\n"
+ " view1 = null;\n"
+ " }\n"
+ "}"
);
assertAbout(javaSource()).that(source)
.withCompilerOptions("-Xlint:-processing")
.processedWith(new ButterKnifeProcessor())
.compilesWithoutWarnings()
.and()
.generatesSources(bindingSource);
}
@Test public void defaultReturnValue() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", ""
+ "package test;\n"
+ "import butterknife.OnTouch;\n"
+ "public class Test {\n"
+ " @OnTouch(1) void doStuff() {}\n"
+ "}"
);
JavaFileObject bindingSource = JavaFileObjects.forSourceString("test/Test_ViewBinding", ""
+ "package test;\n"
+ "import android.annotation.SuppressLint;\n"
+ "import android.view.MotionEvent;\n"
+ "import android.view.View;\n"
+ "import androidx.annotation.CallSuper;\n"
+ "import androidx.annotation.UiThread;\n"
+ "import butterknife.Unbinder;\n"
+ "import butterknife.internal.Utils;\n"
+ "import java.lang.IllegalStateException;\n"
+ "import java.lang.Override;\n"
+ "public class Test_ViewBinding implements Unbinder {\n"
+ " private Test target;\n"
+ " private View view1;\n"
+ " @UiThread\n"
+ " @SuppressLint(\"ClickableViewAccessibility\")\n"
+ " public Test_ViewBinding(final Test target, View source) {\n"
+ " this.target = target;\n"
+ " View view;\n"
+ " view = Utils.findRequiredView(source, 1, \"method 'doStuff'\");\n"
+ " view1 = view;\n"
+ " view.setOnTouchListener(new View.OnTouchListener() {\n"
+ " @Override\n"
+ " public boolean onTouch(View p0, MotionEvent p1) {\n"
+ " target.doStuff();\n"
+ " return true;\n"
+ " }\n"
+ " });\n"
+ " }\n"
+ " @Override\n"
+ " @CallSuper\n"
+ " public void unbind() {\n"
+ " if (target == null) throw new IllegalStateException(\"Bindings already cleared.\");\n"
+ " target = null;\n"
+ " view1.setOnTouchListener(null);\n"
+ " view1 = null;\n"
+ " }\n"
+ "}"
);
assertAbout(javaSource()).that(source)
.withCompilerOptions("-Xlint:-processing")
.processedWith(new ButterKnifeProcessor())
.compilesWithoutWarnings()
.and()
.generatesSources(bindingSource);
}
@Test public void failsMultipleListenersWithReturnValue() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", ""
+ "package test;\n"
+ "import butterknife.OnTouch;\n"
+ "public class Test {\n"
+ " @OnTouch(1) boolean doStuff1() {}\n"
+ " @OnTouch(1) boolean doStuff2() {}\n"
+ "}"
);
assertAbout(javaSource()).that(source)
.processedWith(new ButterKnifeProcessor())
.failsToCompile()
.withErrorContaining(
"Multiple listener methods with return value specified for ID 1. (test.Test.doStuff2)")
.in(source).onLine(5);
}
}