Sfoglia il codice sorgente

Button unmount (#3856)

Unmount buttons when corresponding screen is unmounted

Currently buttons were unmounted each time a screen was pushed to the stack.
As we're clearing props when screens are unmounted from the prop store - when a screen
was popped to - its buttons's props were undefined.

This commit changes things so that buttons are unmounted when buttons are set
using mergeOptions and when the corresponding screen is unmounted.
Guy Carmeli 6 anni fa
parent
commit
68373759c0
No account linked to committer's email address
32 ha cambiato i file con 504 aggiunte e 317 eliminazioni
  1. 1
    1
      e2e/ScreenStyle.test.js
  2. 1
    1
      e2e/init.js
  3. 1
    1
      lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutFactory.java
  4. 4
    0
      lib/android/app/src/main/java/com/reactnativenavigation/parse/params/Button.java
  5. 122
    28
      lib/android/app/src/main/java/com/reactnativenavigation/presentation/StackOptionsPresenter.java
  6. 45
    7
      lib/android/app/src/main/java/com/reactnativenavigation/utils/CollectionUtils.java
  7. 9
    0
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ChildController.java
  8. 0
    6
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ComponentViewController.java
  9. 20
    10
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TitleBarButtonController.java
  10. 1
    2
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java
  11. 4
    7
      lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/topbar/TopBarController.java
  12. 2
    2
      lib/android/app/src/main/java/com/reactnativenavigation/views/ComponentLayout.java
  13. 4
    9
      lib/android/app/src/main/java/com/reactnativenavigation/views/StackLayout.java
  14. 3
    4
      lib/android/app/src/main/java/com/reactnativenavigation/views/element/ElementTransitionManager.java
  15. 10
    43
      lib/android/app/src/main/java/com/reactnativenavigation/views/titlebar/TitleBar.java
  16. 11
    17
      lib/android/app/src/main/java/com/reactnativenavigation/views/topbar/TopBar.java
  17. 2
    2
      lib/android/app/src/main/java/com/reactnativenavigation/views/toptabs/TopTabsViewPager.java
  18. 3
    5
      lib/android/app/src/test/java/com/reactnativenavigation/TestUtils.java
  19. 2
    2
      lib/android/app/src/test/java/com/reactnativenavigation/mocks/TestComponentLayout.java
  20. 45
    0
      lib/android/app/src/test/java/com/reactnativenavigation/utils/TitleBarHelper.java
  21. 2
    1
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java
  22. 3
    4
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/OptionsApplyingTest.java
  23. 160
    18
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackOptionsPresenterTest.java
  24. 11
    48
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TitleBarTest.java
  25. 2
    2
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopBarButtonControllerTest.java
  26. 5
    7
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopBarControllerTest.java
  27. 8
    13
      lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.java
  28. 2
    12
      lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarBackgroundComponentTest.java
  29. 2
    45
      lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarTest.java
  30. 5
    6
      lib/android/app/src/test/java/com/reactnativenavigation/views/element/TransitionAnimatorCreatorTest.java
  31. 13
    13
      lib/android/app/src/test/java/com/reactnativenavigation/views/element/TransitionValidatorTest.java
  32. 1
    1
      scripts/test-e2e.js

+ 1
- 1
e2e/ScreenStyle.test.js Vedi File

115
     await expect(elementByLabel(`Two`)).toExist();
115
     await expect(elementByLabel(`Two`)).toExist();
116
   });
116
   });
117
 
117
 
118
-  test(':ios: pass props to custom button component should exist after screen rerender', async () => {
118
+  test('pass props to custom button component should exist after push pop', async () => {
119
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
119
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
120
     await expect(elementByLabel(`Two`)).toExist();
120
     await expect(elementByLabel(`Two`)).toExist();
121
     await elementById(testIDs.SCROLLVIEW_SCREEN_BUTTON).tap();
121
     await elementById(testIDs.SCROLLVIEW_SCREEN_BUTTON).tap();

+ 1
- 1
e2e/init.js Vedi File

3
 const exec = require('shell-utils').exec;
3
 const exec = require('shell-utils').exec;
4
 const adapter = require('detox/runners/jest/adapter');
4
 const adapter = require('detox/runners/jest/adapter');
5
 
5
 
6
-jest.setTimeout(300000);
6
+jest.setTimeout(1000 * 60);
7
 jasmine.getEnv().addReporter(adapter); // don't forget this line
7
 jasmine.getEnv().addReporter(adapter); // don't forget this line
8
 
8
 
9
 beforeAll(async () => {
9
 beforeAll(async () => {

+ 1
- 1
lib/android/app/src/main/java/com/reactnativenavigation/parse/LayoutFactory.java Vedi File

166
                 .setTopBarController(new TopBarController())
166
                 .setTopBarController(new TopBarController())
167
                 .setId(node.id)
167
                 .setId(node.id)
168
                 .setInitialOptions(parse(typefaceManager, node.getOptions()))
168
                 .setInitialOptions(parse(typefaceManager, node.getOptions()))
169
-                .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreator(reactInstanceManager), defaultOptions))
169
+                .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreator(reactInstanceManager), new TitleBarButtonCreator(reactInstanceManager), new ImageLoader(), defaultOptions))
170
                 .setPresenter(new OptionsPresenter(activity, defaultOptions))
170
                 .setPresenter(new OptionsPresenter(activity, defaultOptions))
171
                 .build();
171
                 .build();
172
 	}
172
 	}

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/params/Button.java Vedi File

9
 import com.reactnativenavigation.parse.parsers.ColorParser;
9
 import com.reactnativenavigation.parse.parsers.ColorParser;
10
 import com.reactnativenavigation.parse.parsers.NumberParser;
10
 import com.reactnativenavigation.parse.parsers.NumberParser;
11
 import com.reactnativenavigation.parse.parsers.TextParser;
11
 import com.reactnativenavigation.parse.parsers.TextParser;
12
+import com.reactnativenavigation.utils.CompatUtils;
12
 import com.reactnativenavigation.utils.TypefaceLoader;
13
 import com.reactnativenavigation.utils.TypefaceLoader;
13
 
14
 
14
 import org.json.JSONArray;
15
 import org.json.JSONArray;
17
 import java.util.ArrayList;
18
 import java.util.ArrayList;
18
 
19
 
19
 public class Button {
20
 public class Button {
21
+    public String instanceId = "btn" + CompatUtils.generateViewId();
22
+
20
     @Nullable public String id;
23
     @Nullable public String id;
21
     public Text text = new NullText();
24
     public Text text = new NullText();
22
     public Bool enabled = new NullBool();
25
     public Bool enabled = new NullBool();
125
         if (other.showAsAction.hasValue()) showAsAction = other.showAsAction;
128
         if (other.showAsAction.hasValue()) showAsAction = other.showAsAction;
126
         if (other.icon.hasValue()) icon = other.icon;
129
         if (other.icon.hasValue()) icon = other.icon;
127
         if (other.id != null) id = other.id;
130
         if (other.id != null) id = other.id;
131
+        if (other.instanceId != null) instanceId = other.instanceId;
128
     }
132
     }
129
 
133
 
130
     public void mergeWithDefault(Button defaultOptions) {
134
     public void mergeWithDefault(Button defaultOptions) {

+ 122
- 28
lib/android/app/src/main/java/com/reactnativenavigation/presentation/StackOptionsPresenter.java Vedi File

19
 import com.reactnativenavigation.parse.TopTabsOptions;
19
 import com.reactnativenavigation.parse.TopTabsOptions;
20
 import com.reactnativenavigation.parse.params.Button;
20
 import com.reactnativenavigation.parse.params.Button;
21
 import com.reactnativenavigation.parse.params.Colour;
21
 import com.reactnativenavigation.parse.params.Colour;
22
+import com.reactnativenavigation.utils.ButtonOptionsPresenter;
23
+import com.reactnativenavigation.utils.ImageLoader;
22
 import com.reactnativenavigation.utils.UiUtils;
24
 import com.reactnativenavigation.utils.UiUtils;
23
 import com.reactnativenavigation.viewcontrollers.IReactView;
25
 import com.reactnativenavigation.viewcontrollers.IReactView;
26
+import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
27
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
24
 import com.reactnativenavigation.viewcontrollers.TitleBarReactViewController;
28
 import com.reactnativenavigation.viewcontrollers.TitleBarReactViewController;
29
+import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
25
 import com.reactnativenavigation.views.Component;
30
 import com.reactnativenavigation.views.Component;
26
 import com.reactnativenavigation.views.titlebar.TitleBarReactViewCreator;
31
 import com.reactnativenavigation.views.titlebar.TitleBarReactViewCreator;
27
 import com.reactnativenavigation.views.topbar.TopBar;
32
 import com.reactnativenavigation.views.topbar.TopBar;
28
 
33
 
29
 import java.util.ArrayList;
34
 import java.util.ArrayList;
35
+import java.util.Collections;
30
 import java.util.HashMap;
36
 import java.util.HashMap;
31
 import java.util.List;
37
 import java.util.List;
32
 import java.util.Map;
38
 import java.util.Map;
33
 
39
 
40
+import static com.reactnativenavigation.utils.CollectionUtils.forEach;
41
+import static com.reactnativenavigation.utils.CollectionUtils.keyBy;
42
+import static com.reactnativenavigation.utils.CollectionUtils.merge;
43
+
34
 public class StackOptionsPresenter {
44
 public class StackOptionsPresenter {
35
     private static final int DEFAULT_TITLE_COLOR = Color.BLACK;
45
     private static final int DEFAULT_TITLE_COLOR = Color.BLACK;
36
     private static final int DEFAULT_SUBTITLE_COLOR = Color.GRAY;
46
     private static final int DEFAULT_SUBTITLE_COLOR = Color.GRAY;
41
     private final Activity activity;
51
     private final Activity activity;
42
 
52
 
43
     private TopBar topBar;
53
     private TopBar topBar;
44
-    private TitleBarReactViewCreator titleViewCreator;
54
+    private final TitleBarReactViewCreator titleViewCreator;
55
+    private TitleBarButtonController.OnClickListener onClickListener;
56
+    private final ImageLoader imageLoader;
57
+    private final ReactViewCreator buttonCreator;
45
     private Options defaultOptions;
58
     private Options defaultOptions;
46
     private Map<Component, TitleBarReactViewController> titleComponentViewControllers = new HashMap<>();
59
     private Map<Component, TitleBarReactViewController> titleComponentViewControllers = new HashMap<>();
60
+    private Map<Component, Map<String, TitleBarButtonController>> componentRightButtons = new HashMap<>();
61
+    private Map<Component, Map<String, TitleBarButtonController>> componentLeftButtons = new HashMap<>();
47
 
62
 
48
-    public StackOptionsPresenter(Activity activity, TitleBarReactViewCreator titleViewCreator, Options defaultOptions) {
63
+    public StackOptionsPresenter(Activity activity, TitleBarReactViewCreator titleViewCreator, ReactViewCreator buttonCreator, ImageLoader imageLoader, Options defaultOptions) {
49
         this.activity = activity;
64
         this.activity = activity;
50
         this.titleViewCreator = titleViewCreator;
65
         this.titleViewCreator = titleViewCreator;
66
+        this.buttonCreator = buttonCreator;
67
+        this.imageLoader = imageLoader;
51
         this.defaultOptions = defaultOptions;
68
         this.defaultOptions = defaultOptions;
52
         defaultTitleFontSize = UiUtils.dpToSp(activity, 18);
69
         defaultTitleFontSize = UiUtils.dpToSp(activity, 18);
53
         defaultSubtitleFontSize = UiUtils.dpToSp(activity, 14);
70
         defaultSubtitleFontSize = UiUtils.dpToSp(activity, 14);
57
         this.defaultOptions = defaultOptions;
74
         this.defaultOptions = defaultOptions;
58
     }
75
     }
59
 
76
 
77
+    public void setButtonOnClickListener(TitleBarButtonController.OnClickListener onClickListener) {
78
+        this.onClickListener = onClickListener;
79
+    }
80
+
60
     public Options getDefaultOptions() {
81
     public Options getDefaultOptions() {
61
         return defaultOptions;
82
         return defaultOptions;
62
     }
83
     }
63
 
84
 
85
+    public List<TitleBarButtonController> getComponentButtons(Component child) {
86
+        return merge(getRightButtons(child), getLeftButtons(child), Collections.EMPTY_LIST);
87
+    }
88
+
89
+    public List<TitleBarButtonController> getComponentButtons(Component child, List<TitleBarButtonController> defaultValue) {
90
+        return merge(getRightButtons(child), getLeftButtons(child), defaultValue);
91
+    }
92
+
93
+    private List<TitleBarButtonController> getRightButtons(Component child) {
94
+        return componentRightButtons.containsKey(child) ? new ArrayList<>(componentRightButtons.get(child).values()) : null;
95
+    }
96
+
97
+    private List<TitleBarButtonController> getLeftButtons(Component child) {
98
+        return componentLeftButtons.containsKey(child) ? new ArrayList<>(componentLeftButtons.get(child).values()) : null;
99
+    }
100
+
64
     public void bindView(TopBar topBar) {
101
     public void bindView(TopBar topBar) {
65
         this.topBar = topBar;
102
         this.topBar = topBar;
66
     }
103
     }
80
     public void applyChildOptions(Options options, Component child) {
117
     public void applyChildOptions(Options options, Component child) {
81
         Options withDefault = options.copy().withDefaultOptions(defaultOptions);
118
         Options withDefault = options.copy().withDefaultOptions(defaultOptions);
82
         applyOrientation(withDefault.layout.orientation);
119
         applyOrientation(withDefault.layout.orientation);
83
-        applyButtons(withDefault.topBar, withDefault.topBar.rightButtonColor, withDefault.topBar.leftButtonColor, withDefault.topBar.rightButtonDisabledColor, withDefault.topBar.leftButtonDisabledColor);
120
+        applyButtons(withDefault.topBar, child);
84
         applyTopBarOptions(withDefault.topBar, withDefault.animations, child, options);
121
         applyTopBarOptions(withDefault.topBar, withDefault.animations, child, options);
85
         applyTopTabsOptions(withDefault.topTabs);
122
         applyTopTabsOptions(withDefault.topTabs);
86
         applyTopTabOptions(withDefault.topTabOptions);
123
         applyTopTabOptions(withDefault.topTabOptions);
96
         if (removed != null) {
133
         if (removed != null) {
97
             removed.destroy();
134
             removed.destroy();
98
         }
135
         }
136
+        destroyButtons(componentRightButtons.get(child));
137
+        destroyButtons(componentLeftButtons.get(child));
138
+        componentRightButtons.remove(child);
139
+        componentLeftButtons.remove(child);
140
+    }
141
+
142
+    private void destroyButtons(Map<String, TitleBarButtonController> buttons) {
143
+        if (buttons != null) {
144
+            for (TitleBarButtonController button : buttons.values()) {
145
+                button.destroy();
146
+            }
147
+        }
99
     }
148
     }
100
 
149
 
101
     private void applyTopBarOptions(TopBarOptions options, AnimationsOptions animationOptions, Component component, Options componentOptions) {
150
     private void applyTopBarOptions(TopBarOptions options, AnimationsOptions animationOptions, Component component, Options componentOptions) {
166
         }
215
         }
167
     }
216
     }
168
 
217
 
169
-    private void applyButtons(TopBarOptions options, Colour rightButtonColor, Colour leftButtonColor, Colour rightButtonDisabledColor, Colour leftButtonDisabledColor) {
170
-        List<Button> rightButtons = mergeButtonsWithColor(options.buttons.right, rightButtonColor, rightButtonDisabledColor);
171
-        List<Button> leftButtons = mergeButtonsWithColor(options.buttons.left, leftButtonColor, leftButtonDisabledColor);
172
-        topBar.setRightButtons(rightButtons);
173
-        topBar.setLeftButtons(leftButtons);
174
-        if (options.buttons.back.visible.isTrue() && !options.buttons.hasLeftButtons()) topBar.setBackButton(options.buttons.back);
218
+    private void applyButtons(TopBarOptions options, Component child) {
219
+        List<Button> rightButtons = mergeButtonsWithColor(options.buttons.right, options.rightButtonColor, options.rightButtonDisabledColor);
220
+        List<Button> leftButtons = mergeButtonsWithColor(options.buttons.left, options.leftButtonColor, options.leftButtonDisabledColor);
221
+
222
+        if (rightButtons != null) {
223
+            List<TitleBarButtonController> rightButtonControllers = getOrCreateButtonControllers(componentRightButtons.get(child), rightButtons);
224
+            componentRightButtons.put(child, keyBy(rightButtonControllers, TitleBarButtonController::getButtonInstanceId));
225
+            topBar.setRightButtons(rightButtonControllers);
226
+        } else {
227
+            topBar.setRightButtons(null);
228
+        }
229
+
230
+        if (leftButtons != null) {
231
+            List<TitleBarButtonController> leftButtonControllers = getOrCreateButtonControllers(componentLeftButtons.get(child), leftButtons);
232
+            componentLeftButtons.put(child, keyBy(leftButtonControllers, TitleBarButtonController::getButtonInstanceId));
233
+            topBar.setLeftButtons(leftButtonControllers);
234
+        } else {
235
+            topBar.setLeftButtons(null);
236
+        }
237
+
238
+        if (options.buttons.back.visible.isTrue() && !options.buttons.hasLeftButtons()) {
239
+            topBar.setBackButton(createButtonController(options.buttons.back));
240
+        }
241
+    }
242
+
243
+    private List<TitleBarButtonController> getOrCreateButtonControllers(@Nullable Map<String, TitleBarButtonController> currentButtons, @Nullable List<Button> buttons) {
244
+        if (buttons == null) return null;
245
+        Map<String, TitleBarButtonController> result = new HashMap<>();
246
+        for (Button b : buttons) {
247
+            result.put(b.instanceId, currentButtons != null && currentButtons.containsKey(b.instanceId) ? currentButtons.get(b.instanceId) : createButtonController(b));
248
+        }
249
+        return new ArrayList<>(result.values());
250
+    }
251
+
252
+    private TitleBarButtonController createButtonController(Button button) {
253
+        return new TitleBarButtonController(activity,
254
+                new NavigationIconResolver(activity, imageLoader),
255
+                imageLoader,
256
+                new ButtonOptionsPresenter(topBar.getTitleBar(), button),
257
+                button,
258
+                buttonCreator,
259
+                onClickListener
260
+        );
175
     }
261
     }
176
 
262
 
177
     private void applyTopTabsOptions(TopTabsOptions options) {
263
     private void applyTopTabsOptions(TopTabsOptions options) {
195
         }
281
         }
196
     }
282
     }
197
 
283
 
198
-    public void mergeChildOptions(Options options, Options childOptions, Component child) {
199
-        TopBarOptions topBar = options.copy().mergeWith(childOptions).withDefaultOptions(defaultOptions).topBar;
200
-        mergeOrientation(options.layout.orientation);
201
-        mergeButtons(options.topBar.buttons,
202
-                topBar.rightButtonColor,
203
-                topBar.leftButtonColor,
204
-                topBar.rightButtonDisabledColor,
205
-                topBar.leftButtonDisabledColor
206
-        );
207
-        mergeTopBarOptions(options.topBar, options.animations, child);
208
-        mergeTopTabsOptions(options.topTabs);
209
-        mergeTopTabOptions(options.topTabOptions);
284
+    public void mergeChildOptions(Options toMerge, Options resolvedOptions, Component child) {
285
+        TopBarOptions topBar = toMerge.copy().mergeWith(resolvedOptions).withDefaultOptions(defaultOptions).topBar;
286
+        mergeOrientation(toMerge.layout.orientation);
287
+        mergeButtons(topBar, toMerge.topBar.buttons, child);
288
+        mergeTopBarOptions(toMerge.topBar, toMerge.animations, child);
289
+        mergeTopTabsOptions(toMerge.topTabs);
290
+        mergeTopTabOptions(toMerge.topTabOptions);
210
     }
291
     }
211
 
292
 
212
     private void mergeOrientation(OrientationOptions orientationOptions) {
293
     private void mergeOrientation(OrientationOptions orientationOptions) {
213
         if (orientationOptions.hasValue()) applyOrientation(orientationOptions);
294
         if (orientationOptions.hasValue()) applyOrientation(orientationOptions);
214
     }
295
     }
215
 
296
 
216
-    private void mergeButtons(TopBarButtons buttons, Colour rightButtonColor, Colour leftButtonColor, Colour rightButtonDisabledColor, Colour leftButtonDisabledColor) {
217
-        List<Button> rightButtons = mergeButtonsWithColor(buttons.right, rightButtonColor, rightButtonDisabledColor);
218
-        List<Button> leftButtons = mergeButtonsWithColor(buttons.left, leftButtonColor, leftButtonDisabledColor);
219
-        if (buttons.right != null) topBar.setRightButtons(rightButtons);
220
-        if (buttons.left != null) topBar.setLeftButtons(leftButtons);
221
-        if (buttons.back.hasValue()) topBar.setBackButton(buttons.back);
297
+    private void mergeButtons(TopBarOptions options, TopBarButtons buttons, Component child) {
298
+        List<Button> rightButtons = mergeButtonsWithColor(buttons.right, options.rightButtonColor, options.rightButtonDisabledColor);
299
+        List<Button> leftButtons = mergeButtonsWithColor(buttons.left, options.leftButtonColor, options.leftButtonDisabledColor);
300
+
301
+        List<TitleBarButtonController> rightButtonControllers = getOrCreateButtonControllers(componentRightButtons.get(child), rightButtons);
302
+        List<TitleBarButtonController> leftButtonControllers = getOrCreateButtonControllers(componentLeftButtons.get(child), leftButtons);
303
+
304
+        if (rightButtonControllers != null) {
305
+            Map previousRightButtons = componentRightButtons.put(child, keyBy(rightButtonControllers, TitleBarButtonController::getButtonInstanceId));
306
+            if (previousRightButtons != null) forEach(previousRightButtons.values(), TitleBarButtonController::destroy);
307
+        }
308
+        if (leftButtonControllers != null) {
309
+            Map previousLeftButtons = componentLeftButtons.put(child, keyBy(leftButtonControllers, TitleBarButtonController::getButtonInstanceId));
310
+            if (previousLeftButtons != null) forEach(previousLeftButtons.values(), TitleBarButtonController::destroy);
311
+        }
312
+
313
+        if (buttons.right != null) topBar.setRightButtons(rightButtonControllers);
314
+        if (buttons.left != null) topBar.setLeftButtons(leftButtonControllers);
315
+        if (buttons.back.hasValue()) topBar.setBackButton(createButtonController(buttons.back));
222
     }
316
     }
223
 
317
 
224
     @Nullable
318
     @Nullable
308
     }
402
     }
