blob: 6ecd01706e118f1282e5cc3b8283cf7ca4bd53b9 [file] [log] [blame]
/*
* Copyright (C) 2015 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.
*/
package android.databinding.testapp;
import android.app.Instrumentation;
import android.content.Context;
import android.databinding.testapp.databinding.TwoWayBinding;
import android.databinding.testapp.vo.TwoWayBindingObject;
import android.os.Debug;
import android.os.SystemClock;
import android.test.UiThreadTest;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.BackgroundColorSpan;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TabHost.TabSpec;
import java.util.Calendar;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class TwoWayBindingAdapterTest extends BaseDataBinderTest<TwoWayBinding> {
TwoWayBindingObject mBindingObject;
public TwoWayBindingAdapterTest() {
super(TwoWayBinding.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
initBinder(new Runnable() {
@Override
public void run() {
Context context = getBinder().getRoot().getContext();
mBindingObject = new TwoWayBindingObject(context);
getBinder().setObj(mBindingObject);
getBinder().executePendingBindings();
}
});
}
public void testListViewSelectedItemPosition() throws Throwable {
makeVisible(mBinder.listView);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(0, mBindingObject.selectedItemPosition.get());
assertEquals(0, mBinder.listView.getSelectedItemPosition());
mBinder.listView.setSelection(1);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.selectedItemPosition.get() == 0;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1, mBinder.listView.getSelectedItemPosition());
assertEquals(1, mBindingObject.selectedItemPosition.get());
}
});
}
public void testSpinnerSelectedItemPosition() throws Throwable {
makeVisible(mBinder.spinner);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(0, mBindingObject.selectedItemPosition.get());
assertEquals(0, mBinder.spinner.getSelectedItemPosition());
mBinder.spinner.setSelection(1);
}
});
long timeout = SystemClock.uptimeMillis() + 500;
while (mBindingObject.selectedItemPosition.get() == 0 &&
SystemClock.uptimeMillis() < timeout) {
Thread.sleep(1);
}
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1, mBinder.spinner.getSelectedItemPosition());
assertEquals(1, mBindingObject.selectedItemPosition.get());
}
});
}
private void clickView(final View view, float offsetX) throws Throwable {
final int[] xy = new int[2];
final int[] viewSize = new int[2];
do {
runTestOnUiThread(new Runnable() {
@Override
public void run() {
view.getLocationOnScreen(xy);
viewSize[0] = view.getWidth();
viewSize[1] = view.getHeight();
}
});
} while (xy[0] < 0 || xy[1] < 0);
final float x = xy[0] + offsetX;
final float y = xy[1] + (viewSize[1] / 2f);
Instrumentation inst = getInstrumentation();
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_DOWN, x, y, 0);
inst.sendPointerSync(event);
waitForUISync();
eventTime = SystemClock.uptimeMillis();
final int touchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
inst.sendPointerSync(event);
waitForUISync();
eventTime = SystemClock.uptimeMillis();
event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
inst.sendPointerSync(event);
waitForUISync();
}
private void clickChild(View view, float offsetX) throws Throwable {
View childView = view;
while (childView != null) {
childView.callOnClick();
if (childView instanceof ViewGroup) {
final ViewGroup viewGroup = (ViewGroup) childView;
if (viewGroup.getChildCount() > 0) {
childView = viewGroup.getChildAt(0);
} else {
childView = null;
}
} else {
clickView(childView, offsetX);
childView = null;
}
}
}
public void testCalendarViewDate() throws Throwable {
makeVisible(mBinder.calendarView);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(mBindingObject.date.get() != 0);
assertDatesMatch(mBindingObject.date.get(), mBinder.calendarView.getDate());
}
});
final long[] date = new long[2];
float offsetX = 0;
long timeout = SystemClock.uptimeMillis() + 1500;
do {
// Just randomly poke at the CalendarView to set the date
clickChild(mBinder.calendarView, offsetX);
offsetX += 48;
runTestOnUiThread(new Runnable() {
@Override
public void run() {
date[0] = mBinder.calendarView.getDate();
if (date[1] == 0) {
date[1] = date[0];
}
}
});
} while (date[0] == date[1] && SystemClock.uptimeMillis() < timeout);
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.date.get() == 0;
}
});
assertDatesMatch(date[0], mBindingObject.date.get());
}
public void assertDatesMatch(long expectedTimeMillis, long testTimeMillis) {
Calendar expected = Calendar.getInstance();
expected.setTimeInMillis(expectedTimeMillis);
Calendar testValue = Calendar.getInstance();
testValue.setTimeInMillis(testTimeMillis);
assertEquals(expected.get(Calendar.YEAR), testValue.get(Calendar.YEAR));
assertEquals(expected.get(Calendar.MONTH), testValue.get(Calendar.MONTH));
assertEquals(expected.get(Calendar.DAY_OF_MONTH),
testValue.get(Calendar.DAY_OF_MONTH));
}
public void testCheckBoxChecked() throws Throwable {
makeVisible(mBinder.checkBox);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertFalse(mBindingObject.checked.get());
assertFalse(mBinder.checkBox.isChecked());
mBinder.checkBox.setChecked(true);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return !mBindingObject.checked.get();
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(mBinder.checkBox.isChecked());
assertTrue(mBindingObject.checked.get());
}
});
}
private boolean focusOn(final View view) throws Throwable {
runTestOnUiThread(new Runnable() {
@Override
public void run() {
view.requestFocus();
}
});
long timeout = SystemClock.uptimeMillis() + 500;
final boolean[] focused = new boolean[1];
while (SystemClock.uptimeMillis() < timeout) {
runTestOnUiThread(new Runnable() {
@Override
public void run() {
focused[0] = view.isFocused();
}
});
if (focused[0]) {
return true;
}
}
return false;
}
public void testNumberPickerNumber() throws Throwable {
makeVisible(mBinder.textView, mBinder.numberPicker);
assertTrue(focusOn(mBinder.textView));
final EditText[] pickerText = new EditText[1];
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1, mBindingObject.number.get());
assertEquals(1, mBinder.numberPicker.getValue());
for (int i = 0; i < mBinder.numberPicker.getChildCount(); i++) {
View view = mBinder.numberPicker.getChildAt(i);
if (view instanceof EditText) {
pickerText[0] = (EditText) view;
break;
}
}
}
});
assertNotNull(pickerText[0]);
assertTrue(focusOn(pickerText[0]));
runTestOnUiThread(new Runnable() {
@Override
public void run() {
pickerText[0].setText("10");
}
});
assertTrue(focusOn(mBinder.textView));
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.number.get() == 1;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(10, mBinder.numberPicker.getValue());
assertEquals(10, mBindingObject.number.get());
}
});
}
public void testRatingBarRating() throws Throwable {
makeVisible(mBinder.ratingBar);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1f, mBindingObject.rating.get());
assertEquals(1f, mBinder.ratingBar.getRating());
mBinder.ratingBar.setRating(2.5f);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.rating.get() == 1f;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(2.5f, mBinder.ratingBar.getRating());
assertEquals(2.5f, mBindingObject.rating.get());
}
});
}
public void testSeekBarProgress() throws Throwable {
makeVisible(mBinder.seekBar);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1, mBindingObject.progress.get());
assertEquals(1, mBinder.seekBar.getProgress());
mBinder.seekBar.setProgress(30);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.progress.get() == 1;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(30, mBinder.seekBar.getProgress());
assertEquals(30, mBindingObject.progress.get());
}
});
}
public void testTabHostCurrentTab() throws Throwable {
makeVisible(mBinder.tabhost);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.tabhost.setup();
TabSpec tab1 = mBinder.tabhost.newTabSpec("Tab1");
TabSpec tab2 = mBinder.tabhost.newTabSpec("Tab2");
tab1.setIndicator("tab1");
tab1.setContent(R.id.foo);
tab2.setIndicator("tab2");
tab2.setContent(R.id.bar);
mBinder.tabhost.addTab(tab1);
mBinder.tabhost.addTab(tab2);
mBinder.tabhost.setCurrentTab(1);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.currentTab.get() == 0;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1, mBinder.tabhost.getCurrentTab());
assertEquals(1, mBindingObject.currentTab.get());
}
});
}
public void testTextViewText() throws Throwable {
makeVisible(mBinder.textView);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(null, mBindingObject.text.get());
assertEquals("", mBinder.textView.getText().toString());
mBinder.textView.setText("Hello World");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.text.get().isEmpty();
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals("Hello World", mBinder.textView.getText().toString());
assertEquals("Hello World", mBindingObject.text.get());
}
});
}
public void testDatePicker() throws Throwable {
makeVisible(mBinder.datePicker);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1972, mBindingObject.year.get());
assertEquals(9, mBindingObject.month.get());
assertEquals(21, mBindingObject.day.get());
assertEquals(1972, mBinder.datePicker.getYear());
assertEquals(9, mBinder.datePicker.getMonth());
assertEquals(21, mBinder.datePicker.getDayOfMonth());
mBinder.datePicker.updateDate(2003, 4, 17);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.year.get() == 1972;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(2003, mBindingObject.year.get());
assertEquals(4, mBindingObject.month.get());
assertEquals(17, mBindingObject.day.get());
}
});
}
public void testExpressions1() throws Throwable {
makeVisible(mBinder.expressions1);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1972, mBindingObject.year.get());
assertEquals(9, mBindingObject.month.get());
assertEquals(21, mBindingObject.day.get());
assertEquals(1972000, mBinder.expressions1.getYear());
assertEquals(2, mBinder.expressions1.getMonth());
assertEquals(22, mBinder.expressions1.getDayOfMonth());
mBinder.expressions1.updateDate(2003000, 3, 18);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.year.get() == 1972;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(2003, mBindingObject.year.get());
assertEquals(8, mBindingObject.month.get());
assertEquals(17, mBindingObject.day.get());
}
});
}
public void testExpressions2() throws Throwable {
makeVisible(mBinder.expressions2);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1972, mBindingObject.year.get());
assertEquals(9, mBindingObject.month.get());
assertEquals(21, mBindingObject.day.get());
assertEquals(1, mBinder.expressions2.getYear());
assertEquals(9, mBinder.expressions2.getMonth());
assertEquals(21, mBinder.expressions2.getDayOfMonth());
mBinder.expressions2.updateDate(2, 4, 17);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.year.get() == 1972;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(2000, mBindingObject.year.get());
assertEquals(4, mBindingObject.month.get());
assertEquals(17, mBindingObject.day.get());
}
});
}
public void testExpressions3() throws Throwable {
makeVisible(mBinder.expressions3);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals((Integer)1, mBindingObject.list.get(1));
assertEquals((Integer)2, mBindingObject.map.get("two"));
assertEquals(2, mBindingObject.array.get()[1]);
assertEquals(1, mBinder.expressions3.getYear());
assertEquals(2, mBinder.expressions3.getMonth());
assertEquals(2, mBinder.expressions3.getDayOfMonth());
mBinder.expressions3.updateDate(2003, 4, 17);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.year.get() == 1972;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals((Integer)2003, mBindingObject.list.get(1));
assertEquals((Integer)4, mBindingObject.map.get("two"));
assertEquals(17, mBindingObject.array.get()[1]);
}
});
}
public void testExpressions4() throws Throwable {
makeVisible(mBinder.expressions4);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(1972, mBindingObject.year.get());
assertEquals(9, mBindingObject.month.get());
assertEquals(21, mBindingObject.day.get());
assertEquals(50, mBinder.expressions4.getYear());
assertEquals(5, mBinder.expressions4.getMonth());
assertEquals(21, mBinder.expressions4.getDayOfMonth());
mBinder.expressions4.updateDate(49, 4, 17);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.year.get() == 1972;
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(2040, mBindingObject.year.get());
assertEquals(6, mBindingObject.month.get());
assertEquals(17, mBindingObject.day.get());
}
});
}
public void testChaining() throws Throwable {
makeVisible(mBinder.checkBox, mBinder.checkBox2);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertTrue(mBinder.checkBox2.isChecked());
mBindingObject.checked.set(true);
mBinder.executePendingBindings();
assertFalse(mBinder.checkBox2.isChecked());
}
});
}
public void testTwoWayChaining() throws Throwable {
makeVisible(mBinder.checkBox3, mBinder.checkBox4);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertFalse(mBinder.checkBox3.isChecked());
assertTrue(mBinder.checkBox4.isChecked());
mBinder.checkBox3.setChecked(true);
mBinder.executePendingBindings();
assertTrue(mBinder.checkBox3.isChecked());
assertFalse(mBinder.checkBox4.isChecked());
}
});
}
public void testIncludedTwoWay1() throws Throwable {
makeVisible(mBinder.included.editText1, mBinder.textView);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(null, mBindingObject.text.get());
assertEquals("", mBinder.textView.getText().toString());
assertEquals("", mBinder.included.editText1.getText().toString());
mBinder.included.editText1.setText("Hello World");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.text.get().isEmpty();
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals("Hello World", mBinder.included.editText1.getText().toString());
assertEquals("Hello World", mBinder.textView.getText().toString());
assertEquals("Hello World", mBindingObject.text.get());
}
});
}
public void testIncludedTwoWay2() throws Throwable {
makeVisible(mBinder.included.editText2, mBinder.textView);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(null, mBindingObject.text.get());
assertEquals("", mBinder.textView.getText().toString());
assertEquals("", mBinder.included.editText2.getText().toString());
mBinder.included.editText2.setText("Hello World");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.text.get().isEmpty();
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals("Hello World", mBinder.included.editText2.getText().toString());
assertEquals("Hello World", mBinder.textView.getText().toString());
assertEquals("Hello World", mBindingObject.text.get());
}
});
}
public void testNoEditableLoop() throws Throwable {
makeVisible(mBinder.editText1, mBinder.editText2);
final SpannableString text = new SpannableString("Hello World Also");
BackgroundColorSpan highlight = new BackgroundColorSpan(0xFFFFFF80);
text.setSpan(highlight, 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mBindingObject.textLatch = new CountDownLatch(2);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals("", mBinder.editText1.getText().toString());
assertEquals(0, mBindingObject.text1Changes);
assertEquals(0, mBindingObject.text2Changes);
// Change the text of one of the controls
mBinder.editText1.setText("Hello World");
}
});
assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS));
mBindingObject.textLatch = new CountDownLatch(2);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertNotNull(mBindingObject.editText.get());
assertEquals("Hello World", mBindingObject.editText.get().toString());
// They should both be set
assertEquals(1, mBindingObject.text1Changes);
assertEquals(1, mBindingObject.text2Changes);
// Edit the span, but the text remains the same.
mBinder.editText2.setText(text);
}
});
assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS));
mBindingObject.textLatch = new CountDownLatch(1);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
// The one control should notify a change, but not the other.
assertEquals(2, mBindingObject.text1Changes);
assertEquals(2, mBindingObject.text2Changes);
// No more changes should occur
mBinder.executePendingBindings();
}
});
assertFalse(mBindingObject.textLatch.await(200, TimeUnit.MILLISECONDS));
mBindingObject.textLatch = new CountDownLatch(2);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
// Nothing changed:
assertEquals(2, mBindingObject.text1Changes);
assertEquals(2, mBindingObject.text2Changes);
// Now try changing the value to the same thing. Because the
// value is Spannable, it will set it to the EditText
// and then get back a String in the onTextChanged.
mBindingObject.editText.set(text);
}
});
assertTrue(mBindingObject.textLatch.await(500, TimeUnit.MILLISECONDS));
runTestOnUiThread(new Runnable() {
@Override
public void run() {
assertEquals(3, mBindingObject.text1Changes);
assertEquals(3, mBindingObject.text2Changes);
assertEquals("Hello World Also", mBindingObject.editText.get());
}
});
}
public void testStringConversions() throws Throwable {
makeVisible(mBinder.convertBool, mBinder.convertByte, mBinder.convertShort,
mBinder.convertInt, mBinder.convertLong, mBinder.convertFloat,
mBinder.convertDouble, mBinder.convertChar);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.convertBool.setText("True");
mBinder.convertByte.setText("123");
mBinder.convertShort.setText("1234");
mBinder.convertInt.setText("12345");
mBinder.convertLong.setText("123456");
mBinder.convertFloat.setText("1.2345");
mBinder.convertDouble.setText("1.23456");
mBinder.convertChar.setText("a");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return !mBindingObject.booleanField.get();
}
});
waitForUISync();
assertTrue(mBindingObject.booleanField.get());
assertEquals(123, mBindingObject.byteField.get());
assertEquals(1234, mBindingObject.shortField.get());
assertEquals(12345, mBindingObject.intField.get());
assertEquals(123456, mBindingObject.longField.get());
assertEquals(1.2345f, mBindingObject.floatField.get(), 0.0001f);
assertEquals(1.23456, mBindingObject.doubleField.get(), 0.000001);
assertEquals('a', mBindingObject.charField.get());
}
public void testBadStringConversions() throws Throwable {
makeVisible(mBinder.convertBool, mBinder.convertByte, mBinder.convertShort,
mBinder.convertInt, mBinder.convertLong, mBinder.convertFloat,
mBinder.convertDouble, mBinder.convertChar);
mBindingObject.booleanField.set(true);
mBindingObject.charField.set('1');
mBindingObject.byteField.set((byte) 1);
mBindingObject.shortField.set((short) 12);
mBindingObject.intField.set(123);
mBindingObject.longField.set(1234);
mBindingObject.floatField.set(1.2345f);
mBindingObject.doubleField.set(1.23456);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
mBinder.convertBool.setText("foobar");
mBinder.convertByte.setText("fred");
mBinder.convertShort.setText("wilma");
mBinder.convertInt.setText("barney");
mBinder.convertLong.setText("betty");
mBinder.convertFloat.setText("pebbles");
mBinder.convertDouble.setText("bam-bam");
mBinder.convertChar.setText("");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.booleanField.get();
}
});
waitForUISync();
assertFalse(mBindingObject.booleanField.get());
assertEquals(1, mBindingObject.byteField.get());
assertEquals(12, mBindingObject.shortField.get());
assertEquals(123, mBindingObject.intField.get());
assertEquals(1234, mBindingObject.longField.get());
assertEquals(1.2345f, mBindingObject.floatField.get(), 0.0001f);
assertEquals(1.23456, mBindingObject.doubleField.get(), 0.00001);
assertEquals('1', mBindingObject.charField.get());
}
public void testBindPojo() throws Throwable {
makeVisible(mBinder.toField);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertEquals("Hello", mBinder.toField.getText().toString());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.toField.setText("Goodbye");
}
});
final long timeout = SystemClock.uptimeMillis() + 500;
while ("Hello".equals(mBindingObject.textField) && SystemClock.uptimeMillis() < timeout) {
Thread.sleep(1);
}
assertEquals("Goodbye", mBindingObject.textField);
}
public void testBindStaticField() throws Throwable {
makeVisible(mBinder.toStaticField);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertEquals("World", mBinder.toStaticField.getText().toString());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.toStaticField.setText("Cruel");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return "World".equals(mBindingObject.staticField);
}
});
assertEquals("Cruel", mBindingObject.staticField);
}
public void testSimpleInstanceMethod() throws Throwable {
mBindingObject.intField.set(5);
makeVisible(mBinder.simpleInstanceMethod);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertEquals("5", mBinder.simpleInstanceMethod.getText().toString());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.simpleInstanceMethod.setText("6");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.intField.get() == 5;
}
});
assertEquals(6, mBindingObject.intField.get());
}
public void testSimpleStaticMethod() throws Throwable {
mBindingObject.floatField.set(5f);
makeVisible(mBinder.simpleStaticMethod);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertEquals("5.0", mBinder.simpleStaticMethod.getText().toString());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.simpleStaticMethod.setText("6.0");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.floatField.get() == 5;
}
});
assertEquals(6f, mBindingObject.floatField.get());
}
public void testGenericInstanceMethod() throws Throwable {
makeVisible(mBinder.genericInstanceMethod);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
assertEquals("one,two,three,four,five,six,seven,eight,nine,ten",
mBinder.genericInstanceMethod.getText().toString());
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.genericInstanceMethod.setText("hello,world");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.stringList.get().size() != 2;
}
});
assertEquals(2, mBindingObject.stringList.get().size());
assertEquals("hello", mBindingObject.stringList.get().get(0));
}
public void testTypedInstanceMethod() throws Throwable {
makeVisible(mBinder.typedInstanceMethod);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
assertEquals("one,two,three,four,five,six,seven,eight,nine,ten",
mBinder.typedInstanceMethod.getText().toString());
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.typedInstanceMethod.setText("hello,world");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.stringList.get().size() != 2;
}
});
assertEquals(2, mBindingObject.stringList.get().size());
assertEquals("hello", mBindingObject.stringList.get().get(0));
}
public void testArrayMethod() throws Throwable {
makeVisible(mBinder.arrayMethod);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
assertEquals("1,2,3,4,5,6,7,8,9,10", mBinder.arrayMethod.getText().toString());
}
});
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.arrayMethod.setText("2,3");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBindingObject.anotherArray.get().length > 2;
}
});
assertEquals(2, mBindingObject.anotherArray.get().length);
assertEquals(2, mBindingObject.anotherArray.get()[0]);
}
private void waitWhile(final TestCondition check) throws Throwable {
final long timeout = SystemClock.uptimeMillis() + 500;
final boolean[] val = new boolean[1];
do {
runTestOnUiThread(new Runnable() {
@Override
public void run() {
val[0] = check.testValue();
}
});
Thread.sleep(1);
} while (SystemClock.uptimeMillis() < timeout && !val[0]);
}
/**
* This tests whether the implicit inversion also works. We've declared a conversion
* to pig latin, and this ensures that binding to the inversion (from pig latin) is
* also declared implicitly.
*/
public void testReversPigLatin() throws Throwable {
mBindingObject.pigLatin.set("atinLay");
makeVisible(mBinder.pigLatin);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertEquals("Latin", mBinder.pigLatin.getText().toString());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.pigLatin.setText("Pig");
}
});
final long timeout = SystemClock.uptimeMillis() + 500;
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return "atinLay".equals(mBindingObject.pigLatin.get());
}
});
assertEquals("igPay", mBindingObject.pigLatin.get());
}
/**
* Tests two-way binding when the target is the same Target as expression.
*/
public void testSameTarget() throws Throwable {
makeVisible(mBinder.sameTarget);
assertEquals("Hello World", mBinder.sameTarget.getError().toString());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.sameTarget.setText("Goodbye World");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return mBinder.sameTarget.getError().toString().equals("Hello World");
}
});
assertEquals("Goodbye World", mBinder.sameTarget.getError().toString());
}
/**
* Two-way binding introduces new attribute expressions, so if there is already an expression on
* a View, it must resolve the multi-attribute binding adapters after the two-way expressions
* are resolved.
*/
public void testCrossAttributes() throws Throwable {
makeVisible(mBinder.mixView1, mBinder.mixView2);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertFalse(mBinder.mixView2.isEnabled());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.mixView1.setText("a");
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return !mBinder.mixView2.isEnabled();
}
});
assertTrue(mBinder.mixView2.isEnabled());
}
/**
* This tests whether the unary not properly converts back
*/
public void testUnaryNot() throws Throwable {
mBindingObject.checked.set(false);
makeVisible(mBinder.unaryNot);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.executePendingBindings();
}
});
assertTrue(mBinder.unaryNot.isChecked());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.unaryNot.setChecked(false);
}
});
waitWhile(new TestCondition() {
@Override
public boolean testValue() {
return !mBindingObject.checked.get();
}
});
assertTrue(mBindingObject.checked.get());
}
private void makeVisible(final View... views) throws Throwable {
runTestOnUiThread(new Runnable() {
@Override
public void run() {
mBinder.calendarView.setVisibility(View.GONE);
mBinder.listView.setVisibility(View.GONE);
mBinder.checkBox.setVisibility(View.GONE);
mBinder.numberPicker.setVisibility(View.GONE);
mBinder.ratingBar.setVisibility(View.GONE);
mBinder.seekBar.setVisibility(View.GONE);
mBinder.tabhost.setVisibility(View.GONE);
mBinder.textView.setVisibility(View.GONE);
mBinder.timePicker.setVisibility(View.GONE);
mBinder.datePicker.setVisibility(View.GONE);
mBinder.expressions1.setVisibility(View.GONE);
mBinder.expressions2.setVisibility(View.GONE);
mBinder.expressions3.setVisibility(View.GONE);
mBinder.expressions4.setVisibility(View.GONE);
mBinder.checkBox2.setVisibility(View.GONE);
mBinder.checkBox3.setVisibility(View.GONE);
mBinder.checkBox4.setVisibility(View.GONE);
mBinder.editText1.setVisibility(View.GONE);
mBinder.editText2.setVisibility(View.GONE);
mBinder.included.editText1.setVisibility(View.GONE);
mBinder.included.editText2.setVisibility(View.GONE);
mBinder.convertBool.setVisibility(View.GONE);
mBinder.convertByte.setVisibility(View.GONE);
mBinder.convertShort.setVisibility(View.GONE);
mBinder.convertInt.setVisibility(View.GONE);
mBinder.convertLong.setVisibility(View.GONE);
mBinder.convertFloat.setVisibility(View.GONE);
mBinder.convertDouble.setVisibility(View.GONE);
mBinder.convertChar.setVisibility(View.GONE);
mBinder.toField.setVisibility(View.GONE);
mBinder.toStaticField.setVisibility(View.GONE);
mBinder.simpleInstanceMethod.setVisibility(View.GONE);
mBinder.simpleStaticMethod.setVisibility(View.GONE);
mBinder.genericInstanceMethod.setVisibility(View.GONE);
mBinder.typedInstanceMethod.setVisibility(View.GONE);
mBinder.arrayMethod.setVisibility(View.GONE);
mBinder.sameTarget.setVisibility(View.GONE);
mBinder.mixView1.setVisibility(View.GONE);
mBinder.mixView2.setVisibility(View.GONE);
mBinder.unaryNot.setVisibility(View.GONE);
for (View view : views) {
view.setVisibility(View.VISIBLE);
}
}
});
waitForUISync();
}
private interface TestCondition {
boolean testValue();
}
}