1/*
2 * Copyright 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.work.impl.utils;
18
19import static org.hamcrest.CoreMatchers.is;
20import static org.hamcrest.CoreMatchers.nullValue;
21import static org.hamcrest.MatcherAssert.assertThat;
22
23import android.arch.core.executor.testing.InstantTaskExecutorRule;
24import android.arch.core.util.Function;
25import android.arch.lifecycle.LiveData;
26import android.arch.lifecycle.MutableLiveData;
27import android.arch.lifecycle.Observer;
28import android.support.annotation.Nullable;
29import android.support.test.filters.SmallTest;
30import android.support.test.runner.AndroidJUnit4;
31
32import androidx.work.TestLifecycleOwner;
33
34import org.junit.Rule;
35import org.junit.Test;
36import org.junit.runner.RunWith;
37
38@SmallTest
39@RunWith(AndroidJUnit4.class)
40public class LiveDataUtilsTest {
41
42    @Rule
43    public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();
44
45    @Rule
46    public androidx.work.impl.utils.taskexecutor.InstantTaskExecutorRule
47            instantWorkManagerTaskExecutorRule =
48            new androidx.work.impl.utils.taskexecutor.InstantTaskExecutorRule();
49
50    @Test
51    public void testDedupedMappedLiveData_dedupesValues() {
52        Function<String, String> identityMapping = new Function<String, String>() {
53            @Override
54            public String apply(String input) {
55                return input;
56            }
57        };
58
59        MutableLiveData<String> originalLiveData = new MutableLiveData<>();
60        LiveData<String> dedupedLiveData =
61                LiveDataUtils.dedupedMappedLiveDataFor(originalLiveData, identityMapping);
62        assertThat(dedupedLiveData.getValue(), is(nullValue()));
63
64        TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner();
65        CountingObserver<String> observer = new CountingObserver<>();
66        dedupedLiveData.observe(testLifecycleOwner, observer);
67        assertThat(observer.mTimesUpdated, is(0));
68
69        String value = "new value";
70        originalLiveData.setValue(value);
71        assertThat(dedupedLiveData.getValue(), is(value));
72        assertThat(observer.mTimesUpdated, is(1));
73
74        originalLiveData.setValue(value);
75        assertThat(dedupedLiveData.getValue(), is(value));
76        assertThat(observer.mTimesUpdated, is(1));
77
78        String newerValue = "newer value";
79        originalLiveData.setValue(newerValue);
80        assertThat(dedupedLiveData.getValue(), is(newerValue));
81        assertThat(observer.mTimesUpdated, is(2));
82
83        dedupedLiveData.removeObservers(testLifecycleOwner);
84    }
85
86    @Test
87    public void testDedupedMappedLiveData_mapsValues() {
88        Function<Integer, String> intToStringMapping = new Function<Integer, String>() {
89            @Override
90            public String apply(Integer input) {
91                return (input == null) ? "" : input.toString();
92            }
93        };
94
95        MutableLiveData<Integer> originalLiveData = new MutableLiveData<>();
96        LiveData<String> mappedLiveData = LiveDataUtils.dedupedMappedLiveDataFor(
97                originalLiveData,
98                intToStringMapping);
99        assertThat(mappedLiveData.getValue(), is(nullValue()));
100
101        TestLifecycleOwner testLifecycleOwner = new TestLifecycleOwner();
102        CountingObserver<String> observer = new CountingObserver<>();
103        mappedLiveData.observe(testLifecycleOwner, observer);
104        assertThat(observer.mTimesUpdated, is(0));
105
106        Integer value = null;
107        originalLiveData.setValue(value);
108        assertThat(mappedLiveData.getValue(), is(""));
109
110        value = 1337;
111        originalLiveData.setValue(value);
112        assertThat(mappedLiveData.getValue(), is(value.toString()));
113
114        value = -0;
115        originalLiveData.setValue(value);
116        assertThat(mappedLiveData.getValue(), is(value.toString()));
117
118        mappedLiveData.removeObservers(testLifecycleOwner);
119    }
120
121    private static class CountingObserver<T> implements Observer<T> {
122
123        int mTimesUpdated;
124
125        @Override
126        public void onChanged(@Nullable T t) {
127            ++mTimesUpdated;
128        }
129    }
130}
131