309
 
403
 
310
     private LayoutParams getComponentLayoutParams(com.reactnativenavigation.parse.Component component) {
404
     private LayoutParams getComponentLayoutParams(com.reactnativenavigation.parse.Component component) {
311
-        return new Toolbar.LayoutParams(component.alignment == Alignment.Center ? Gravity.CENTER : Gravity.START);
405
+        return new Toolbar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, component.alignment == Alignment.Center ? Gravity.CENTER : Gravity.START);
312
     }
406
     }
313
 
407
 
314
     @RestrictTo(RestrictTo.Scope.TESTS)
408
     @RestrictTo(RestrictTo.Scope.TESTS)

+ 45
- 7
lib/android/app/src/main/java/com/reactnativenavigation/utils/CollectionUtils.java Vedi File

1
 package com.reactnativenavigation.utils;
1
 package com.reactnativenavigation.utils;
2
 
2
 
3
+import android.support.annotation.NonNull;
4
+import android.support.annotation.Nullable;
5
+
3
 import java.util.ArrayList;
6
 import java.util.ArrayList;
4
 import java.util.Collection;
7
 import java.util.Collection;
8
+import java.util.Collections;
5
 import java.util.HashMap;
9
 import java.util.HashMap;
6
 import java.util.List;
10
 import java.util.List;
7
 import java.util.Map;
11
 import java.util.Map;
8
 
12
 
9
 public class CollectionUtils {
13
 public class CollectionUtils {
14
+    public interface Apply<T> {
15
+        void on(T t);
16
+    }
17
+
10
     public static boolean isNullOrEmpty(Collection collection) {
18
     public static boolean isNullOrEmpty(Collection collection) {
11
         return collection == null || collection.isEmpty();
19
         return collection == null || collection.isEmpty();
12
     }
20
     }
13
 
21
 
14
-    public interface Mapper<K, V> {
15
-        K map(V value);
22
+    public interface KeyBy<K, V> {
23
+        K by(V value);
16
     }
24
     }
17
 
25
 
18
-    public static <K, V> Map<K, V> map(Collection<V> elements, Mapper<K, V> mapper) {
26
+    public static <K, V> Map<K, V> keyBy(Collection<V> elements, KeyBy<K, V> key) {
19
         Map<K, V> map = new HashMap<>();
27
         Map<K, V> map = new HashMap<>();
20
         for (V value : elements) {
28
         for (V value : elements) {
21
-            map.put(mapper.map(value), value);
29
+            map.put(key.by(value), value);
22
         }
30
         }
23
         return map;
31
         return map;
24
     }
32
     }
25
 
33
 
34
+    public interface Mapper<T, S> {
35
+        S map(T value);
36
+    }
37
+
38
+    public static @Nullable <T, S> List<S> map(@Nullable Collection<T> items, Mapper<T, S> map) {
39
+        if (items == null) return null;
40
+        List<S> result = new ArrayList<>();
41
+        for (T item : items) {
42
+            result.add(map.map(item));
43
+        }
44
+        return result;
45
+    }
46
+
26
     public interface Filter<T> {
47
     public interface Filter<T> {
27
         boolean filter(T value);
48
         boolean filter(T value);
28
     }
49
     }
35
         return result;
56
         return result;
36
     }
57
     }
37
 
58
 
38
-    public static <T> List<T> merge(Collection<T> a, Collection<T> b) {
39
-        List<T> result = new ArrayList<>(a);
40
-        result.addAll(b);
59
+    public static <T> List<T> merge(@Nullable Collection<T> a, @Nullable Collection<T> b, @NonNull List<T> defaultValue) {
60
+        List<T> result = merge(a, b);
61
+        return result == null ? defaultValue : result;
62
+    }
63
+
64
+    public static <T> List<T> merge(@Nullable Collection<T> a, @Nullable Collection<T> b) {
65
+        if (a == null && b == null) return null;
66
+        List<T> result = new ArrayList<>(get(a));
67
+        result.addAll(get(b));
41
         return result;
68
         return result;
42
     }
69
     }
70
+
71
+    public static <T> void forEach(@Nullable Collection<T> items, Apply<T> apply) {
72
+        if (items == null) return;
73
+        for (T item : items) {
74
+            apply.on(item);
75
+        }
76
+    }
77
+
78
+    private static @NonNull <T> Collection<T> get(@Nullable Collection<T> t) {
79
+        return t == null ? Collections.EMPTY_LIST : t;
80
+    }
43
 }
81
 }

+ 9
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ChildController.java Vedi File

6
 
6
 
7
 import com.reactnativenavigation.parse.Options;
7
 import com.reactnativenavigation.parse.Options;
8
 import com.reactnativenavigation.presentation.OptionsPresenter;
8
 import com.reactnativenavigation.presentation.OptionsPresenter;
9
+import com.reactnativenavigation.views.Component;
9
 
10
 
10
 public abstract class ChildController<T extends ViewGroup> extends ViewController<T>  {
11
 public abstract class ChildController<T extends ViewGroup> extends ViewController<T>  {
11
     final OptionsPresenter presenter;
12
     final OptionsPresenter presenter;
52
         }
53
         }
53
     }
54
     }
54
 
55
 
56
+    @Override
57
+    public void destroy() {
58
+        if (!isDestroyed() && getView() instanceof Component) {
59
+            performOnParentController(parent -> parent.onChildDestroyed((Component) getView()));
60
+        }
61
+        super.destroy();
62
+    }
63
+
55
     protected boolean isRoot() {
64
     protected boolean isRoot() {
56
         return getParentController() == null &&
65
         return getParentController() == null &&
57
                 !(this instanceof Navigator) &&
66
                 !(this instanceof Navigator) &&

+ 0
- 6
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ComponentViewController.java Vedi File

67
         super.mergeOptions(options);
67
         super.mergeOptions(options);
68
     }
68
     }
69
 
69
 
70
-    @Override
71
-    public void destroy() {
72
-        if (!isDestroyed()) performOnParentController(parent -> parent.onChildDestroyed(getView()));
73
-        super.destroy();
74
-    }
75
-
76
     ReactComponent getComponent() {
70
     ReactComponent getComponent() {
77
         return view;
71
         return view;
78
     }
72
     }

lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TopBarButtonController.java → lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/TitleBarButtonController.java Vedi File

5
 import android.graphics.Color;
