1package com.xtremelabs.robolectric.shadows;
2
3import static com.xtremelabs.robolectric.Robolectric.shadowOf;
4import static junit.framework.Assert.assertEquals;
5import static junit.framework.Assert.assertTrue;
6import static org.hamcrest.CoreMatchers.equalTo;
7import static org.hamcrest.CoreMatchers.not;
8import static org.junit.Assert.assertFalse;
9import static org.junit.Assert.assertNotSame;
10import static org.junit.Assert.assertNull;
11import static org.junit.Assert.assertSame;
12import static org.junit.Assert.assertThat;
13
14import android.app.Activity;
15import android.content.ComponentName;
16import android.content.Intent;
17import android.net.Uri;
18import android.os.Bundle;
19import android.os.Parcel;
20import android.os.Parcelable;
21
22import com.xtremelabs.robolectric.Robolectric;
23import com.xtremelabs.robolectric.WithTestDefaultsRunner;
24
25import org.junit.Test;
26import org.junit.runner.RunWith;
27
28import java.io.Serializable;
29import java.util.ArrayList;
30import java.util.Arrays;
31import java.util.Set;
32
33@RunWith(WithTestDefaultsRunner.class)
34public class IntentTest {
35    @Test
36    public void testStringExtra() throws Exception {
37        Intent intent = new Intent();
38        assertSame(intent, intent.putExtra("foo", "bar"));
39        assertEquals("bar", intent.getExtras().get("foo"));
40    }
41
42    @Test
43    public void testCharSequenceExtra() throws Exception {
44        Intent intent = new Intent();
45        CharSequence cs = new TestCharSequence("bar");
46        assertSame(intent, intent.putExtra("foo", cs));
47        assertSame(cs, intent.getExtras().get("foo"));
48    }
49
50    @Test
51    public void testIntExtra() throws Exception {
52        Intent intent = new Intent();
53        assertSame(intent, intent.putExtra("foo", 2));
54        assertEquals(2, intent.getExtras().get("foo"));
55        assertEquals(2, intent.getIntExtra("foo", -1));
56    }
57
58    @Test
59    public void testDoubleExtra() throws Exception {
60        Intent intent = new Intent();
61        assertSame(intent, intent.putExtra("foo", 2d));
62        assertEquals(2d, intent.getExtras().get("foo"));
63        assertEquals(2d, intent.getDoubleExtra("foo", -1));
64    }
65
66    @Test
67    public void testFloatExtra() throws Exception {
68        Intent intent = new Intent();
69        assertSame(intent, intent.putExtra("foo", 2f));
70        assertEquals(2f, intent.getExtras().get("foo"));
71        assertEquals(2f, intent.getFloatExtra("foo", -1));
72    }
73
74    @Test
75    public void testIntArrayExtra() throws Exception {
76        Intent intent = new Intent();
77        int[] array = new int[2];
78        array[0] = 1;
79        array[1] = 2;
80        assertSame(intent, intent.putExtra("foo", array));
81        assertEquals(1, intent.getIntArrayExtra("foo")[0]);
82        assertEquals(2, intent.getIntArrayExtra("foo")[1]);
83    }
84
85    @Test
86    public void testLongArrayExtra() throws Exception {
87        Intent intent = new Intent();
88        long[] array = new long[2];
89        array[0] = 1L;
90        array[1] = 2L;
91        assertSame(intent, intent.putExtra("foo", array));
92        assertEquals(1L, intent.getLongArrayExtra("foo")[0]);
93        assertEquals(2L, intent.getLongArrayExtra("foo")[1]);
94    }
95
96    @Test
97    public void testSerializableExtra() throws Exception {
98        Intent intent = new Intent();
99        TestSerializable serializable = new TestSerializable("some string");
100        assertSame(intent, intent.putExtra("foo", serializable));
101        assertEquals(serializable, intent.getExtras().get("foo"));
102        assertNotSame(serializable, intent.getExtras().get("foo"));
103        assertEquals(serializable, intent.getSerializableExtra("foo"));
104        assertNotSame(serializable, intent.getSerializableExtra("foo"));
105    }
106
107    @Test
108    public void testParcelableExtra() throws Exception {
109        Intent intent = new Intent();
110        Parcelable parcelable = new TestParcelable(44);
111        assertSame(intent, intent.putExtra("foo", parcelable));
112        assertSame(parcelable, intent.getExtras().get("foo"));
113        assertSame(parcelable, intent.getParcelableExtra("foo"));
114    }
115
116    @Test
117    public void testParcelableArrayExtra() throws Exception {
118        Intent intent = new Intent();
119        Parcelable parcelable = new TestParcelable(11);
120        intent.putExtra("foo", parcelable);
121        assertSame(null, intent.getParcelableArrayExtra("foo"));
122        Parcelable[] parcelables = {new TestParcelable(12), new TestParcelable(13)};
123        assertSame(intent, intent.putExtra("bar", parcelables));
124        assertSame(parcelables, intent.getParcelableArrayExtra("bar"));
125    }
126
127    @Test
128    public void testParcelableArrayListExtra() {
129        Intent intent = new Intent();
130        Parcelable parcel1 = new TestParcelable(22);
131        Parcelable parcel2 = new TestParcelable(23);
132        ArrayList<Parcelable> parcels = new ArrayList<Parcelable>();
133        parcels.add(parcel1);
134        parcels.add(parcel2);
135
136        assertSame(intent, intent.putParcelableArrayListExtra("foo", parcels));
137        assertSame(parcels, intent.getParcelableArrayListExtra("foo"));
138        assertSame(parcel1, intent.getParcelableArrayListExtra("foo").get(0));
139        assertSame(parcel2, intent.getParcelableArrayListExtra("foo").get(1));
140        assertSame(parcels, intent.getExtras().getParcelableArrayList("foo"));
141    }
142
143    @Test
144    public void testLongExtra() throws Exception {
145        Intent intent = new Intent();
146        assertSame(intent, intent.putExtra("foo", 2L));
147        assertEquals(2L, shadowOf(intent).getExtras().get("foo"));
148        assertEquals(2L, intent.getLongExtra("foo", -1));
149        assertEquals(-1L, intent.getLongExtra("bar", -1));
150    }
151
152    @Test
153    public void testBundleExtra() throws Exception {
154        Intent intent = new Intent();
155        Bundle bundle = new Bundle();
156        bundle.putInt("bar", 5);
157        assertSame(intent, intent.putExtra("foo", bundle));
158        assertEquals(5, intent.getBundleExtra("foo").getInt("bar"));
159    }
160
161    @Test
162    public void testHasExtra() throws Exception {
163        Intent intent = new Intent();
164        assertSame(intent, intent.putExtra("foo", ""));
165        assertTrue(intent.hasExtra("foo"));
166        assertFalse(intent.hasExtra("bar"));
167    }
168
169    @Test
170    public void testGetActionReturnsWhatWasSet() throws Exception {
171        Intent intent = new Intent();
172        assertSame(intent, intent.setAction("foo"));
173        assertEquals("foo", intent.getAction());
174    }
175
176    @Test
177    public void testSetData() throws Exception {
178        Intent intent = new Intent();
179        Uri uri = Uri.parse("content://this/and/that");
180        intent.setType("abc");
181        assertSame(intent, intent.setData(uri));
182        assertSame(uri, intent.getData());
183        assertNull(intent.getType());
184    }
185
186    @Test
187    public void testSetType() throws Exception {
188        Intent intent = new Intent();
189        intent.setData(Uri.parse("content://this/and/that"));
190        assertSame(intent, intent.setType("def"));
191        assertNull(intent.getData());
192        assertEquals("def", intent.getType());
193    }
194
195    @Test
196    public void testSetDataAndType() throws Exception {
197        Intent intent = new Intent();
198        Uri uri = Uri.parse("content://this/and/that");
199        assertSame(intent, intent.setDataAndType(uri, "ghi"));
200        assertSame(uri, intent.getData());
201        assertEquals("ghi", intent.getType());
202    }
203
204    @Test
205    public void testSetClass() throws Exception {
206        Intent intent = new Intent();
207        Class<? extends IntentTest> thisClass = getClass();
208        Intent output = intent.setClass(new Activity(), thisClass);
209
210        assertSame(output, intent);
211        ShadowIntent si = shadowOf(intent);
212        assertSame(si.getIntentClass(), thisClass);
213    }
214
215    @Test
216    public void testSetClassName() throws Exception {
217        Intent intent = new Intent();
218        Class<? extends IntentTest> thisClass = getClass();
219        intent.setClassName("package.name", thisClass.getName());
220        assertSame(thisClass.getName(), intent.getComponent().getClassName());
221        assertEquals("package.name", intent.getComponent().getPackageName());
222        ShadowIntent si = shadowOf(intent);
223        assertSame(si.getIntentClass(), thisClass);
224    }
225
226    @Test
227    public void testSetClassThroughConstructor() throws Exception {
228        Intent intent = new Intent(new Activity(), getClass());
229        assertEquals(shadowOf(intent).getIntentClass(), getClass());
230    }
231
232    @Test
233    public void shouldSetFlags() throws Exception {
234        Intent intent = new Intent();
235        Intent self = intent.setFlags(1234);
236        assertEquals(1234, intent.getFlags());
237        assertSame(self, intent);
238    }
239
240    @Test
241    public void shouldAddFlags() throws Exception {
242        Intent intent = new Intent();
243        Intent self = intent.addFlags(4);
244        self.addFlags(8);
245        assertEquals(12, intent.getFlags());
246        assertSame(self, intent);
247    }
248
249    @Test
250    public void shouldSupportCategories() throws Exception {
251        Intent intent = new Intent();
252        Intent self = intent.addCategory("category.name.1");
253        intent.addCategory("category.name.2");
254
255        assertTrue(intent.hasCategory("category.name.1"));
256        assertTrue(intent.hasCategory("category.name.2"));
257
258        Set<String> categories = intent.getCategories();
259        assertTrue(categories.contains("category.name.1"));
260        assertTrue(categories.contains("category.name.2"));
261
262        intent.removeCategory("category.name.1");
263        assertFalse(intent.hasCategory("category.name.1"));
264        assertTrue(intent.hasCategory("category.name.2"));
265
266        intent.removeCategory("category.name.2");
267        assertFalse(intent.hasCategory("category.name.2"));
268
269        assertEquals(0, intent.getCategories().size());
270
271        assertSame(self, intent);
272    }
273
274    @Test
275    public void shouldAddCategories() throws Exception {
276        Intent intent = new Intent();
277        Intent self = intent.addCategory("foo");
278        assertTrue(intent.getCategories().contains("foo"));
279        assertSame(self, intent);
280    }
281
282    @Test
283    public void shouldFillIn() throws Exception {
284        Intent intentA = new Intent();
285        Intent intentB = new Intent();
286
287        intentB.setAction("foo");
288        Uri uri = Uri.parse("http://www.foo.com");
289        intentB.setDataAndType(uri, "text/html");
290        String category = "category";
291        intentB.addCategory(category);
292        intentB.setPackage("com.foobar.app");
293        ComponentName cn = new ComponentName("com.foobar.app", "activity");
294        intentB.setComponent(cn);
295        intentB.putExtra("FOO", 23);
296
297        int flags = Intent.FILL_IN_ACTION |
298                Intent.FILL_IN_DATA |
299                Intent.FILL_IN_CATEGORIES |
300                Intent.FILL_IN_PACKAGE |
301                Intent.FILL_IN_COMPONENT;
302
303        int result = intentA.fillIn(intentB, flags);
304        assertEquals("foo", intentA.getAction());
305        assertSame(uri, intentA.getData());
306        assertEquals("text/html", intentA.getType());
307        assertTrue(intentA.getCategories().contains(category));
308        assertEquals("com.foobar.app", intentA.getPackage());
309        assertSame(cn, intentA.getComponent());
310        assertEquals(23, intentA.getIntExtra("FOO", -1));
311        assertEquals(result, flags);
312    }
313
314    @Test
315    public void equals_shouldTestActionComponentNameDataAndExtras() throws Exception {
316        Intent intentA = new Intent()
317                .setAction("action")
318                .setData(Uri.parse("content:1"))
319                .setComponent(new ComponentName("pkg", "cls"))
320                .putExtra("extra", "blah")
321                .setType("image/*")
322                .addCategory("category.name");
323
324        Intent intentB = new Intent()
325                .setAction("action")
326                .setData(Uri.parse("content:1"))
327                .setComponent(new ComponentName("pkg", "cls"))
328                .putExtra("extra", "blah")
329                .setType("image/*")
330                .addCategory("category.name");
331
332        assertThat(intentA, equalTo(intentB));
333
334        intentB.setAction("other action");
335        assertThat(intentA, not(equalTo(intentB)));
336
337        intentB.setAction("action");
338        intentB.setData(Uri.parse("content:other"));
339        assertThat(intentA, not(equalTo(intentB)));
340
341        intentB.setData(Uri.parse("content:1"));
342        intentB.setComponent(new ComponentName("other-pkg", "other-cls"));
343        assertThat(intentA, not(equalTo(intentB)));
344
345        intentB.setComponent(new ComponentName("pkg", "cls"));
346        intentB.putExtra("extra", "foo");
347        assertThat(intentA, not(equalTo(intentB)));
348
349        intentB.putExtra("extra", "blah");
350        intentB.setType("other/*");
351        assertThat(intentA, not(equalTo(intentB)));
352
353        intentB.setType("image/*");
354        assertThat(intentA, equalTo(intentB));
355
356        intentB.removeCategory("category.name");
357        assertThat(intentA, not(equalTo(intentB)));
358    }
359
360    @Test
361    public void equals_whenOtherObjectIsNotAnIntent_shouldReturnFalse() throws Exception {
362        assertThat(new Intent(), not(equalTo(new Object())));
363    }
364
365    @Test
366    public void createChooser_shouldWrapIntent() throws Exception {
367        Intent originalIntent = new Intent(Intent.ACTION_BATTERY_CHANGED, Uri.parse("foo://blah"));
368        Intent chooserIntent = Intent.createChooser(originalIntent, "The title");
369        Intent expectedIntent = new Intent(Intent.ACTION_CHOOSER);
370        expectedIntent.putExtra(Intent.EXTRA_INTENT, originalIntent);
371        expectedIntent.putExtra(Intent.EXTRA_TITLE, "The title");
372        assertEquals(expectedIntent, chooserIntent);
373    }
374
375    @Test
376    public void putStringArrayListExtra_addsListToExtras() {
377        Intent intent = new Intent();
378        final ArrayList<String> strings = new ArrayList<String>(Arrays.asList("hi", "there"));
379
380        intent.putStringArrayListExtra("KEY", strings);
381        assertThat(intent.getStringArrayListExtra("KEY"), equalTo(strings));
382        assertThat(Robolectric.shadowOf(intent.getExtras()).getStringArrayList("KEY"), equalTo(strings));
383    }
384
385    @Test
386    public void putIntegerArrayListExtra_addsListToExtras() {
387        Intent intent = new Intent();
388        final ArrayList<Integer> integers = new ArrayList<Integer>(Arrays.asList(100, 200, 300));
389
390        intent.putIntegerArrayListExtra("KEY", integers);
391        assertThat(intent.getIntegerArrayListExtra("KEY"), equalTo(integers));
392        assertThat(Robolectric.shadowOf(intent.getExtras()).getIntegerArrayList("KEY"), equalTo(integers));
393    }
394
395    @Test
396    public void testParcelIo_explicitIntent() {
397        Intent intent = new Intent(new Activity(), getClass());
398        intent.putExtra("boolean", true);
399        intent.putExtra("string", "string value");
400        Bundle bundle = new Bundle();
401        bundle.putDouble("bundle double", 3.14);
402        intent.putExtra("bundle", bundle);
403        intent.putExtra("long", 893);
404
405        verifyIntentReadIsWhatWasWrittenToParcel(intent);
406    }
407
408    @Test
409    public void testParcelIo_actionTypeCategory() {
410        Intent intent = new Intent("action");
411        intent.setType("type");
412        intent.addCategory("category");
413        verifyIntentReadIsWhatWasWrittenToParcel(intent);
414    }
415
416    @Test
417    public void shouldHaveCreator() throws Exception {
418        Intent expected = new Intent("action");
419        expected.setType("type");
420        expected.addCategory("category");
421        Parcel p = Parcel.obtain();
422        expected.writeToParcel(p, 0);
423
424        p.setDataPosition(0);
425
426        Intent actual = Intent.CREATOR.createFromParcel(p);
427        assertThat(expected, equalTo(actual));
428    }
429
430    private void verifyIntentReadIsWhatWasWrittenToParcel(Intent expected) {
431        Parcel parcel = Parcel.obtain();
432        expected.writeToParcel(parcel, 0);
433        parcel.setDataPosition(0);
434        Intent actual = new Intent();
435        actual.readFromParcel(parcel);
436
437        assertThat(expected, equalTo(actual));
438    }
439
440    private static class TestSerializable implements Serializable {
441        private final String someValue;
442
443        public TestSerializable(String someValue) {
444            this.someValue = someValue;
445        }
446
447        @Override
448        public boolean equals(Object o) {
449            if (this == o) return true;
450            if (o == null || getClass() != o.getClass()) return false;
451
452            TestSerializable that = (TestSerializable) o;
453
454            if (someValue != null ? !someValue.equals(that.someValue) : that.someValue != null) return false;
455
456            return true;
457        }
458
459        @Override
460        public int hashCode() {
461            return someValue != null ? someValue.hashCode() : 0;
462        }
463    }
464
465    private class TestCharSequence implements CharSequence {
466        String s;
467
468        public TestCharSequence(String s) {
469            this.s = s;
470        }
471
472        @Override
473        public char charAt(int index) {
474            return s.charAt(index);
475        }
476
477        @Override
478        public int length() {
479            return s.length();
480        }
481
482        @Override
483        public CharSequence subSequence(int start, int end) {
484            return s.subSequence(start, end);
485        }
486
487    }
488}
489