blob: b81b37c4d9d8523f8d5805743e0ad90346510374 [file] [log] [blame]
/*
* Copyright (C) 2008 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.widget.cts;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.util.AttributeSet;
import android.util.StateSet;
import android.util.Xml;
import android.view.Gravity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.cts.util.TestUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;
/**
* Test {@link CompoundButton}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CompoundButtonTest {
private Instrumentation mInstrumentation;
private Activity mActivity;
private CompoundButton mCompoundButton;
@Rule
public ActivityTestRule<CompoundButtonCtsActivity> mActivityRule =
new ActivityTestRule<>(CompoundButtonCtsActivity.class);
@Before
public void setup() {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mActivity = mActivityRule.getActivity();
mCompoundButton = (CompoundButton) mActivity.findViewById(R.id.compound_button);
}
@Test
public void testConstructor() {
XmlPullParser parser = mActivity.getResources().getXml(R.layout.compoundbutton_layout);
AttributeSet mAttrSet = Xml.asAttributeSet(parser);
new MockCompoundButton(mActivity, mAttrSet, 0);
new MockCompoundButton(mActivity, mAttrSet);
new MockCompoundButton(mActivity);
}
@Test(expected=NullPointerException.class)
public void testConstructorWithNullContext1() {
new MockCompoundButton(null);
}
@Test(expected=NullPointerException.class)
public void testConstructorWithNullContext2() {
new MockCompoundButton(null, null);
}
@Test(expected=NullPointerException.class)
public void testConstructorWithNullContext3() {
new MockCompoundButton(null, null, -1);
}
@UiThreadTest
@Test
public void testAccessChecked() {
CompoundButton.OnCheckedChangeListener mockCheckedChangeListener =
mock(CompoundButton.OnCheckedChangeListener.class);
mCompoundButton.setOnCheckedChangeListener(mockCheckedChangeListener);
assertFalse(mCompoundButton.isChecked());
verifyZeroInteractions(mockCheckedChangeListener);
mCompoundButton.setChecked(true);
assertTrue(mCompoundButton.isChecked());
verify(mockCheckedChangeListener, times(1)).onCheckedChanged(mCompoundButton, true);
reset(mockCheckedChangeListener);
mCompoundButton.setChecked(true);
assertTrue(mCompoundButton.isChecked());
verifyZeroInteractions(mockCheckedChangeListener);
mCompoundButton.setChecked(false);
assertFalse(mCompoundButton.isChecked());
verify(mockCheckedChangeListener, times(1)).onCheckedChanged(mCompoundButton, false);
}
@UiThreadTest
@Test
public void testSetOnCheckedChangeListener() {
CompoundButton.OnCheckedChangeListener mockCheckedChangeListener =
mock(CompoundButton.OnCheckedChangeListener.class);
mCompoundButton.setOnCheckedChangeListener(mockCheckedChangeListener);
assertFalse(mCompoundButton.isChecked());
verifyZeroInteractions(mockCheckedChangeListener);
mCompoundButton.setChecked(true);
verify(mockCheckedChangeListener, times(1)).onCheckedChanged(mCompoundButton, true);
// set null
mCompoundButton.setOnCheckedChangeListener(null);
reset(mockCheckedChangeListener);
mCompoundButton.setChecked(false);
verifyZeroInteractions(mockCheckedChangeListener);
}
@UiThreadTest
@Test
public void testToggle() {
assertFalse(mCompoundButton.isChecked());
mCompoundButton.toggle();
assertTrue(mCompoundButton.isChecked());
mCompoundButton.toggle();
assertFalse(mCompoundButton.isChecked());
mCompoundButton.setChecked(true);
mCompoundButton.toggle();
assertFalse(mCompoundButton.isChecked());
}
@UiThreadTest
@Test
public void testPerformClick() {
assertFalse(mCompoundButton.isChecked());
// performClick without OnClickListener will return false.
assertFalse(mCompoundButton.performClick());
assertTrue(mCompoundButton.isChecked());
assertFalse(mCompoundButton.performClick());
assertFalse(mCompoundButton.isChecked());
// performClick with OnClickListener will return true.
mCompoundButton.setOnClickListener((view) -> {});
assertTrue(mCompoundButton.performClick());
assertTrue(mCompoundButton.isChecked());
assertTrue(mCompoundButton.performClick());
assertFalse(mCompoundButton.isChecked());
}
@UiThreadTest
@Test
public void testDrawableStateChanged() {
MockCompoundButton compoundButton = new MockCompoundButton(mActivity);
assertFalse(compoundButton.isChecked());
// drawableStateChanged without any drawables.
compoundButton.drawableStateChanged();
// drawableStateChanged when CheckMarkDrawable is not null.
Drawable drawable = mActivity.getDrawable(R.drawable.statelistdrawable);
compoundButton.setButtonDrawable(drawable);
drawable.setState(null);
assertNull(drawable.getState());
compoundButton.drawableStateChanged();
assertNotNull(drawable.getState());
assertSame(compoundButton.getDrawableState(), drawable.getState());
}
@UiThreadTest
@Test
public void testSetButtonDrawableByDrawable() {
// set null drawable
mCompoundButton.setButtonDrawable(null);
assertNull(mCompoundButton.getButtonDrawable());
// set drawable when button is GONE
mCompoundButton.setVisibility(View.GONE);
Drawable firstDrawable = mActivity.getDrawable(R.drawable.scenery);
firstDrawable.setVisible(true, false);
assertEquals(StateSet.WILD_CARD, firstDrawable.getState());
mCompoundButton.setButtonDrawable(firstDrawable);
assertSame(firstDrawable, mCompoundButton.getButtonDrawable());
assertFalse(firstDrawable.isVisible());
// update drawable when button is VISIBLE
mCompoundButton.setVisibility(View.VISIBLE);
Drawable secondDrawable = mActivity.getDrawable(R.drawable.pass);
secondDrawable.setVisible(true, false);
assertEquals(StateSet.WILD_CARD, secondDrawable.getState());
mCompoundButton.setButtonDrawable(secondDrawable);
assertSame(secondDrawable, mCompoundButton.getButtonDrawable());
assertTrue(secondDrawable.isVisible());
// the firstDrawable is not active.
assertFalse(firstDrawable.isVisible());
}
@UiThreadTest
@Test
public void testSetButtonDrawableById() {
// resId is 0
mCompoundButton.setButtonDrawable(0);
// set drawable
mCompoundButton.setButtonDrawable(R.drawable.scenery);
// set the same drawable again
mCompoundButton.setButtonDrawable(R.drawable.scenery);
// update drawable
mCompoundButton.setButtonDrawable(R.drawable.pass);
}
@Test
public void testOnCreateDrawableState() {
// compoundButton is not checked, append 0 to state array.
MockCompoundButton compoundButton = new MockCompoundButton(mActivity);
int[] state = compoundButton.onCreateDrawableState(0);
assertEquals(0, state[state.length - 1]);
// compoundButton is checked, append R.attr.state_checked to state array.
compoundButton.setChecked(true);
int[] checkedState = compoundButton.onCreateDrawableState(0);
assertEquals(state[0], checkedState[0]);
assertEquals(android.R.attr.state_checked,
checkedState[checkedState.length - 1]);
// compoundButton is not checked again.
compoundButton.setChecked(false);
state = compoundButton.onCreateDrawableState(0);
assertEquals(0, state[state.length - 1]);
}
@Test
public void testOnDraw() {
int viewHeight;
int drawableWidth;
int drawableHeight;
Rect bounds;
Drawable drawable;
Canvas canvas = new Canvas(android.graphics.Bitmap.createBitmap(100, 100,
android.graphics.Bitmap.Config.ARGB_8888));
MockCompoundButton compoundButton;
// onDraw when there is no drawable
compoundButton = new MockCompoundButton(mActivity);
compoundButton.onDraw(canvas);
// onDraw when Gravity.TOP, it's default.
compoundButton = new MockCompoundButton(mActivity);
drawable = mActivity.getDrawable(R.drawable.scenery);
compoundButton.setButtonDrawable(drawable);
viewHeight = compoundButton.getHeight();
drawableWidth = drawable.getIntrinsicWidth();
drawableHeight = drawable.getIntrinsicHeight();
compoundButton.onDraw(canvas);
bounds = drawable.copyBounds();
assertEquals(0, bounds.left);
assertEquals(drawableWidth, bounds.right);
assertEquals(0, bounds.top);
assertEquals(drawableHeight, bounds.bottom);
// onDraw when Gravity.BOTTOM
compoundButton.setGravity(Gravity.BOTTOM);
compoundButton.onDraw(canvas);
bounds = drawable.copyBounds();
assertEquals(0, bounds.left);
assertEquals(drawableWidth, bounds.right);
assertEquals(viewHeight - drawableHeight, bounds.top);
assertEquals(viewHeight, bounds.bottom);
// onDraw when Gravity.CENTER_VERTICAL
compoundButton.setGravity(Gravity.CENTER_VERTICAL);
compoundButton.onDraw(canvas);
bounds = drawable.copyBounds();
assertEquals(0, bounds.left);
assertEquals(drawableWidth, bounds.right);
assertEquals( (viewHeight - drawableHeight) / 2, bounds.top);
assertEquals( (viewHeight - drawableHeight) / 2 + drawableHeight, bounds.bottom);
}
@UiThreadTest
@Test
public void testAccessInstanceState() {
Parcelable state;
assertFalse(mCompoundButton.isChecked());
assertFalse(mCompoundButton.getFreezesText());
state = mCompoundButton.onSaveInstanceState();
assertNotNull(state);
assertFalse(mCompoundButton.getFreezesText());
mCompoundButton.setChecked(true);
mCompoundButton.onRestoreInstanceState(state);
assertFalse(mCompoundButton.isChecked());
assertTrue(mCompoundButton.isLayoutRequested());
}
@Test
public void testVerifyDrawable() {
MockCompoundButton compoundButton = new MockCompoundButton(mActivity);
Drawable drawable = mActivity.getDrawable(R.drawable.scenery);
assertTrue(compoundButton.verifyDrawable(null));
assertFalse(compoundButton.verifyDrawable(drawable));
compoundButton.setButtonDrawable(drawable);
assertTrue(compoundButton.verifyDrawable(null));
assertTrue(compoundButton.verifyDrawable(drawable));
}
@UiThreadTest
@Test
public void testButtonTint() {
CompoundButton tintedButton = (CompoundButton) mActivity.findViewById(R.id.button_tint);
assertEquals("Button tint inflated correctly",
Color.WHITE, tintedButton.getButtonTintList().getDefaultColor());
assertEquals("Button tint mode inflated correctly",
PorterDuff.Mode.SRC_OVER, tintedButton.getButtonTintMode());
Drawable mockDrawable = spy(new ColorDrawable(Color.GREEN));
mCompoundButton.setButtonDrawable(mockDrawable);
// No button tint applied by default
verify(mockDrawable, never()).setTintList(any(ColorStateList.class));
mCompoundButton.setButtonTintList(ColorStateList.valueOf(Color.WHITE));
// Button tint applied when setButtonTintList() called after setButton()
verify(mockDrawable, times(1)).setTintList(TestUtils.colorStateListOf(Color.WHITE));
reset(mockDrawable);
mCompoundButton.setButtonDrawable(null);
mCompoundButton.setButtonDrawable(mockDrawable);
// Button tint applied when setButtonTintList() called before setButton()
verify(mockDrawable, times(1)).setTintList(TestUtils.colorStateListOf(Color.WHITE));
}
public static final class MockCompoundButton extends CompoundButton {
public MockCompoundButton(Context context) {
super(context);
}
public MockCompoundButton(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}
public MockCompoundButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
return super.onCreateDrawableState(extraSpace);
}
@Override
protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who);
}
}
}