5
 import android.graphics.Color;
6
 import android.graphics.drawable.Drawable;
6
 import android.graphics.drawable.Drawable;
7
 import android.support.annotation.NonNull;
7
 import android.support.annotation.NonNull;
8
+import android.support.annotation.RestrictTo;
8
 import android.support.v7.widget.ActionMenuView;
9
 import android.support.v7.widget.ActionMenuView;
9
 import android.support.v7.widget.Toolbar;
10
 import android.support.v7.widget.Toolbar;
10
 import android.view.MenuItem;
11
 import android.view.MenuItem;
28
 import java.util.Collections;
29
 import java.util.Collections;
29
 import java.util.List;
30
 import java.util.List;
30
 
31
 
31
-public class TopBarButtonController extends ViewController<TitleBarReactButtonView> implements MenuItem.OnMenuItemClickListener {
32
+public class TitleBarButtonController extends ViewController<TitleBarReactButtonView> implements MenuItem.OnMenuItemClickListener {
32
     public interface OnClickListener {
33
     public interface OnClickListener {
33
         void onPress(String buttonId);
34
         void onPress(String buttonId);
34
     }
35
     }
38
     private ButtonOptionsPresenter optionsPresenter;
39
     private ButtonOptionsPresenter optionsPresenter;
39
     private final Button button;
40
     private final Button button;
40
     private final ReactViewCreator viewCreator;
41
     private final ReactViewCreator viewCreator;
41
-    private TopBarButtonController.OnClickListener onPressListener;
42
+    private TitleBarButtonController.OnClickListener onPressListener;
42
     private Drawable icon;
43
     private Drawable icon;
43
 
44
 
44
-    public TopBarButtonController(Activity activity,
45
-                                  NavigationIconResolver navigationIconResolver,
46
-                                  ImageLoader imageLoader,
47
-                                  ButtonOptionsPresenter optionsPresenter,
48
-                                  Button button,
49
-                                  ReactViewCreator viewCreator,
50
-                                  OnClickListener onClickListener) {
45
+    @RestrictTo(RestrictTo.Scope.TESTS)
46
+    public Button getButton() {
47
+        return button;
48
+    }
49
+
50
+    public String getButtonInstanceId() {
51
+        return button.instanceId;
52
+    }
53
+
54
+    public TitleBarButtonController(Activity activity,
55
+                                    NavigationIconResolver navigationIconResolver,
56
+                                    ImageLoader imageLoader,
57
+                                    ButtonOptionsPresenter optionsPresenter,
58
+                                    Button button,
59
+                                    ReactViewCreator viewCreator,
60
+                                    OnClickListener onClickListener) {
51
         super(activity, button.id, new Options());
61
         super(activity, button.id, new Options());
52
         this.navigationIconResolver = navigationIconResolver;
62
         this.navigationIconResolver = navigationIconResolver;
53
         this.imageLoader = imageLoader;
63
         this.imageLoader = imageLoader;
124
                     @Override
134
                     @Override
125
                     public void onComplete(@NonNull List<Drawable> icons) {
135
                     public void onComplete(@NonNull List<Drawable> icons) {
126
                         Drawable icon = icons.get(0);
136
                         Drawable icon = icons.get(0);
127
-                        TopBarButtonController.this.icon = icon;
137
+                        TitleBarButtonController.this.icon = icon;
128
                         setIconColor(icon);
138
                         setIconColor(icon);
129
                         menuItem.setIcon(icon);
139
                         menuItem.setIcon(icon);
130
                     }
140
                     }

+ 1
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java Vedi File

52
         this.animator = animator;
52
         this.animator = animator;
53
         this.backButtonHelper = backButtonHelper;
53
         this.backButtonHelper = backButtonHelper;
54
         this.presenter = stackPresenter;
54
         this.presenter = stackPresenter;
55
+        stackPresenter.setButtonOnClickListener(this::onNavigationButtonPressed);
55
         for (ViewController child : children) {
56
         for (ViewController child : children) {
56
             stack.push(child.getId(), child);
57
             stack.push(child.getId(), child);
57
             child.setParentController(this);
58
             child.setParentController(this);
298
     @Override
299
     @Override
299
     protected StackLayout createView() {
300
     protected StackLayout createView() {
300
         StackLayout stackLayout = new StackLayout(getActivity(),
301
         StackLayout stackLayout = new StackLayout(getActivity(),
301
-                topBarButtonCreator,
302
                 topBarBackgroundViewController,
302
                 topBarBackgroundViewController,
303
                 topBarController,
303
                 topBarController,
304
-                this::onNavigationButtonPressed,
305
                 getId()
304
                 getId()
306
         );
305
         );
307
         presenter.bindView(topBarController.getView());
306
         presenter.bindView(topBarController.getView());

+ 4
- 7
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/topbar/TopBarController.java Vedi File

5
 import android.view.View;
5
 import android.view.View;
6
 
6
 
7
 import com.reactnativenavigation.utils.CompatUtils;
7
 import com.reactnativenavigation.utils.CompatUtils;
8
-import com.reactnativenavigation.utils.ImageLoader;
9
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
10
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
11
 import com.reactnativenavigation.views.StackLayout;
8
 import com.reactnativenavigation.views.StackLayout;
12
 import com.reactnativenavigation.views.topbar.TopBar;
9
 import com.reactnativenavigation.views.topbar.TopBar;
13
 
10
 
15
 public class TopBarController {
12
 public class TopBarController {
16
     private TopBar topBar;
13
     private TopBar topBar;
17
 
14
 
18
-    public View createView(Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener topBarButtonClickListener, StackLayout stackLayout) {
15
+    public View createView(Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout stackLayout) {
19
         if (topBar == null) {
16
         if (topBar == null) {
20
-            topBar = createTopBar(context, buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, stackLayout, new ImageLoader());
17
+            topBar = createTopBar(context, topBarBackgroundViewController, stackLayout);
21
             topBar.setId(CompatUtils.generateViewId());
18
             topBar.setId(CompatUtils.generateViewId());
22
         }
19
         }
23
         return topBar;
20
         return topBar;
24
     }
21
     }
25
 
22
 
26
-    protected TopBar createTopBar(Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener topBarButtonClickListener, StackLayout stackLayout, ImageLoader imageLoader) {
27
-        return new TopBar(context, buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, stackLayout, imageLoader);
23
+    protected TopBar createTopBar(Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout stackLayout) {
24
+        return new TopBar(context, topBarBackgroundViewController, stackLayout);
28
     }
25
     }
29
 
26
 
30
     public void clear() {
27
     public void clear() {

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/views/ComponentLayout.java Vedi File

12
 import com.reactnativenavigation.utils.UiUtils;
12
 import com.reactnativenavigation.utils.UiUtils;
13
 import com.reactnativenavigation.utils.ViewUtils;
13
 import com.reactnativenavigation.utils.ViewUtils;
14
 import com.reactnativenavigation.viewcontrollers.IReactView;
14
 import com.reactnativenavigation.viewcontrollers.IReactView;
15
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
15
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
16
 import com.reactnativenavigation.views.element.Element;
16
 import com.reactnativenavigation.views.element.Element;
17
 import com.reactnativenavigation.views.topbar.TopBar;
17
 import com.reactnativenavigation.views.topbar.TopBar;
18
 import com.reactnativenavigation.views.touch.OverlayTouchDelegate;
18
 import com.reactnativenavigation.views.touch.OverlayTouchDelegate;
22
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
22
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
23
 
23
 
24
 @SuppressLint("ViewConstructor")
24
 @SuppressLint("ViewConstructor")
25
-public class ComponentLayout extends FrameLayout implements ReactComponent, TopBarButtonController.OnClickListener {
25
+public class ComponentLayout extends FrameLayout implements ReactComponent, TitleBarButtonController.OnClickListener {
26
 
26
 
27
     private IReactView reactView;
27
     private IReactView reactView;
28
     private final OverlayTouchDelegate touchDelegate;
28
     private final OverlayTouchDelegate touchDelegate;

+ 4
- 9
lib/android/app/src/main/java/com/reactnativenavigation/views/StackLayout.java Vedi File

4
 import android.content.Context;
4
 import android.content.Context;
5
 import android.widget.RelativeLayout;
5
 import android.widget.RelativeLayout;
6
 
6
 
7
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
8
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
9
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
7
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
10
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
8
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
11
 import com.reactnativenavigation.views.topbar.TopBar;
9
 import com.reactnativenavigation.views.topbar.TopBar;
12
 
10
 
13
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
14
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
15
-
16
 @SuppressLint("ViewConstructor")
11
 @SuppressLint("ViewConstructor")
17
 public class StackLayout extends RelativeLayout implements Component {
12
 public class StackLayout extends RelativeLayout implements Component {
18
     private String stackId;
13
     private String stackId;
19
 
14
 
20
-    public StackLayout(Context context, ReactViewCreator topBarButtonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarController topBarController, TopBarButtonController.OnClickListener topBarButtonClickListener, String stackId) {
15
+    public StackLayout(Context context, TopBarBackgroundViewController topBarBackgroundViewController, TopBarController topBarController, String stackId) {
21
         super(context);
16
         super(context);
22
         this.stackId = stackId;
17
         this.stackId = stackId;
23
-        createLayout(topBarButtonCreator, topBarBackgroundViewController, topBarController, topBarButtonClickListener);
18
+        createLayout(topBarBackgroundViewController, topBarController);
24
         setContentDescription("StackLayout");
19
         setContentDescription("StackLayout");
25
     }
20
     }
26
 
21
 
27
-    private void createLayout(ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarController topBarController, TopBarButtonController.OnClickListener topBarButtonClickListener) {
28
-        addView(topBarController.createView(getContext(), buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, this), MATCH_PARENT, WRAP_CONTENT);
22
+    private void createLayout(TopBarBackgroundViewController topBarBackgroundViewController, TopBarController topBarController) {
23
+        addView(topBarController.createView(getContext(), topBarBackgroundViewController, this));
29
     }
24
     }
30
 
25
 
31
     public String getStackId() {
26
     public String getStackId() {

+ 3
- 4
lib/android/app/src/main/java/com/reactnativenavigation/views/element/ElementTransitionManager.java Vedi File

2
 
2
 
3
 import android.animation.Animator;
3
 import android.animation.Animator;
4
 import android.support.annotation.RestrictTo;
4
 import android.support.annotation.RestrictTo;
5
-import android.util.Log;
6
 
5
 
7
 import com.reactnativenavigation.parse.Transition;
6
 import com.reactnativenavigation.parse.Transition;
8
 import com.reactnativenavigation.parse.Transitions;
7
 import com.reactnativenavigation.parse.Transitions;
13
 import java.util.Map;
12
 import java.util.Map;
14
 
13
 
15
 import static com.reactnativenavigation.utils.CollectionUtils.filter;
14
 import static com.reactnativenavigation.utils.CollectionUtils.filter;
16
-import static com.reactnativenavigation.utils.CollectionUtils.map;
15
+import static com.reactnativenavigation.utils.CollectionUtils.keyBy;
17
 
16
 
18
 public class ElementTransitionManager {
17
 public class ElementTransitionManager {
19
 
18
 
33
 
32
 
34
     public Collection<Animator> createTransitions(Transitions transitions, List<Element> fromElements, List<Element> toElements) {
33
     public Collection<Animator> createTransitions(Transitions transitions, List<Element> fromElements, List<Element> toElements) {
35
         if (!transitions.hasValue() || fromElements.isEmpty() || toElements.isEmpty()) return Collections.EMPTY_LIST;
34
         if (!transitions.hasValue() || fromElements.isEmpty() || toElements.isEmpty()) return Collections.EMPTY_LIST;
36
-        Map<String, Element> from = map(fromElements, Element::getElementId);
37
-        Map<String, Element> to = map(toElements, Element::getElementId);
35
+        Map<String, Element> from = keyBy(fromElements, Element::getElementId);
36
+        Map<String, Element> to = keyBy(toElements, Element::getElementId);
38
         List<Transition> validTransitions = filter(transitions.get(), (t) -> validator.validate(t, from, to));
37
         List<Transition> validTransitions = filter(transitions.get(), (t) -> validator.validate(t, from, to));
39
 
38
 
40
         return animatorCreator.create(validTransitions, from, to);
39
         return animatorCreator.create(validTransitions, from, to);

+ 10
- 43
lib/android/app/src/main/java/com/reactnativenavigation/views/titlebar/TitleBar.java Vedi File

1
 package com.reactnativenavigation.views.titlebar;
1
 package com.reactnativenavigation.views.titlebar;
2
 
2
 
3
 import android.annotation.SuppressLint;
3
 import android.annotation.SuppressLint;
4
-import android.app.Activity;
5
 import android.content.Context;
4
 import android.content.Context;
6
 import android.graphics.Typeface;
5
 import android.graphics.Typeface;
7
 import android.support.v7.widget.Toolbar;
6
 import android.support.v7.widget.Toolbar;
11
 import android.widget.TextView;
10
 import android.widget.TextView;
12
 
11
 
13
 import com.reactnativenavigation.parse.Alignment;
12
 import com.reactnativenavigation.parse.Alignment;
14
-import com.reactnativenavigation.parse.BackButton;
15
-import com.reactnativenavigation.parse.params.Button;
16
 import com.reactnativenavigation.parse.params.Colour;
13
 import com.reactnativenavigation.parse.params.Colour;
17
-import com.reactnativenavigation.utils.ButtonOptionsPresenter;
18
-import com.reactnativenavigation.utils.ImageLoader;
19
 import com.reactnativenavigation.utils.UiUtils;
14
 import com.reactnativenavigation.utils.UiUtils;
20
 import com.reactnativenavigation.utils.ViewUtils;
15
 import com.reactnativenavigation.utils.ViewUtils;
21
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
22
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
23
-import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
16
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
24
 
17
 
25
-import java.util.ArrayList;
26
 import java.util.List;
18
 import java.util.List;
27
 
19
 
28
 import javax.annotation.Nullable;
20
 import javax.annotation.Nullable;
31
 public class TitleBar extends Toolbar {
23
 public class TitleBar extends Toolbar {
32
     public static final int DEFAULT_LEFT_MARGIN = 16;
24
     public static final int DEFAULT_LEFT_MARGIN = 16;
33
 
25
 
34
-    private final ReactViewCreator buttonCreator;
35
-    private final TopBarButtonController.OnClickListener onClickListener;
36
-    private final List<TopBarButtonController> rightButtonControllers = new ArrayList<>();
37
-    private TopBarButtonController leftButtonController;
38
-    private ImageLoader imageLoader;
26
+    private TitleBarButtonController leftButtonController;
39
     private View component;
27
     private View component;
40
 
28
 
41
-    public TitleBar(Context context, ReactViewCreator buttonCreator, TopBarButtonController.OnClickListener onClickListener, ImageLoader imageLoader) {
29
+    public TitleBar(Context context) {
42
         super(context);
30
         super(context);
43
-        this.buttonCreator = buttonCreator;
44
-        this.imageLoader = imageLoader;
45
-        this.onClickListener = onClickListener;
46
         getMenu();
31
         getMenu();
47
         setContentDescription("titleBar");
32
         setContentDescription("titleBar");
48
     }
33
     }
160
     }
145
     }
161
 
146
 
162
     private void clearRightButtons() {
147
     private void clearRightButtons() {
163
-        for (TopBarButtonController button : rightButtonControllers) {
164
-            button.destroy();
165
-        }
166
-        rightButtonControllers.clear();
167
         if (getMenu().size() > 0) getMenu().clear();
148
         if (getMenu().size() > 0) getMenu().clear();
168
     }
149
     }
169
 
150
 
170
-    public void setBackButton(BackButton button) {
151
+    public void setBackButton(TitleBarButtonController button) {
171
         setLeftButton(button);
152
         setLeftButton(button);
172
     }
153
     }
173
 
154
 
174
-    public void setLeftButtons(List<Button> leftButtons) {
155
+    public void setLeftButtons(List<TitleBarButtonController> leftButtons) {
175
         if (leftButtons == null) return;
156
         if (leftButtons == null) return;
176
         if (leftButtons.isEmpty()) {
157
         if (leftButtons.isEmpty()) {
177
             clearLeftButton();
158
             clearLeftButton();
183
         setLeftButton(leftButtons.get(0));
164
         setLeftButton(leftButtons.get(0));
184
     }
165
     }
185
 
166
 
186
-    private void setLeftButton(final Button button) {
187
-        TopBarButtonController controller = createButtonController(button);
188
-        leftButtonController = controller;
189
-        controller.applyNavigationIcon(this);
167
+    private void setLeftButton(TitleBarButtonController button) {
168
+        leftButtonController = button;
169
+        button.applyNavigationIcon(this);
190
     }
170
     }
191
 
171
 
192
-    public void setRightButtons(List<Button> rightButtons) {
172
+    public void setRightButtons(List<TitleBarButtonController> rightButtons) {
193
         if (rightButtons == null) return;
173
         if (rightButtons == null) return;
194
         clearRightButtons();
174
         clearRightButtons();
195
         for (int i = 0; i < rightButtons.size(); i++) {
175
         for (int i = 0; i < rightButtons.size(); i++) {
196
-            TopBarButtonController controller = createButtonController(rightButtons.get(i));
197
-            rightButtonControllers.add(controller);
198
-            controller.addToMenu(this, rightButtons.size() - i - 1);
176
+            rightButtons.get(i).addToMenu(this, rightButtons.size() - i - 1);
199
         }
177
         }
200
     }
178
     }
201
 
179
 
202
-    public TopBarButtonController createButtonController(Button button) {
203
-        return new TopBarButtonController((Activity) getContext(),
204
-                new NavigationIconResolver(getContext(), imageLoader),
205
-                imageLoader,
206
-                new ButtonOptionsPresenter(this, button),
207
-                button,
208
-                buttonCreator,
209
-                onClickListener
210
-        );
211
-    }
212
-
213
     public void setHeight(int height) {
180
     public void setHeight(int height) {
214
         if (height == getLayoutParams().height) return;
181
         if (height == getLayoutParams().height) return;
215
         ViewGroup.LayoutParams lp = getLayoutParams();
182
         ViewGroup.LayoutParams lp = getLayoutParams();

+ 11
- 17
lib/android/app/src/main/java/com/reactnativenavigation/views/topbar/TopBar.java Vedi File

26
 import com.reactnativenavigation.interfaces.ScrollEventListener;
26
 import com.reactnativenavigation.interfaces.ScrollEventListener;
27
 import com.reactnativenavigation.parse.Alignment;
27
 import com.reactnativenavigation.parse.Alignment;
28
 import com.reactnativenavigation.parse.AnimationOptions;
28
 import com.reactnativenavigation.parse.AnimationOptions;
29
-import com.reactnativenavigation.parse.BackButton;
30
 import com.reactnativenavigation.parse.Component;
29
 import com.reactnativenavigation.parse.Component;
31
-import com.reactnativenavigation.parse.params.Button;
32
 import com.reactnativenavigation.parse.params.Colour;
30
 import com.reactnativenavigation.parse.params.Colour;
33
 import com.reactnativenavigation.parse.params.Number;
31
 import com.reactnativenavigation.parse.params.Number;
34
 import com.reactnativenavigation.utils.CompatUtils;
32
 import com.reactnativenavigation.utils.CompatUtils;
35
-import com.reactnativenavigation.utils.ImageLoader;
36
 import com.reactnativenavigation.utils.UiUtils;
33
 import com.reactnativenavigation.utils.UiUtils;
37
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
38
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
34
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
39
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
35
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
40
 import com.reactnativenavigation.views.StackLayout;
36
 import com.reactnativenavigation.views.StackLayout;
41
 import com.reactnativenavigation.views.titlebar.TitleBar;
37
 import com.reactnativenavigation.views.titlebar.TitleBar;
55
     private FrameLayout root;
51
     private FrameLayout root;
56
     private TopBarBackgroundViewController topBarBackgroundViewController;
52
     private TopBarBackgroundViewController topBarBackgroundViewController;
57
     private View border;
53
     private View border;
58
-    private ImageLoader imageLoader;
59
 
54
 
60
-    public TopBar(final Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener onClickListener, StackLayout parentView, ImageLoader imageLoader) {
55
+    public TopBar(final Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout parentView) {
61
         super(context);
56
         super(context);
62
         context.setTheme(R.style.TopBar);
57
         context.setTheme(R.style.TopBar);
63
-        this.imageLoader = imageLoader;
64
         collapsingBehavior = new TopBarCollapseBehavior(this);
58
         collapsingBehavior = new TopBarCollapseBehavior(this);
65
         this.topBarBackgroundViewController = topBarBackgroundViewController;
59
         this.topBarBackgroundViewController = topBarBackgroundViewController;
66
         topTabs = new TopTabs(getContext());
60
         topTabs = new TopTabs(getContext());
67
         animator = new TopBarAnimator(this, parentView.getStackId());
61
         animator = new TopBarAnimator(this, parentView.getStackId());
68
-        createLayout(buttonCreator, onClickListener);
62
+        createLayout();
69
     }
63
     }
70
 
64
 
71
-    private void createLayout(ReactViewCreator buttonCreator, TopBarButtonController.OnClickListener onClickListener) {
65
+    private void createLayout() {
72
         setId(CompatUtils.generateViewId());
66
         setId(CompatUtils.generateViewId());
73
-        titleBar = createTitleBar(getContext(), buttonCreator, onClickListener, imageLoader);
67
+        titleBar = createTitleBar(getContext());
74
         topTabs = createTopTabs();
68
         topTabs = createTopTabs();
75
         border = createBorder();
69
         border = createBorder();
76
         LinearLayout content = createContentLayout();
70
         LinearLayout content = createContentLayout();
77
 
71
 
78
         root = new FrameLayout(getContext());
72
         root = new FrameLayout(getContext());
79
         root.setId(CompatUtils.generateViewId());
73
         root.setId(CompatUtils.generateViewId());
80
-        content.addView(titleBar);
74
+        content.addView(titleBar, MATCH_PARENT, WRAP_CONTENT);
81
         content.addView(topTabs);
75
         content.addView(topTabs);
82
         root.addView(content);
76
         root.addView(content);
83
         root.addView(border);
77
         root.addView(border);
110
         return border;
104
         return border;
111
     }
105
     }
112
 
106
 
113
-    protected TitleBar createTitleBar(Context context, ReactViewCreator buttonCreator, TopBarButtonController.OnClickListener onClickListener, ImageLoader imageLoader) {
114
-        TitleBar titleBar = new TitleBar(context, buttonCreator, onClickListener, imageLoader);
107
+    protected TitleBar createTitleBar(Context context) {
108
+        TitleBar titleBar = new TitleBar(context);
115
         titleBar.setId(CompatUtils.generateViewId());
109
         titleBar.setId(CompatUtils.generateViewId());
116
         return titleBar;
110
         return titleBar;
117
     }
111
     }
209
         topTabs.setLayoutParams(topTabs.getLayoutParams());
203
         topTabs.setLayoutParams(topTabs.getLayoutParams());
210
     }
204
     }
211
 
205
 
212
-    public void setBackButton(BackButton backButton) {
206
+    public void setBackButton(TitleBarButtonController backButton) {
213
         titleBar.setBackButton(backButton);
207
         titleBar.setBackButton(backButton);
214
     }
208
     }
215
 
209
 
216
-    public void setLeftButtons(List<Button> leftButtons) {
210
+    public void setLeftButtons(List<TitleBarButtonController> leftButtons) {
217
         titleBar.setLeftButtons(leftButtons);
211
         titleBar.setLeftButtons(leftButtons);
218
     }
212
     }
219
 
213
 
220
-    public void setRightButtons(List<Button> rightButtons) {
214
+    public void setRightButtons(List<TitleBarButtonController> rightButtons) {
221
         titleBar.setRightButtons(rightButtons);
215
         titleBar.setRightButtons(rightButtons);
222
     }
216
     }
223
 
217
 

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/views/toptabs/TopTabsViewPager.java Vedi File

9
 
9
 
10
 import com.reactnativenavigation.parse.Options;
10
 import com.reactnativenavigation.parse.Options;
11
 import com.reactnativenavigation.viewcontrollers.IReactView;
11
 import com.reactnativenavigation.viewcontrollers.IReactView;
12
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
12
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
13
 import com.reactnativenavigation.viewcontrollers.ViewController;
13
 import com.reactnativenavigation.viewcontrollers.ViewController;
14
 import com.reactnativenavigation.viewcontrollers.toptabs.TopTabsAdapter;
14
 import com.reactnativenavigation.viewcontrollers.toptabs.TopTabsAdapter;
15
 import com.reactnativenavigation.views.Component;
15
 import com.reactnativenavigation.views.Component;
21
 import static android.widget.RelativeLayout.BELOW;
21
 import static android.widget.RelativeLayout.BELOW;
22
 
22
 
23
 @SuppressLint("ViewConstructor")
23
 @SuppressLint("ViewConstructor")
24
-public class TopTabsViewPager extends ViewPager implements Component, TopBarButtonController.OnClickListener {
24
+public class TopTabsViewPager extends ViewPager implements Component, TitleBarButtonController.OnClickListener {
25
 
25
 
26
     private static final int OFFSCREEN_PAGE_LIMIT = 99;
26
     private static final int OFFSCREEN_PAGE_LIMIT = 99;
27
     private List<ViewController> tabs;
27
     private List<ViewController> tabs;

+ 3
- 5
lib/android/app/src/test/java/com/reactnativenavigation/TestUtils.java Vedi File

10
 import com.reactnativenavigation.presentation.StackOptionsPresenter;
10
 import com.reactnativenavigation.presentation.StackOptionsPresenter;
11
 import com.reactnativenavigation.utils.ImageLoader;
11
 import com.reactnativenavigation.utils.ImageLoader;
12
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
12
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
13
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
14
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
15
 import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
13
 import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
16
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
14
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
17
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
15
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
27
                 .setTopBarBackgroundViewController(new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock()))
25
                 .setTopBarBackgroundViewController(new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock()))
28
                 .setTopBarController(new TopBarController() {
26
                 .setTopBarController(new TopBarController() {
29
                     @Override
27
                     @Override
30
-                    protected TopBar createTopBar(Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener topBarButtonClickListener, StackLayout stackLayout, ImageLoader imageLoader) {
31
-                        TopBar topBar = super.createTopBar(context, buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, stackLayout, imageLoader);
28
+                    protected TopBar createTopBar(Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout stackLayout) {
29
+                        TopBar topBar = super.createTopBar(context, topBarBackgroundViewController, stackLayout);
32
                         topBar.layout(0, 0, 1000, 100);
30
                         topBar.layout(0, 0, 1000, 100);
33
                         return topBar;
31
                         return topBar;
34
                     }
32
                     }
35
                 })
33
                 })
36
-                .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()))
34
+                .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new Options())                )
37
                 .setInitialOptions(new Options());
35
                 .setInitialOptions(new Options());
38
     }
36
     }
39
 }
37
 }

+ 2
- 2
lib/android/app/src/test/java/com/reactnativenavigation/mocks/TestComponentLayout.java Vedi File

7
 import com.reactnativenavigation.interfaces.ScrollEventListener;
7
 import com.reactnativenavigation.interfaces.ScrollEventListener;
8
 import com.reactnativenavigation.parse.Options;
8
 import com.reactnativenavigation.parse.Options;
9
 import com.reactnativenavigation.viewcontrollers.IReactView;
9
 import com.reactnativenavigation.viewcontrollers.IReactView;
10
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
10
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
11
 import com.reactnativenavigation.views.ComponentLayout;
11
 import com.reactnativenavigation.views.ComponentLayout;
12
 
12
 
13
-public class TestComponentLayout extends ComponentLayout implements TopBarButtonController.OnClickListener {
13
+public class TestComponentLayout extends ComponentLayout implements TitleBarButtonController.OnClickListener {
14
 
14
 
15
     private IReactView reactView;
15
     private IReactView reactView;
16
 
16
 

+ 45
- 0
lib/android/app/src/test/java/com/reactnativenavigation/utils/TitleBarHelper.java Vedi File

1
 package com.reactnativenavigation.utils;
1
 package com.reactnativenavigation.utils;
2
 
2
 
3
+import android.app.Activity;
3
 import android.support.v7.view.menu.ActionMenuItemView;
4
 import android.support.v7.view.menu.ActionMenuItemView;
4
 import android.support.v7.widget.Toolbar;
5
 import android.support.v7.widget.Toolbar;
5
 
6
 
7
+import com.reactnativenavigation.mocks.ImageLoaderMock;
8
+import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
9
+import com.reactnativenavigation.parse.Component;
10
+import com.reactnativenavigation.parse.params.Button;
11
+import com.reactnativenavigation.parse.params.Text;
12
+import com.reactnativenavigation.viewcontrollers.TitleBarButtonController;
13
+import com.reactnativenavigation.viewcontrollers.button.NavigationIconResolver;
14
+import com.reactnativenavigation.views.titlebar.TitleBar;
15
+
6
 public class TitleBarHelper {
16
 public class TitleBarHelper {
7
     public static ActionMenuItemView getRightButton(Toolbar toolbar, int index) {
17
     public static ActionMenuItemView getRightButton(Toolbar toolbar, int index) {
8
         return (ActionMenuItemView) ViewUtils.findChildrenByClassRecursive(toolbar, ActionMenuItemView.class).get(toolbar.getMenu().size() - index - 1);
18
         return (ActionMenuItemView) ViewUtils.findChildrenByClassRecursive(toolbar, ActionMenuItemView.class).get(toolbar.getMenu().size() - index - 1);
9
     }
19
     }
20
+
21
+    public static Button textualButton(String text) {
22
+        Button button = new Button();
23
+        button.id = text + CompatUtils.generateViewId();
24
+        button.text = new Text(text);
25
+        return button;
26
+    }
27
+
28
+    public static Button reactViewButton(String name) {
29
+        Button button = new Button();
30
+        button.id = name + CompatUtils.generateViewId();
31
+        button.component = new Component();
32
+        button.component.name = new Text("com.example" + name + CompatUtils.generateViewId());
33
+        button.component.componentId = new Text(name + CompatUtils.generateViewId());
34
+        return button;
35
+    }
36
+
37
+    public static Button iconButton(String id, String icon) {
38
+        Button button = new Button();
39
+        button.id = "someButton";
40
+        button.icon = new Text(icon);
41
+        return button;
42
+    }
43
+
44
+
45
+    public static TitleBarButtonController createButtonController(Activity activity, TitleBar titleBar, Button button) {
46
+        return new TitleBarButtonController(activity,
47
+                new NavigationIconResolver(activity, ImageLoaderMock.mock()),
48
+                ImageLoaderMock.mock(),
49
+                new ButtonOptionsPresenter(titleBar, button),
50
+                button,
51
+                new TopBarButtonCreatorMock(),
52
+                buttonId -> {}
53
+        );
54
+    }
10
 }
55
 }

+ 2
- 1
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/BottomTabsControllerTest.java Vedi File

12
 import com.reactnativenavigation.mocks.ImageLoaderMock;
12
 import com.reactnativenavigation.mocks.ImageLoaderMock;
13
 import com.reactnativenavigation.mocks.SimpleViewController;
13
 import com.reactnativenavigation.mocks.SimpleViewController;
14
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
14
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
15
+import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
15
 import com.reactnativenavigation.parse.Options;
16
 import com.reactnativenavigation.parse.Options;
16
 import com.reactnativenavigation.parse.params.Bool;
17
 import com.reactnativenavigation.parse.params.Bool;
17
 import com.reactnativenavigation.parse.params.Colour;
18
 import com.reactnativenavigation.parse.params.Colour;
284
         return TestUtils.newStackController(activity)
285
         return TestUtils.newStackController(activity)
285
                 .setId(id)
286
                 .setId(id)
286
                 .setInitialOptions(tabOptions)
287
                 .setInitialOptions(tabOptions)
287
-                .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()))
288
+                .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new Options()))
288
                 .build();
289
                 .build();
289
     }
290
     }
290
 
291
 

+ 3
- 4
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/OptionsApplyingTest.java Vedi File

69
         );
69
         );
70
         TopBarController topBarController = new TopBarController() {
70
         TopBarController topBarController = new TopBarController() {
71
             @Override
71
             @Override
72
-            protected TopBar createTopBar(Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener topBarButtonClickListener, StackLayout stackLayout, ImageLoader imageLoader) {
73
-                topBar =
74
-                        spy(super.createTopBar(context, buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, stackLayout, imageLoader));
72
+            protected TopBar createTopBar(Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout stackLayout) {
73
+                topBar = spy(super.createTopBar(context, topBarBackgroundViewController, stackLayout));
75
                 return topBar;
74
                 return topBar;
76
             }
75
             }
77
         };
76
         };
104
                         .setTopBarController(new TopBarController())
103
                         .setTopBarController(new TopBarController())
105
                         .setId("stackId")
104
                         .setId("stackId")
106
                         .setInitialOptions(new Options())
105
                         .setInitialOptions(new Options())
107
-                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()))
106
+                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new Options()))
108
                         .build();
107
                         .build();
109
         stackController.ensureViewIsCreated();
108
         stackController.ensureViewIsCreated();
110
         stackController.push(uut, new CommandListenerAdapter());
109
         stackController.push(uut, new CommandListenerAdapter());

+ 160
- 18
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackOptionsPresenterTest.java Vedi File

3
 import android.app.Activity;
3
 import android.app.Activity;
4
 import android.graphics.Typeface;
4
 import android.graphics.Typeface;
5
 import android.support.v7.widget.Toolbar;
5
 import android.support.v7.widget.Toolbar;
6
+import android.util.Log;
6
 import android.view.Gravity;
7
 import android.view.Gravity;
7
 import android.view.View;
8
 import android.view.View;
8
 
9
 
9
 import com.reactnativenavigation.BaseTest;
10
 import com.reactnativenavigation.BaseTest;
11
+import com.reactnativenavigation.mocks.ImageLoaderMock;
10
 import com.reactnativenavigation.mocks.TestComponentLayout;
12
 import com.reactnativenavigation.mocks.TestComponentLayout;
11
 import com.reactnativenavigation.mocks.TestReactView;
13
 import com.reactnativenavigation.mocks.TestReactView;
12
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
14
 import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
15
+import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
13
 import com.reactnativenavigation.parse.Alignment;
16
 import com.reactnativenavigation.parse.Alignment;
14
 import com.reactnativenavigation.parse.Component;
17
 import com.reactnativenavigation.parse.Component;
15
 import com.reactnativenavigation.parse.Options;
18
 import com.reactnativenavigation.parse.Options;
23
 import com.reactnativenavigation.parse.params.Number;
26
 import com.reactnativenavigation.parse.params.Number;
24
 import com.reactnativenavigation.parse.params.Text;
27
 import com.reactnativenavigation.parse.params.Text;
25
 import com.reactnativenavigation.presentation.StackOptionsPresenter;
28
 import com.reactnativenavigation.presentation.StackOptionsPresenter;
29
+import com.reactnativenavigation.utils.TitleBarHelper;
26
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
30
 import com.reactnativenavigation.views.titlebar.TitleBarReactView;
27
 import com.reactnativenavigation.views.topbar.TopBar;
31
 import com.reactnativenavigation.views.topbar.TopBar;
28
 
32
 
32
 import org.mockito.Mockito;
36
 import org.mockito.Mockito;
33
 
37
 
34
 import java.util.ArrayList;
38
 import java.util.ArrayList;
39
+import java.util.Collections;
35
 import java.util.List;
40
 import java.util.List;
36
 
41
 
42
+import static com.reactnativenavigation.utils.CollectionUtils.forEach;
37
 import static org.assertj.core.api.Java6Assertions.assertThat;
43
 import static org.assertj.core.api.Java6Assertions.assertThat;
38
 import static org.mockito.ArgumentMatchers.any;
44
 import static org.mockito.ArgumentMatchers.any;
39
 import static org.mockito.ArgumentMatchers.anyBoolean;
45
 import static org.mockito.ArgumentMatchers.anyBoolean;
54
     private Activity activity;
60
     private Activity activity;
55
     private TopBar topBar;
61
     private TopBar topBar;
56
 
62
 
63
+    private Button textBtn1 = TitleBarHelper.textualButton("btn1");
64
+    private Button textBtn2 = TitleBarHelper.textualButton("btn2");
65
+    private Button componentBtn1 = TitleBarHelper.reactViewButton("btn1_");
66
+    private Button componentBtn2 = TitleBarHelper.reactViewButton("btn2_");
67
+
57
     @Override
68
     @Override
58
     public void beforeEach() {
69
     public void beforeEach() {
59
         activity = spy(newActivity());
70
         activity = spy(newActivity());
71
+        //noinspection Convert2Lambda
72
+        TitleBarButtonController.OnClickListener onClickListener = spy(new TitleBarButtonController.OnClickListener() {
73
+            @Override
74
+            public void onPress(String buttonId) {
75
+                Log.i("TopBarTest", "onPress: " + buttonId);
76
+            }
77
+        });
60
 
78
 
61
         TitleBarReactViewCreatorMock titleViewCreator = new TitleBarReactViewCreatorMock() {
79
         TitleBarReactViewCreatorMock titleViewCreator = new TitleBarReactViewCreatorMock() {
62
             @Override
80
             @Override
64
                 return spy(super.create(activity, componentId, componentName));
82
                 return spy(super.create(activity, componentId, componentName));
65
             }
83
             }
66
         };
84
         };
67
-        uut = spy(new StackOptionsPresenter(activity, titleViewCreator, new Options()));
85
+        uut = spy(new StackOptionsPresenter(activity, titleViewCreator, new TopBarButtonCreatorMock(), ImageLoaderMock.mock(), new Options()));
68
         topBar = mockTopBar();
86
         topBar = mockTopBar();
69
         uut.bindView(topBar);
87
         uut.bindView(topBar);
88
+        uut.setButtonOnClickListener(onClickListener);
70
         child = spy(new TestComponentLayout(activity, new TestReactView(activity)));
89
         child = spy(new TestComponentLayout(activity, new TestReactView(activity)));
71
         otherChild = new TestComponentLayout(activity, new TestReactView(activity));
90
         otherChild = new TestComponentLayout(activity, new TestReactView(activity));
72
     }
91
     }
130
 
149
 
131
     @Test
150
     @Test
132
     public void mergeButtons() {
151
     public void mergeButtons() {
133
-        Options options = new Options();
134
-        uut.mergeChildOptions(options, EMPTY_OPTIONS, child);
152
+        uut.mergeChildOptions(EMPTY_OPTIONS, EMPTY_OPTIONS, child);
135
         verify(topBar, times(0)).setRightButtons(any());
153
         verify(topBar, times(0)).setRightButtons(any());
136
         verify(topBar, times(0)).setLeftButtons(any());
154
         verify(topBar, times(0)).setLeftButtons(any());
137
 
155
 
156
+        Options options = new Options();
138
         options.topBar.buttons.right = new ArrayList<>();
157
         options.topBar.buttons.right = new ArrayList<>();
139
         uut.mergeChildOptions(options, EMPTY_OPTIONS, child);
158
         uut.mergeChildOptions(options, EMPTY_OPTIONS, child);
140
         verify(topBar, times(1)).setRightButtons(any());
159
         verify(topBar, times(1)).setRightButtons(any());
144
         verify(topBar, times(1)).setLeftButtons(any());
163
         verify(topBar, times(1)).setLeftButtons(any());
145
     }
164
     }
146
 
165
 
166
+    @Test
167
+    public void mergeButtons_previousRightButtonsAreDestroyed() {
168
+        Options options = new Options();
169
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn1));
170
+        uut.applyChildOptions(options, child);
171
+        List<TitleBarButtonController> initialButtons = uut.getComponentButtons(child);
172
+        forEach(initialButtons, ViewController::ensureViewIsCreated);
173
+
174
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn2));
175
+        uut.mergeChildOptions(options, new Options(), child);
176
+        for (TitleBarButtonController button : initialButtons) {
177
+            assertThat(button.isDestroyed()).isTrue();
178
+        }
179
+    }
180
+
181
+    @Test
182
+    public void mergeButtons_mergingRightButtonsOnlyDestroysRightButtons() {
183
+        Options a = new Options();
184
+        a.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn1));
185
+        a.topBar.buttons.left = new ArrayList<>(Collections.singletonList(componentBtn2));
186
+        uut.applyChildOptions(a, child);
187
+        List<TitleBarButtonController> initialButtons = uut.getComponentButtons(child);
188
+        forEach(initialButtons, ViewController::ensureViewIsCreated);
189
+
190
+        Options b = new Options();
191
+        b.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn2));
192
+        uut.mergeChildOptions(b, new Options(), child);
193
+        assertThat(initialButtons.get(0).isDestroyed()).isTrue();
194
+        assertThat(initialButtons.get(1).isDestroyed()).isFalse();
195
+    }
196
+
197
+    @Test
198
+    public void mergeButtons_mergingLeftButtonsOnlyDestroysLeftButtons() {
199
+        Options a = new Options();
200
+        a.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn1));
201
+        a.topBar.buttons.left = new ArrayList<>(Collections.singletonList(componentBtn2));
202
+        uut.applyChildOptions(a, child);
203
+        List<TitleBarButtonController> initialButtons = uut.getComponentButtons(child);
204
+        forEach(initialButtons, ViewController::ensureViewIsCreated);
205
+
206
+        Options b = new Options();
207
+        b.topBar.buttons.left = new ArrayList<>(Collections.singletonList(componentBtn2));
208
+        uut.mergeChildOptions(b, new Options(), child);
209
+        assertThat(initialButtons.get(0).isDestroyed()).isFalse();
210
+        assertThat(initialButtons.get(1).isDestroyed()).isTrue();
211
+    }
212
+
147
     @Test
