TransformationsTest.java revision ba069d50913c3fb250bb60ec310439db36895337
1/*
2 * Copyright (C) 2017 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 androidx.lifecycle;
18
19import static org.hamcrest.CoreMatchers.is;
20import static org.hamcrest.MatcherAssert.assertThat;
21import static org.mockito.Matchers.anyString;
22import static org.mockito.Mockito.mock;
23import static org.mockito.Mockito.never;
24import static org.mockito.Mockito.only;
25import static org.mockito.Mockito.reset;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.when;
28
29import androidx.arch.core.util.Function;
30import androidx.executor.ArchTaskExecutor;
31import androidx.lifecycle.util.InstantTaskExecutor;
32
33import org.junit.Before;
34import org.junit.Test;
35import org.junit.runner.RunWith;
36import org.junit.runners.JUnit4;
37
38@SuppressWarnings("unchecked")
39@RunWith(JUnit4.class)
40public class TransformationsTest {
41
42    private LifecycleOwner mOwner;
43
44    @Before
45    public void swapExecutorDelegate() {
46        ArchTaskExecutor.getInstance().setDelegate(new InstantTaskExecutor());
47    }
48
49    @Before
50    public void setup() {
51        mOwner = mock(LifecycleOwner.class);
52        LifecycleRegistry registry = new LifecycleRegistry(mOwner);
53        when(mOwner.getLifecycle()).thenReturn(registry);
54        registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
55        registry.handleLifecycleEvent(Lifecycle.Event.ON_START);
56    }
57
58    @Test
59    public void testMap() {
60        LiveData<String> source = new MutableLiveData<>();
61        LiveData<Integer> mapped = Transformations.map(source, new Function<String, Integer>() {
62            @Override
63            public Integer apply(String input) {
64                return input.length();
65            }
66        });
67        Observer<Integer> observer = mock(Observer.class);
68        mapped.observe(mOwner, observer);
69        source.setValue("four");
70        verify(observer).onChanged(4);
71    }
72
73    @Test
74    public void testSwitchMap() {
75        LiveData<Integer> trigger = new MutableLiveData<>();
76        final LiveData<String> first = new MutableLiveData<>();
77        final LiveData<String> second = new MutableLiveData<>();
78        LiveData<String> result = Transformations.switchMap(trigger,
79                new Function<Integer, LiveData<String>>() {
80                    @Override
81                    public LiveData<String> apply(Integer input) {
82                        if (input == 1) {
83                            return first;
84                        } else {
85                            return second;
86                        }
87                    }
88                });
89
90        Observer<String> observer = mock(Observer.class);
91        result.observe(mOwner, observer);
92        verify(observer, never()).onChanged(anyString());
93        first.setValue("first");
94        trigger.setValue(1);
95        verify(observer).onChanged("first");
96        second.setValue("second");
97        reset(observer);
98        verify(observer, never()).onChanged(anyString());
99        trigger.setValue(2);
100        verify(observer).onChanged("second");
101        reset(observer);
102        first.setValue("failure");
103        verify(observer, never()).onChanged(anyString());
104    }
105
106    @Test
107    public void testSwitchMap2() {
108        LiveData<Integer> trigger = new MutableLiveData<>();
109        final LiveData<String> first = new MutableLiveData<>();
110        final LiveData<String> second = new MutableLiveData<>();
111        LiveData<String> result = Transformations.switchMap(trigger,
112                new Function<Integer, LiveData<String>>() {
113                    @Override
114                    public LiveData<String> apply(Integer input) {
115                        if (input == 1) {
116                            return first;
117                        } else {
118                            return second;
119                        }
120                    }
121                });
122
123        Observer<String> observer = mock(Observer.class);
124        result.observe(mOwner, observer);
125
126        verify(observer, never()).onChanged(anyString());
127        trigger.setValue(1);
128        verify(observer, never()).onChanged(anyString());
129        first.setValue("fi");
130        verify(observer).onChanged("fi");
131        first.setValue("rst");
132        verify(observer).onChanged("rst");
133
134        second.setValue("second");
135        reset(observer);
136        verify(observer, never()).onChanged(anyString());
137        trigger.setValue(2);
138        verify(observer).onChanged("second");
139        reset(observer);
140        first.setValue("failure");
141        verify(observer, never()).onChanged(anyString());
142    }
143
144    @Test
145    public void testNoRedispatchSwitchMap() {
146        LiveData<Integer> trigger = new MutableLiveData<>();
147        final LiveData<String> first = new MutableLiveData<>();
148        LiveData<String> result = Transformations.switchMap(trigger,
149                new Function<Integer, LiveData<String>>() {
150                    @Override
151                    public LiveData<String> apply(Integer input) {
152                        return first;
153                    }
154                });
155
156        Observer<String> observer = mock(Observer.class);
157        result.observe(mOwner, observer);
158        verify(observer, never()).onChanged(anyString());
159        first.setValue("first");
160        trigger.setValue(1);
161        verify(observer).onChanged("first");
162        reset(observer);
163        trigger.setValue(2);
164        verify(observer, never()).onChanged(anyString());
165    }
166
167    @Test
168    public void testSwitchMapToNull() {
169        LiveData<Integer> trigger = new MutableLiveData<>();
170        final LiveData<String> first = new MutableLiveData<>();
171        LiveData<String> result = Transformations.switchMap(trigger,
172                new Function<Integer, LiveData<String>>() {
173                    @Override
174                    public LiveData<String> apply(Integer input) {
175                        if (input == 1) {
176                            return first;
177                        } else {
178                            return null;
179                        }
180                    }
181                });
182
183        Observer<String> observer = mock(Observer.class);
184        result.observe(mOwner, observer);
185        verify(observer, never()).onChanged(anyString());
186        first.setValue("first");
187        trigger.setValue(1);
188        verify(observer).onChanged("first");
189        reset(observer);
190
191        trigger.setValue(2);
192        verify(observer, never()).onChanged(anyString());
193        assertThat(first.hasObservers(), is(false));
194    }
195
196    @Test
197    public void noObsoleteValueTest() {
198        MutableLiveData<Integer> numbers = new MutableLiveData<>();
199        LiveData<Integer> squared = Transformations.map(numbers, new Function<Integer, Integer>() {
200            @Override
201            public Integer apply(Integer input) {
202                return input * input;
203            }
204        });
205
206        Observer observer = mock(Observer.class);
207        squared.setValue(1);
208        squared.observeForever(observer);
209        verify(observer).onChanged(1);
210        squared.removeObserver(observer);
211        reset(observer);
212        numbers.setValue(2);
213        squared.observeForever(observer);
214        verify(observer, only()).onChanged(4);
215    }
216}
217