activityRule =
26 | new ActivityTestRule<>(PokemonDetailsActivity.class, true, false);
27 |
28 | @Before
29 | public void setUp() throws Exception {
30 | //TODO Reinject the app with mock networking module.
31 | DaggerAppComponent.builder()
32 | .build()
33 | .inject(PokemonApp.getInstance());
34 |
35 | }
36 |
37 | @After
38 | public void tearDown() throws Exception {
39 | }
40 |
41 | @Test
42 | public void testDetails() throws Exception {
43 | //TODO test goes here
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/co/infinum/pokemon/test/helpers/ResourceUtils.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.test.helpers;
2 |
3 | import java.io.InputStream;
4 | import java.util.Scanner;
5 |
6 | /**
7 | * Utility methods for accessing resources bundled with test APK. Standard Android Resources don't seem to work for test APK
8 | * (unable to fetch R.java).
9 | *
10 | * Resources should be placed under /resources/mockdata folder in androidTest flavour. Use {@link #readFromFile(String)} to read a text
11 | * file to String giving only a name of the file located in /resources/mockdata folder.
12 | */
13 | public class ResourceUtils {
14 |
15 | private static final String MOCK_DATA_DIRECTORY = "mockdata/%s";
16 |
17 | /**
18 | * Converts InputStream to String.
19 | */
20 | public static String convertStreamToString(InputStream is) {
21 | Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A");
22 | return s.hasNext() ? s.next() : "";
23 | }
24 |
25 | /**
26 | * Reads a resource file to String
.
27 | */
28 | public static String readFromFile(String filename) {
29 | InputStream is = ResourceUtils.class.getClassLoader().getResourceAsStream(String.format(MOCK_DATA_DIRECTORY, filename));
30 | return convertStreamToString(is);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/co/infinum/pokemon/test/helpers/TestHelper.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.test.helpers;
2 |
3 | import org.mockito.InOrder;
4 |
5 | import co.infinum.pokemon.mvp.views.BaseView;
6 |
7 | import static org.mockito.Mockito.inOrder;
8 | import static org.mockito.Mockito.timeout;
9 | import static org.mockito.Mockito.verify;
10 |
11 | /**
12 | * Created by dino on 30/06/14.
13 | */
14 | public class TestHelper {
15 |
16 | public static final int CALLBACK_TIMEOUT_MS = 1000;
17 |
18 | public static void verifyShowHideProgress(BaseView baseView) {
19 | verify(baseView, timeout(CALLBACK_TIMEOUT_MS)).hideProgress();
20 | InOrder inOrder = inOrder(baseView);
21 | inOrder.verify(baseView).showProgress();
22 | inOrder.verify(baseView).hideProgress();
23 | }
24 |
25 | public static T verifyAsync(T mock) {
26 | return verifyAsync(mock, CALLBACK_TIMEOUT_MS);
27 | }
28 |
29 | public static T verifyAsync(T mock, long timeoutMillis) {
30 | return verify(mock, timeout(timeoutMillis));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/dagger/components/PokemonDetailsTestComponent.java:
--------------------------------------------------------------------------------
1 | package dagger.components;
2 |
3 | import dagger.modules.MockNetworkModule;
4 | import co.infinum.pokemon.dagger.modules.PokemonDetailsModule;
5 | import co.infinum.pokemon.mvp.presenters.PokemonDetailsPresenter;
6 | import dagger.Component;
7 |
8 | /**
9 | * Created by dino on 12/05/15.
10 | */
11 | @Component(modules = {
12 | MockNetworkModule.class,
13 | PokemonDetailsModule.class
14 | })
15 | public interface PokemonDetailsTestComponent {
16 |
17 | PokemonDetailsPresenter presenter();
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/dagger/components/PokemonListTestComponent.java:
--------------------------------------------------------------------------------
1 | package dagger.components;
2 |
3 | import dagger.modules.MockNetworkModule;
4 | import co.infinum.pokemon.dagger.modules.PokemonListModule;
5 | import co.infinum.pokemon.mvp.presenters.PokemonListPresenter;
6 | import dagger.Component;
7 |
8 | /**
9 | * Created by dino on 12/05/15.
10 | */
11 | @Component(modules = {
12 | MockNetworkModule.class,
13 | PokemonListModule.class
14 | })
15 | public interface PokemonListTestComponent {
16 |
17 | PokemonListPresenter presenter();
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/dagger/modules/MockHostModule.java:
--------------------------------------------------------------------------------
1 | package dagger.modules;
2 |
3 | import com.squareup.okhttp.mockwebserver.MockWebServer;
4 |
5 | import java.io.IOException;
6 |
7 | import dagger.Module;
8 | import dagger.Provides;
9 | import retrofit.Endpoint;
10 | import retrofit.Endpoints;
11 |
12 | /**
13 | * Created by dino on 27/02/15.
14 | */
15 | @Module
16 | public class MockHostModule {
17 |
18 | private MockWebServer mockWebServer;
19 |
20 | public MockHostModule() {
21 | mockWebServer = new MockWebServer();
22 | try {
23 | mockWebServer.start();
24 | } catch (IOException e) {
25 | e.printStackTrace();
26 | }
27 | }
28 |
29 | @Provides
30 | public Endpoint provideEndpoint() {
31 | return Endpoints.newFixedEndpoint(mockWebServer.getUrl("/").toString());
32 | }
33 |
34 | public MockWebServer getMockWebServer() {
35 | return mockWebServer;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/dagger/modules/MockNetworkModule.java:
--------------------------------------------------------------------------------
1 | package dagger.modules;
2 |
3 | import dagger.Module;
4 |
5 | /**
6 | * Created by dino on 12/05/15.
7 | */
8 | @Module(includes = {
9 | MockHostModule.class,
10 | ApiModule.class
11 | })
12 | public class MockNetworkModule {
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/androidTest/resources/mockdata/charizard_details.json:
--------------------------------------------------------------------------------
1 | {
2 | "abilities": [
3 | {
4 | "name": "blaze",
5 | "resource_uri": "/api/v1/ability/66/"
6 | },
7 | {
8 | "name": "solar-power",
9 | "resource_uri": "/api/v1/ability/94/"
10 | }
11 | ],
12 | "attack": 84,
13 | "catch_rate": 0,
14 | "created": "2013-11-03T15:05:41.275724",
15 | "defense": 78,
16 | "descriptions": [
17 | {
18 | "name": "charizard_gen_1",
19 | "resource_uri": "/api/v1/description/80/"
20 | },
21 | {
22 | "name": "charizard_gen_1",
23 | "resource_uri": "/api/v1/description/81/"
24 | },
25 | {
26 | "name": "charizard_gen_1",
27 | "resource_uri": "/api/v1/description/82/"
28 | },
29 | {
30 | "name": "charizard_gen_1",
31 | "resource_uri": "/api/v1/description/83/"
32 | },
33 | {
34 | "name": "charizard_gen_1",
35 | "resource_uri": "/api/v1/description/84/"
36 | },
37 | {
38 | "name": "charizard_gen_2",
39 | "resource_uri": "/api/v1/description/85/"
40 | },
41 | {
42 | "name": "charizard_gen_2",
43 | "resource_uri": "/api/v1/description/86/"
44 | },
45 | {
46 | "name": "charizard_gen_3",
47 | "resource_uri": "/api/v1/description/87/"
48 | },
49 | {
50 | "name": "charizard_gen_3",
51 | "resource_uri": "/api/v1/description/88/"
52 | },
53 | {
54 | "name": "charizard_gen_3",
55 | "resource_uri": "/api/v1/description/89/"
56 | },
57 | {
58 | "name": "charizard_gen_4",
59 | "resource_uri": "/api/v1/description/92/"
60 | },
61 | {
62 | "name": "charizard_gen_5",
63 | "resource_uri": "/api/v1/description/93/"
64 | },
65 | {
66 | "name": "charizard_gen_6",
67 | "resource_uri": "/api/v1/description/94/"
68 | },
69 | {
70 | "name": "charizard_gen_6",
71 | "resource_uri": "/api/v1/description/95/"
72 | },
73 | {
74 | "name": "charizard_gen_4",
75 | "resource_uri": "/api/v1/description/90/"
76 | },
77 | {
78 | "name": "charizard_gen_4",
79 | "resource_uri": "/api/v1/description/91/"
80 | }
81 | ],
82 | "egg_cycles": 0,
83 | "egg_groups": [
84 | {
85 | "name": "Dragon",
86 | "resource_uri": "/api/v1/egg/14/"
87 | },
88 | {
89 | "name": "Monster",
90 | "resource_uri": "/api/v1/egg/1/"
91 | }
92 | ],
93 | "ev_yield": "",
94 | "evolutions": [
95 | {
96 | "detail": "mega",
97 | "method": "other",
98 | "resource_uri": "/api/v1/pokemon/10035/",
99 | "to": "Charizard-mega-y"
100 | },
101 | {
102 | "detail": "mega",
103 | "method": "other",
104 | "resource_uri": "/api/v1/pokemon/10034/",
105 | "to": "Charizard-mega-x"
106 | }
107 | ],
108 | "exp": 240,
109 | "growth_rate": "",
110 | "happiness": 0,
111 | "height": "17",
112 | "hp": 78,
113 | "male_female_ratio": "",
114 | "modified": "2013-11-23T13:13:23.762594",
115 | "moves": [
116 | {
117 | "learn_type": "machine",
118 | "name": "Dragon-tail",
119 | "resource_uri": "/api/v1/move/525/"
120 | },
121 | {
122 | "learn_type": "machine",
123 | "name": "Bulldoze",
124 | "resource_uri": "/api/v1/move/523/"
125 | },
126 | {
127 | "learn_type": "tutor",
128 | "name": "Fire-pledge",
129 | "resource_uri": "/api/v1/move/519/"
130 | },
131 | {
132 | "learn_type": "level up",
133 | "level": 62,
134 | "name": "Inferno",
135 | "resource_uri": "/api/v1/move/517/"
136 | },
137 | {
138 | "learn_type": "machine",
139 | "name": "Incinerate",
140 | "resource_uri": "/api/v1/move/510/"
141 | },
142 | {
143 | "learn_type": "machine",
144 | "name": "Sky-drop",
145 | "resource_uri": "/api/v1/move/507/"
146 | },
147 | {
148 | "learn_type": "machine",
149 | "name": "Echoed-voice",
150 | "resource_uri": "/api/v1/move/497/"
151 | },
152 | {
153 | "learn_type": "machine",
154 | "name": "Round",
155 | "resource_uri": "/api/v1/move/496/"
156 | },
157 | {
158 | "learn_type": "machine",
159 | "name": "Flame-charge",
160 | "resource_uri": "/api/v1/move/488/"
161 | },
162 | {
163 | "learn_type": "level up",
164 | "level": 32,
165 | "name": "Flame-burst",
166 | "resource_uri": "/api/v1/move/481/"
167 | },
168 | {
169 | "learn_type": "machine",
170 | "name": "Hone-claws",
171 | "resource_uri": "/api/v1/move/468/"
172 | },
173 | {
174 | "learn_type": "tutor",
175 | "name": "Tailwind",
176 | "resource_uri": "/api/v1/move/366/"
177 | },
178 | {
179 | "learn_type": "tutor",
180 | "name": "Ominous-wind",
181 | "resource_uri": "/api/v1/move/466/"
182 | },
183 | {
184 | "learn_type": "tutor",
185 | "name": "Air-cutter",
186 | "resource_uri": "/api/v1/move/314/"
187 | },
188 | {
189 | "learn_type": "tutor",
190 | "name": "Twister",
191 | "resource_uri": "/api/v1/move/239/"
192 | },
193 | {
194 | "learn_type": "tutor",
195 | "name": "Outrage",
196 | "resource_uri": "/api/v1/move/200/"
197 | },
198 | {
199 | "learn_type": "tutor",
200 | "name": "Thunderpunch",
201 | "resource_uri": "/api/v1/move/9/"
202 | },
203 | {
204 | "learn_type": "machine",
205 | "name": "Captivate",
206 | "resource_uri": "/api/v1/move/445/"
207 | },
208 | {
209 | "learn_type": "machine",
210 | "name": "Defog",
211 | "resource_uri": "/api/v1/move/432/"
212 | },
213 | {
214 | "learn_type": "level up",
215 | "level": 28,
216 | "name": "Fire-fang",
217 | "resource_uri": "/api/v1/move/424/"
218 | },
219 | {
220 | "learn_type": "level up",
221 | "level": 1,
222 | "name": "Shadow-claw",
223 | "resource_uri": "/api/v1/move/421/"
224 | },
225 | {
226 | "learn_type": "machine",
227 | "name": "Giga-impact",
228 | "resource_uri": "/api/v1/move/416/"
229 | },
230 | {
231 | "learn_type": "machine",
232 | "name": "Focus-blast",
233 | "resource_uri": "/api/v1/move/411/"
234 | },
235 | {
236 | "learn_type": "machine",
237 | "name": "Dragon-pulse",
238 | "resource_uri": "/api/v1/move/406/"
239 | },
240 | {
241 | "learn_type": "level up",
242 | "level": 1,
243 | "name": "Air-slash",
244 | "resource_uri": "/api/v1/move/403/"
245 | },
246 | {
247 | "learn_type": "level up",
248 | "level": 66,
249 | "name": "Flare-blitz",
250 | "resource_uri": "/api/v1/move/394/"
251 | },
252 | {
253 | "learn_type": "machine",
254 | "name": "Fling",
255 | "resource_uri": "/api/v1/move/374/"
256 | },
257 | {
258 | "learn_type": "machine",
259 | "name": "Natural-gift",
260 | "resource_uri": "/api/v1/move/363/"
261 | },
262 | {
263 | "learn_type": "machine",
264 | "name": "Roost",
265 | "resource_uri": "/api/v1/move/355/"
266 | },
267 | {
268 | "learn_type": "machine",
269 | "name": "Rock-tomb",
270 | "resource_uri": "/api/v1/move/317/"
271 | },
272 | {
273 | "learn_type": "machine",
274 | "name": "Will-o-wisp",
275 | "resource_uri": "/api/v1/move/261/"
276 | },
277 | {
278 | "learn_type": "machine",
279 | "name": "Solarbeam",
280 | "resource_uri": "/api/v1/move/76/"
281 | },
282 | {
283 | "learn_type": "tutor",
284 | "name": "Blast-burn",
285 | "resource_uri": "/api/v1/move/307/"
286 | },
287 | {
288 | "learn_type": "level up",
289 | "level": 1,
290 | "name": "Heat-wave",
291 | "resource_uri": "/api/v1/move/257/"
292 | },
293 | {
294 | "learn_type": "level up",
295 | "level": 1,
296 | "name": "Metal-claw",
297 | "resource_uri": "/api/v1/move/232/"
298 | },
299 | {
300 | "learn_type": "tutor",
301 | "name": "Rock-slide",
302 | "resource_uri": "/api/v1/move/157/"
303 | },
304 | {
305 | "learn_type": "machine",
306 | "name": "Dragon-claw",
307 | "resource_uri": "/api/v1/move/337/"
308 | },
309 | {
310 | "learn_type": "machine",
311 | "name": "Aerial-ace",
312 | "resource_uri": "/api/v1/move/332/"
313 | },
314 | {
315 | "learn_type": "machine",
316 | "name": "Overheat",
317 | "resource_uri": "/api/v1/move/315/"
318 | },
319 | {
320 | "learn_type": "machine",
321 | "name": "Secret-power",
322 | "resource_uri": "/api/v1/move/290/"
323 | },
324 | {
325 | "learn_type": "machine",
326 | "name": "Brick-break",
327 | "resource_uri": "/api/v1/move/280/"
328 | },
329 | {
330 | "learn_type": "machine",
331 | "name": "Focus-punch",
332 | "resource_uri": "/api/v1/move/264/"
333 | },
334 | {
335 | "learn_type": "machine",
336 | "name": "Facade",
337 | "resource_uri": "/api/v1/move/263/"
338 | },
339 | {
340 | "learn_type": "machine",
341 | "name": "Rock-smash",
342 | "resource_uri": "/api/v1/move/249/"
343 | },
344 | {
345 | "learn_type": "machine",
346 | "name": "Sunny-day",
347 | "resource_uri": "/api/v1/move/241/"
348 | },
349 | {
350 | "learn_type": "machine",
351 | "name": "Hidden-power",
352 | "resource_uri": "/api/v1/move/237/"
353 | },
354 | {
355 | "learn_type": "machine",
356 | "name": "Iron-tail",
357 | "resource_uri": "/api/v1/move/231/"
358 | },
359 | {
360 | "learn_type": "machine",
361 | "name": "Dragonbreath",
362 | "resource_uri": "/api/v1/move/225/"
363 | },
364 | {
365 | "learn_type": "machine",
366 | "name": "Dynamicpunch",
367 | "resource_uri": "/api/v1/move/223/"
368 | },
369 | {
370 | "learn_type": "machine",
371 | "name": "Frustration",
372 | "resource_uri": "/api/v1/move/218/"
373 | },
374 | {
375 | "learn_type": "machine",
376 | "name": "Return",
377 | "resource_uri": "/api/v1/move/216/"
378 | },
379 | {
380 | "learn_type": "machine",
381 | "name": "Sleep-talk",
382 | "resource_uri": "/api/v1/move/214/"
383 | },
384 | {
385 | "learn_type": "machine",
386 | "name": "Attract",
387 | "resource_uri": "/api/v1/move/213/"
388 | },
389 | {
390 | "learn_type": "machine",
391 | "name": "Steel-wing",
392 | "resource_uri": "/api/v1/move/211/"
393 | },
394 | {
395 | "learn_type": "machine",
396 | "name": "Fury-cutter",
397 | "resource_uri": "/api/v1/move/210/"
398 | },
399 | {
400 | "learn_type": "machine",
401 | "name": "Swagger",
402 | "resource_uri": "/api/v1/move/207/"
403 | },
404 | {
405 | "learn_type": "machine",
406 | "name": "Endure",
407 | "resource_uri": "/api/v1/move/203/"
408 | },
409 | {
410 | "learn_type": "machine",
411 | "name": "Sandstorm",
412 | "resource_uri": "/api/v1/move/201/"
413 | },
414 | {
415 | "learn_type": "machine",
416 | "name": "Mud-slap",
417 | "resource_uri": "/api/v1/move/189/"
418 | },
419 | {
420 | "learn_type": "level up",
421 | "level": 27,
422 | "name": "Scary-face",
423 | "resource_uri": "/api/v1/move/184/"
424 | },
425 | {
426 | "learn_type": "machine",
427 | "name": "Protect",
428 | "resource_uri": "/api/v1/move/182/"
429 | },
430 | {
431 | "learn_type": "machine",
432 | "name": "Curse",
433 | "resource_uri": "/api/v1/move/174/"
434 | },
435 | {
436 | "learn_type": "machine",
437 | "name": "Snore",
438 | "resource_uri": "/api/v1/move/173/"
439 | },
440 | {
441 | "learn_type": "machine",
442 | "name": "Defense-curl",
443 | "resource_uri": "/api/v1/move/111/"
444 | },
445 | {
446 | "learn_type": "level up",
447 | "level": 1,
448 | "name": "Smokescreen",
449 | "resource_uri": "/api/v1/move/108/"
450 | },
451 | {
452 | "learn_type": "machine",
453 | "name": "Roar",
454 | "resource_uri": "/api/v1/move/46/"
455 | },
456 | {
457 | "learn_type": "machine",
458 | "name": "Headbutt",
459 | "resource_uri": "/api/v1/move/29/"
460 | },
461 | {
462 | "learn_type": "level up",
463 | "level": 36,
464 | "name": "Wing-attack",
465 | "resource_uri": "/api/v1/move/17/"
466 | },
467 | {
468 | "learn_type": "machine",
469 | "name": "Fire-punch",
470 | "resource_uri": "/api/v1/move/7/"
471 | },
472 | {
473 | "learn_type": "machine",
474 | "name": "Fly",
475 | "resource_uri": "/api/v1/move/19/"
476 | },
477 | {
478 | "learn_type": "machine",
479 | "name": "Substitute",
480 | "resource_uri": "/api/v1/move/164/"
481 | },
482 | {
483 | "learn_type": "level up",
484 | "level": 36,
485 | "name": "Slash",
486 | "resource_uri": "/api/v1/move/163/"
487 | },
488 | {
489 | "learn_type": "machine",
490 | "name": "Rest",
491 | "resource_uri": "/api/v1/move/156/"
492 | },
493 | {
494 | "learn_type": "machine",
495 | "name": "Skull-bash",
496 | "resource_uri": "/api/v1/move/130/"
497 | },
498 | {
499 | "learn_type": "machine",
500 | "name": "Swift",
501 | "resource_uri": "/api/v1/move/129/"
502 | },
503 | {
504 | "learn_type": "machine",
505 | "name": "Fire-blast",
506 | "resource_uri": "/api/v1/move/126/"
507 | },
508 | {
509 | "learn_type": "machine",
510 | "name": "Bide",
511 | "resource_uri": "/api/v1/move/117/"
512 | },
513 | {
514 | "learn_type": "machine",
515 | "name": "Reflect",
516 | "resource_uri": "/api/v1/move/115/"
517 | },
518 | {
519 | "learn_type": "machine",
520 | "name": "Double-team",
521 | "resource_uri": "/api/v1/move/104/"
522 | },
523 | {
524 | "learn_type": "machine",
525 | "name": "Mimic",
526 | "resource_uri": "/api/v1/move/102/"
527 | },
528 | {
529 | "learn_type": "level up",
530 | "level": 24,
531 | "name": "Rage",
532 | "resource_uri": "/api/v1/move/99/"
533 | },
534 | {
535 | "learn_type": "machine",
536 | "name": "Toxic",
537 | "resource_uri": "/api/v1/move/92/"
538 | },
539 | {
540 | "learn_type": "machine",
541 | "name": "Dig",
542 | "resource_uri": "/api/v1/move/91/"
543 | },
544 | {
545 | "learn_type": "machine",
546 | "name": "Fissure",
547 | "resource_uri": "/api/v1/move/90/"
548 | },
549 | {
550 | "learn_type": "machine",
551 | "name": "Earthquake",
552 | "resource_uri": "/api/v1/move/89/"
553 | },
554 | {
555 | "learn_type": "level up",
556 | "level": 55,
557 | "name": "Fire-spin",
558 | "resource_uri": "/api/v1/move/83/"
559 | },
560 | {
561 | "learn_type": "machine",
562 | "name": "Dragon-rage",
563 | "resource_uri": "/api/v1/move/82/"
564 | },
565 | {
566 | "learn_type": "machine",
567 | "name": "Strength",
568 | "resource_uri": "/api/v1/move/70/"
569 | },
570 | {
571 | "learn_type": "machine",
572 | "name": "Seismic-toss",
573 | "resource_uri": "/api/v1/move/69/"
574 | },
575 | {
576 | "learn_type": "machine",
577 | "name": "Counter",
578 | "resource_uri": "/api/v1/move/68/"
579 | },
580 | {
581 | "learn_type": "machine",
582 | "name": "Submission",
583 | "resource_uri": "/api/v1/move/66/"
584 | },
585 | {
586 | "learn_type": "machine",
587 | "name": "Hyper-beam",
588 | "resource_uri": "/api/v1/move/63/"
589 | },
590 | {
591 | "learn_type": "level up",
592 | "level": 46,
593 | "name": "Flamethrower",
594 | "resource_uri": "/api/v1/move/53/"
595 | },
596 | {
597 | "learn_type": "level up",
598 | "level": 1,
599 | "name": "Ember",
600 | "resource_uri": "/api/v1/move/52/"
601 | },
602 | {
603 | "learn_type": "level up",
604 | "level": 1,
605 | "name": "Growl",
606 | "resource_uri": "/api/v1/move/45/"
607 | },
608 | {
609 | "learn_type": "level up",
610 | "level": 1,
611 | "name": "Leer",
612 | "resource_uri": "/api/v1/move/43/"
613 | },
614 | {
615 | "learn_type": "machine",
616 | "name": "Double-edge",
617 | "resource_uri": "/api/v1/move/38/"
618 | },
619 | {
620 | "learn_type": "machine",
621 | "name": "Take-down",
622 | "resource_uri": "/api/v1/move/36/"
623 | },
624 | {
625 | "learn_type": "machine",
626 | "name": "Body-slam",
627 | "resource_uri": "/api/v1/move/34/"
628 | },
629 | {
630 | "learn_type": "machine",
631 | "name": "Mega-kick",
632 | "resource_uri": "/api/v1/move/25/"
633 | },
634 | {
635 | "learn_type": "machine",
636 | "name": "Cut",
637 | "resource_uri": "/api/v1/move/15/"
638 | },
639 | {
640 | "learn_type": "machine",
641 | "name": "Swords-dance",
642 | "resource_uri": "/api/v1/move/14/"
643 | },
644 | {
645 | "learn_type": "level up",
646 | "level": 1,
647 | "name": "Scratch",
648 | "resource_uri": "/api/v1/move/10/"
649 | },
650 | {
651 | "learn_type": "machine",
652 | "name": "Mega-punch",
653 | "resource_uri": "/api/v1/move/5/"
654 | }
655 | ],
656 | "name": "Charizard",
657 | "national_id": 6,
658 | "pkdx_id": 6,
659 | "resource_uri": "/api/v1/pokemon/6/",
660 | "sp_atk": 109,
661 | "sp_def": 85,
662 | "species": "",
663 | "speed": 100,
664 | "sprites": [
665 | {
666 | "name": "charizard",
667 | "resource_uri": "/api/v1/sprite/7/"
668 | }
669 | ],
670 | "total": 0,
671 | "types": [
672 | {
673 | "name": "flying",
674 | "resource_uri": "/api/v1/type/3/"
675 | },
676 | {
677 | "name": "fire",
678 | "resource_uri": "/api/v1/type/10/"
679 | }
680 | ],
681 | "weight": "905"
682 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/PokemonApp.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon;
2 |
3 | import android.app.Application;
4 |
5 | import co.infinum.pokemon.dagger.components.AppComponent;
6 | import co.infinum.pokemon.dagger.components.DaggerAppComponent;
7 |
8 | public class PokemonApp extends Application {
9 |
10 | private static PokemonApp instance;
11 |
12 | private AppComponent applicationComponent;
13 |
14 | public static PokemonApp getInstance() {
15 | return instance;
16 | }
17 |
18 | public static void setInstance(PokemonApp instance) {
19 | PokemonApp.instance = instance;
20 | }
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | setInstance(this);
26 |
27 | applicationComponent = DaggerAppComponent.create();
28 | }
29 |
30 | public AppComponent getApplicationComponent() {
31 | return applicationComponent;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/activities/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.activities;
2 |
3 | import android.app.AlertDialog;
4 | import android.app.Dialog;
5 | import android.app.ProgressDialog;
6 | import android.os.Bundle;
7 | import android.support.annotation.Nullable;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.text.Html;
10 |
11 | import co.infinum.pokemon.PokemonApp;
12 | import co.infinum.pokemon.R;
13 | import co.infinum.pokemon.dagger.components.AppComponent;
14 | import co.infinum.pokemon.mvp.views.BaseView;
15 |
16 | /**
17 | * Created by dino on 21/03/15.
18 | */
19 | public abstract class BaseActivity extends AppCompatActivity implements BaseView {
20 |
21 | protected Dialog progressDialog;
22 |
23 | protected abstract void injectDependencies(AppComponent appComponent);
24 |
25 | @Override
26 | protected void onCreate(@Nullable Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | injectDependencies(PokemonApp.getInstance().getApplicationComponent());
29 | }
30 |
31 | protected void showProgressDialog() {
32 | if (progressDialog == null || !progressDialog.isShowing()) {
33 | progressDialog = new ProgressDialog(this);
34 | progressDialog.setCanceledOnTouchOutside(false);
35 | if (!isFinishing()) {
36 | progressDialog.show();
37 | }
38 | }
39 | }
40 |
41 | protected void hideProgressDialog() {
42 | if (progressDialog != null && progressDialog.isShowing()) {
43 | if (!isFinishing()) {
44 | progressDialog.dismiss();
45 | }
46 | }
47 | }
48 |
49 | protected void showDialog(final String message) {
50 | final AlertDialog.Builder builder = new AlertDialog.Builder(this);
51 |
52 | builder.setTitle(R.string.app_name);
53 | if (message != null) {
54 | builder.setMessage(Html.fromHtml(message));
55 | } else {
56 | builder.setMessage("");
57 | }
58 | builder.setPositiveButton(android.R.string.ok, null);
59 |
60 | if (!isFinishing()) {
61 | builder.show();
62 | }
63 | }
64 |
65 | @Override
66 | public void showProgress() {
67 | showProgressDialog();
68 | }
69 |
70 | @Override
71 | public void hideProgress() {
72 | hideProgressDialog();
73 | }
74 |
75 | @Override
76 | public void showError(String message) {
77 | showDialog(message);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/activities/PokemonDetailsActivity.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.activities;
2 |
3 | import android.os.Bundle;
4 | import android.widget.TextView;
5 |
6 | import javax.inject.Inject;
7 |
8 | import butterknife.ButterKnife;
9 | import butterknife.InjectView;
10 | import co.infinum.pokemon.R;
11 | import co.infinum.pokemon.dagger.components.AppComponent;
12 | import co.infinum.pokemon.dagger.modules.PokemonDetailsModule;
13 | import co.infinum.pokemon.models.Pokemon;
14 | import co.infinum.pokemon.mvp.presenters.PokemonDetailsPresenter;
15 | import co.infinum.pokemon.mvp.views.PokemonDetailsView;
16 |
17 | public class PokemonDetailsActivity extends BaseActivity implements PokemonDetailsView {
18 |
19 | public static final String EXTRA_POKEMON = "pokemon";
20 |
21 | @InjectView(R.id.name)
22 | protected TextView nameText;
23 |
24 | @InjectView(R.id.hp)
25 | protected TextView hpText;
26 |
27 | @InjectView(R.id.weight)
28 | protected TextView weightText;
29 |
30 | @InjectView(R.id.height)
31 | protected TextView heightText;
32 |
33 | @InjectView(R.id.attack)
34 | protected TextView attackText;
35 |
36 | @InjectView(R.id.defense)
37 | protected TextView defenseText;
38 |
39 | @Inject
40 | protected PokemonDetailsPresenter pokemonDetailsPresenter;
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | setContentView(R.layout.activity_pokemon_details);
46 | ButterKnife.inject(this);
47 |
48 | Pokemon pokemon = (Pokemon) getIntent().getSerializableExtra(EXTRA_POKEMON);
49 | pokemonDetailsPresenter.loadDetails(pokemon);
50 | }
51 |
52 | @Override
53 | protected void injectDependencies(AppComponent appComponent) {
54 | appComponent.plus(new PokemonDetailsModule(this)).inject(this);
55 | }
56 |
57 |
58 | @Override
59 | protected void onDestroy() {
60 | pokemonDetailsPresenter.cancel();
61 | super.onDestroy();
62 | }
63 |
64 | @Override
65 | public void showName(String name) {
66 | nameText.setText(name);
67 | }
68 |
69 | @Override
70 | public void showHp(String hp) {
71 | hpText.setText(hp);
72 | }
73 |
74 | @Override
75 | public void showWeight(String weight) {
76 | weightText.setText(weight);
77 | }
78 |
79 | @Override
80 | public void showHeight(String height) {
81 | heightText.setText(height);
82 | }
83 |
84 | @Override
85 | public void showAttack(String attack) {
86 | attackText.setText(attack);
87 | }
88 |
89 | @Override
90 | public void showDefense(String defense) {
91 | defenseText.setText(defense);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/activities/PokemonListActivity.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.activities;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 |
8 | import java.util.List;
9 |
10 | import javax.inject.Inject;
11 |
12 | import butterknife.ButterKnife;
13 | import butterknife.InjectView;
14 | import co.infinum.pokemon.R;
15 | import co.infinum.pokemon.adapters.PokemonAdapter;
16 | import co.infinum.pokemon.dagger.components.AppComponent;
17 | import co.infinum.pokemon.dagger.modules.PokemonListModule;
18 | import co.infinum.pokemon.models.Pokemon;
19 | import co.infinum.pokemon.mvp.presenters.PokemonListPresenter;
20 | import co.infinum.pokemon.mvp.views.PokemonListView;
21 |
22 | public class PokemonListActivity extends BaseActivity implements PokemonListView, PokemonAdapter.PokemonClickListener {
23 |
24 | @InjectView(R.id.recycler_pokemon_list)
25 | protected RecyclerView pokemonListRecycler;
26 |
27 | @Inject
28 | protected PokemonListPresenter pokemonListPresenter;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_pokemon_list);
34 | ButterKnife.inject(this);
35 |
36 | pokemonListRecycler.setHasFixedSize(true);
37 | pokemonListRecycler.setLayoutManager(new LinearLayoutManager(this));
38 |
39 | pokemonListPresenter.loadPokemonList();
40 | }
41 |
42 | @Override
43 | protected void injectDependencies(AppComponent appComponent) {
44 | appComponent.plus(new PokemonListModule(this)).inject(this);
45 | }
46 |
47 | @Override
48 | public void showPokemons(List pokemons) {
49 | PokemonAdapter pokemonAdapter = new PokemonAdapter(pokemons);
50 | pokemonAdapter.setPokemonClickListener(this);
51 | pokemonListRecycler.setAdapter(pokemonAdapter);
52 | }
53 |
54 | @Override
55 | public void onPokemonClicked(Pokemon pokemon) {
56 | pokemonListPresenter.onPokemonSelected(pokemon);
57 | }
58 |
59 | @Override
60 | public void showPokemonDetails(Pokemon pokemon) {
61 | Intent intent = new Intent(this, PokemonDetailsActivity.class);
62 | intent.putExtra(PokemonDetailsActivity.EXTRA_POKEMON, pokemon);
63 | startActivity(intent);
64 | }
65 |
66 | @Override
67 | protected void onDestroy() {
68 | pokemonListPresenter.cancel();
69 | super.onDestroy();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/adapters/PokemonAdapter.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.adapters;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 | import java.util.Collections;
10 | import java.util.Comparator;
11 | import java.util.List;
12 |
13 | import butterknife.ButterKnife;
14 | import butterknife.InjectView;
15 | import co.infinum.pokemon.R;
16 | import co.infinum.pokemon.models.Pokemon;
17 |
18 | /**
19 | * Created by dino on 21/03/15.
20 | */
21 | public class PokemonAdapter extends RecyclerView.Adapter {
22 |
23 | private List pokemonList;
24 |
25 | private PokemonClickListener pokemonClickListener;
26 |
27 | public PokemonAdapter(List pokemonList) {
28 | this.pokemonList = pokemonList;
29 | Collections.sort(this.pokemonList, new Comparator() {
30 | @Override
31 | public int compare(Pokemon lhs, Pokemon rhs) {
32 | return lhs.getId() - rhs.getId();
33 | }
34 | });
35 | }
36 |
37 | @Override
38 | public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
39 | View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item_pokemon, viewGroup, false);
40 | return new ViewHolder(v);
41 | }
42 |
43 | @Override
44 | public void onBindViewHolder(ViewHolder viewHolder, int i) {
45 | final Pokemon pokemon = pokemonList.get(i);
46 | viewHolder.pokemonId.setText("#" + pokemon.getId());
47 | viewHolder.pokemonName.setText(pokemon.getName());
48 | viewHolder.rootView.setOnClickListener(new View.OnClickListener() {
49 | @Override
50 | public void onClick(View v) {
51 | if (pokemonClickListener != null) {
52 | pokemonClickListener.onPokemonClicked(pokemon);
53 | }
54 | }
55 | });
56 | }
57 |
58 | @Override
59 | public int getItemCount() {
60 | return pokemonList.size();
61 | }
62 |
63 | public void setPokemonClickListener(PokemonClickListener pokemonClickListener) {
64 | this.pokemonClickListener = pokemonClickListener;
65 | }
66 |
67 | public static class ViewHolder extends RecyclerView.ViewHolder {
68 |
69 | View rootView;
70 |
71 | @InjectView(R.id.pokemon_id)
72 | TextView pokemonId;
73 |
74 | @InjectView(R.id.pokemon_name)
75 | TextView pokemonName;
76 |
77 | public ViewHolder(View itemView) {
78 | super(itemView);
79 | rootView = itemView;
80 |
81 | ButterKnife.inject(this, itemView);
82 | }
83 | }
84 |
85 | public interface PokemonClickListener {
86 |
87 | public void onPokemonClicked(Pokemon pokemon);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/components/AppComponent.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.components;
2 |
3 | import javax.inject.Singleton;
4 |
5 | import co.infinum.pokemon.PokemonApp;
6 | import co.infinum.pokemon.dagger.modules.DefaultExecutorsModule;
7 | import co.infinum.pokemon.dagger.modules.HostModule;
8 | import co.infinum.pokemon.dagger.modules.NetworkModule;
9 | import co.infinum.pokemon.dagger.modules.PokemonDetailsModule;
10 | import co.infinum.pokemon.dagger.modules.PokemonListModule;
11 | import dagger.Component;
12 |
13 | /**
14 | * Created by dino on 13/10/15.
15 | */
16 | @Component(modules = {
17 | NetworkModule.class,
18 | HostModule.class,
19 | DefaultExecutorsModule.class,
20 | })
21 | @Singleton
22 | public interface AppComponent {
23 |
24 | void inject(PokemonApp app);
25 |
26 | PokemonListComponent plus(PokemonListModule pokemonListModule);
27 |
28 | PokemonDetailsComponent plus(PokemonDetailsModule pokemonDetailsModule);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/components/PokemonDetailsComponent.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.components;
2 |
3 | import co.infinum.pokemon.activities.PokemonDetailsActivity;
4 | import co.infinum.pokemon.dagger.modules.PokemonDetailsModule;
5 | import co.infinum.pokemon.dagger.scopes.ActivityScope;
6 | import dagger.Subcomponent;
7 |
8 | /**
9 | * Created by dino on 12/05/15.
10 | */
11 | @ActivityScope
12 | @Subcomponent(modules = {
13 | PokemonDetailsModule.class
14 | })
15 | public interface PokemonDetailsComponent {
16 |
17 | void inject(PokemonDetailsActivity activity);
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/components/PokemonListComponent.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.components;
2 |
3 | import co.infinum.pokemon.activities.PokemonListActivity;
4 | import co.infinum.pokemon.dagger.modules.PokemonListModule;
5 | import co.infinum.pokemon.dagger.scopes.ActivityScope;
6 | import dagger.Subcomponent;
7 |
8 | /**
9 | * Created by dino on 12/05/15.
10 | */
11 | @ActivityScope
12 | @Subcomponent(modules = {
13 | PokemonListModule.class
14 | })
15 | public interface PokemonListComponent {
16 |
17 | void inject(PokemonListActivity activity);
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/modules/DefaultExecutorsModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import java.util.concurrent.Executor;
4 | import java.util.concurrent.Executors;
5 |
6 | import javax.inject.Named;
7 | import javax.inject.Singleton;
8 |
9 | import dagger.Module;
10 | import dagger.Provides;
11 | import retrofit.android.MainThreadExecutor;
12 |
13 | /**
14 | * This module uses to inject HTTP Client
15 | * and Callback executors. This implementation of Executors inject the default executors set
16 | * up by Retrofit RestClient.Builder.
17 | */
18 | @Module
19 | public class DefaultExecutorsModule {
20 |
21 | @Provides
22 | @Singleton
23 | @Named("HttpExecutor")
24 | public Executor provideHttpExecutor() {
25 | return Executors.newCachedThreadPool();
26 | }
27 |
28 | @Provides
29 | @Singleton
30 | @Named("CallbackExecutor")
31 | public Executor provideCallbackExecutor() {
32 | return new MainThreadExecutor();
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/modules/HostModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import javax.inject.Singleton;
4 |
5 | import co.infinum.pokemon.BuildConfig;
6 | import dagger.Module;
7 | import dagger.Provides;
8 | import retrofit.Endpoint;
9 | import retrofit.Endpoints;
10 |
11 | /**
12 | * Created by dino on 27/02/15.
13 | */
14 | @Module
15 | public class HostModule {
16 |
17 | public static final int NETWORK_TIMEOUT_SECONDS = 10;
18 |
19 | @Provides
20 | @Singleton
21 | public Endpoint provideEndpoint() {
22 | return Endpoints.newFixedEndpoint(BuildConfig.API_URL);
23 | }
24 |
25 | @Provides
26 | @Singleton
27 | public Integer provideNetworkTimeout() {
28 | return NETWORK_TIMEOUT_SECONDS;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/modules/NetworkModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import com.squareup.okhttp.OkHttpClient;
4 |
5 | import android.util.Log;
6 |
7 | import java.util.concurrent.Executor;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | import javax.inject.Named;
11 | import javax.inject.Singleton;
12 |
13 | import co.infinum.pokemon.network.PokemonService;
14 | import dagger.Module;
15 | import dagger.Provides;
16 | import retrofit.Endpoint;
17 | import retrofit.RestAdapter;
18 | import retrofit.client.OkClient;
19 |
20 | /**
21 | * Created by dino on 12/05/15.
22 | */
23 | @Module
24 | public class NetworkModule {
25 |
26 | @Provides
27 | @Singleton
28 | public RestAdapter.Log provideLogger() {
29 | return new RestAdapter.Log() {
30 | @Override
31 | public void log(String message) {
32 | Log.d("REST-ADAPTER", message);
33 | }
34 | };
35 | }
36 |
37 | @Provides
38 | @Singleton
39 | public OkHttpClient provideClient(Integer networkTimeout) {
40 | OkHttpClient okHttpClient = new OkHttpClient();
41 | okHttpClient.setConnectTimeout(networkTimeout, TimeUnit.SECONDS);
42 | okHttpClient.setReadTimeout(networkTimeout, TimeUnit.SECONDS);
43 | return okHttpClient;
44 | }
45 |
46 |
47 | @Provides
48 | @Singleton
49 | public PokemonService provideService(Endpoint endpoint, @Named("HttpExecutor") Executor httpExecutor,
50 | @Named("CallbackExecutor") Executor callbackExecutor, OkHttpClient client,
51 | RestAdapter.Log log) {
52 |
53 | return new RestAdapter.Builder()
54 | .setClient(new OkClient(client))
55 | .setEndpoint(endpoint)
56 | .setLog(log)
57 | .setLogLevel(RestAdapter.LogLevel.FULL)
58 | .setExecutors(httpExecutor, callbackExecutor)
59 | .build().create(PokemonService.class);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/modules/PokemonDetailsModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import co.infinum.pokemon.dagger.scopes.ActivityScope;
4 | import co.infinum.pokemon.mvp.interactors.PokemonDetailsInteractor;
5 | import co.infinum.pokemon.mvp.interactors.impl.PokemonDetailsInteractorImpl;
6 | import co.infinum.pokemon.mvp.presenters.PokemonDetailsPresenter;
7 | import co.infinum.pokemon.mvp.presenters.impl.PokemonDetailsPresenterImpl;
8 | import co.infinum.pokemon.mvp.views.PokemonDetailsView;
9 | import dagger.Module;
10 | import dagger.Provides;
11 |
12 | /**
13 | * Created by dino on 12/05/15.
14 | */
15 | @Module
16 | public class PokemonDetailsModule {
17 |
18 | private PokemonDetailsView view;
19 |
20 | public PokemonDetailsModule(PokemonDetailsView view) {
21 | this.view = view;
22 | }
23 |
24 | @ActivityScope
25 | @Provides
26 | public PokemonDetailsView provideView() {
27 | return view;
28 | }
29 |
30 | @ActivityScope
31 | @Provides
32 | public PokemonDetailsInteractor provideInteractor(PokemonDetailsInteractorImpl interactor) {
33 | return interactor;
34 | }
35 |
36 | @ActivityScope
37 | @Provides
38 | public PokemonDetailsPresenter providePresenter(PokemonDetailsPresenterImpl presenter) {
39 | return presenter;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/modules/PokemonListModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import co.infinum.pokemon.dagger.scopes.ActivityScope;
4 | import co.infinum.pokemon.mvp.interactors.PokemonListInteractor;
5 | import co.infinum.pokemon.mvp.interactors.impl.PokemonListInteractorImpl;
6 | import co.infinum.pokemon.mvp.presenters.PokemonListPresenter;
7 | import co.infinum.pokemon.mvp.presenters.impl.PokemonListPresenterImpl;
8 | import co.infinum.pokemon.mvp.views.PokemonListView;
9 | import dagger.Module;
10 | import dagger.Provides;
11 |
12 | /**
13 | * Created by dino on 12/05/15.
14 | */
15 | @Module
16 | public class PokemonListModule {
17 |
18 | private PokemonListView view;
19 |
20 | public PokemonListModule(PokemonListView view) {
21 | this.view = view;
22 | }
23 |
24 | @ActivityScope
25 | @Provides
26 | public PokemonListView provideView() {
27 | return view;
28 | }
29 |
30 | @ActivityScope
31 | @Provides
32 | public PokemonListInteractor provideInteractor(PokemonListInteractorImpl interactor) {
33 | return interactor;
34 | }
35 |
36 | @ActivityScope
37 | @Provides
38 | public PokemonListPresenter providePresenter(PokemonListPresenterImpl presenter) {
39 | return presenter;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/dagger/scopes/ActivityScope.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.scopes;
2 |
3 | import java.lang.annotation.Retention;
4 | import java.lang.annotation.RetentionPolicy;
5 |
6 | import javax.inject.Scope;
7 |
8 | /**
9 | * @author Koc
10 | * ivan.kocijan@infinum.hr
11 | * @since 21/11/15
12 | */
13 | @Scope
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface ActivityScope {
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/models/Pokedex.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.models;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import java.io.Serializable;
6 | import java.util.List;
7 |
8 | /**
9 | * Created by dino on 20/03/15.
10 | */
11 | public class Pokedex implements Serializable {
12 |
13 | public static final String POKEMON = "pokemon";
14 |
15 | @SerializedName(POKEMON)
16 | private List pokemons;
17 |
18 | public List getPokemons() {
19 | return pokemons;
20 | }
21 |
22 | public void setPokemons(List pokemons) {
23 | this.pokemons = pokemons;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/models/Pokemon.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.models;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import android.text.TextUtils;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * Created by dino on 20/03/15.
11 | */
12 | public class Pokemon implements Serializable {
13 |
14 | public static final String NAME = "name";
15 |
16 | public static final String RESOURCE_URI = "resource_uri";
17 |
18 | public static final String HP = "hp";
19 |
20 | public static final String ATTACK = "attack";
21 |
22 | public static final String DEFENSE = "defense";
23 |
24 | public static final String HEIGHT = "height";
25 |
26 | public static final String WEIGHT = "weight";
27 |
28 | @SerializedName(NAME)
29 | private String name;
30 |
31 | @SerializedName(RESOURCE_URI)
32 | private String resourceUri;
33 |
34 | @SerializedName(HP)
35 | private int hp;
36 |
37 | @SerializedName(ATTACK)
38 | private int attack;
39 |
40 | @SerializedName(DEFENSE)
41 | private int defense;
42 |
43 | @SerializedName(HEIGHT)
44 | private String height;
45 |
46 | @SerializedName(WEIGHT)
47 | private String weight;
48 |
49 | public int getId() {
50 | try {
51 | String[] tokens = TextUtils.split(resourceUri, "/");
52 | String id = TextUtils.isEmpty(tokens[tokens.length - 1]) ? tokens[tokens.length - 2] : tokens[tokens.length - 1];
53 | return Integer.parseInt(id);
54 | } catch (Exception e) {
55 | return 0;
56 | }
57 | }
58 |
59 | public String getName() {
60 | return name;
61 | }
62 |
63 | public void setName(String name) {
64 | this.name = name;
65 | }
66 |
67 | public String getResourceUri() {
68 | return resourceUri;
69 | }
70 |
71 | public void setResourceUri(String resourceUri) {
72 | this.resourceUri = resourceUri;
73 | }
74 |
75 | public int getHp() {
76 | return hp;
77 | }
78 |
79 | public void setHp(int hp) {
80 | this.hp = hp;
81 | }
82 |
83 | public int getAttack() {
84 | return attack;
85 | }
86 |
87 | public void setAttack(int attack) {
88 | this.attack = attack;
89 | }
90 |
91 | public int getDefense() {
92 | return defense;
93 | }
94 |
95 | public void setDefense(int defense) {
96 | this.defense = defense;
97 | }
98 |
99 | public String getHeight() {
100 | String heightStr = height;
101 | try {
102 | double centimeters;
103 | if (height.contains("'")) {
104 | String[] parts = height.split("'");
105 | centimeters = Double.parseDouble(parts[0]) / 0.032808;
106 | centimeters += Double.parseDouble(parts[1]) * 2.54;
107 | } else {
108 | centimeters = Double.parseDouble(height) / 0.032808;
109 | }
110 | heightStr = String.valueOf((int) centimeters) + " cm";
111 | } catch (Exception e) {
112 | System.err.println(e.getMessage());
113 | }
114 | return heightStr;
115 | }
116 |
117 | public void setHeight(String height) {
118 | this.height = height;
119 | }
120 |
121 | public String getWeight() {
122 | String weightStr = weight;
123 | try {
124 | double lbs;
125 | if (weight.contains("lbs")) {
126 | lbs = Double.parseDouble(weight.substring(0, weight.indexOf('l') - 1));
127 | } else {
128 | lbs = Double.parseDouble(weight);
129 | }
130 | int kg = (int) (lbs * 0.45359237);
131 | weightStr = String.valueOf(kg) + " kg";
132 | } catch (Exception e) {
133 | System.err.println(e.getMessage());
134 | }
135 | return weightStr;
136 | }
137 |
138 | public void setWeight(String weight) {
139 | this.weight = weight;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/interactors/BaseInteractor.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.interactors;
2 |
3 | /**
4 | * Created by dino on 20/03/15.
5 | */
6 | public interface BaseInteractor {
7 |
8 | void cancel();
9 |
10 | void reset();
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/interactors/PokemonDetailsInteractor.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.interactors;
2 |
3 | import co.infinum.pokemon.mvp.listeners.PokemonDetailsListener;
4 |
5 | /**
6 | * Created by dino on 21/03/15.
7 | */
8 | public interface PokemonDetailsInteractor extends BaseInteractor {
9 |
10 | void loadPokemonDetails(String resourceUri, PokemonDetailsListener pokemonDetailsListener);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/interactors/PokemonListInteractor.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.interactors;
2 |
3 | import co.infinum.pokemon.mvp.listeners.PokemonListListener;
4 |
5 | /**
6 | * Created by dino on 21/03/15.
7 | */
8 | public interface PokemonListInteractor extends BaseInteractor {
9 |
10 | void loadPokemonList(PokemonListListener pokemonListListener);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/interactors/impl/PokemonDetailsInteractorImpl.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.interactors.impl;
2 |
3 | import javax.inject.Inject;
4 |
5 | import co.infinum.pokemon.models.Pokemon;
6 | import co.infinum.pokemon.mvp.interactors.PokemonDetailsInteractor;
7 | import co.infinum.pokemon.mvp.listeners.PokemonDetailsListener;
8 | import co.infinum.pokemon.network.PokemonService;
9 | import retrofit.Callback;
10 | import retrofit.RetrofitError;
11 | import retrofit.client.Response;
12 |
13 | /**
14 | * Created by dino on 21/03/15.
15 | */
16 | public class PokemonDetailsInteractorImpl implements PokemonDetailsInteractor, Callback {
17 |
18 | private PokemonDetailsListener pokemonDetailsListener;
19 |
20 | private boolean isCanceled;
21 |
22 | private PokemonService pokemonService;
23 |
24 | @Inject
25 | public PokemonDetailsInteractorImpl(PokemonService pokemonService) {
26 | this.pokemonService = pokemonService;
27 | }
28 |
29 | @Override
30 | public void loadPokemonDetails(String resourceUri, PokemonDetailsListener pokemonDetailsListener) {
31 | reset();
32 | this.pokemonDetailsListener = pokemonDetailsListener;
33 | pokemonService.getPokemon(resourceUri, this);
34 | }
35 |
36 | @Override
37 | public void cancel() {
38 | isCanceled = true;
39 | }
40 |
41 | @Override
42 | public void reset() {
43 | isCanceled = false;
44 | }
45 |
46 | @Override
47 | public void success(Pokemon pokemon, Response response) {
48 | if (!isCanceled) {
49 | pokemonDetailsListener.onSuccess(pokemon);
50 | }
51 | }
52 |
53 | @Override
54 | public void failure(RetrofitError error) {
55 | if (!isCanceled) {
56 | pokemonDetailsListener.onFailure(error.getMessage());
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/interactors/impl/PokemonListInteractorImpl.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.interactors.impl;
2 |
3 | import javax.inject.Inject;
4 |
5 | import co.infinum.pokemon.models.Pokedex;
6 | import co.infinum.pokemon.mvp.interactors.PokemonListInteractor;
7 | import co.infinum.pokemon.mvp.listeners.PokemonListListener;
8 | import co.infinum.pokemon.network.PokemonService;
9 | import retrofit.Callback;
10 | import retrofit.RetrofitError;
11 | import retrofit.client.Response;
12 |
13 | /**
14 | * Created by dino on 21/03/15.
15 | */
16 | public class PokemonListInteractorImpl implements PokemonListInteractor, Callback {
17 |
18 | private PokemonListListener pokemonListListener;
19 |
20 | private boolean isCanceled;
21 |
22 | private PokemonService pokemonService;
23 |
24 | @Inject
25 | public PokemonListInteractorImpl(PokemonService pokemonService) {
26 | this.pokemonService = pokemonService;
27 | }
28 |
29 | @Override
30 | public void loadPokemonList(PokemonListListener pokemonListListener) {
31 | reset();
32 | this.pokemonListListener = pokemonListListener;
33 | pokemonService.getPokedex(this);
34 | }
35 |
36 | @Override
37 | public void cancel() {
38 | isCanceled = true;
39 | }
40 |
41 | @Override
42 | public void reset() {
43 | isCanceled = false;
44 | }
45 |
46 | @Override
47 | public void success(Pokedex pokedex, Response response) {
48 | if (!isCanceled) {
49 | pokemonListListener.onSuccess(pokedex);
50 | }
51 | }
52 |
53 | @Override
54 | public void failure(RetrofitError error) {
55 | if (!isCanceled) {
56 | pokemonListListener.onFailure(error.getMessage());
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/listeners/BaseListener.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.listeners;
2 |
3 | /**
4 | * Created by dino on 20/03/15.
5 | */
6 | public interface BaseListener {
7 |
8 | void onFailure(String message);
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/listeners/PokemonDetailsListener.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.listeners;
2 |
3 | import co.infinum.pokemon.models.Pokemon;
4 |
5 | /**
6 | * Created by dino on 21/03/15.
7 | */
8 | public interface PokemonDetailsListener extends BaseListener {
9 |
10 | void onSuccess(Pokemon pokemon);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/listeners/PokemonListListener.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.listeners;
2 |
3 | import co.infinum.pokemon.models.Pokedex;
4 |
5 | /**
6 | * Created by dino on 21/03/15.
7 | */
8 | public interface PokemonListListener extends BaseListener {
9 |
10 | void onSuccess(Pokedex pokedex);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/presenters/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.presenters;
2 |
3 | /**
4 | * Created by dino on 20/03/15.
5 | */
6 | public interface BasePresenter {
7 |
8 | void cancel();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/presenters/PokemonDetailsPresenter.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.presenters;
2 |
3 | import co.infinum.pokemon.models.Pokemon;
4 |
5 | /**
6 | * Created by dino on 21/03/15.
7 | */
8 | public interface PokemonDetailsPresenter extends BasePresenter {
9 |
10 | void loadDetails(Pokemon pokemon);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/presenters/PokemonListPresenter.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.presenters;
2 |
3 | import co.infinum.pokemon.models.Pokemon;
4 |
5 | /**
6 | * Created by dino on 21/03/15.
7 | */
8 | public interface PokemonListPresenter extends BasePresenter {
9 |
10 | void loadPokemonList();
11 |
12 | void onPokemonSelected(Pokemon pokemon);
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/presenters/impl/PokemonDetailsPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.presenters.impl;
2 |
3 | import javax.inject.Inject;
4 |
5 | import co.infinum.pokemon.models.Pokemon;
6 | import co.infinum.pokemon.mvp.interactors.PokemonDetailsInteractor;
7 | import co.infinum.pokemon.mvp.listeners.PokemonDetailsListener;
8 | import co.infinum.pokemon.mvp.presenters.PokemonDetailsPresenter;
9 | import co.infinum.pokemon.mvp.views.PokemonDetailsView;
10 |
11 | /**
12 | * Created by dino on 21/03/15.
13 | */
14 | public class PokemonDetailsPresenterImpl implements PokemonDetailsPresenter, PokemonDetailsListener {
15 |
16 | private final PokemonDetailsView pokemonDetailsView;
17 |
18 | private final PokemonDetailsInteractor pokemonDetailsInteractor;
19 |
20 | @Inject
21 | public PokemonDetailsPresenterImpl(PokemonDetailsView pokemonDetailsView, PokemonDetailsInteractor pokemonDetailsInteractor) {
22 | this.pokemonDetailsView = pokemonDetailsView;
23 | this.pokemonDetailsInteractor = pokemonDetailsInteractor;
24 | }
25 |
26 | @Override
27 | public void loadDetails(Pokemon pokemon) {
28 | pokemonDetailsView.showProgress();
29 | pokemonDetailsInteractor.loadPokemonDetails(pokemon.getResourceUri(), this);
30 | }
31 |
32 | @Override
33 | public void cancel() {
34 | pokemonDetailsView.hideProgress();
35 | pokemonDetailsInteractor.cancel();
36 | }
37 |
38 | @Override
39 | public void onSuccess(Pokemon pokemon) {
40 | // APIs are not to be trusted so we wrap interaction with data from API in try/catch
41 | try {
42 | pokemonDetailsView.showName(pokemon.getName());
43 | pokemonDetailsView.showHp(String.valueOf(pokemon.getHp()));
44 | pokemonDetailsView.showWeight(pokemon.getWeight());
45 | pokemonDetailsView.showHeight(pokemon.getHeight());
46 | pokemonDetailsView.showAttack(String.valueOf(pokemon.getAttack()));
47 | pokemonDetailsView.showDefense(String.valueOf(pokemon.getDefense()));
48 | } catch (Exception e) {
49 | e.printStackTrace();
50 | pokemonDetailsView.showError("Unknown error while using data from API!");
51 | } finally {
52 | pokemonDetailsView.hideProgress();
53 | }
54 | }
55 |
56 | @Override
57 | public void onFailure(String message) {
58 | pokemonDetailsView.hideProgress();
59 | pokemonDetailsView.showError(message);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/presenters/impl/PokemonListPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.presenters.impl;
2 |
3 | import javax.inject.Inject;
4 |
5 | import co.infinum.pokemon.models.Pokedex;
6 | import co.infinum.pokemon.models.Pokemon;
7 | import co.infinum.pokemon.mvp.interactors.PokemonListInteractor;
8 | import co.infinum.pokemon.mvp.listeners.PokemonListListener;
9 | import co.infinum.pokemon.mvp.presenters.PokemonListPresenter;
10 | import co.infinum.pokemon.mvp.views.PokemonListView;
11 |
12 | /**
13 | * Created by dino on 21/03/15.
14 | */
15 | public class PokemonListPresenterImpl implements PokemonListPresenter, PokemonListListener {
16 |
17 | private final PokemonListView pokemonListView;
18 |
19 | private final PokemonListInteractor pokemonListInteractor;
20 |
21 | @Inject
22 | public PokemonListPresenterImpl(PokemonListView pokemonListView, PokemonListInteractor pokemonListInteractor) {
23 | this.pokemonListView = pokemonListView;
24 | this.pokemonListInteractor = pokemonListInteractor;
25 | }
26 |
27 | @Override
28 | public void loadPokemonList() {
29 | pokemonListView.showProgress();
30 | pokemonListInteractor.loadPokemonList(this);
31 | }
32 |
33 | @Override
34 | public void onPokemonSelected(Pokemon pokemon) {
35 | pokemonListView.showPokemonDetails(pokemon);
36 | }
37 |
38 | @Override
39 | public void cancel() {
40 | pokemonListView.hideProgress();
41 | pokemonListInteractor.cancel();
42 | }
43 |
44 | @Override
45 | public void onSuccess(Pokedex pokedex) {
46 | pokemonListView.hideProgress();
47 | pokemonListView.showPokemons(pokedex.getPokemons());
48 | }
49 |
50 | @Override
51 | public void onFailure(String message) {
52 | pokemonListView.hideProgress();
53 | pokemonListView.showError(message);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/views/BaseView.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.views;
2 |
3 | /**
4 | * Created by dino on 20/03/15.
5 | */
6 | public interface BaseView {
7 |
8 | void showProgress();
9 |
10 | void hideProgress();
11 |
12 | void showError(String message);
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/views/PokemonDetailsView.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.views;
2 |
3 | /**
4 | * Created by dino on 21/03/15.
5 | */
6 | public interface PokemonDetailsView extends BaseView {
7 |
8 | void showName(String name);
9 |
10 | void showHp(String hp);
11 |
12 | void showWeight(String weight);
13 |
14 | void showHeight(String height);
15 |
16 | void showAttack(String attack);
17 |
18 | void showDefense(String defense);
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/mvp/views/PokemonListView.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.mvp.views;
2 |
3 | import java.util.List;
4 |
5 | import co.infinum.pokemon.models.Pokemon;
6 |
7 | /**
8 | * Created by dino on 21/03/15.
9 | */
10 | public interface PokemonListView extends BaseView {
11 |
12 | void showPokemons(List pokemons);
13 |
14 | void showPokemonDetails(Pokemon pokemon);
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/co/infinum/pokemon/network/PokemonService.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.network;
2 |
3 | import co.infinum.pokemon.models.Pokedex;
4 | import co.infinum.pokemon.models.Pokemon;
5 | import retrofit.Callback;
6 | import retrofit.http.GET;
7 | import retrofit.http.Path;
8 |
9 | /**
10 | * Created by ivan on 09/06/14.
11 | */
12 | public interface PokemonService {
13 |
14 | @GET("/api/v1/pokedex/1")
15 | void getPokedex(Callback callback);
16 |
17 | @GET("/{resource_uri}")
18 | void getPokemon(@Path(value = "resource_uri", encode = false) String resourceUri, Callback callback);
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_pokemon_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
23 |
24 |
30 |
31 |
36 |
37 |
43 |
44 |
49 |
50 |
56 |
57 |
62 |
63 |
69 |
70 |
75 |
76 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_pokemon_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_pokemon.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinum/Dagger-2-Example/bc147fee74992ab202958a20caee9a63d7fe104d/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinum/Dagger-2-Example/bc147fee74992ab202958a20caee9a63d7fe104d/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinum/Dagger-2-Example/bc147fee74992ab202958a20caee9a63d7fe104d/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinum/Dagger-2-Example/bc147fee74992ab202958a20caee9a63d7fe104d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #AAFF4444
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 | 4dp
7 |
8 | 1px
9 | 100dp
10 |
11 | 1px
12 | -1px
13 |
14 | 5dp
15 | 5dp
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Pokemon
5 | There was a network problem.
6 | Login failed.
7 | Unknown error occurred
8 | You don\'t have the budget to do this.
9 | Login currently unavailable.
10 | HP
11 | Weight
12 | Height
13 | Attack
14 | Defense
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/PokemonTestApp.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import com.squareup.okhttp.mockwebserver.MockWebServer;
6 |
7 | import org.robolectric.TestLifecycleApplication;
8 |
9 | import android.annotation.SuppressLint;
10 |
11 | import java.lang.reflect.Method;
12 |
13 | import co.infinum.pokemon.dagger.components.AppTestComponent;
14 | import co.infinum.pokemon.dagger.components.DaggerAppTestComponent;
15 | import co.infinum.pokemon.dagger.modules.MockHostModule;
16 |
17 | /**
18 | * Test application that is run instead of {@link PokemonApp} when Robolectric tests are run.
19 | */
20 | public class PokemonTestApp extends PokemonApp implements TestLifecycleApplication {
21 |
22 | private static MockWebServer mockWebServer;
23 |
24 | public static MockWebServer getMockWebServer() {
25 | return mockWebServer;
26 | }
27 |
28 | public static void setMockWebServer(MockHostModule mockHostModule) {
29 | mockWebServer = mockHostModule.getMockWebServer();
30 | }
31 |
32 | public static Gson getGson() {
33 | return new Gson();
34 | }
35 |
36 | @SuppressLint("MissingSuperCall")
37 | @Override
38 | public void onCreate() {
39 | // Don't call super so the dependencies don't get injected.
40 | setInstance(this);
41 | }
42 |
43 | /**
44 | * Prepares the MockWebServer before each test
45 | */
46 | @Override
47 | public void beforeTest(Method method) {
48 | MockHostModule mockHostModule = new MockHostModule();
49 | setMockWebServer(mockHostModule);
50 | AppTestComponent appTestComponent = DaggerAppTestComponent.builder()
51 | .mockHostModule(mockHostModule)
52 | .build();
53 | appTestComponent.inject(this);
54 | }
55 |
56 | @Override
57 | public void prepareTest(Object test) {
58 |
59 | }
60 |
61 | @Override
62 | public void afterTest(Method method) {
63 | try {
64 | mockWebServer.shutdown();
65 | } catch (Exception e) {
66 | e.printStackTrace();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/dagger/components/AppTestComponent.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.components;
2 |
3 | import javax.inject.Singleton;
4 |
5 | import co.infinum.pokemon.PokemonApp;
6 | import co.infinum.pokemon.dagger.modules.MockHostModule;
7 | import co.infinum.pokemon.dagger.modules.SynchronousExecutorsModule;
8 | import dagger.Component;
9 |
10 | /**
11 | * Created by dino on 13/10/15.
12 | */
13 | @Component(modules = {
14 | MockHostModule.class,
15 | SynchronousExecutorsModule.class,
16 | ApiModule.class
17 | })
18 | @Singleton
19 | public interface AppTestComponent {
20 |
21 | void inject(PokemonApp app);
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/dagger/modules/MockHostModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import com.squareup.okhttp.mockwebserver.MockWebServer;
4 |
5 | import java.io.IOException;
6 |
7 | import javax.inject.Singleton;
8 |
9 | import dagger.Module;
10 | import dagger.Provides;
11 | import retrofit.Endpoint;
12 | import retrofit.Endpoints;
13 |
14 | /**
15 | * Created by dino on 27/02/15.
16 | */
17 | @Module
18 | public class MockHostModule {
19 |
20 | public static final int NETWORK_TIMEOUT_SECONDS = 1;
21 |
22 | private MockWebServer mockWebServer;
23 |
24 | public MockHostModule() {
25 | mockWebServer = new MockWebServer();
26 | try {
27 | mockWebServer.start();
28 | } catch (IOException e) {
29 | e.printStackTrace();
30 | throw new RuntimeException("Failed to start mockWebServer!");
31 | }
32 | }
33 |
34 | @Provides
35 | @Singleton
36 | public Endpoint provideEndpoint() {
37 | return Endpoints.newFixedEndpoint(mockWebServer.url("/").toString());
38 | }
39 |
40 | public MockWebServer getMockWebServer() {
41 | return mockWebServer;
42 | }
43 |
44 | @Provides
45 | @Singleton
46 | public Integer provideNetworkTimeout() {
47 | return NETWORK_TIMEOUT_SECONDS;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/dagger/modules/SynchronousExecutorsModule.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.dagger.modules;
2 |
3 | import java.util.concurrent.Executor;
4 |
5 | import javax.inject.Named;
6 |
7 | import dagger.Module;
8 | import dagger.Provides;
9 |
10 | /**
11 | * This module uses to inject HTTP Client
12 | * and Callback executors. This implementation of Executors run the HTTP Client requests and
13 | * Callbacks on the same thread as the caller.
14 | *
15 | * Beware as this should be used only for testing purposes, running on a device will result in
16 | * {@link android.os.NetworkOnMainThreadException}.
17 | */
18 | @Module
19 | public class SynchronousExecutorsModule {
20 |
21 | class SynchronousExecutor implements Executor {
22 |
23 | @Override
24 | public void execute(Runnable command) {
25 | command.run();
26 | }
27 | }
28 |
29 | @Provides
30 | @Named("HttpExecutor")
31 | public Executor provideHttpExecutor() {
32 | return new SynchronousExecutor();
33 | }
34 |
35 | @Provides
36 | @Named("CallbackExecutor")
37 | public Executor provideCallbackExecutor() {
38 | return new SynchronousExecutor();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/helpers/CustomRobolectricGradleTestRunner.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.helpers;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import org.junit.runners.model.InitializationError;
6 | import org.robolectric.RobolectricGradleTestRunner;
7 | import org.robolectric.annotation.Config;
8 | import org.robolectric.internal.bytecode.InstrumentationConfiguration;
9 | import org.robolectric.manifest.AndroidManifest;
10 |
11 | import retrofit.converter.GsonConverter;
12 |
13 | /**
14 | * Created by zeljkoplesac on 05/02/15.
15 | */
16 | public class CustomRobolectricGradleTestRunner extends RobolectricGradleTestRunner {
17 |
18 | public CustomRobolectricGradleTestRunner(Class> testClass) throws InitializationError {
19 | super(testClass);
20 | }
21 |
22 | @Override
23 | protected AndroidManifest getAppManifest(Config config) {
24 | AndroidManifest appManifest = super.getAppManifest(config);
25 | appManifest.setPackageName("co.infinum.pokemon"); // needs to be the java package name, not applicationId
26 | return appManifest;
27 | }
28 |
29 | @Override
30 | public InstrumentationConfiguration createClassLoaderConfig() {
31 | InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
32 | builder.addInstrumentedClass(Gson.class.getName());
33 | builder.addInstrumentedClass(GsonConverter.class.getName());
34 | return builder.build();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/helpers/ResourceUtils.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.helpers;
2 |
3 | import java.io.InputStream;
4 | import java.util.Scanner;
5 |
6 | /**
7 | * Utility methods for accessing resources bundled with test APK. Standard Android Resources don't seem to work for test APK
8 | * (unable to fetch R.java).
9 | *
10 | * Resources should be placed under /resources/mockdata folder in androidTest flavour. Use {@link #readFromFile(String)} to read a text
11 | * file to String giving only a name of the file located in /resources/mockdata folder.
12 | */
13 | public class ResourceUtils {
14 |
15 | private static final String MOCK_DATA_DIRECTORY = "mockdata/%s";
16 |
17 | private ResourceUtils() {
18 | }
19 |
20 | /**
21 | * Converts InputStream to String.
22 | */
23 | public static String convertStreamToString(InputStream is) {
24 | Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A");
25 | return s.hasNext() ? s.next() : "";
26 | }
27 |
28 | /**
29 | * Reads a resource file to String
.
30 | */
31 | public static String readFromFile(String filename) {
32 | InputStream is = ResourceUtils.class.getClassLoader().getResourceAsStream(String.format(MOCK_DATA_DIRECTORY, filename));
33 | return convertStreamToString(is);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/shadows/ShadowGson.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.shadows;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.JsonIOException;
5 | import com.google.gson.JsonSyntaxException;
6 |
7 | import org.robolectric.annotation.Implementation;
8 | import org.robolectric.annotation.Implements;
9 | import org.robolectric.annotation.RealObject;
10 |
11 | import android.util.Log;
12 |
13 | import java.io.Reader;
14 | import java.lang.reflect.Type;
15 |
16 | import static org.robolectric.internal.Shadow.directlyOn;
17 |
18 | /**
19 | * Created by ivan on 20/10/15.
20 | */
21 | @Implements(Gson.class)
22 | public class ShadowGson {
23 |
24 | /**
25 | * Real object that will be injected when shadow is constructed.
26 | */
27 | @RealObject
28 | private Gson gson;
29 |
30 | /**
31 | * Shadowed constructor.
32 | */
33 | public void __constructor__() {
34 |
35 | }
36 |
37 | @Implementation
38 | public T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
39 | //Log that we're deserializing an object.
40 | Log.d("GsonShadow", "Deserializing " + typeOfT.toString());
41 |
42 | //Use directlyOn to invoke a shadowed method directly on a
43 | //Real object. Otherwise you'll get stack overflow exception.
44 | return directlyOn(gson, Gson.class).fromJson(json, typeOfT);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/test/BaseTest.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.test;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import com.squareup.okhttp.mockwebserver.MockResponse;
6 | import com.squareup.okhttp.mockwebserver.MockWebServer;
7 | import com.squareup.okhttp.mockwebserver.RecordedRequest;
8 |
9 | import org.junit.Before;
10 | import org.robolectric.shadows.ShadowLog;
11 |
12 | import java.net.HttpURLConnection;
13 | import java.util.concurrent.TimeUnit;
14 |
15 | import co.infinum.pokemon.PokemonTestApp;
16 | import co.infinum.pokemon.helpers.ResourceUtils;
17 |
18 | /**
19 | * Created by Željko Plesac on 07/09/15.
20 | */
21 | public class BaseTest {
22 |
23 | private MockWebServer mockWebServer;
24 |
25 | @Before
26 | public void setup() throws Exception {
27 | mockWebServer = PokemonTestApp.getMockWebServer();
28 |
29 | ShadowLog.stream = System.out;
30 | }
31 |
32 | protected Gson getGson() {
33 | return PokemonTestApp.getGson();
34 | }
35 |
36 | protected void enqueueResponse(String filename) {
37 | String body = ResourceUtils.readFromFile(filename);
38 | MockResponse mockResponse = new MockResponse().setBody(body).setResponseCode(HttpURLConnection.HTTP_OK);
39 | mockWebServer.enqueue(mockResponse);
40 | }
41 |
42 | protected void enqueueResponse(String filename, int statusCode) {
43 | String body = ResourceUtils.readFromFile(filename);
44 | MockResponse mockResponse = new MockResponse().setBody(body).setResponseCode(statusCode);
45 | mockWebServer.enqueue(mockResponse);
46 | }
47 |
48 | protected void enqueueEmptyResponse(int statusCode) {
49 | MockResponse mockResponse = new MockResponse().setBody("").setResponseCode(statusCode);
50 | mockWebServer.enqueue(mockResponse);
51 | }
52 |
53 | protected RecordedRequest takeLastRequest() throws InterruptedException {
54 | int requestCount = mockWebServer.getRequestCount();
55 | while (requestCount > 1) {
56 | mockWebServer.takeRequest(10, TimeUnit.SECONDS);
57 | requestCount--;
58 | }
59 |
60 | return mockWebServer.takeRequest(10, TimeUnit.SECONDS);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/test/PokemonDetailsTest.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.test;
2 |
3 | import com.squareup.okhttp.mockwebserver.MockResponse;
4 | import com.squareup.okhttp.mockwebserver.RecordedRequest;
5 |
6 | import junit.framework.Assert;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.robolectric.Robolectric;
11 | import org.robolectric.RuntimeEnvironment;
12 | import org.robolectric.annotation.Config;
13 |
14 | import android.app.Activity;
15 | import android.content.Intent;
16 | import android.widget.TextView;
17 |
18 | import co.infinum.pokemon.PokemonTestApp;
19 | import co.infinum.pokemon.R;
20 | import co.infinum.pokemon.activities.PokemonDetailsActivity;
21 | import co.infinum.pokemon.helpers.CustomRobolectricGradleTestRunner;
22 | import co.infinum.pokemon.models.Pokemon;
23 | import co.infinum.pokemon.shadows.ShadowGson;
24 | import co.infinum.pokemon.utils.ResourceUtils;
25 |
26 | import static org.assertj.android.api.Assertions.assertThat;
27 |
28 |
29 | /**
30 | * Created by ivan on 12/10/15.
31 | */
32 | @RunWith(CustomRobolectricGradleTestRunner.class)
33 | @Config(shadows = {ShadowGson.class})
34 | public class PokemonDetailsTest extends BaseTest {
35 |
36 | private PokemonDetailsActivity buildActivity(Pokemon pokemon) {
37 | Intent intent = new Intent(RuntimeEnvironment.application, PokemonDetailsActivity.class);
38 | intent.putExtra(PokemonDetailsActivity.EXTRA_POKEMON, pokemon);
39 | return Robolectric.buildActivity(PokemonDetailsActivity.class)
40 | .withIntent(intent)
41 | .create()
42 | .start()
43 | .resume()
44 | .visible()
45 | .get();
46 | }
47 |
48 | @Test
49 | public void shouldMakeRequestToCorrectResourceUri() throws Exception {
50 | String resourceUri = "api/v1/pokemon/6/";
51 | Pokemon pokemon = new Pokemon();
52 | pokemon.setResourceUri(resourceUri);
53 |
54 | Activity activity = buildActivity(pokemon);
55 |
56 | RecordedRequest request = takeLastRequest();
57 | Assert.assertEquals("/" + resourceUri, request.getPath());
58 | }
59 |
60 | @Test
61 | public void nameOk() throws Exception {
62 | PokemonTestApp.getMockWebServer().enqueue(
63 | new MockResponse()
64 | .setResponseCode(200)
65 | .setBody(ResourceUtils.readFromFile("charizard.json"))
66 | );
67 |
68 | String resourceUri = "api/v1/pokemon/6/";
69 | Pokemon pokemon = new Pokemon();
70 | pokemon.setResourceUri(resourceUri);
71 |
72 | Activity activity = buildActivity(pokemon);
73 |
74 | RecordedRequest request = takeLastRequest();
75 |
76 | //Check that name in details is displayed properly.
77 | assertThat(activity.findViewById(R.id.name)).isVisible();
78 | assertThat((TextView) activity.findViewById(R.id.name)).hasText("Charizard");
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/test/java/co/infinum/pokemon/utils/ResourceUtils.java:
--------------------------------------------------------------------------------
1 | package co.infinum.pokemon.utils;
2 |
3 | import android.app.Application;
4 | import android.content.pm.PackageManager;
5 | import android.content.res.Resources;
6 |
7 | import java.io.InputStream;
8 |
9 | /**
10 | * Utility methods for accessing resources bundled with test APK. Standard Android Resources don't seem to work for test APK
11 | * (unable to fetch R.java).
12 | *
13 | * Resources should be placed under /resources/mockdata folder in androidTest flavour. Use {@link #readFromFile(String)} to read a text
14 | * file to String giving only a name of the file located in /resources folder.
15 | */
16 | public class ResourceUtils {
17 |
18 | private static final String MOCK_DATA_DIRECTORY = "mockdata/%s";
19 |
20 | /**
21 | * Converts InputStream to String.
22 | */
23 | public static String convertStreamToString(InputStream is) {
24 | java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
25 | return s.hasNext() ? s.next() : "";
26 | }
27 |
28 |
29 | /**
30 | *
31 | * @param packageName
32 | * @return
33 | * @throws PackageManager.NameNotFoundException
34 | */
35 | protected static Resources getResources(Application application, String packageName) throws PackageManager.NameNotFoundException {
36 | PackageManager pm = application.getPackageManager();
37 | return pm.getResourcesForApplication(packageName);
38 | }
39 |
40 | /**
41 | * Reads a resource file to String
.
42 | */
43 | public static String readFromFile(String filename) {
44 | InputStream is = ResourceUtils.class.getClassLoader().getResourceAsStream(String.format(MOCK_DATA_DIRECTORY, filename));
45 | return convertStreamToString(is);
46 |
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/test/resources/mockdata/charizard.json:
--------------------------------------------------------------------------------
1 | {
2 | "abilities": [
3 | {
4 | "name": "blaze",
5 | "resource_uri": "/api/v1/ability/66/"
6 | },
7 | {
8 | "name": "solar-power",
9 | "resource_uri": "/api/v1/ability/94/"
10 | }
11 | ],
12 | "attack": 84,
13 | "catch_rate": 0,
14 | "created": "2013-11-03T15:05:41.275724",
15 | "defense": 78,
16 | "descriptions": [
17 | {
18 | "name": "charizard_gen_1",
19 | "resource_uri": "/api/v1/description/80/"
20 | },
21 | {
22 | "name": "charizard_gen_1",
23 | "resource_uri": "/api/v1/description/81/"
24 | },
25 | {
26 | "name": "charizard_gen_1",
27 | "resource_uri": "/api/v1/description/82/"
28 | },
29 | {
30 | "name": "charizard_gen_1",
31 | "resource_uri": "/api/v1/description/83/"
32 | },
33 | {
34 | "name": "charizard_gen_1",
35 | "resource_uri": "/api/v1/description/84/"
36 | },
37 | {
38 | "name": "charizard_gen_2",
39 | "resource_uri": "/api/v1/description/85/"
40 | },
41 | {
42 | "name": "charizard_gen_2",
43 | "resource_uri": "/api/v1/description/86/"
44 | },
45 | {
46 | "name": "charizard_gen_3",
47 | "resource_uri": "/api/v1/description/87/"
48 | },
49 | {
50 | "name": "charizard_gen_3",
51 | "resource_uri": "/api/v1/description/88/"
52 | },
53 | {
54 | "name": "charizard_gen_3",
55 | "resource_uri": "/api/v1/description/89/"
56 | },
57 | {
58 | "name": "charizard_gen_4",
59 | "resource_uri": "/api/v1/description/92/"
60 | },
61 | {
62 | "name": "charizard_gen_5",
63 | "resource_uri": "/api/v1/description/93/"
64 | },
65 | {
66 | "name": "charizard_gen_6",
67 | "resource_uri": "/api/v1/description/94/"
68 | },
69 | {
70 | "name": "charizard_gen_6",
71 | "resource_uri": "/api/v1/description/95/"
72 | },
73 | {
74 | "name": "charizard_gen_4",
75 | "resource_uri": "/api/v1/description/90/"
76 | },
77 | {
78 | "name": "charizard_gen_4",
79 | "resource_uri": "/api/v1/description/91/"
80 | }
81 | ],
82 | "egg_cycles": 0,
83 | "egg_groups": [
84 | {
85 | "name": "Dragon",
86 | "resource_uri": "/api/v1/egg/14/"
87 | },
88 | {
89 | "name": "Monster",
90 | "resource_uri": "/api/v1/egg/1/"
91 | }
92 | ],
93 | "ev_yield": "",
94 | "evolutions": [
95 | {
96 | "detail": "mega",
97 | "method": "other",
98 | "resource_uri": "/api/v1/pokemon/10035/",
99 | "to": "Charizard-mega-y"
100 | },
101 | {
102 | "detail": "mega",
103 | "method": "other",
104 | "resource_uri": "/api/v1/pokemon/10034/",
105 | "to": "Charizard-mega-x"
106 | }
107 | ],
108 | "exp": 240,
109 | "growth_rate": "",
110 | "happiness": 0,
111 | "height": "17",
112 | "hp": 78,
113 | "male_female_ratio": "",
114 | "modified": "2013-11-23T13:13:23.762594",
115 | "moves": [
116 | {
117 | "learn_type": "machine",
118 | "name": "Dragon-tail",
119 | "resource_uri": "/api/v1/move/525/"
120 | },
121 | {
122 | "learn_type": "machine",
123 | "name": "Bulldoze",
124 | "resource_uri": "/api/v1/move/523/"
125 | },
126 | {
127 | "learn_type": "tutor",
128 | "name": "Fire-pledge",
129 | "resource_uri": "/api/v1/move/519/"
130 | },
131 | {
132 | "learn_type": "level up",
133 | "level": 62,
134 | "name": "Inferno",
135 | "resource_uri": "/api/v1/move/517/"
136 | },
137 | {
138 | "learn_type": "machine",
139 | "name": "Incinerate",
140 | "resource_uri": "/api/v1/move/510/"
141 | },
142 | {
143 | "learn_type": "machine",
144 | "name": "Sky-drop",
145 | "resource_uri": "/api/v1/move/507/"
146 | },
147 | {
148 | "learn_type": "machine",
149 | "name": "Echoed-voice",
150 | "resource_uri": "/api/v1/move/497/"
151 | },
152 | {
153 | "learn_type": "machine",
154 | "name": "Round",
155 | "resource_uri": "/api/v1/move/496/"
156 | },
157 | {
158 | "learn_type": "machine",
159 | "name": "Flame-charge",
160 | "resource_uri": "/api/v1/move/488/"
161 | },
162 | {
163 | "learn_type": "level up",
164 | "level": 32,
165 | "name": "Flame-burst",
166 | "resource_uri": "/api/v1/move/481/"
167 | },
168 | {
169 | "learn_type": "machine",
170 | "name": "Hone-claws",
171 | "resource_uri": "/api/v1/move/468/"
172 | },
173 | {
174 | "learn_type": "tutor",
175 | "name": "Tailwind",
176 | "resource_uri": "/api/v1/move/366/"
177 | },
178 | {
179 | "learn_type": "tutor",
180 | "name": "Ominous-wind",
181 | "resource_uri": "/api/v1/move/466/"
182 | },
183 | {
184 | "learn_type": "tutor",
185 | "name": "Air-cutter",
186 | "resource_uri": "/api/v1/move/314/"
187 | },
188 | {
189 | "learn_type": "tutor",
190 | "name": "Twister",
191 | "resource_uri": "/api/v1/move/239/"
192 | },
193 | {
194 | "learn_type": "tutor",
195 | "name": "Outrage",
196 | "resource_uri": "/api/v1/move/200/"
197 | },
198 | {
199 | "learn_type": "tutor",
200 | "name": "Thunderpunch",
201 | "resource_uri": "/api/v1/move/9/"
202 | },
203 | {
204 | "learn_type": "machine",
205 | "name": "Captivate",
206 | "resource_uri": "/api/v1/move/445/"
207 | },
208 | {
209 | "learn_type": "machine",
210 | "name": "Defog",
211 | "resource_uri": "/api/v1/move/432/"
212 | },
213 | {
214 | "learn_type": "level up",
215 | "level": 28,
216 | "name": "Fire-fang",
217 | "resource_uri": "/api/v1/move/424/"
218 | },
219 | {
220 | "learn_type": "level up",
221 | "level": 1,
222 | "name": "Shadow-claw",
223 | "resource_uri": "/api/v1/move/421/"
224 | },
225 | {
226 | "learn_type": "machine",
227 | "name": "Giga-impact",
228 | "resource_uri": "/api/v1/move/416/"
229 | },
230 | {
231 | "learn_type": "machine",
232 | "name": "Focus-blast",
233 | "resource_uri": "/api/v1/move/411/"
234 | },
235 | {
236 | "learn_type": "machine",
237 | "name": "Dragon-pulse",
238 | "resource_uri": "/api/v1/move/406/"
239 | },
240 | {
241 | "learn_type": "level up",
242 | "level": 1,
243 | "name": "Air-slash",
244 | "resource_uri": "/api/v1/move/403/"
245 | },
246 | {
247 | "learn_type": "level up",
248 | "level": 66,
249 | "name": "Flare-blitz",
250 | "resource_uri": "/api/v1/move/394/"
251 | },
252 | {
253 | "learn_type": "machine",
254 | "name": "Fling",
255 | "resource_uri": "/api/v1/move/374/"
256 | },
257 | {
258 | "learn_type": "machine",
259 | "name": "Natural-gift",
260 | "resource_uri": "/api/v1/move/363/"
261 | },
262 | {
263 | "learn_type": "machine",
264 | "name": "Roost",
265 | "resource_uri": "/api/v1/move/355/"
266 | },
267 | {
268 | "learn_type": "machine",
269 | "name": "Rock-tomb",
270 | "resource_uri": "/api/v1/move/317/"
271 | },
272 | {
273 | "learn_type": "machine",
274 | "name": "Will-o-wisp",
275 | "resource_uri": "/api/v1/move/261/"
276 | },
277 | {
278 | "learn_type": "machine",
279 | "name": "Solarbeam",
280 | "resource_uri": "/api/v1/move/76/"
281 | },
282 | {
283 | "learn_type": "tutor",
284 | "name": "Blast-burn",
285 | "resource_uri": "/api/v1/move/307/"
286 | },
287 | {
288 | "learn_type": "level up",
289 | "level": 1,
290 | "name": "Heat-wave",
291 | "resource_uri": "/api/v1/move/257/"
292 | },
293 | {
294 | "learn_type": "level up",
295 | "level": 1,
296 | "name": "Metal-claw",
297 | "resource_uri": "/api/v1/move/232/"
298 | },
299 | {
300 | "learn_type": "tutor",
301 | "name": "Rock-slide",
302 | "resource_uri": "/api/v1/move/157/"
303 | },
304 | {
305 | "learn_type": "machine",
306 | "name": "Dragon-claw",
307 | "resource_uri": "/api/v1/move/337/"
308 | },
309 | {
310 | "learn_type": "machine",
311 | "name": "Aerial-ace",
312 | "resource_uri": "/api/v1/move/332/"
313 | },
314 | {
315 | "learn_type": "machine",
316 | "name": "Overheat",
317 | "resource_uri": "/api/v1/move/315/"
318 | },
319 | {
320 | "learn_type": "machine",
321 | "name": "Secret-power",
322 | "resource_uri": "/api/v1/move/290/"
323 | },
324 | {
325 | "learn_type": "machine",
326 | "name": "Brick-break",
327 | "resource_uri": "/api/v1/move/280/"
328 | },
329 | {
330 | "learn_type": "machine",
331 | "name": "Focus-punch",
332 | "resource_uri": "/api/v1/move/264/"
333 | },
334 | {
335 | "learn_type": "machine",
336 | "name": "Facade",
337 | "resource_uri": "/api/v1/move/263/"
338 | },
339 | {
340 | "learn_type": "machine",
341 | "name": "Rock-smash",
342 | "resource_uri": "/api/v1/move/249/"
343 | },
344 | {
345 | "learn_type": "machine",
346 | "name": "Sunny-day",
347 | "resource_uri": "/api/v1/move/241/"
348 | },
349 | {
350 | "learn_type": "machine",
351 | "name": "Hidden-power",
352 | "resource_uri": "/api/v1/move/237/"
353 | },
354 | {
355 | "learn_type": "machine",
356 | "name": "Iron-tail",
357 | "resource_uri": "/api/v1/move/231/"
358 | },
359 | {
360 | "learn_type": "machine",
361 | "name": "Dragonbreath",
362 | "resource_uri": "/api/v1/move/225/"
363 | },
364 | {
365 | "learn_type": "machine",
366 | "name": "Dynamicpunch",
367 | "resource_uri": "/api/v1/move/223/"
368 | },
369 | {
370 | "learn_type": "machine",
371 | "name": "Frustration",
372 | "resource_uri": "/api/v1/move/218/"
373 | },
374 | {
375 | "learn_type": "machine",
376 | "name": "Return",
377 | "resource_uri": "/api/v1/move/216/"
378 | },
379 | {
380 | "learn_type": "machine",
381 | "name": "Sleep-talk",
382 | "resource_uri": "/api/v1/move/214/"
383 | },
384 | {
385 | "learn_type": "machine",
386 | "name": "Attract",
387 | "resource_uri": "/api/v1/move/213/"
388 | },
389 | {
390 | "learn_type": "machine",
391 | "name": "Steel-wing",
392 | "resource_uri": "/api/v1/move/211/"
393 | },
394 | {
395 | "learn_type": "machine",
396 | "name": "Fury-cutter",
397 | "resource_uri": "/api/v1/move/210/"
398 | },
399 | {
400 | "learn_type": "machine",
401 | "name": "Swagger",
402 | "resource_uri": "/api/v1/move/207/"
403 | },
404 | {
405 | "learn_type": "machine",
406 | "name": "Endure",
407 | "resource_uri": "/api/v1/move/203/"
408 | },
409 | {
410 | "learn_type": "machine",
411 | "name": "Sandstorm",
412 | "resource_uri": "/api/v1/move/201/"
413 | },
414 | {
415 | "learn_type": "machine",
416 | "name": "Mud-slap",
417 | "resource_uri": "/api/v1/move/189/"
418 | },
419 | {
420 | "learn_type": "level up",
421 | "level": 27,
422 | "name": "Scary-face",
423 | "resource_uri": "/api/v1/move/184/"
424 | },
425 | {
426 | "learn_type": "machine",
427 | "name": "Protect",
428 | "resource_uri": "/api/v1/move/182/"
429 | },
430 | {
431 | "learn_type": "machine",
432 | "name": "Curse",
433 | "resource_uri": "/api/v1/move/174/"
434 | },
435 | {
436 | "learn_type": "machine",
437 | "name": "Snore",
438 | "resource_uri": "/api/v1/move/173/"
439 | },
440 | {
441 | "learn_type": "machine",
442 | "name": "Defense-curl",
443 | "resource_uri": "/api/v1/move/111/"
444 | },
445 | {
446 | "learn_type": "level up",
447 | "level": 1,
448 | "name": "Smokescreen",
449 | "resource_uri": "/api/v1/move/108/"
450 | },
451 | {
452 | "learn_type": "machine",
453 | "name": "Roar",
454 | "resource_uri": "/api/v1/move/46/"
455 | },
456 | {
457 | "learn_type": "machine",
458 | "name": "Headbutt",
459 | "resource_uri": "/api/v1/move/29/"
460 | },
461 | {
462 | "learn_type": "level up",
463 | "level": 36,
464 | "name": "Wing-attack",
465 | "resource_uri": "/api/v1/move/17/"
466 | },
467 | {
468 | "learn_type": "machine",
469 | "name": "Fire-punch",
470 | "resource_uri": "/api/v1/move/7/"
471 | },
472 | {
473 | "learn_type": "machine",
474 | "name": "Fly",
475 | "resource_uri": "/api/v1/move/19/"
476 | },
477 | {
478 | "learn_type": "machine",
479 | "name": "Substitute",
480 | "resource_uri": "/api/v1/move/164/"
481 | },
482 | {
483 | "learn_type": "level up",
484 | "level": 36,
485 | "name": "Slash",
486 | "resource_uri": "/api/v1/move/163/"
487 | },
488 | {
489 | "learn_type": "machine",
490 | "name": "Rest",
491 | "resource_uri": "/api/v1/move/156/"
492 | },
493 | {
494 | "learn_type": "machine",
495 | "name": "Skull-bash",
496 | "resource_uri": "/api/v1/move/130/"
497 | },
498 | {
499 | "learn_type": "machine",
500 | "name": "Swift",
501 | "resource_uri": "/api/v1/move/129/"
502 | },
503 | {
504 | "learn_type": "machine",
505 | "name": "Fire-blast",
506 | "resource_uri": "/api/v1/move/126/"
507 | },
508 | {
509 | "learn_type": "machine",
510 | "name": "Bide",
511 | "resource_uri": "/api/v1/move/117/"
512 | },
513 | {
514 | "learn_type": "machine",
515 | "name": "Reflect",
516 | "resource_uri": "/api/v1/move/115/"
517 | },
518 | {
519 | "learn_type": "machine",
520 | "name": "Double-team",
521 | "resource_uri": "/api/v1/move/104/"
522 | },
523 | {
524 | "learn_type": "machine",
525 | "name": "Mimic",
526 | "resource_uri": "/api/v1/move/102/"
527 | },
528 | {
529 | "learn_type": "level up",
530 | "level": 24,
531 | "name": "Rage",
532 | "resource_uri": "/api/v1/move/99/"
533 | },
534 | {
535 | "learn_type": "machine",
536 | "name": "Toxic",
537 | "resource_uri": "/api/v1/move/92/"
538 | },
539 | {
540 | "learn_type": "machine",
541 | "name": "Dig",
542 | "resource_uri": "/api/v1/move/91/"
543 | },
544 | {
545 | "learn_type": "machine",
546 | "name": "Fissure",
547 | "resource_uri": "/api/v1/move/90/"
548 | },
549 | {
550 | "learn_type": "machine",
551 | "name": "Earthquake",
552 | "resource_uri": "/api/v1/move/89/"
553 | },
554 | {
555 | "learn_type": "level up",
556 | "level": 55,
557 | "name": "Fire-spin",
558 | "resource_uri": "/api/v1/move/83/"
559 | },
560 | {
561 | "learn_type": "machine",
562 | "name": "Dragon-rage",
563 | "resource_uri": "/api/v1/move/82/"
564 | },
565 | {
566 | "learn_type": "machine",
567 | "name": "Strength",
568 | "resource_uri": "/api/v1/move/70/"
569 | },
570 | {
571 | "learn_type": "machine",
572 | "name": "Seismic-toss",
573 | "resource_uri": "/api/v1/move/69/"
574 | },
575 | {
576 | "learn_type": "machine",
577 | "name": "Counter",
578 | "resource_uri": "/api/v1/move/68/"
579 | },
580 | {
581 | "learn_type": "machine",
582 | "name": "Submission",
583 | "resource_uri": "/api/v1/move/66/"
584 | },
585 | {
586 | "learn_type": "machine",
587 | "name": "Hyper-beam",
588 | "resource_uri": "/api/v1/move/63/"
589 | },
590 | {
591 | "learn_type": "level up",
592 | "level": 46,
593 | "name": "Flamethrower",
594 | "resource_uri": "/api/v1/move/53/"
595 | },
596 | {
597 | "learn_type": "level up",
598 | "level": 1,
599 | "name": "Ember",
600 | "resource_uri": "/api/v1/move/52/"
601 | },
602 | {
603 | "learn_type": "level up",
604 | "level": 1,
605 | "name": "Growl",
606 | "resource_uri": "/api/v1/move/45/"
607 | },
608 | {
609 | "learn_type": "level up",
610 | "level": 1,
611 | "name": "Leer",
612 | "resource_uri": "/api/v1/move/43/"
613 | },
614 | {
615 | "learn_type": "machine",
616 | "name": "Double-edge",
617 | "resource_uri": "/api/v1/move/38/"
618 | },
619 | {
620 | "learn_type": "machine",
621 | "name": "Take-down",
622 | "resource_uri": "/api/v1/move/36/"
623 | },
624 | {
625 | "learn_type": "machine",
626 | "name": "Body-slam",
627 | "resource_uri": "/api/v1/move/34/"
628 | },
629 | {
630 | "learn_type": "machine",
631 | "name": "Mega-kick",
632 | "resource_uri": "/api/v1/move/25/"
633 | },
634 | {
635 | "learn_type": "machine",
636 | "name": "Cut",
637 | "resource_uri": "/api/v1/move/15/"
638 | },
639 | {
640 | "learn_type": "machine",
641 | "name": "Swords-dance",
642 | "resource_uri": "/api/v1/move/14/"
643 | },
644 | {
645 | "learn_type": "level up",
646 | "level": 1,
647 | "name": "Scratch",
648 | "resource_uri": "/api/v1/move/10/"
649 | },
650 | {
651 | "learn_type": "machine",
652 | "name": "Mega-punch",
653 | "resource_uri": "/api/v1/move/5/"
654 | }
655 | ],
656 | "name": "Charizard",
657 | "national_id": 6,
658 | "pkdx_id": 6,
659 | "resource_uri": "/api/v1/pokemon/6/",
660 | "sp_atk": 109,
661 | "sp_def": 85,
662 | "species": "",
663 | "speed": 100,
664 | "sprites": [
665 | {
666 | "name": "charizard",
667 | "resource_uri": "/api/v1/sprite/7/"
668 | }
669 | ],
670 | "total": 0,
671 | "types": [
672 | {
673 | "name": "flying",
674 | "resource_uri": "/api/v1/type/3/"
675 | },
676 | {
677 | "name": "fire",
678 | "resource_uri": "/api/v1/type/10/"
679 | }
680 | ],
681 | "weight": "905"
682 | }
--------------------------------------------------------------------------------
/app/src/test/resources/robolectric.properties:
--------------------------------------------------------------------------------
1 | sdk=21
2 | robolectric.logging.enable=true
3 | constants=co.infinum.pokemon.BuildConfig
4 | application=co.infinum.pokemon.PokemonTestApp
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 | dependencies {
6 | classpath 'com.android.tools.build:gradle:2.1.0'
7 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infinum/Dagger-2-Example/bc147fee74992ab202958a20caee9a63d7fe104d/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun May 15 21:01:09 CEST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------