213
     @Test
148
     public void mergeTopBarOptions() {
214
     public void mergeTopBarOptions() {
149
         Options options = new Options();
215
         Options options = new Options();
253
         options.topBar.buttons.left.add(leftButton);
319
         options.topBar.buttons.left.add(leftButton);
254
 
320
 
255
         uut.applyChildOptions(options, child);
321
         uut.applyChildOptions(options, child);
256
-        ArgumentCaptor<List<Button>> rightCaptor = ArgumentCaptor.forClass(List.class);
322
+        ArgumentCaptor<List<TitleBarButtonController>> rightCaptor = ArgumentCaptor.forClass(List.class);
257
         verify(topBar).setRightButtons(rightCaptor.capture());
323
         verify(topBar).setRightButtons(rightCaptor.capture());
258
-        assertThat(rightCaptor.getValue().get(0).color.get()).isEqualTo(options.topBar.rightButtonColor.get());
259
-        assertThat(rightCaptor.getValue().get(1).color.get()).isEqualTo(options.topBar.rightButtonColor.get());
324
+        assertThat(rightCaptor.getValue().get(0).getButton().color.get()).isEqualTo(options.topBar.rightButtonColor.get());
325
+        assertThat(rightCaptor.getValue().get(1).getButton().color.get()).isEqualTo(options.topBar.rightButtonColor.get());
260
         assertThat(rightCaptor.getValue().get(0)).isNotEqualTo(rightButton1);
326
         assertThat(rightCaptor.getValue().get(0)).isNotEqualTo(rightButton1);
261
         assertThat(rightCaptor.getValue().get(1)).isNotEqualTo(rightButton2);
327
         assertThat(rightCaptor.getValue().get(1)).isNotEqualTo(rightButton2);
262
 
328
 
263
-        ArgumentCaptor<List<Button>> leftCaptor = ArgumentCaptor.forClass(List.class);
329
+        ArgumentCaptor<List<TitleBarButtonController>> leftCaptor = ArgumentCaptor.forClass(List.class);
264
         verify(topBar).setLeftButtons(leftCaptor.capture());
330
         verify(topBar).setLeftButtons(leftCaptor.capture());
265
-        assertThat(leftCaptor.getValue().get(0).color).isEqualTo(options.topBar.leftButtonColor);
331
+        assertThat(leftCaptor.getValue().get(0).getButton().color).isEqualTo(options.topBar.leftButtonColor);
266
         assertThat(leftCaptor.getValue().get(0)).isNotEqualTo(leftButton);
332
         assertThat(leftCaptor.getValue().get(0)).isNotEqualTo(leftButton);
267
     }
333
     }
