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.v17.leanback.widget;
18
19import static junit.framework.Assert.assertEquals;
20
21import static org.mockito.Mockito.times;
22import static org.mockito.Mockito.verify;
23
24import android.support.test.filters.SmallTest;
25import android.support.test.runner.AndroidJUnit4;
26import android.util.Property;
27
28import org.junit.Before;
29import org.junit.Test;
30import org.junit.runner.RunWith;
31import org.mockito.Mock;
32import org.mockito.Mockito;
33import org.mockito.MockitoAnnotations;
34
35@RunWith(AndroidJUnit4.class)
36@SmallTest
37public class ParallaxIntEffectTest {
38
39    Parallax<Parallax.IntProperty> mSource;
40    int mScreenMax;
41    ParallaxEffect.IntEffect mEffect;
42    @Mock ParallaxTarget mTarget;
43
44    static void assertFloatEquals(float expected, float actual) {
45        org.junit.Assert.assertEquals((double) expected, (double) actual, 0.0001d);
46    }
47
48    @Before
49    public void setUp() throws Exception {
50        MockitoAnnotations.initMocks(this);
51        mSource = new Parallax<Parallax.IntProperty>() {
52
53            @Override
54            public float getMaxValue() {
55                return mScreenMax;
56            }
57
58            @Override
59            public IntProperty createProperty(String name, int index) {
60                return new IntProperty(name, index);
61            }
62        };
63        mEffect = new ParallaxEffect.IntEffect();
64    }
65
66    @Test
67    public void testOneVariable() {
68        mScreenMax = 1080;
69        Parallax.IntProperty var1 = mSource.addProperty("var1");
70
71        mEffect.setPropertyRanges(var1.atAbsolute(540), var1.atAbsolute(0));
72        mEffect.target(mTarget);
73
74        // start
75        var1.setValue(mSource, 540);
76        mEffect.performMapping(mSource);
77        verify(mTarget, times(1)).update(0f);
78        Mockito.reset(mTarget);
79
80        // 25% complete
81        var1.setValue(mSource, 405);
82        mEffect.performMapping(mSource);
83        verify(mTarget, times(1)).update(0.25f);
84        Mockito.reset(mTarget);
85
86        // middle
87        var1.setValue(mSource, 270);
88        mEffect.performMapping(mSource);
89        verify(mTarget, times(1)).update(.5f);
90        Mockito.reset(mTarget);
91
92        // 75% complete
93        var1.setValue(mSource, 135);
94        mEffect.performMapping(mSource);
95        verify(mTarget, times(1)).update(0.75f);
96        Mockito.reset(mTarget);
97
98        // end
99        var1.setValue(mSource, 0);
100        mEffect.performMapping(mSource);
101        verify(mTarget, times(1)).update(1f);
102        Mockito.reset(mTarget);
103
104        // after end
105        var1.setValue(mSource, -1000);
106        mEffect.performMapping(mSource);
107        verify(mTarget, times(1)).update(1f);
108        Mockito.reset(mTarget);
109
110        // before start
111        var1.setValue(mSource, 1000);
112        mEffect.performMapping(mSource);
113        verify(mTarget, times(1)).update(0f);
114        Mockito.reset(mTarget);
115
116        // unknown_before
117        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
118        mEffect.performMapping(mSource);
119        verify(mTarget, times(1)).update(1f);
120        Mockito.reset(mTarget);
121
122        // unknown_after
123        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
124        mEffect.performMapping(mSource);
125        verify(mTarget, times(1)).update(0f);
126        Mockito.reset(mTarget);
127    }
128
129    @Test(expected=IllegalStateException.class)
130    public void testVerifyKeyValueOfSameVariableInDesendantOrder() {
131        mScreenMax = 1080;
132        Parallax.IntProperty var1 = mSource.addProperty("var1");
133
134        mEffect.setPropertyRanges(var1.atAbsolute(540), var1.atAbsolute(550));
135        mEffect.target(mTarget);
136        var1.setValue(mSource, 0);
137        mEffect.performMapping(mSource);
138    }
139
140    @Test
141    public void testTwoVariable() {
142        mScreenMax = 1080;
143        Parallax.IntProperty var1 = mSource.addProperty("var1");
144        Parallax.IntProperty var2 = mSource.addProperty("var2");
145
146        mEffect.setPropertyRanges(var1.atAbsolute(540), var2.atAbsolute(540));
147        mEffect.target(mTarget);
148
149        // start
150        var1.setValue(mSource, 540);
151        var2.setValue(mSource, 840);
152        mEffect.performMapping(mSource);
153        verify(mTarget, times(1)).update(0f);
154        Mockito.reset(mTarget);
155
156        // middle
157        var1.setValue(mSource, 390);
158        var2.setValue(mSource, 690);
159        mEffect.performMapping(mSource);
160        verify(mTarget, times(1)).update(.5f);
161        Mockito.reset(mTarget);
162
163        // end
164        var1.setValue(mSource, 240);
165        var2.setValue(mSource, 540);
166        mEffect.performMapping(mSource);
167        verify(mTarget, times(1)).update(1f);
168        Mockito.reset(mTarget);
169
170        // after end
171        var1.setValue(mSource, 200);
172        var2.setValue(mSource, 500);
173        mEffect.performMapping(mSource);
174        verify(mTarget, times(1)).update(1f);
175        Mockito.reset(mTarget);
176
177        // before start
178        var1.setValue(mSource, 1000);
179        var2.setValue(mSource, 1300);
180        mEffect.performMapping(mSource);
181        verify(mTarget, times(1)).update(0f);
182        Mockito.reset(mTarget);
183
184        // unknown_before
185        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
186        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
187        mEffect.performMapping(mSource);
188        verify(mTarget, times(1)).update(1f);
189        Mockito.reset(mTarget);
190
191        // unknown_before
192        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
193        var2.setValue(mSource, -1000);
194        mEffect.performMapping(mSource);
195        verify(mTarget, times(1)).update(1f);
196        Mockito.reset(mTarget);
197
198        // unknown_after
199        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
200        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
201        mEffect.performMapping(mSource);
202        verify(mTarget, times(1)).update(0f);
203        Mockito.reset(mTarget);
204
205        // unknown_after
206        var1.setValue(mSource, 1000);
207        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
208        mEffect.performMapping(mSource);
209        verify(mTarget, times(1)).update(0f);
210        Mockito.reset(mTarget);
211
212        // unknown_before and less
213        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
214        var2.setValue(mSource, 500);
215        mEffect.performMapping(mSource);
216        verify(mTarget, times(1)).update(1f);
217        Mockito.reset(mTarget);
218
219        // unknown_before and hit second
220        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
221        var2.setValue(mSource, 540);
222        mEffect.performMapping(mSource);
223        verify(mTarget, times(1)).update(1f);
224        Mockito.reset(mTarget);
225
226        // unknown_before with estimation
227        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
228        var2.setValue(mSource, 1080);
229        mEffect.performMapping(mSource);
230        verify(mTarget, times(1)).update(0.5f);
231        Mockito.reset(mTarget);
232
233        // unknown_after with estimation
234        var1.setValue(mSource, 0);
235        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
236        mEffect.performMapping(mSource);
237        verify(mTarget, times(1)).update(0.5f);
238        Mockito.reset(mTarget);
239    }
240
241    @Test
242    public void testDirectMapping() {
243        mScreenMax = 1080;
244        Parallax.IntProperty var1 = mSource.addProperty("var1");
245
246        mEffect.setPropertyRanges(var1.atAbsolute((int) 540.45), var1.atAbsolute((int) 0.22));
247        Object object = new Object();
248        final int[] properValue = new int[1];
249        Property<Object, Integer> property = new Property<Object, Integer>(Integer.class, "attr") {
250            @Override
251            public void set(Object object, Integer value) {
252                properValue[0] = value;
253            }
254
255            @Override
256            public Integer get(Object o) {
257                return properValue[0];
258            }
259        };
260        mTarget = new ParallaxTarget.DirectPropertyTarget<>(object, property);
261        mEffect.target(mTarget);
262
263        var1.setValue(mSource, (int) 540.45);
264        mEffect.performMapping(mSource);
265        assertEquals((int) 540.45, properValue[0]);
266
267        var1.setValue(mSource, (int) 405.85);
268        mEffect.performMapping(mSource);
269        assertEquals((int) 405.85, properValue[0]);
270
271        var1.setValue(mSource, 2000);
272        mEffect.performMapping(mSource);
273        assertEquals((int) 540.45, properValue[0]);
274
275        var1.setValue(mSource, (int) 0.22);
276        mEffect.performMapping(mSource);
277        assertEquals((int) 0.22, properValue[0]);
278
279        var1.setValue(mSource, (int) 0.12);
280        mEffect.performMapping(mSource);
281        assertEquals((int) 0.22, properValue[0]);
282    }
283}
284