Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added @OnAutoCompleteItemClick annotation to bind onItemClickListener on... #242

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions butterknife/src/main/java/butterknife/ButterKnife.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
*
* @see InjectView
* @see InjectViews
* @see OnAutoCompleteItemClick
* @see OnCheckedChanged
* @see OnClick
* @see OnEditorAction
Expand Down
47 changes: 47 additions & 0 deletions butterknife/src/main/java/butterknife/OnAutoCompleteItemClick.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package butterknife;

import android.view.View;
import butterknife.internal.ListenerClass;
import butterknife.internal.ListenerMethod;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static android.widget.AdapterView.OnItemClickListener;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.CLASS;

/**
* Bind a method to an
* {@link android.widget.AutoCompleteTextView OnItemClickListener} on the view for each ID
* specified.
* <pre><code>
* {@literal @}OnItemClick(R.id.example_list) void onItemClick(int position) {
* Toast.makeText(this, "Clicked position " + position + "!", LENGTH_SHORT).show();
* }
* </code></pre>
* Any number of parameters from
* {@link OnItemClickListener#onItemClick(android.widget.AdapterView,
* android.view.View, int, long) onItemClick} may be used on the method.
*
* @see OnItemClickListener
* @see Optional
*/
@Target(METHOD)
@Retention(CLASS)
@ListenerClass(
targetType = "android.widget.AutoCompleteTextView",
setter = "setOnItemClickListener",
type = "android.widget.AdapterView.OnItemClickListener",
method = @ListenerMethod(
name = "onItemClick",
parameters = {
"android.widget.AdapterView<?>",
"android.view.View",
"int",
"long"
}
)
)
public @interface OnAutoCompleteItemClick {
int[] value() default { View.NO_ID };
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.view.View;
import butterknife.InjectView;
import butterknife.InjectViews;
import butterknife.OnAutoCompleteItemClick;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import butterknife.OnEditorAction;
Expand Down Expand Up @@ -63,6 +64,7 @@ public final class ButterKnifeProcessor extends AbstractProcessor {
static final String VIEW_TYPE = "android.view.View";
private static final String LIST_TYPE = List.class.getCanonicalName();
private static final List<Class<? extends Annotation>> LISTENERS = Arrays.asList(//
OnAutoCompleteItemClick.class, //
OnCheckedChanged.class, //
OnClick.class, //
OnEditorAction.class, //
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package butterknife.internal;

import com.google.common.base.Joiner;
import com.google.testing.compile.JavaFileObjects;
import org.junit.Test;

import javax.tools.JavaFileObject;

import static butterknife.internal.ProcessorTestUtilities.butterknifeProcessors;
import static com.google.common.truth.Truth.ASSERT;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;

public class OnAutoCompleteItemClickTest {
@Test public void onClickInjection() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join(
"package test;",
"import android.app.Activity;",
"import butterknife.OnAutoCompleteItemClick;",
"public class Test extends Activity {",
" @OnAutoCompleteItemClick(1) void doStuff() {}",
"}"));

JavaFileObject expectedSource = JavaFileObjects.forSourceString("test/Test$$ViewInjector",
Joiner.on('\n').join(
"package test;",
"import android.view.View;",
"import butterknife.ButterKnife.Finder;",
"import butterknife.ButterKnife.Injector;",
"public class Test$$ViewInjector<T extends test.Test> implements Injector<T> {",
" @Override public void inject(final Finder finder, final T target, Object source) {",
" View view;",
" view = finder.findRequiredView(source, 1, \"method 'doStuff'\");",
" ((android.widget.AutoCompleteTextView) view).setOnItemClickListener(",
" new android.widget.AdapterView.OnItemClickListener() {",
" @Override public void onItemClick(",
" android.widget.AdapterView<?> p0, android.view.View p1, int p2, long p3) {",
" target.doStuff();",
" }",
" });",
" }",
" @Override public void reset(T target) {",
" }",
"}"
));

ASSERT.about(javaSource()).that(source)
.processedWith(butterknifeProcessors())
.compilesWithoutError()
.and()
.generatesSources(expectedSource);
}

@Test public void onClickInjectionWithParameters() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join(
"package test;",
"import android.app.Activity;",
"import android.view.View;",
"import android.widget.AdapterView;",
"import butterknife.OnAutoCompleteItemClick;",
"public class Test extends Activity {",
" @OnAutoCompleteItemClick(1) void doStuff(",
" AdapterView<?> parent,",
" View view,",
" int position,",
" long id",
" ) {}",
"}"));

JavaFileObject expectedSource = JavaFileObjects.forSourceString("test/Test$$ViewInjector",
Joiner.on('\n').join(
"package test;",
"import android.view.View;",
"import butterknife.ButterKnife.Finder;",
"import butterknife.ButterKnife.Injector;",
"public class Test$$ViewInjector<T extends test.Test> implements Injector<T> {",
" @Override public void inject(final Finder finder, final T target, Object source) {",
" View view;",
" view = finder.findRequiredView(source, 1, \"method 'doStuff'\");",
" ((android.widget.AutoCompleteTextView) view).setOnItemClickListener(",
" new android.widget.AdapterView.OnItemClickListener() {",
" @Override public void onItemClick(",
" android.widget.AdapterView<?> p0, android.view.View p1, int p2, long p3) {",
" target.doStuff(p0, p1, p2, p3);",
" }",
" });",
" }",
" @Override public void reset(T target) {",
" }",
"}"
));

ASSERT.about(javaSource()).that(source)
.processedWith(butterknifeProcessors())
.compilesWithoutError()
.and()
.generatesSources(expectedSource);
}

