1package com.xtremelabs.robolectric.shadows;
2
3import android.os.Handler;
4import android.os.HandlerThread;
5import android.os.Looper;
6
7import com.xtremelabs.robolectric.WithTestDefaultsRunner;
8import org.junit.Test;
9import org.junit.runner.RunWith;
10
11import static com.xtremelabs.robolectric.Robolectric.shadowOf;
12import static org.junit.Assert.*;
13
14@RunWith(WithTestDefaultsRunner.class)
15public class LooperTest {
16
17    @Test
18    public void testMainLooperAndMyLooperAreTheSameInstanceOnMainThread() throws Exception {
19        assertSame(Looper.myLooper(), Looper.getMainLooper());
20    }
21
22    @Test
23    public void idleMainLooper_executesScheduledTasks() {
24        final boolean[] wasRun = new boolean[]{false};
25        new Handler().postDelayed(new Runnable() {
26            @Override
27            public void run() {
28                wasRun[0] = true;
29            }
30        }, 2000);
31
32        assertFalse(wasRun[0]);
33        ShadowLooper.idleMainLooper(1999);
34        assertFalse(wasRun[0]);
35        ShadowLooper.idleMainLooper(1);
36        assertTrue(wasRun[0]);
37    }
38
39    @Test
40    public void differentThreadsGetDifferentLoopers() {
41        Looper mainLooper = Looper.getMainLooper();
42        Looper thisThreadsLooper = Looper.myLooper();
43
44        assertSame("junit test's thread should use the main looper", mainLooper, thisThreadsLooper);
45
46        final Looper[] thread1Looper = new Looper[1];
47        new Thread() {
48            @Override
49            public void run() {
50                Looper.prepare();
51                thread1Looper[0] = Looper.myLooper();
52            }
53        }.start();
54
55        while(thread1Looper[0] == null) {
56            Thread.yield();
57        }
58
59        assertNotSame(mainLooper, thread1Looper[0]);
60    }
61
62    @Test(expected = RuntimeException.class)
63    public void shouldThrowRuntimeExceptionIfTryingToQuitMainLooper() throws Exception {
64        Looper.getMainLooper().quit();
65    }
66
67    @Test
68    public void shouldNotQueueMessagesIfLooperIsQuit() throws Exception {
69        HandlerThread ht = new HandlerThread("test1");
70        ht.start();
71        Looper looper = ht.getLooper();
72        looper.quit();
73        assertTrue(shadowOf(looper).hasQuit());
74        assertFalse(shadowOf(looper).post(new Runnable() {
75            @Override public void run() { }
76        }, 0));
77
78        assertFalse(shadowOf(looper).postAtFrontOfQueue(new Runnable() {
79            @Override
80            public void run() {
81            }
82        }));
83        assertFalse(shadowOf(looper).getScheduler().areAnyRunnable());
84    }
85
86    @Test
87    public void shouldThrowawayRunnableQueueIfLooperQuits() throws Exception {
88        HandlerThread ht = new HandlerThread("test1");
89        ht.start();
90        Looper looper = ht.getLooper();
91        shadowOf(looper).pause();
92        shadowOf(looper).post(new Runnable() {
93            @Override
94            public void run() {
95            }
96        }, 0);
97        looper.quit();
98        assertTrue(shadowOf(looper).hasQuit());
99        assertFalse(shadowOf(looper).getScheduler().areAnyRunnable());
100    }
101
102    @Test
103    public void testLoopThread() {
104    	assertTrue(shadowOf(Looper.getMainLooper()).getThread() == Thread.currentThread());
105    }
106}
107