268
 
334
 
285
         options2.topBar.buttons.left.add(leftButton);
351
         options2.topBar.buttons.left.add(leftButton);
286
 
352
 
287
         uut.mergeChildOptions(options2, appliedOptions, child);
353
         uut.mergeChildOptions(options2, appliedOptions, child);
288
-        ArgumentCaptor<List<Button>> rightCaptor = ArgumentCaptor.forClass(List.class);
354
+        ArgumentCaptor<List<TitleBarButtonController>> rightCaptor = ArgumentCaptor.forClass(List.class);
289
         verify(topBar, times(1)).setRightButtons(rightCaptor.capture());
355
         verify(topBar, times(1)).setRightButtons(rightCaptor.capture());
290
-        assertThat(rightCaptor.getValue().get(0).color.get()).isEqualTo(appliedOptions.topBar.rightButtonColor.get());
291
-        assertThat(rightCaptor.getValue().get(1).color.get()).isEqualTo(appliedOptions.topBar.rightButtonColor.get());
356
+        assertThat(rightCaptor.getValue().get(0).getButton().color.get()).isEqualTo(appliedOptions.topBar.rightButtonColor.get());
357
+        assertThat(rightCaptor.getValue().get(1).getButton().color.get()).isEqualTo(appliedOptions.topBar.rightButtonColor.get());
292
         assertThat(rightCaptor.getValue().get(0)).isNotEqualTo(rightButton1);