@Test public void onClickRootViewInjection() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join(
"package test;",
"import android.content.Context;",
"import android.widget.AutoCompleteTextView;",
"import butterknife.OnAutoCompleteItemClick;",
"public class Test extends AutoCompleteTextView {",
" @OnAutoCompleteItemClick void doStuff() {}",
" public Test(Context context) {",
" super(context);",
" }",
"}"));

JavaFileObject expectedSource = JavaFileObjects.forSourceString("test/Test$$ViewInjector",
Joiner.on('\n').join(
"package test;",
"import android.view.View;",
"import butterknife.ButterKnife.Finder;",
"import butterknife.ButterKnife.Injector;",
"public class Test$$ViewInjector<T extends test.Test> implements Injector<T> {",
" @Override public void inject(final Finder finder, final T target, Object source) {",
" View view;",
" view = target;",
" ((android.widget.AutoCompleteTextView) view).setOnItemClickListener(",
" new android.widget.AdapterView.OnItemClickListener() {",
" @Override public void onItemClick(",
" android.widget.AdapterView<?> p0,",
" android.view.View p1,",
" int p2,",
" long p3",
" ) {",
" target.doStuff();",
" }",
" });",
" }",
" @Override public void reset(T target) {",
" }",
"}"
));

ASSERT.about(javaSource()).that(source)
.processedWith(butterknifeProcessors())
.compilesWithoutError()
.and()
.generatesSources(expectedSource);
}

@Test public void failsWithInvalidId() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join(
"package test;",
"import android.content.Context;",
"import android.app.Activity;",
"import butterknife.OnAutoCompleteItemClick;",
"public class Test extends Activity {",
" @OnAutoCompleteItemClick({1, -1}) void doStuff() {}",
"}"));

ASSERT.about(javaSource()).that(source)
.processedWith(butterknifeProcessors())
.failsToCompile()
.withErrorContaining("@OnAutoCompleteItemClick annotation contains invalid ID -1. (test.Test.doStuff)")
.in(source).onLine(6);
}

@Test public void failsWithInvalidParameterConfiguration() {
JavaFileObject source = JavaFileObjects.forSourceString("test.Test", Joiner.on('\n').join(
"package test;",
"import android.app.Activity;",
"import android.view.View;",
"import android.widget.AdapterView;",
"import butterknife.OnAutoCompleteItemClick;",
"public class Test extends Activity {",
" @OnAutoCompleteItemClick(1) void doStuff(",
" AdapterView<?> parent,",
" View view,",
" View whatIsThis",
" ) {}",
"}"));

ASSERT.about(javaSource()).that(source)
.processedWith(butterknifeProcessors())
.failsToCompile()
.withErrorContaining(Joiner.on('\n').join(
"Unable to match @OnAutoCompleteItemClick method arguments. (test.Test.doStuff)",
" ",
" Parameter #1: android.widget.AdapterView<?>",
" matched listener parameter #1: android.widget.AdapterView<?>",
" ",
" Parameter #2: android.view.View",
" matched listener parameter #2: android.view.View",
" ",
" Parameter #3: android.view.View",
" did not match any listener parameters",
" ",
" Methods may have up to 4 parameter(s):",
" ",
" android.widget.AdapterView<?>",
" android.view.View",
" int",
" long",
" ",
" These may be listed in any order but will be searched for from top to bottom."))
.in(source).onLine(7);
}
}