1/*
2 * Copyright 2012 AndroidPlot.com
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 com.androidplot;
18
19import android.content.Context;
20import android.graphics.*;
21import android.os.Handler;
22import android.util.Log;
23import android.view.View;
24import com.androidplot.mock.MockContext;
25import com.androidplot.mock.MockPaint;
26import com.androidplot.ui.SeriesAndFormatterList;
27import com.androidplot.exception.PlotRenderException;
28import com.androidplot.ui.SeriesRenderer;
29import com.androidplot.ui.Formatter;
30//import mockit.*;
31import com.androidplot.ui.widget.TextLabelWidget;
32import com.androidplot.util.Configurator;
33import com.androidplot.util.FontUtils;
34import com.androidplot.util.PixelUtils;
35import mockit.*;
36import org.junit.After;
37import org.junit.Before;
38import org.junit.Test;
39
40import java.util.ArrayList;
41import java.util.HashMap;
42import java.util.LinkedHashMap;
43import java.util.List;
44
45import static junit.framework.Assert.assertEquals;
46import static junit.framework.Assert.assertNotSame;
47import static junit.framework.Assert.assertNull;
48import static org.junit.Assert.assertFalse;
49import static org.junit.Assert.assertNotNull;
50import static org.junit.Assert.assertTrue;
51
52@UsingMocksAndStubs({Log.class, View.class,Handler.class,Paint.class,Color.class,
53        RectF.class, Rect.class, FontUtils.class, Canvas.class,
54        PixelUtils.class,Context.class})
55
56public class PlotTest {
57
58    static class MockPlotListener implements PlotListener {
59
60        @Override
61        public void onBeforeDraw(Plot source, Canvas canvas) {}
62
63        @Override
64        public void onAfterDraw(Plot source, Canvas canvas) {}
65    }
66
67    static class MockSeries implements Series {
68        @Override
69        public String getTitle() {
70            return null;
71        }
72
73    }
74
75    static class MockSeries2 implements Series {
76        @Override
77        public String getTitle() {
78            return null;
79        }
80    }
81
82    static class MockSeries3 implements Series {
83        @Override
84        public String getTitle() {
85            return null;
86        }
87    }
88
89    static class MockRenderer1 extends SeriesRenderer {
90
91        public MockRenderer1(Plot plot) {
92            super(plot);
93        }
94
95        @Override
96        public void onRender(Canvas canvas, RectF plotArea) throws PlotRenderException {
97
98        }
99
100        @Override
101        public void doDrawLegendIcon(Canvas canvas, RectF rect, Formatter formatter) {
102
103        }
104    }
105    static class MockRenderer2 extends SeriesRenderer {
106
107        public MockRenderer2(Plot plot) {
108            super(plot);
109        }
110
111        @Override
112        public void onRender(Canvas canvas, RectF plotArea) throws PlotRenderException {
113
114        }
115
116        @Override
117        public void doDrawLegendIcon(Canvas canvas, RectF rect, Formatter formatter) {
118
119        }
120    }
121
122    static class MockFormatter1 extends Formatter<MockPlot> {
123
124        @Override
125        public Class<? extends SeriesRenderer> getRendererClass() {
126            return MockRenderer1.class;
127        }
128
129        @Override
130        public SeriesRenderer getRendererInstance(MockPlot plot) {
131            return new MockRenderer1(plot);
132        }
133    }
134
135    static class MockFormatter2 extends Formatter<MockPlot> {
136
137        @Override
138        public Class<? extends SeriesRenderer> getRendererClass() {
139            return MockRenderer2.class;
140        }
141
142        @Override
143        public SeriesRenderer getRendererInstance(MockPlot plot) {
144            return new MockRenderer2(plot);
145        }
146    }
147
148    //@MockClass(realClass = Plot.class)
149    public static class MockPlot extends Plot<MockSeries, Formatter, SeriesRenderer> {
150        public MockPlot(Context context, String title) {
151            super(context, title);
152        }
153
154        @Override
155        protected void onPreInit() {
156
157        }
158
159        /*@Override
160        protected SeriesRenderer doGetRendererInstance(Class clazz) {
161            if(clazz == MockRenderer1.class) {
162                return new MockRenderer1(this);
163            } else if(clazz == MockRenderer2.class) {
164                return new MockRenderer2(this);
165            } else {
166                return null;
167            }
168        }*/
169    }
170
171    @Before
172    public void setUp() throws Exception {
173        Mockit.setUpMocks(MockPaint.class,MockContext.class);
174    }
175
176    @After
177    public void tearDown() throws Exception {
178
179    }
180
181    @Test
182    public void testAddSeries() throws Exception {
183        Context context = Mockit.setUpMock(new MockContext());
184        //Plot plot = Mockit.setUpMock(Plot.class, new MockPlot(context, "MockPlot"));
185        //Plot plot = Mockit.setUpMock(new MockPlot());
186        Plot plot = new MockPlot(context, "MockPlot");
187
188        MockSeries m1 = new MockSeries();
189        Class cl = MockRenderer1.class;
190
191
192
193        plot.addSeries(m1, new MockFormatter1());
194
195        LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
196        assertEquals(1, registry.size());
197        assertEquals(1, registry.get(cl).size());
198
199        plot.addSeries(m1, new MockFormatter1());
200
201        // duplicate Renderer added, registry size should not grow:
202        assertEquals(1, registry.size());
203        assertEquals(1, registry.get(cl).size());
204
205        MockSeries m2 = new MockSeries();
206
207        plot.addSeries(m2, new MockFormatter1());
208
209        // still should only be one renderer type:
210        assertEquals(1, registry.size());
211
212        // we added a new instance of cl to the renderer so there should be 2 in the subregistry:
213        assertEquals(2, registry.get(cl).size());
214
215
216        // lets add another renderer:
217        plot.addSeries(m1, new MockFormatter2());
218
219        assertEquals(2, registry.size());
220    }
221
222    @Test
223    public void testRemoveSeries() throws Exception {
224
225        Context context = Mockit.setUpMock(new MockContext());
226        Plot plot = new MockPlot(context, "MockPlot");
227        LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
228
229        MockSeries m1 = new MockSeries();
230        MockSeries m2 = new MockSeries();
231        MockSeries m3 = new MockSeries();
232
233        plot.addSeries(m1, new MockFormatter1());
234        plot.addSeries(m2, new MockFormatter1());
235        plot.addSeries(m3, new MockFormatter1());
236
237        plot.addSeries(m1, new MockFormatter2());
238        plot.addSeries(m2, new MockFormatter2());
239        plot.addSeries(m3, new MockFormatter2());
240
241
242        // a quick sanity check:
243        assertEquals(2, registry.size());
244        assertEquals(3, registry.get(MockRenderer1.class).size());
245        assertEquals(3, registry.get(MockRenderer2.class).size());
246
247        plot.removeSeries(m1, MockRenderer1.class);
248        assertEquals(2, registry.get(MockRenderer1.class).size());
249
250        plot.removeSeries(m2, MockRenderer1.class);
251        assertEquals(1, registry.get(MockRenderer1.class).size());
252
253        plot.removeSeries(m2, MockRenderer1.class);
254        assertEquals(1, registry.get(MockRenderer1.class).size());
255
256        plot.removeSeries(m3, MockRenderer1.class);
257
258        // all the elements should be gone from MockRenderer1, thus the renderer should
259        // also be gone:
260        assertNull(registry.get(MockRenderer1.class));
261
262
263        // add em all back
264        plot.addSeries(m1, new MockFormatter1());
265        plot.addSeries(m2, new MockFormatter1());
266        plot.addSeries(m3, new MockFormatter1());
267
268        plot.addSeries(m1, new MockFormatter1());
269        plot.addSeries(m2, new MockFormatter1());
270        plot.addSeries(m3, new MockFormatter1());
271
272
273        // a quick sanity check:
274        assertEquals(2, registry.size());
275        assertEquals(3, registry.get(MockRenderer1.class).size());
276        assertEquals(3, registry.get(MockRenderer2.class).size());
277
278        // now lets try removing a series from all renderers:
279        plot.removeSeries(m1);
280        assertEquals(2, registry.get(MockRenderer1.class).size());
281        assertEquals(2, registry.get(MockRenderer2.class).size());
282
283        // and now lets remove the remaining series:
284        plot.removeSeries(m2);
285        plot.removeSeries(m3);
286
287        // nothing should be left:
288        assertNull(registry.get(MockRenderer1.class));
289        assertNull(registry.get(MockRenderer2.class));
290    }
291
292
293    @Test
294    public void testGetFormatter() throws Exception {
295        Context context = Mockit.setUpMock(new MockContext());
296        Plot plot = new MockPlot(context, "MockPlot");
297        LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
298
299        MockSeries m1 = new MockSeries();
300        MockSeries m2 = new MockSeries();
301        MockSeries m3 = new MockSeries();
302
303        MockFormatter1 f1 = new MockFormatter1();
304        MockFormatter1 f2 = new MockFormatter1();
305        MockFormatter2 f3 = new MockFormatter2();
306
307        plot.addSeries(m1, f1);
308        plot.addSeries(m2, f2);
309        plot.addSeries(m3, new MockFormatter1());
310
311        plot.addSeries(m1, new MockFormatter1());
312        plot.addSeries(m2, f3);
313        plot.addSeries(m3, new MockFormatter1());
314
315        assertEquals(registry.get(MockRenderer1.class).getFormatter(m1), f1);
316        assertEquals(registry.get(MockRenderer1.class).getFormatter(m2), f2);
317        assertEquals(registry.get(MockRenderer2.class).getFormatter(m2), f3);
318
319        assertNotSame(registry.get(MockRenderer2.class).getFormatter(m2), f1);
320
321    }
322
323    @Test
324    public void testGetSeriesListForRenderer() throws Exception {
325
326        Context context = Mockit.setUpMock(new MockContext());
327        Plot plot = new MockPlot(context, "MockPlot");
328        //LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
329
330        MockSeries m1 = new MockSeries();
331        MockSeries m2 = new MockSeries();
332        MockSeries m3 = new MockSeries();
333
334        plot.addSeries(m1, new MockFormatter1());
335        plot.addSeries(m2, new MockFormatter1());
336        plot.addSeries(m3, new MockFormatter1());
337
338        plot.addSeries(m1, new MockFormatter1());
339        plot.addSeries(m2, new MockFormatter1());
340        plot.addSeries(m3, new MockFormatter1());
341
342        List<MockSeries> m1List = plot.getSeriesListForRenderer(MockRenderer1.class);
343        assertEquals(3, m1List.size());
344        assertEquals(m1, m1List.get(0));
345        assertNotSame(m2, m1List.get(0));
346        assertEquals(m2, m1List.get(1));
347        assertEquals(m3, m1List.get(2));
348    }
349
350    @Test
351    public void testGetRendererList() throws Exception {
352
353        Context context = Mockit.setUpMock(new MockContext());
354        Plot plot = new MockPlot(context, "MockPlot");
355        //LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
356
357        MockSeries m1 = new MockSeries();
358        MockSeries m2 = new MockSeries();
359        MockSeries m3 = new MockSeries();
360
361        plot.addSeries(m1, new MockFormatter1());
362        plot.addSeries(m2, new MockFormatter1());
363        plot.addSeries(m3, new MockFormatter1());
364
365        plot.addSeries(m1, new MockFormatter2());
366        plot.addSeries(m2, new MockFormatter2());
367        plot.addSeries(m3, new MockFormatter2());
368
369        List<SeriesRenderer> rList = plot.getRendererList();
370        assertEquals(2, rList.size());
371
372        assertEquals(MockRenderer1.class, rList.get(0).getClass());
373        assertEquals(MockRenderer2.class, rList.get(1).getClass());
374    }
375
376    @Test
377    public void testAddListener() throws Exception {
378        Context context = Mockit.setUpMock(new MockContext());
379        Plot plot = new MockPlot(context, "MockPlot");
380        ArrayList<PlotListener> listeners = Deencapsulation.getField(plot, "listeners");
381        //LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
382
383        assertEquals(0, listeners.size());
384
385        MockPlotListener pl1 = new MockPlotListener();
386        MockPlotListener pl2 = new MockPlotListener();
387
388        plot.addListener(pl1);
389
390        assertEquals(1, listeners.size());
391
392        // should return false on a double entry attempt
393        assertFalse(plot.addListener(pl1));
394
395        // make sure the listener wasnt added anyway:
396        assertEquals(1, listeners.size());
397
398        plot.addListener(pl2);
399
400        assertEquals(2, listeners.size());
401
402    }
403
404    @Test
405    public void testRemoveListener() throws Exception {
406        Context context = Mockit.setUpMock(new MockContext());
407        Plot plot = new MockPlot(context, "MockPlot");
408        ArrayList<PlotListener> listeners = Deencapsulation.getField(plot, "listeners");
409        //LinkedHashMap<Class<SeriesRenderer>, SeriesAndFormatterList<MockSeries,MockFormatter1>> registry = Deencapsulation.getField(plot, "seriesRegistry");
410
411        assertEquals(0, listeners.size());
412
413        MockPlotListener pl1 = new MockPlotListener();
414        MockPlotListener pl2 = new MockPlotListener();
415        MockPlotListener pl3 = new MockPlotListener();
416
417        plot.addListener(pl1);
418        plot.addListener(pl2);
419
420        assertEquals(2, listeners.size());
421
422        assertFalse(plot.removeListener(pl3));
423
424        assertTrue(plot.removeListener(pl1));
425
426        assertEquals(1, listeners.size());
427
428        assertFalse(plot.removeListener(pl1));
429
430        assertEquals(1, listeners.size());
431
432        assertTrue(plot.removeListener(pl2));
433
434        assertEquals(0, listeners.size());
435
436    }
437
438    /*@Test
439    public void testGuessGetterName() throws Exception {
440        Context context = Mockit.setUpMock(new MockContext());
441        Plot plot = new MockPlot(context, "MockPlot");
442
443        Method m = Plot.class.getDeclaredMethod("guessGetterMethod", Object.class, String.class);
444        assertNotNull(m);
445    }
446
447    @Test
448    public void testGuessSetterName() throws Exception {
449        Context context = Mockit.setUpMock(new MockContext());
450        Plot plot = new MockPlot(context, "MockPlot");
451
452        Method m = Plot.class.getDeclaredMethod("guessSetterMethod", Object.class, String.class, Class.class);
453        assertNotNull(m);
454    }*/
455
456
457
458    @Test
459    public void testConfigure() throws Exception {
460        //Context context = Mockit.setUpMock(new MockContext.MockContext2());
461        Context context = new MockContext.MockContext2();
462        Plot plot = new MockPlot(context, "MockPlot");
463
464        HashMap<String, String> params = new HashMap<String, String>();
465        String param1 = "this is a test.";
466        //String param2 = Plot.RenderMode.USE_BACKGROUND_THREAD.toString();
467        String param2 = "use_background_thread";
468        String param3 = "#FF0000";
469        params.put("title", param1);
470        params.put("renderMode", param2);
471        params.put("backgroundPaint.color", param3);
472
473
474        //Method m = Plot.class.getDeclaredMethod("configure", params.getClass());
475        //m.setAccessible(true);
476        //m.invoke(plot, params);
477        Configurator.configure(context, plot, params);
478
479        assertEquals(param1, plot.getTitle());
480        assertEquals(Plot.RenderMode.USE_BACKGROUND_THREAD, plot.getRenderMode());
481        assertEquals(Color.parseColor(param3), plot.getBackgroundPaint().getColor());
482    }
483}
484