358
         assertThat(rightCaptor.getValue().get(0)).isNotEqualTo(rightButton1);
293
         assertThat(rightCaptor.getValue().get(1)).isNotEqualTo(rightButton2);
359
         assertThat(rightCaptor.getValue().get(1)).isNotEqualTo(rightButton2);
294
 
360
 
295
-        ArgumentCaptor<List<Button>> leftCaptor = ArgumentCaptor.forClass(List.class);
361
+        ArgumentCaptor<List<TitleBarButtonController>> leftCaptor = ArgumentCaptor.forClass(List.class);
296
         verify(topBar, times(1)).setLeftButtons(leftCaptor.capture());
362
         verify(topBar, times(1)).setLeftButtons(leftCaptor.capture());
297
-        assertThat(leftCaptor.getValue().get(0).color.get()).isEqualTo(appliedOptions.topBar.leftButtonColor.get());
363
+        assertThat(leftCaptor.getValue().get(0).getButton().color.get()).isEqualTo(appliedOptions.topBar.leftButtonColor.get());
298
         assertThat(leftCaptor.getValue().get(0)).isNotEqualTo(leftButton);
364
         assertThat(leftCaptor.getValue().get(0)).isNotEqualTo(leftButton);
299
     }
365
     }
300
 
366
 
317
         options2.topBar.buttons.left.add(leftButton);
383
         options2.topBar.buttons.left.add(leftButton);
318
 
384
 
319
         uut.mergeChildOptions(options2, resolvedOptions, child);
385
         uut.mergeChildOptions(options2, resolvedOptions, child);
320
-        ArgumentCaptor<List<Button>> rightCaptor = ArgumentCaptor.forClass(List.class);
386
+        ArgumentCaptor<List<TitleBarButtonController>> rightCaptor = ArgumentCaptor.forClass(List.class);
321
         verify(topBar).setRightButtons(rightCaptor.capture());
387
         verify(topBar).setRightButtons(rightCaptor.capture());
322
-        assertThat(rightCaptor.getValue().get(0).color.get()).isEqualTo(resolvedOptions.topBar.rightButtonColor.get());
323
-        assertThat(rightCaptor.getValue().get(1).color.get()).isEqualTo(resolvedOptions.topBar.rightButtonColor.get());
388
+        assertThat(rightCaptor.getValue().get(0).getButton().color.get()).isEqualTo(resolvedOptions.topBar.rightButtonColor.get());
389
+        assertThat(rightCaptor.getValue().get(1).getButton().color.get()).isEqualTo(resolvedOptions.topBar.rightButtonColor.get());
324
         assertThat(rightCaptor.getValue().get(0)).isNotEqualTo(rightButton1);
390
         assertThat(rightCaptor.getValue().get(0)).isNotEqualTo(rightButton1);
325
         assertThat(rightCaptor.getValue().get(1)).isNotEqualTo(rightButton2);
391
         assertThat(rightCaptor.getValue().get(1)).isNotEqualTo(rightButton2);
326
 
392
 
327
-        ArgumentCaptor<List<Button>> leftCaptor = ArgumentCaptor.forClass(List.class);
393
+        ArgumentCaptor<List<TitleBarButtonController>> leftCaptor = ArgumentCaptor.forClass(List.class);
328
         verify(topBar).setLeftButtons(leftCaptor.capture());
394
         verify(topBar).setLeftButtons(leftCaptor.capture());
329
-        assertThat(leftCaptor.getValue().get(0).color.get()).isEqualTo(resolvedOptions.topBar.leftButtonColor.get());
395
+        assertThat(leftCaptor.getValue().get(0).getButton().color.get()).isEqualTo(resolvedOptions.topBar.leftButtonColor.get());
330
         assertThat(leftCaptor.getValue().get(0)).isNotEqualTo(leftButton);
396
         assertThat(leftCaptor.getValue().get(0)).isNotEqualTo(leftButton);
331
     }
397
     }
332
 
398
 
399
+    @Test
400
+    public void getButtonControllers_buttonControllersArePassedToTopBar() {
401
+        Options options = new Options();
402
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(textBtn1));
403
+        options.topBar.buttons.left = new ArrayList<>(Collections.singletonList(textBtn1));
404
+        uut.applyChildOptions(options, child);
405
+
406
+        ArgumentCaptor<List<TitleBarButtonController>> rightCaptor = ArgumentCaptor.forClass(List.class);
407
+        ArgumentCaptor<List<TitleBarButtonController>> leftCaptor = ArgumentCaptor.forClass(List.class);
408
+        verify(topBar).setRightButtons(rightCaptor.capture());
409
+        verify(topBar).setLeftButtons(leftCaptor.capture());
410
+
411
+        assertThat(rightCaptor.getValue().size()).isOne();
412
+        assertThat(leftCaptor.getValue().size()).isOne();
413
+    }
414
+
415
+    @Test
416
+    public void getButtonControllers_storesButtonsByComponent() {
417
+        Options options = new Options();
418
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(textBtn1));
419
+        options.topBar.buttons.left = new ArrayList<>(Collections.singletonList(textBtn2));
420
+        uut.applyChildOptions(options, child);
421
+
422
+        List<TitleBarButtonController> componentButtons = uut.getComponentButtons(child);
423
+        assertThat(componentButtons.size()).isEqualTo(2);
424
+        assertThat(componentButtons.get(0).getButton().text.get()).isEqualTo(textBtn1.text.get());
425
+        assertThat(componentButtons.get(1).getButton().text.get()).isEqualTo(textBtn2.text.get());
426
+    }
427
+
428
+    @Test
429
+    public void getButtonControllers_createdOnce() {
430
+        Options options = new Options();
431
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(textBtn1));
432
+        options.topBar.buttons.left = new ArrayList<>(Collections.singletonList(textBtn2));
433
+
434
+        uut.applyChildOptions(options, child);
435
+        List<TitleBarButtonController> buttons1 = uut.getComponentButtons(child);
436
+
437
+        uut.applyChildOptions(options, child);
438
+        List<TitleBarButtonController> buttons2 = uut.getComponentButtons(child);
439
+        for (int i = 0; i < 2; i++) {
440
+            assertThat(buttons1.get(i)).isEqualTo(buttons2.get(i));
441
+        }
442
+    }
443
+
444
+    @Test
445
+    public void applyButtons_doesNotDestroyOtherComponentButtons() {
446
+        Options options = new Options();
447
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn1));
448
+        options.topBar.buttons.left = new ArrayList<>(Collections.singletonList(componentBtn2));
449
+        uut.applyChildOptions(options, child);
450
+        List<TitleBarButtonController> buttons = uut.getComponentButtons(child);
451
+        forEach(buttons, ViewController::ensureViewIsCreated);
452
+
453
+        uut.applyChildOptions(options, otherChild);
454
+        for (TitleBarButtonController button : buttons) {
455
+            assertThat(button.isDestroyed()).isFalse();
456
+        }
457
+    }
458
+
459
+    @Test
460
+    public void onChildDestroyed_destroyedButtons() {
461
+        Options options = new Options();
462
+        options.topBar.buttons.right = new ArrayList<>(Collections.singletonList(componentBtn1));
463
+        options.topBar.buttons.left = new ArrayList<>(Collections.singletonList(componentBtn2));
464
+        uut.applyChildOptions(options, child);
465
+        List<TitleBarButtonController> buttons = uut.getComponentButtons(child);
466
+        forEach(buttons, ViewController::ensureViewIsCreated);
467
+
468
+        uut.onChildDestroyed(child);
469
+        for (TitleBarButtonController button : buttons) {
470
+            assertThat(button.isDestroyed()).isTrue();
471
+        }
472
+        assertThat(uut.getComponentButtons(child, null)).isNull();
473
+    }
474
+
333
     private void assertTopBarOptions(Options options, int t) {
475
     private void assertTopBarOptions(Options options, int t) {
334
         if (options.topBar.title.component.hasValue()) {
476
         if (options.topBar.title.component.hasValue()) {
335
             verify(topBar, times(0)).setTitle(any());
477
             verify(topBar, times(0)).setTitle(any());

+ 11
- 48
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TitleBarTest.java Vedi File

4
 import android.view.View;
4
 import android.view.View;
5
 
5
 
6
 import com.reactnativenavigation.BaseTest;
6
 import com.reactnativenavigation.BaseTest;
7
-import com.reactnativenavigation.mocks.ImageLoaderMock;
8
-import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
9
 import com.reactnativenavigation.parse.params.Button;
7
 import com.reactnativenavigation.parse.params.Button;
10
 import com.reactnativenavigation.parse.params.Text;
8
 import com.reactnativenavigation.parse.params.Text;
11
 import com.reactnativenavigation.react.Constants;
9
 import com.reactnativenavigation.react.Constants;
12
 import com.reactnativenavigation.react.ReactView;
10
 import com.reactnativenavigation.react.ReactView;
11
+import com.reactnativenavigation.utils.CollectionUtils;
13
 import com.reactnativenavigation.views.titlebar.TitleBar;
12
 import com.reactnativenavigation.views.titlebar.TitleBar;
14
 
13
 
15
 import org.junit.Test;
14
 import org.junit.Test;
21
 import java.util.List;
20
 import java.util.List;
22
 import java.util.Map;
21
 import java.util.Map;
23
 
22
 
23
+import static com.reactnativenavigation.utils.TitleBarHelper.createButtonController;
24
 import static org.assertj.core.api.Java6Assertions.assertThat;
24
 import static org.assertj.core.api.Java6Assertions.assertThat;
25
 import static org.mockito.Mockito.spy;
25
 import static org.mockito.Mockito.spy;
26
-import static org.mockito.Mockito.times;
27
 import static org.mockito.Mockito.verify;
26
 import static org.mockito.Mockito.verify;
28
 
27
 
29
 public class TitleBarTest extends BaseTest {
28
 public class TitleBarTest extends BaseTest {
32
     private Button leftButton;
31
     private Button leftButton;
33
     private Button textButton;
32
     private Button textButton;
34
     private Button customButton;
33
     private Button customButton;
35
-    private Map<String, TopBarButtonController> buttonControllers;
34
+    private Map<String, TitleBarButtonController> buttonControllers;
36
     private Activity activity;
35
     private Activity activity;
37
 
36
 
38
     @Override
37
     @Override
39
     public void beforeEach() {
38
     public void beforeEach() {
40
-        final TopBarButtonCreatorMock buttonCreator = new TopBarButtonCreatorMock();
41
         activity = newActivity();
39
         activity = newActivity();
42
         createButtons();
40
         createButtons();
43
         buttonControllers = new HashMap<>();
41
         buttonControllers = new HashMap<>();
44
-        uut = spy(new TitleBar(activity, buttonCreator, buttonId -> {}, ImageLoaderMock.mock()) {
45
-            @Override
46
-            public TopBarButtonController createButtonController(Button button) {
47
-                TopBarButtonController controller = spy(super.createButtonController(button));
48
-                buttonControllers.put(button.id, controller);
49
-                return controller;
50
-            }
51
-        });
42
+        uut = spy(new TitleBar(activity));
52
     }
43
     }
53
 
44
 
54
     private void createButtons() {
45
     private void createButtons() {
80
         assertThat(btnView.getComponentName()).isEqualTo(customButton.component.name.get());
71
         assertThat(btnView.getComponentName()).isEqualTo(customButton.component.name.get());
81
     }
72
     }
82
 
73
 
83
-    @Test
84
-    public void destroy_destroysButtonControllers() {
85
-        uut.setLeftButtons(leftButton(leftButton));
86
-        uut.setRightButtons(rightButtons(customButton, textButton));
87
-        uut.clear();
88
-        for (TopBarButtonController controller : buttonControllers.values()) {
89
-            verify(controller, times(1)).destroy();
90
-        }
91
-    }
92
-
93
-    @Test
94
-    public void setRightButtons_destroysRightButtons() {
95
-        uut.setRightButtons(rightButtons(customButton));
96
-        uut.setLeftButtons(leftButton(leftButton));
97
-        uut.setRightButtons(rightButtons(textButton));
98
-        verify(buttonControllers.get(customButton.id), times(1)).destroy();
99
-    }
100
-
101
-    @Test
102
-    public void setRightButtons_onlyDestroysRightButtons() {
103
-        uut.setLeftButtons(leftButton(leftButton));
104
-        uut.setRightButtons(rightButtons(customButton));
105
-        uut.setLeftButtons(null);
106
-        uut.setRightButtons(rightButtons(textButton));
107
-        verify(buttonControllers.get(leftButton.id), times(0)).destroy();
108
-    }
109
-
110
     @Test
74
     @Test
111
     public void setRightButtons_emptyButtonsListClearsRightButtons() {
75
     public void setRightButtons_emptyButtonsListClearsRightButtons() {
112
         uut.setLeftButtons(new ArrayList<>());
76
         uut.setLeftButtons(new ArrayList<>());
113
         uut.setRightButtons(rightButtons(customButton, textButton));
77
         uut.setRightButtons(rightButtons(customButton, textButton));
114
         uut.setLeftButtons(new ArrayList<>());
78
         uut.setLeftButtons(new ArrayList<>());
115
         uut.setRightButtons(new ArrayList<>());
79
         uut.setRightButtons(new ArrayList<>());
116
-        for (TopBarButtonController controller : buttonControllers.values()) {
117
-            verify(controller, times(1)).destroy();
118
-        }
119
         assertThat(uut.getMenu().size()).isEqualTo(0);
80
         assertThat(uut.getMenu().size()).isEqualTo(0);
120
     }
81
     }
121
 
82
 
123
     public void setLeftButtons_emptyButtonsListClearsLeftButton() {
84
     public void setLeftButtons_emptyButtonsListClearsLeftButton() {
124
         uut.setLeftButtons(leftButton(leftButton));
85
         uut.setLeftButtons(leftButton(leftButton));
125
         uut.setRightButtons(rightButtons(customButton));
86
         uut.setRightButtons(rightButtons(customButton));
87
+        assertThat(uut.getNavigationIcon()).isNotNull();
88
+
126
         uut.setLeftButtons(new ArrayList<>());
89
         uut.setLeftButtons(new ArrayList<>());
127
         uut.setRightButtons(rightButtons(textButton));
90
         uut.setRightButtons(rightButtons(textButton));
128
-        verify(buttonControllers.get(leftButton.id), times(1)).destroy();
91
+        assertThat(uut.getNavigationIcon()).isNull();
129
     }
92
     }
130
 
93
 
131
     @Test
94
     @Test
155
         verify(uut).removeView(title);
118
         verify(uut).removeView(title);
156
     }
119
     }
157
 
120
 
158
-    private List<Button> leftButton(Button leftButton) {
159
-        return Collections.singletonList(leftButton);
121
+    private List<TitleBarButtonController> leftButton(Button leftButton) {
122
+        return Collections.singletonList(createButtonController(activity, uut, leftButton));
160
     }
123
     }
161
 
124
 
162
-    private List<Button> rightButtons(Button... buttons) {
163
-        return Arrays.asList(buttons);
125
+    private List<TitleBarButtonController> rightButtons(Button... buttons) {
126
+        return CollectionUtils.map(Arrays.asList(buttons), button -> createButtonController(activity, uut, button));
164
     }
127
     }
165
 }
128
 }

+ 2
- 2
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopBarButtonControllerTest.java Vedi File

32
 
32
 
33
 public class TopBarButtonControllerTest extends BaseTest {
33
 public class TopBarButtonControllerTest extends BaseTest {
34
 
34
 
35
-    private TopBarButtonController uut;
35
+    private TitleBarButtonController uut;
36
     private StackController stackController;
36
     private StackController stackController;
37
     private Button button;
37
     private Button button;
38
     private ButtonOptionsPresenter optionsPresenter;
38
     private ButtonOptionsPresenter optionsPresenter;
53
         getTitleBar().layout(0, 0, 1080, 200);
53
         getTitleBar().layout(0, 0, 1080, 200);
54
 
54
 
55
         optionsPresenter = spy(new ButtonOptionsPresenter(getTitleBar(), button));
55
         optionsPresenter = spy(new ButtonOptionsPresenter(getTitleBar(), button));
56
-        uut = new TopBarButtonController(activity, new NavigationIconResolver(activity, ImageLoaderMock.mock()), ImageLoaderMock.mock(), optionsPresenter, button, buttonCreatorMock, (buttonId) -> {});
56
+        uut = new TitleBarButtonController(activity, new NavigationIconResolver(activity, ImageLoaderMock.mock()), ImageLoaderMock.mock(), optionsPresenter, button, buttonCreatorMock, (buttonId) -> {});
57
 
57
 
58
         stackController.ensureViewIsCreated();
58
         stackController.ensureViewIsCreated();
59
     }
59
     }

+ 5
- 7
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopBarControllerTest.java Vedi File

6
 
6
 
7
 import com.reactnativenavigation.BaseTest;
7
 import com.reactnativenavigation.BaseTest;
8
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
8
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
9
-import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
10
-import com.reactnativenavigation.utils.ImageLoader;
11
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
9
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
12
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
10
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
13
 import com.reactnativenavigation.views.StackLayout;
11
 import com.reactnativenavigation.views.StackLayout;
36
         uut = new TopBarController() {
34
         uut = new TopBarController() {
37
             @NonNull
35
             @NonNull
38
             @Override
36
             @Override
39
-            protected TopBar createTopBar(Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener topBarButtonClickListener, StackLayout stackLayout, ImageLoader imageLoader) {
40
-                return new TopBar(context, buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, stackLayout, imageLoader) {
37
+            protected TopBar createTopBar(Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout stackLayout) {
38
+                return new TopBar(context, topBarBackgroundViewController, stackLayout) {
41
                     @Override
39
                     @Override
42
-                    protected TitleBar createTitleBar(Context context, ReactViewCreator buttonCreator, TopBarButtonController.OnClickListener onClickListener, ImageLoader imageLoader) {
43
-                        titleBar[0] = spy(super.createTitleBar(context, buttonCreator, onClickListener, imageLoader));
40
+                    protected TitleBar createTitleBar(Context context) {
41
+                        titleBar[0] = spy(super.createTitleBar(context));
44
                         return titleBar[0];
42
                         return titleBar[0];
45
                     }
43
                     }
46
                 };
44
                 };
47
             }
45
             }
48
         };
46
         };
49
         Activity activity = newActivity();
47
         Activity activity = newActivity();
50
-        uut.createView(activity, new TopBarButtonCreatorMock(), new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock()), buttonId -> {}, Mockito.mock(StackLayout.class));
48
+        uut.createView(activity, new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock()), Mockito.mock(StackLayout.class));
51
         uut.clear();
