1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package android.support.v7.preference.tests;
18
19import android.content.Context;
20import android.graphics.Canvas;
21import android.graphics.ColorFilter;
22import android.graphics.drawable.Drawable;
23import android.support.test.InstrumentationRegistry;
24import android.support.test.filters.SmallTest;
25import android.support.test.runner.AndroidJUnit4;
26import android.support.v7.preference.CheckBoxPreference;
27import android.support.v7.preference.DropDownPreference;
28import android.support.v7.preference.Preference;
29import android.support.v7.preference.PreferenceManager;
30import android.support.v7.preference.TwoStatePreference;
31
32import org.junit.Before;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35
36import static org.junit.Assert.assertFalse;
37import static org.junit.Assert.assertTrue;
38
39@RunWith(AndroidJUnit4.class)
40@SmallTest
41public class SimplePreferenceComparisonCallbackTest {
42
43    private Preference mPref1;
44    private Preference mPref2;
45    private PreferenceManager.PreferenceComparisonCallback mComparisonCallback;
46
47    @Before
48    public void setup() throws Exception {
49        final Context context = InstrumentationRegistry.getTargetContext();
50        mPref1 = new Preference(context);
51        mPref2 = new Preference(context);
52        mComparisonCallback = new PreferenceManager.SimplePreferenceComparisonCallback();
53    }
54
55    /**
56     * Basic sanity test, all fields blank should compare the same
57     * @throws Exception
58     */
59    @Test
60    public void testNull() throws Exception {
61        assertTrue("Compare all null",
62                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
63    }
64
65    /**
66     * Two different classes should not compare the same
67     * @throws Exception
68     */
69    @Test
70    public void testClassComparison() throws Exception {
71        final Preference checkboxPreference =
72                new CheckBoxPreference(InstrumentationRegistry.getTargetContext());
73        assertFalse("Compare class",
74                mComparisonCallback.arePreferenceContentsTheSame(mPref1, checkboxPreference));
75    }
76
77    /**
78     * Same instance, but detached and reattached should not compare the same
79     * @throws Exception
80     */
81    @Test
82    public void testDetached() throws Exception {
83        mPref1.onDetached();
84        mPref1.onAttached();
85        assertFalse("Compare same, detached",
86                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref1));
87    }
88
89    /**
90     * Title differences should be detected
91     * @throws Exception
92     */
93    @Test
94    public void testTitleComparison() throws Exception {
95        mPref1.setTitle("value 1");
96
97        assertFalse("Compare non-null to null",
98                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
99        assertFalse("Compare null to non-null",
100                mComparisonCallback.arePreferenceContentsTheSame(mPref2, mPref1));
101
102        mPref2.setTitle("value 1");
103
104        assertTrue("Compare identical",
105                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
106
107        mPref2.setTitle("value 2");
108
109        assertFalse("Compare different",
110                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
111    }
112
113    /**
114     * Summary differences should be detected
115     * @throws Exception
116     */
117    @Test
118    public void testSummaryComparison() throws Exception {
119        mPref1.setSummary("value 1");
120
121        assertFalse("Compare non-null to null",
122                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
123        assertFalse("Compare null to non-null",
124                mComparisonCallback.arePreferenceContentsTheSame(mPref2, mPref1));
125
126        mPref2.setSummary("value 1");
127
128        assertTrue("Compare identical",
129                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
130
131        mPref2.setSummary("value 2");
132
133        assertFalse("Compare different",
134                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
135    }
136
137    private static class ComparisonDrawable extends Drawable {
138
139        private final int mId;
140
141        public ComparisonDrawable(int id) {
142            mId = id;
143        }
144
145        public int getId() {
146            return mId;
147        }
148
149        @Override
150        public void draw(Canvas canvas) {}
151
152        @Override
153        public void setAlpha(int alpha) {}
154
155        @Override
156        public void setColorFilter(ColorFilter colorFilter) {}
157
158        @Override
159        public int getOpacity() {
160            return 0;
161        }
162
163        @Override
164        public boolean equals(Object o) {
165            return o instanceof ComparisonDrawable && ((ComparisonDrawable)o).getId() == mId;
166        }
167
168        @Override
169        public int hashCode() {
170            return mId;
171        }
172    }
173
174    /**
175     * Icon differences should be detected
176     * @throws Exception
177     */
178    @Test
179    public void testIconComparison() throws Exception {
180        final Drawable drawable1 = new ComparisonDrawable(1);
181        final Drawable drawable1a = new ComparisonDrawable(1);
182        final Drawable drawable2 = new ComparisonDrawable(2);
183
184        mPref1.setIcon(drawable1);
185
186        assertFalse("Compare non-null to null",
187                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
188        assertFalse("Compare null to non-null",
189                mComparisonCallback.arePreferenceContentsTheSame(mPref2, mPref1));
190
191        mPref2.setIcon(drawable1);
192
193        assertTrue("Compare aliased",
194                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
195
196        mPref2.setIcon(drawable1a);
197
198        assertTrue("Compare equal",
199                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
200
201        mPref2.setIcon(drawable2);
202
203        assertFalse("Compare unequal",
204                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
205    }
206
207    /**
208     * Enabled differences should be detected
209     * @throws Exception
210     */
211    @Test
212    public void testEnabledComparison() throws Exception {
213        mPref1.setEnabled(true);
214        mPref2.setEnabled(true);
215
216        assertTrue("Compare enabled",
217                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
218
219        mPref2.setEnabled(false);
220
221        assertFalse("Compare enabled/disabled",
222                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
223        assertFalse("Compare disable/enabled",
224                mComparisonCallback.arePreferenceContentsTheSame(mPref2, mPref1));
225
226        mPref1.setEnabled(false);
227
228        assertTrue("Compare disabled",
229                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
230    }
231
232    /**
233     * Selectable differences should be detected
234     * @throws Exception
235     */
236    @Test
237    public void testSelectableComparison() throws Exception {
238        mPref1.setSelectable(true);
239        mPref2.setSelectable(true);
240
241        assertTrue("Compare selectable",
242                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
243
244        mPref2.setSelectable(false);
245
246        assertFalse("Compare selectable/unselectable",
247                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
248        assertFalse("Compare unselectable/selectable",
249                mComparisonCallback.arePreferenceContentsTheSame(mPref2, mPref1));
250
251        mPref1.setSelectable(false);
252
253        assertTrue("Compare unselectable",
254                mComparisonCallback.arePreferenceContentsTheSame(mPref1, mPref2));
255    }
256
257    /**
258     * For {@link TwoStatePreference} objects, checked state differences should be detected
259     * @throws Exception
260     */
261    @Test
262    public void testTwoStateComparison() throws Exception {
263        final TwoStatePreference checkbox1 =
264                new CheckBoxPreference(InstrumentationRegistry.getTargetContext());
265        final TwoStatePreference checkbox2 =
266                new CheckBoxPreference(InstrumentationRegistry.getTargetContext());
267
268        checkbox1.setChecked(true);
269        checkbox2.setChecked(true);
270
271        assertTrue("Compare checked",
272                mComparisonCallback.arePreferenceContentsTheSame(checkbox1, checkbox2));
273
274        checkbox2.setChecked(false);
275
276        assertFalse("Compare checked/unchecked",
277                mComparisonCallback.arePreferenceContentsTheSame(checkbox1, checkbox2));
278        assertFalse("Compare unchecked/checked",
279                mComparisonCallback.arePreferenceContentsTheSame(checkbox2, checkbox1));
280
281        checkbox1.setChecked(false);
282
283        assertTrue("Compare unchecked",
284                mComparisonCallback.arePreferenceContentsTheSame(checkbox1, checkbox2));
285    }
286
287    /**
288     * {@link DropDownPreference} is a special case, the pref object will need to re-bind the
289     * spinner when recycled, so distinct instances are never evaluated as equal
290     * @throws Exception
291     */
292    @Test
293    public void testDropDownComparison() throws Exception {
294        final Preference dropdown1 =
295                new DropDownPreference(InstrumentationRegistry.getTargetContext());
296        final Preference dropdown2 =
297                new DropDownPreference(InstrumentationRegistry.getTargetContext());
298
299        assertTrue("Compare aliased drop down pref",
300                mComparisonCallback.arePreferenceContentsTheSame(dropdown1, dropdown1));
301        assertFalse("Compare distinct drop down prefs",
302                mComparisonCallback.arePreferenceContentsTheSame(dropdown1, dropdown2));
303    }
304}
305