49
         uut.clear();
52
         verify(titleBar[0], times(1)).clear();
50
         verify(titleBar[0], times(1)).clear();
53
     }
51
     }

+ 8
- 13
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/stack/StackControllerTest.java Vedi File

16
 import com.reactnativenavigation.parse.NestedAnimationsOptions;
16
 import com.reactnativenavigation.parse.NestedAnimationsOptions;
17
 import com.reactnativenavigation.parse.Options;
17
 import com.reactnativenavigation.parse.Options;
18
 import com.reactnativenavigation.parse.params.Bool;
18
 import com.reactnativenavigation.parse.params.Bool;
19
-import com.reactnativenavigation.parse.params.Button;
20
 import com.reactnativenavigation.parse.params.Text;
19
 import com.reactnativenavigation.parse.params.Text;
21
 import com.reactnativenavigation.presentation.StackOptionsPresenter;
20
 import com.reactnativenavigation.presentation.StackOptionsPresenter;
22
 import com.reactnativenavigation.utils.CommandListenerAdapter;
21
 import com.reactnativenavigation.utils.CommandListenerAdapter;
23
 import com.reactnativenavigation.utils.ImageLoader;
22
 import com.reactnativenavigation.utils.ImageLoader;
23
+import com.reactnativenavigation.utils.TitleBarHelper;
24
 import com.reactnativenavigation.utils.ViewHelper;
24
 import com.reactnativenavigation.utils.ViewHelper;
25
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
25
 import com.reactnativenavigation.viewcontrollers.ChildControllersRegistry;
26
 import com.reactnativenavigation.viewcontrollers.ParentController;
26
 import com.reactnativenavigation.viewcontrollers.ParentController;
27
-import com.reactnativenavigation.viewcontrollers.ReactViewCreator;
28
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
29
 import com.reactnativenavigation.viewcontrollers.ViewController;
27
 import com.reactnativenavigation.viewcontrollers.ViewController;
30
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
28
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
31
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
29
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
76
         backButtonHelper = spy(new BackButtonHelper());
74
         backButtonHelper = spy(new BackButtonHelper());
77
         activity = newActivity();
75
         activity = newActivity();
78
         childRegistry = new ChildControllersRegistry();
76
         childRegistry = new ChildControllersRegistry();
79
-        presenter = spy(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()));
77
+        presenter = spy(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), ImageLoaderMock.mock(), new Options()));
80
         child1 = spy(new SimpleViewController(activity, childRegistry, "child1", new Options()));
78
         child1 = spy(new SimpleViewController(activity, childRegistry, "child1", new Options()));
81
         child2 = spy(new SimpleViewController(activity, childRegistry, "child2", new Options()));
79
         child2 = spy(new SimpleViewController(activity, childRegistry, "child2", new Options()));
82
         child3 = spy(new SimpleViewController(activity, childRegistry, "child3", new Options()));
80
         child3 = spy(new SimpleViewController(activity, childRegistry, "child3", new Options()));
130
         disablePushAnimation(child1, child2);
128
         disablePushAnimation(child1, child2);
131
         uut.push(child1, new CommandListenerAdapter());
129
         uut.push(child1, new CommandListenerAdapter());
132
 
130
 
133
-        Button leftButton = new Button();
134
-        leftButton.id = "someButton";
135
-        leftButton.icon = new Text("icon.png");
136
-        child2.options.topBar.buttons.left = new ArrayList<>(Collections.singleton(leftButton));
131
+        child2.options.topBar.buttons.left = new ArrayList<>(Collections.singleton(TitleBarHelper.iconButton("someButton", "icon.png")));
137
 
132
 
138
         uut.push(child2, new CommandListenerAdapter());
133
         uut.push(child2, new CommandListenerAdapter());
139
         child2.onViewAppeared();
134
         child2.onViewAppeared();
238
                         .setTopBarController(new TopBarController())
233
                         .setTopBarController(new TopBarController())
239
                         .setId("uut")
234
                         .setId("uut")
240
                         .setInitialOptions(new Options())
235
                         .setInitialOptions(new Options())
241
-                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()))
236
+                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new Options()))
242
                         .build();
237
                         .build();
243
         uut.ensureViewIsCreated();
238
         uut.ensureViewIsCreated();
244
         uut.push(child1, new CommandListenerAdapter());
239
         uut.push(child1, new CommandListenerAdapter());
763
                         .setTopBarController(new TopBarController())
758
                         .setTopBarController(new TopBarController())
764
                         .setId("stack")
759
                         .setId("stack")
765
                         .setInitialOptions(new Options())
760
                         .setInitialOptions(new Options())
766
-                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()))
761
+                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new Options()))
767
                         .build());
762
                         .build());
768
         Options optionsToMerge = new Options();
763
         Options optionsToMerge = new Options();
769
         Component component = mock(Component.class);
764
         Component component = mock(Component.class);
779
                         .setTopBarController(new TopBarController())
774
                         .setTopBarController(new TopBarController())
780
                         .setId("stack")
775
                         .setId("stack")
781
                         .setInitialOptions(new Options())
776
                         .setInitialOptions(new Options())
782
-                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new Options()))
777
+                        .setStackPresenter(new StackOptionsPresenter(activity, new TitleBarReactViewCreatorMock(), new TopBarButtonCreatorMock(), new ImageLoader(), new Options()))
783
                         .build();
778
                         .build();
784
         ParentController parentController = Mockito.mock(ParentController.class);
779
         ParentController parentController = Mockito.mock(ParentController.class);
785
         uut.setParentController(parentController);
780
         uut.setParentController(parentController);
856
     private void createTopBarController() {
851
     private void createTopBarController() {
857
         topBarController = spy(new TopBarController() {
852
         topBarController = spy(new TopBarController() {
858
             @Override
853
             @Override
859
-            protected TopBar createTopBar(Context context, ReactViewCreator buttonCreator, TopBarBackgroundViewController topBarBackgroundViewController, TopBarButtonController.OnClickListener topBarButtonClickListener, StackLayout stackLayout, ImageLoader imageLoader) {
860
-                TopBar spy = spy(super.createTopBar(context, buttonCreator, topBarBackgroundViewController, topBarButtonClickListener, stackLayout, ImageLoaderMock.mock()));
854
+            protected TopBar createTopBar(Context context, TopBarBackgroundViewController topBarBackgroundViewController, StackLayout stackLayout) {
855
+                TopBar spy = spy(super.createTopBar(context, topBarBackgroundViewController, stackLayout));
861
                 spy.layout(0, 0, 1000, 100);
856
                 spy.layout(0, 0, 1000, 100);
862
                 return spy;
857
                 return spy;
863
             }
858
             }

+ 2
- 12
lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarBackgroundComponentTest.java Vedi File

1
 package com.reactnativenavigation.views;
1
 package com.reactnativenavigation.views;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
-import android.util.Log;
5
 import android.view.View;
4
 import android.view.View;
6
 import android.view.ViewGroup;
5
 import android.view.ViewGroup;
7
 
6
 
8
 import com.reactnativenavigation.BaseTest;
7
 import com.reactnativenavigation.BaseTest;
9
 import com.reactnativenavigation.R;
8
 import com.reactnativenavigation.R;
10
-import com.reactnativenavigation.mocks.ImageLoaderMock;
11
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
9
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
12
-import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
13
 import com.reactnativenavigation.parse.Component;
10
 import com.reactnativenavigation.parse.Component;
14
 import com.reactnativenavigation.parse.params.Text;
11
 import com.reactnativenavigation.parse.params.Text;
15
 import com.reactnativenavigation.utils.ViewUtils;
12
 import com.reactnativenavigation.utils.ViewUtils;
16
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
17
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
13
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
18
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
14
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
19
 import com.reactnativenavigation.views.topbar.TopBar;
15
 import com.reactnativenavigation.views.topbar.TopBar;
33
     @SuppressWarnings("Convert2Lambda")
29
     @SuppressWarnings("Convert2Lambda")
34
     @Override
30
     @Override
35
     public void beforeEach() {
31
     public void beforeEach() {
36
-        TopBarButtonController.OnClickListener onClickListener = spy(new TopBarButtonController.OnClickListener() {
37
-            @Override
38
-            public void onPress(String buttonId) {
39
-                Log.i("TopBarTest", "onPress: " + buttonId);
40
-            }
41
-        });
42
         Activity activity = newActivity();
32
         Activity activity = newActivity();
43
         topBarBackgroundViewController = spy(new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock()));
33
         topBarBackgroundViewController = spy(new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock()));
44
-        StackLayout parent = new StackLayout(activity, new TopBarButtonCreatorMock(), topBarBackgroundViewController, new TopBarController(), onClickListener, null);
45
-        uut = new TopBar(activity, new TopBarButtonCreatorMock(), topBarBackgroundViewController, onClickListener, parent, ImageLoaderMock.mock());
34
+        StackLayout parent = new StackLayout(activity, topBarBackgroundViewController, new TopBarController(), null);
35
+        uut = new TopBar(activity, topBarBackgroundViewController, parent);
46
         parent.addView(uut);
36
         parent.addView(uut);
47
     }
37
     }
48
 
38
 

+ 2
- 45
lib/android/app/src/test/java/com/reactnativenavigation/views/TopBarTest.java Vedi File

1
 package com.reactnativenavigation.views;
1
 package com.reactnativenavigation.views;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
-import android.util.Log;
5
-import android.view.MenuItem;
6
 
4
 
7
 import com.reactnativenavigation.BaseTest;
5
 import com.reactnativenavigation.BaseTest;
8
 import com.reactnativenavigation.anim.TopBarAnimator;
6
 import com.reactnativenavigation.anim.TopBarAnimator;
9
-import com.reactnativenavigation.mocks.ImageLoaderMock;
10
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
7
 import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
11
-import com.reactnativenavigation.mocks.TopBarButtonCreatorMock;
12
 import com.reactnativenavigation.parse.AnimationOptions;
8
 import com.reactnativenavigation.parse.AnimationOptions;
13
-import com.reactnativenavigation.parse.params.Button;
14
-import com.reactnativenavigation.parse.params.Number;
15
-import com.reactnativenavigation.parse.params.Text;
16
-import com.reactnativenavigation.utils.TitleBarHelper;
17
-import com.reactnativenavigation.viewcontrollers.TopBarButtonController;
18
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
9
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarBackgroundViewController;
19
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
10
 import com.reactnativenavigation.viewcontrollers.topbar.TopBarController;
20
 import com.reactnativenavigation.views.topbar.TopBar;
11
 import com.reactnativenavigation.views.topbar.TopBar;
21
 
12
 
22
 import org.junit.Test;
13
 import org.junit.Test;
23
 
14
 
24
-import java.util.ArrayList;
25
-
26
 import static org.assertj.core.api.Java6Assertions.assertThat;
15
 import static org.assertj.core.api.Java6Assertions.assertThat;
27
 import static org.mockito.ArgumentMatchers.any;
16
 import static org.mockito.ArgumentMatchers.any;
28
 import static org.mockito.ArgumentMatchers.eq;
17
 import static org.mockito.ArgumentMatchers.eq;
34
 
23
 
35
     private TopBar uut;
24
     private TopBar uut;
36
     private TopBarAnimator animator;
25
     private TopBarAnimator animator;
37
-    private ArrayList<Button> rightButtons;
38
-    private TopBarButtonController.OnClickListener onClickListener;
39
 
26
 
40
     @SuppressWarnings("Convert2Lambda")
27
     @SuppressWarnings("Convert2Lambda")
41
     @Override
28
     @Override
42
     public void beforeEach() {
29
     public void beforeEach() {
43
-        onClickListener = spy(new TopBarButtonController.OnClickListener() {
44
-            @Override
45
-            public void onPress(String buttonId) {
46
-                Log.i("TopBarTest", "onPress: " + buttonId);
47
-            }
48
-        });
49
         Activity activity = newActivity();
30
         Activity activity = newActivity();
50
         TopBarBackgroundViewController topBarBackgroundViewController = new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock());
31
         TopBarBackgroundViewController topBarBackgroundViewController = new TopBarBackgroundViewController(activity, new TopBarBackgroundViewCreatorMock());
51
-        StackLayout parent = new StackLayout(activity, new TopBarButtonCreatorMock(), topBarBackgroundViewController, new TopBarController(), this.onClickListener, null);
52
-        uut = new TopBar(activity, new TopBarButtonCreatorMock(), topBarBackgroundViewController, this.onClickListener, parent, ImageLoaderMock.mock());
32
+        StackLayout parent = new StackLayout(activity, topBarBackgroundViewController, new TopBarController(), null);
33
+        uut = new TopBar(activity, topBarBackgroundViewController, parent);
53
         animator = spy(new TopBarAnimator(uut));
34
         animator = spy(new TopBarAnimator(uut));
54
         uut.setAnimator(animator);
35
         uut.setAnimator(animator);
55
-        rightButtons = createRightButtons();
56
         parent.addView(uut);
36
         parent.addView(uut);
57
     }
37
     }
58
 
38
 
59
-    private ArrayList<Button> createRightButtons() {
60
-        ArrayList<Button> result = new ArrayList<>();
61
-        for (int i = 0; i < 2; i++) {
62
-            Button button = new Button();
63
-            button.id = "rightButtons" + i;
64
-            button.text = new Text("btn" + i);
65
-            button.showAsAction = new Number(MenuItem.SHOW_AS_ACTION_ALWAYS);
66
-            result.add(spy(button));
67
-        }
68
-        return result;
69
-    }
70
-
71
     @Test
39
     @Test
72
     public void title() {
40
     public void title() {
73
         assertThat(uut.getTitle()).isEmpty();
41
         assertThat(uut.getTitle()).isEmpty();
89
         uut.showAnimate(options);
57
         uut.showAnimate(options);
90
         verify(animator, times(1)).show(options);
58
         verify(animator, times(1)).show(options);
91
     }
59
     }
92
-
93
-    @Test
94
-    public void button_TitleBarButtonOnClickInvoked() {
95
-        uut.setLeftButtons(new ArrayList<>());
96
-        uut.setRightButtons(rightButtons);
97
-        for (int i = 0; i < rightButtons.size(); i++) {
98
-            Button rightButton = rightButtons.get(i);
99
-            TitleBarHelper.getRightButton(uut.getTitleBar(), i).callOnClick();
100
-            verify(onClickListener, times(1)).onPress(rightButton.id);
101
-        }
102
-    }
103
 }
60
 }

+ 5
- 6
lib/android/app/src/test/java/com/reactnativenavigation/views/element/TransitionAnimatorCreatorTest.java Vedi File

1
 package com.reactnativenavigation.views.element;
1
 package com.reactnativenavigation.views.element;
2
 
2
 
3
 import android.app.Activity;
3
 import android.app.Activity;
4
-import android.view.View;
5
 
4
 
6
 import com.reactnativenavigation.BaseTest;
5
 import com.reactnativenavigation.BaseTest;
7
 import com.reactnativenavigation.parse.Transition;
6
 import com.reactnativenavigation.parse.Transition;
13
 import java.util.Arrays;
12
 import java.util.Arrays;
14
 import java.util.List;
13
 import java.util.List;
15
 
14
 
16
-import static com.reactnativenavigation.utils.CollectionUtils.map;
15
+import static com.reactnativenavigation.utils.CollectionUtils.keyBy;
17
 import static com.reactnativenavigation.views.element.TransitionTestUtils.createElement;
16
 import static com.reactnativenavigation.views.element.TransitionTestUtils.createElement;
18
 import static com.reactnativenavigation.views.element.TransitionTestUtils.createTransition;
17
 import static com.reactnativenavigation.views.element.TransitionTestUtils.createTransition;
19
 import static org.mockito.Mockito.spy;
18
 import static org.mockito.Mockito.spy;
56
         TransitionAnimatorCreator spy = spy(uut);
55
         TransitionAnimatorCreator spy = spy(uut);
57
         spy.create(
56
         spy.create(
58
                 Arrays.asList(t1, t2),
57
                 Arrays.asList(t1, t2),
59
-                map(Arrays.asList(e1, e3), Element::getElementId),
60
-                map(Arrays.asList(e2, e4), Element::getElementId)
58
+                keyBy(Arrays.asList(e1, e3), Element::getElementId),
59
+                keyBy(Arrays.asList(e2, e4), Element::getElementId)
61
         );
60
         );
62
         verify(spy).create(t1, e1, e2);
61
         verify(spy).create(t1, e1, e2);
63
         verify(spy).create(t2, e3, e4);
62
         verify(spy).create(t2, e3, e4);
68
         List<Transition> transitions = Arrays.asList(t1, t2);
67
         List<Transition> transitions = Arrays.asList(t1, t2);
69
         uut.create(
68
         uut.create(
70
                 transitions,
69
                 transitions,
71
-                map(Arrays.asList(e1, e3), Element::getElementId),
72
-                map(Arrays.asList(e2, e4), Element::getElementId)
70
+                keyBy(Arrays.asList(e1, e3), Element::getElementId),
71
+                keyBy(Arrays.asList(e2, e4), Element::getElementId)
73
         );
72
         );
74
         verify(animator1, times(2)).shouldAnimateProperty();
73
         verify(animator1, times(2)).shouldAnimateProperty();
75
         verify(animator2, times(2)).shouldAnimateProperty();
74
         verify(animator2, times(2)).shouldAnimateProperty();

+ 13
- 13
lib/android/app/src/test/java/com/reactnativenavigation/views/element/TransitionValidatorTest.java Vedi File

13
 
13
 
14
 import java.util.Collections;
14
 import java.util.Collections;
15
 
15
 
16
-import static com.reactnativenavigation.utils.CollectionUtils.map;
16
+import static com.reactnativenavigation.utils.CollectionUtils.keyBy;
17
 import static org.assertj.core.api.Java6Assertions.assertThat;
17
 import static org.assertj.core.api.Java6Assertions.assertThat;
18
 
18
 
19
 public class TransitionValidatorTest extends BaseTest {
19
 public class TransitionValidatorTest extends BaseTest {
50
         transition.toId = new NullText();
50
         transition.toId = new NullText();
51
         boolean result = uut.validate(
51
         boolean result = uut.validate(
52
                 transition,
52
                 transition,
53
-                map(Collections.singletonList(from1), Element::getElementId),
54
-                map(Collections.singletonList(from1), Element::getElementId)
53
+                keyBy(Collections.singletonList(from1), Element::getElementId),
54
+                keyBy(Collections.singletonList(from1), Element::getElementId)
55
         );
55
         );
56
         assertThat(result).isFalse();
56
         assertThat(result).isFalse();
57
     }
57
     }
61
         transition.fromId = new NullText();
61
         transition.fromId = new NullText();
62
         boolean result = uut.validate(
62
         boolean result = uut.validate(
63
                 transition,
63
                 transition,
64
-                map(Collections.singletonList(from1), Element::getElementId),
65
-                map(Collections.singletonList(from1), Element::getElementId)
64
+                keyBy(Collections.singletonList(from1), Element::getElementId),
65
+                keyBy(Collections.singletonList(from1), Element::getElementId)
66
         );
66
         );
67
         assertThat(result).isFalse();
67
         assertThat(result).isFalse();
68
     }
68
     }
71
     public void validate_falseIfFromElementRequiredByTransitionDontExist() {
71
     public void validate_falseIfFromElementRequiredByTransitionDontExist() {
72
         boolean result = uut.validate(
72
         boolean result = uut.validate(
73
                 invalidFromElementTransition,
73
                 invalidFromElementTransition,
74
-                map(Collections.singletonList(from1), Element::getElementId),
75
-                map(Collections.singletonList(to1), Element::getElementId)
74
+                keyBy(Collections.singletonList(from1), Element::getElementId),
75
+                keyBy(Collections.singletonList(to1), Element::getElementId)
76
         );
76
         );
77
         assertThat(result).isFalse();
77
         assertThat(result).isFalse();
78
     }
78
     }
81
     public void validate_falseIfToElementRequiredByTransitionDontExist() {
81
     public void validate_falseIfToElementRequiredByTransitionDontExist() {
82
         boolean result = uut.validate(
82
         boolean result = uut.validate(
83
                 invalidToElementTransition,
83
                 invalidToElementTransition,
84
-                map(Collections.singletonList(from1), Element::getElementId),
85
-                map(Collections.singletonList(to1), Element::getElementId)
84
+                keyBy(Collections.singletonList(from1), Element::getElementId),
85
+                keyBy(Collections.singletonList(to1), Element::getElementId)
86
         );
86
         );
87
         assertThat(result).isFalse();
87
         assertThat(result).isFalse();
88
     }
88
     }
91
     public void validate_trueIfElementsRequiredByTransitionExist() {
91
     public void validate_trueIfElementsRequiredByTransitionExist() {
92
         boolean result = uut.validate(
92
         boolean result = uut.validate(
93
                 transition,
93
                 transition,
94
-                map(Collections.singletonList(from1), Element::getElementId),
95
-                map(Collections.singletonList(to1), Element::getElementId)
94
+                keyBy(Collections.singletonList(from1), Element::getElementId),
95
+                keyBy(Collections.singletonList(to1), Element::getElementId)
96
         );
96
         );
97
         assertThat(result).isTrue();
97
         assertThat(result).isTrue();
98
     }
98
     }
102
         transition.duration = new NullNumber();
102
         transition.duration = new NullNumber();
103
         boolean result = uut.validate(
103
         boolean result = uut.validate(
104
                 transition,
104
                 transition,
105
-                map(Collections.singletonList(from1), Element::getElementId),
106
-                map(Collections.singletonList(to1), Element::getElementId)
105
+                keyBy(Collections.singletonList(from1), Element::getElementId),
106
+                keyBy(Collections.singletonList(to1), Element::getElementId)
107
         );
107
         );
108
         assertThat(result).isFalse();
108
         assertThat(result).isFalse();
109
     }
109
     }

+ 1
- 1
scripts/test-e2e.js Vedi File

21
     if (!skipBuild) {
21
     if (!skipBuild) {
22
         exec.execSync(`detox build --configuration ${configuration}`);
22
         exec.execSync(`detox build --configuration ${configuration}`);
23
     }
23
     }
24
-    exec.execSync(`detox test --configuration ${configuration} --platform ${platform} ${cleanup} ${headless$} ${!android ? `-w ${workers}` : ``}`);
24
+    exec.execSync(`detox test --configuration ${configuration} --platform ${platform} ${cleanup} ${headless$} ${!android ? `-w ${workers}` : ``}`); //--loglevel trace
25
 }
25
 }