Browse Source

V2 async (#2163)

* push/pop promise

* tests

* modal

* other

* fix tests

* probably test fix
Roman Kozlov 7 years ago
parent
commit
55cd3f51a7

+ 2
- 1
README.md View File

@@ -69,7 +69,8 @@ v2 is written in Test Driven Development. We have a test for every feature inclu
69 69
 | dismissOverlay             |  [Contribute](/docs/docs/CONTRIBUTING.md)         |	WIP @cool04ek |
70 70
 | customTransition            |   ✅        |	[Contribute](/docs/docs/CONTRIBUTING.md) |
71 71
 | Screen Visibility        | ✅     |✅|
72
-| async commands (await push)     |  [Contribute](/docs/docs/CONTRIBUTING.md)        | WIP @cool04ek   |
72
+| async commands (await push)     |  [Contribute](/docs/docs/CONTRIBUTING.md)        | ✅   |
73
+
73 74
 
74 75
 ### Navigation Options
75 76
 

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

@@ -89,7 +89,7 @@ public class LayoutFactory {
89 89
 	private ViewController createContainerStack(LayoutNode node) {
90 90
 		StackController stackController = new StackController(activity, node.id);
91 91
 		for (LayoutNode child : node.children) {
92
-			stackController.push(create(child));
92
+			stackController.push(create(child), null);
93 93
 		}
94 94
 		return stackController;
95 95
 	}

+ 19
- 18
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java View File

@@ -3,6 +3,7 @@ package com.reactnativenavigation.react;
3 3
 import android.support.annotation.NonNull;
4 4
 
5 5
 import com.facebook.react.ReactInstanceManager;
6
+import com.facebook.react.bridge.Promise;
6 7
 import com.facebook.react.bridge.ReactApplicationContext;
7 8
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
8 9
 import com.facebook.react.bridge.ReactMethod;
@@ -35,13 +36,13 @@ public class NavigationModule extends ReactContextBaseJavaModule {
35 36
 	}
36 37
 
37 38
 	@ReactMethod
38
-	public void setRoot(final ReadableMap rawLayoutTree) {
39
+	public void setRoot(final ReadableMap rawLayoutTree, final Promise promise) {
39 40
 		final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
40 41
 		handle(new Runnable() {
41 42
 			@Override
42 43
 			public void run() {
43 44
 				final ViewController viewController = newLayoutFactory().create(layoutTree);
44
-				navigator().setRoot(viewController);
45
+				navigator().setRoot(viewController, promise);
45 46
 			}
46 47
 		});
47 48
 	}
@@ -58,86 +59,86 @@ public class NavigationModule extends ReactContextBaseJavaModule {
58 59
 	}
59 60
 
60 61
 	@ReactMethod
61
-	public void push(final String onContainerId, final ReadableMap rawLayoutTree) {
62
+	public void push(final String onContainerId, final ReadableMap rawLayoutTree, final Promise promise) {
62 63
 		final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
63 64
 		handle(new Runnable() {
64 65
 			@Override
65 66
 			public void run() {
66 67
 				final ViewController viewController = newLayoutFactory().create(layoutTree);
67
-				navigator().push(onContainerId, viewController);
68
+				navigator().push(onContainerId, viewController, promise);
68 69
 			}
69 70
 		});
70 71
 	}
71 72
 
72 73
 	@ReactMethod
73
-	public void pop(final String onContainerId) {
74
+	public void pop(final String onContainerId, final Promise promise) {
74 75
 		handle(new Runnable() {
75 76
 			@Override
76 77
 			public void run() {
77
-				navigator().popSpecific(onContainerId);
78
+				navigator().popSpecific(onContainerId, promise);
78 79
 			}
79 80
 		});
80 81
 	}
81 82
 
82 83
 	@ReactMethod
83
-	public void popTo(final String containerId) {
84
+	public void popTo(final String containerId, final Promise promise) {
84 85
 		handle(new Runnable() {
85 86
 			@Override
86 87
 			public void run() {
87
-				navigator().popTo(containerId);
88
+				navigator().popTo(containerId, promise);
88 89
 			}
89 90
 		});
90 91
 	}
91 92
 
92 93
 	@ReactMethod
93
-	public void popToRoot(final String containerId) {
94
+	public void popToRoot(final String containerId, final Promise promise) {
94 95
 		handle(new Runnable() {
95 96
 			@Override
96 97
 			public void run() {
97
-				navigator().popToRoot(containerId);
98
+				navigator().popToRoot(containerId, promise);
98 99
 			}
99 100
 		});
100 101
 	}
101 102
 
102 103
 	@ReactMethod
103
-	public void showModal(final ReadableMap rawLayoutTree) {
104
+	public void showModal(final ReadableMap rawLayoutTree, final Promise promise) {
104 105
 		final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
105 106
 		handle(new Runnable() {
106 107
 			@Override
107 108
 			public void run() {
108 109
 				final ViewController viewController = newLayoutFactory().create(layoutTree);
109
-				navigator().showModal(viewController);
110
+				navigator().showModal(viewController, promise);
110 111
 			}
111 112
 		});
112 113
 	}
113 114
 
114 115
 	@ReactMethod
115
-	public void dismissModal(final String containerId) {
116
+	public void dismissModal(final String containerId, final Promise promise) {
116 117
 		handle(new Runnable() {
117 118
 			@Override
118 119
 			public void run() {
119
-				navigator().dismissModal(containerId);
120
+				navigator().dismissModal(containerId, promise);
120 121
 			}
121 122
 		});
122 123
 	}
123 124
 
124 125
 	@ReactMethod
125
-	public void dismissAllModals() {
126
+	public void dismissAllModals(final Promise promise) {
126 127
 		handle(new Runnable() {
127 128
 			@Override
128 129
 			public void run() {
129
-				navigator().dismissAllModals();
130
+				navigator().dismissAllModals(promise);
130 131
 			}
131 132
 		});
132 133
 	}
133 134
 
134 135
 	@ReactMethod
135
-	public void showOverlay(final String type, final ReadableMap options) {
136
+	public void showOverlay(final String type, final ReadableMap options, final Promise promise) {
136 137
 		final OverlayOptions overlayOptions = OverlayOptions.parse(JSONParser.parse(options));
137 138
 		handle(new Runnable() {
138 139
 			@Override
139 140
 			public void run() {
140
-				navigator().showOverlay(type, overlayOptions);
141
+				navigator().showOverlay(type, overlayOptions, promise);
141 142
 			}
142 143
 		});
143 144
 	}

+ 15
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/ModalStack.java View File

@@ -4,6 +4,7 @@ import android.app.Dialog;
4 4
 import android.support.annotation.Nullable;
5 5
 import android.view.View;
6 6
 
7
+import com.facebook.react.bridge.Promise;
7 8
 import com.reactnativenavigation.R;
8 9
 
9 10
 import java.util.ArrayList;
@@ -16,25 +17,36 @@ public class ModalStack {
16 17
 
17 18
 	private List<Modal> modals = new ArrayList<>();
18 19
 
19
-	public void showModal(final ViewController viewController) {
20
+	public void showModal(final ViewController viewController, Promise promise) {
20 21
 		Modal modal = new Modal(viewController);
21 22
 		modals.add(modal);
22 23
 		modal.show();
24
+		if (promise != null) {
25
+			promise.resolve(viewController.getId());
26
+		}
23 27
 	}
24 28
 
25
-	public void dismissModal(final String containerId) {
29
+	public void dismissModal(final String containerId, Promise promise) {
26 30
 		Modal modal = findModalByContainerId(containerId);
27 31
 		if (modal != null) {
28 32
 			modal.dismiss();
29 33
 			modals.remove(modal);
34
+			if (promise != null) {
35
+				promise.resolve(containerId);
36
+			}
37
+		} else {
38
+			Navigator.rejectPromise(promise);
30 39
 		}
31 40
 	}
32 41
 
33
-	public void dismissAll() {
42
+	public void dismissAll(Promise promise) {
34 43
 		for (Modal modal : modals) {
35 44
 			modal.dismiss();
36 45
 		}
37 46
 		modals.clear();
47
+		if (promise != null) {
48
+			promise.resolve(true);
49
+		}
38 50
 	}
39 51
 
40 52
 	@Nullable

+ 56
- 13
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java View File

@@ -5,6 +5,7 @@ import android.support.annotation.NonNull;
5 5
 import android.view.ViewGroup;
6 6
 import android.widget.FrameLayout;
7 7
 
8
+import com.facebook.react.bridge.Promise;
8 9
 import com.reactnativenavigation.parse.NavigationOptions;
9 10
 import com.reactnativenavigation.parse.OverlayOptions;
10 11
 import com.reactnativenavigation.presentation.OverlayPresenter;
@@ -43,7 +44,7 @@ public class Navigator extends ParentController {
43 44
 
44 45
 	@Override
45 46
 	public void destroy() {
46
-		modalStack.dismissAll();
47
+		modalStack.dismissAll(null);
47 48
 		super.destroy();
48 49
 	}
49 50
 
@@ -52,12 +53,19 @@ public class Navigator extends ParentController {
52 53
 	 */
53 54
 
54 55
 	public void setRoot(final ViewController viewController) {
56
+		setRoot(viewController, null);
57
+	}
58
+
59
+	public void setRoot(final ViewController viewController, Promise promise) {
55 60
 		if (root != null) {
56 61
 			root.destroy();
57 62
 		}
58 63
 
59 64
 		root = viewController;
60 65
 		getView().addView(viewController.getView());
66
+		if (promise != null) {
67
+			promise.resolve(viewController.getId());
68
+		}
61 69
 	}
62 70
 
63 71
 	public void setOptions(final String containerId, NavigationOptions options) {
@@ -68,68 +76,103 @@ public class Navigator extends ParentController {
68 76
 	}
69 77
 
70 78
 	public void push(final String fromId, final ViewController viewController) {
79
+		push(fromId, viewController, null);
80
+	}
81
+
82
+	public void push(final String fromId, final ViewController viewController, Promise promise) {
71 83
 		ViewController from = findControllerById(fromId);
72 84
 		if (from != null) {
73 85
 			StackController parentStackController = from.getParentStackController();
74 86
 			if (parentStackController != null) {
75
-				parentStackController.push(viewController);
87
+				parentStackController.push(viewController, promise);
76 88
 			}
77 89
 		}
78 90
 	}
79 91
 
80 92
 	public void pop(final String fromId) {
93
+		pop(fromId, null);
94
+	}
95
+
96
+	public void pop(final String fromId, Promise promise) {
81 97
 		ViewController from = findControllerById(fromId);
82 98
 		if (from != null) {
83 99
 			StackController parentStackController = from.getParentStackController();
84 100
 			if (parentStackController != null) {
85
-				parentStackController.pop();
101
+				parentStackController.pop(promise);
86 102
 			}
87 103
 		}
88 104
 	}
89 105
 
90 106
 	public void popSpecific(final String id) {
107
+		popSpecific(id, null);
108
+	}
109
+
110
+	public void popSpecific(final String id, Promise promise) {
91 111
 		ViewController from = findControllerById(id);
92 112
 		if (from != null) {
93 113
 			StackController parentStackController = from.getParentStackController();
94 114
 			if (parentStackController != null) {
95
-				parentStackController.popSpecific(from);
115
+				parentStackController.popSpecific(from, promise);
116
+			} else {
117
+				rejectPromise(promise);
96 118
 			}
119
+		} else {
120
+			rejectPromise(promise);
97 121
 		}
98 122
 	}
99 123
 
100 124
 	public void popToRoot(final String id) {
125
+		popToRoot(id, null);
126
+	}
127
+
128
+	public void popToRoot(final String id, Promise promise) {
101 129
 		ViewController from = findControllerById(id);
102 130
 		if (from != null) {
103 131
 			StackController parentStackController = from.getParentStackController();
104 132
 			if (parentStackController != null) {
105
-				parentStackController.popToRoot();
133
+				parentStackController.popToRoot(promise);
106 134
 			}
107 135
 		}
108 136
 	}
109 137
 
110 138
 	public void popTo(final String containerId) {
139
+		popTo(containerId, null);
140
+	}
141
+
142
+	public void popTo(final String containerId, Promise promise) {
111 143
 		ViewController target = findControllerById(containerId);
112 144
 		if (target != null) {
113 145
 			StackController parentStackController = target.getParentStackController();
114 146
 			if (parentStackController != null) {
115
-				parentStackController.popTo(target);
147
+				parentStackController.popTo(target, promise);
148
+			} else {
149
+				rejectPromise(promise);
116 150
 			}
151
+		} else {
152
+			rejectPromise(promise);
117 153
 		}
118 154
 	}
119 155
 
120
-	public void showModal(final ViewController viewController) {
121
-		modalStack.showModal(viewController);
156
+	public void showModal(final ViewController viewController, Promise promise) {
157
+		modalStack.showModal(viewController, promise);
122 158
 	}
123 159
 
124
-	public void dismissModal(final String containerId) {
125
-		modalStack.dismissModal(containerId);
160
+	public void dismissModal(final String containerId, Promise promise) {
161
+		modalStack.dismissModal(containerId, promise);
126 162
 	}
127 163
 
128
-	public void dismissAllModals() {
129
-		modalStack.dismissAll();
164
+	public void dismissAllModals(Promise promise) {
165
+		modalStack.dismissAll(promise);
130 166
 	}
131 167
 
132
-	public void showOverlay(String type, OverlayOptions options) {
168
+	public void showOverlay(String type, OverlayOptions options, Promise promise) {
133 169
 		new OverlayPresenter(getActivity(), type, options).show();
170
+		promise.resolve(true);
171
+	}
172
+
173
+	static void rejectPromise(Promise promise) {
174
+		if (promise != null) {
175
+			promise.reject(new Throwable("Nothing to pop"));
176
+		}
134 177
 	}
135 178
 }

+ 75
- 29
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java View File

@@ -1,22 +1,16 @@
1 1
 package com.reactnativenavigation.viewcontrollers;
2 2
 
3 3
 import android.app.Activity;
4
-import android.graphics.Color;
5 4
 import android.support.annotation.NonNull;
6
-import android.util.Log;
7 5
 import android.view.View;
8 6
 import android.view.ViewGroup;
9 7
 import android.widget.FrameLayout;
10
-import android.widget.LinearLayout;
11
-import android.widget.RelativeLayout;
12 8
 
9
+import com.facebook.react.bridge.Promise;
13 10
 import com.reactnativenavigation.anim.StackAnimator;
14
-import com.reactnativenavigation.utils.CompatUtils;
15
-import com.reactnativenavigation.views.TopBar;
16 11
 
17 12
 import java.util.Collection;
18
-
19
-import static android.widget.RelativeLayout.BELOW;
13
+import java.util.Iterator;
20 14
 
21 15
 public class StackController extends ParentController {
22 16
 
@@ -33,6 +27,10 @@ public class StackController extends ParentController {
33 27
 	}
34 28
 
35 29
 	public void push(final ViewController child) {
30
+		push(child, null);
31
+	}
32
+
33
+	public void push(final ViewController child, final Promise promise) {
36 34
 		final ViewController previousTop = peek();
37 35
 
38 36
 		child.setParentStackController(this);
@@ -46,18 +44,33 @@ public class StackController extends ParentController {
46 44
 				@Override
47 45
 				public void onAnimationEnd() {
48 46
 					getView().removeView(previousTop.getView());
47
+					if (promise != null) {
48
+						promise.resolve(child.getId());
49
+					}
49 50
 				}
50 51
 			});
51
-
52
+		} else if (promise != null) {
53
+			promise.resolve(child.getId());
52 54
 		}
53 55
 	}
54 56
 
55
-	public boolean canPop() {
57
+	boolean canPop() {
56 58
 		return stack.size() > 1;
57 59
 	}
58 60
 
59
-	public void pop() {
60
-		if (!canPop()) return;
61
+	void pop(Promise promise) {
62
+		pop(true, promise);
63
+	}
64
+
65
+	void pop() {
66
+		pop(true, null);
67
+	}
68
+
69
+	private void pop(boolean animate, final Promise promise) {
70
+		if (!canPop()) {
71
+			Navigator.rejectPromise(promise);
72
+			return;
73
+		}
61 74
 
62 75
 		final ViewController poppedTop = stack.pop();
63 76
 		ViewController newTop = peek();
@@ -66,41 +79,74 @@ public class StackController extends ParentController {
66 79
 		final View exitingView = poppedTop.getView();
67 80
 		getView().addView(enteringView, getView().getChildCount() - 1);
68 81
 
69
-		//TODO animatePush only when needed
70
-		animator.animatePop(exitingView, new StackAnimator.StackAnimationListener() {
71
-			@Override
72
-			public void onAnimationEnd() {
73
-				getView().removeView(exitingView);
74
-				poppedTop.destroy();
75
-			}
76
-		});
82
+		if (animate) {
83
+			animator.animatePop(exitingView, new StackAnimator.StackAnimationListener() {
84
+				@Override
85
+				public void onAnimationEnd() {
86
+					finishPopping(exitingView, poppedTop, promise);
87
+				}
88
+			});
89
+		} else {
90
+			finishPopping(exitingView, poppedTop, promise);
91
+		}
92
+	}
93
+
94
+	private void finishPopping(View exitingView, ViewController poppedTop, Promise promise) {
95
+		getView().removeView(exitingView);
96
+		poppedTop.destroy();
97
+		if (promise != null) {
98
+			promise.resolve(poppedTop.getId());
99
+		}
100
+	}
101
+
102
+	void popSpecific(final ViewController childController) {
103
+		popSpecific(childController, null);
77 104
 	}
78 105
 
79
-	public void popSpecific(final ViewController childController) {
106
+	void popSpecific(final ViewController childController, Promise promise) {
80 107
 		if (stack.isTop(childController.getId())) {
81
-			pop();
108
+			pop(promise);
82 109
 		} else {
83 110
 			stack.remove(childController.getId());
84 111
 			childController.destroy();
112
+			if (promise != null) {
113
+				promise.resolve(childController.getId());
114
+			}
85 115
 		}
86 116
 	}
87 117
 
88
-	public void popTo(final ViewController viewController) {
118
+	void popTo(ViewController viewController) {
119
+		popTo(viewController, null);
120
+	}
121
+
122
+	void popTo(final ViewController viewController, Promise promise) {
89 123
 		if (!stack.containsId(viewController.getId())) {
124
+			Navigator.rejectPromise(promise);
90 125
 			return;
91 126
 		}
92
-		while (!stack.isTop(viewController.getId())) {
93
-			pop();
127
+
128
+		Iterator<String> iterator = stack.iterator();
129
+		String currentControlId = iterator.next();
130
+		while (!viewController.getId().equals(currentControlId)) {
131
+			String nextControlId = iterator.next();
132
+			boolean animate = nextControlId.equals(viewController.getId());
133
+			pop(animate, animate ? promise : null);
134
+			currentControlId = nextControlId;
94 135
 		}
95 136
 	}
96 137
 
97
-	public void popToRoot() {
138
+	void popToRoot() {
139
+		popToRoot(null);
140
+	}
141
+
142
+	void popToRoot(Promise promise) {
98 143
 		while (canPop()) {
99
-			pop();
144
+			boolean animate = stack.size() == 2; //first element is root
145
+			pop(animate, animate ? promise : null);
100 146
 		}
101 147
 	}
102 148
 
103
-	public ViewController peek() {
149
+	ViewController peek() {
104 150
 		return stack.peek();
105 151
 	}
106 152
 
@@ -115,7 +161,7 @@ public class StackController extends ParentController {
115 161
 	@Override
116 162
 	public boolean handleBack() {
117 163
 		if (canPop()) {
118
-			pop();
164
+			pop(null);
119 165
 			return true;
120 166
 		} else {
121 167
 			return false;

+ 39
- 0
lib/android/app/src/test/java/com/reactnativenavigation/mocks/MockPromise.java View File

@@ -0,0 +1,39 @@
1
+package com.reactnativenavigation.mocks;
2
+
3
+import com.facebook.react.bridge.Promise;
4
+
5
+import javax.annotation.Nullable;
6
+
7
+
8
+public class MockPromise implements Promise {
9
+
10
+	@Override
11
+	public void resolve(@Nullable Object value) {
12
+
13
+	}
14
+
15
+	@Override
16
+	public void reject(String code, String message) {
17
+
18
+	}
19
+
20
+	@Override
21
+	public void reject(String code, Throwable e) {
22
+
23
+	}
24
+
25
+	@Override
26
+	public void reject(String code, String message, Throwable e) {
27
+
28
+	}
29
+
30
+	@Override
31
+	public void reject(String message) {
32
+
33
+	}
34
+
35
+	@Override
36
+	public void reject(Throwable reason) {
37
+
38
+	}
39
+}

+ 66
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java View File

@@ -4,6 +4,7 @@ import android.app.Activity;
4 4
 import android.support.annotation.NonNull;
5 5
 
6 6
 import com.reactnativenavigation.BaseTest;
7
+import com.reactnativenavigation.mocks.MockPromise;
7 8
 import com.reactnativenavigation.mocks.SimpleContainerViewController;
8 9
 import com.reactnativenavigation.mocks.SimpleViewController;
9 10
 import com.reactnativenavigation.mocks.TestStackAnimator;
@@ -14,6 +15,8 @@ import org.junit.Test;
14 15
 
15 16
 import java.util.Arrays;
16 17
 
18
+import javax.annotation.Nullable;
19
+
17 20
 import static org.assertj.core.api.Java6Assertions.assertThat;
18 21
 import static org.mockito.Mockito.spy;
19 22
 import static org.mockito.Mockito.times;
@@ -29,6 +32,7 @@ public class NavigatorTest extends BaseTest {
29 32
 	private ViewController child4;
30 33
 	private ViewController child5;
31 34
 
35
+
32 36
 	@Override
33 37
 	public void beforeEach() {
34 38
 		super.beforeEach();
@@ -216,4 +220,66 @@ public class NavigatorTest extends BaseTest {
216 220
 	private StackController newStack() {
217 221
 		return new StackController(activity, "stack" + CompatUtils.generateViewId(), new TestStackAnimator());
218 222
 	}
223
+
224
+	@Test
225
+	public void push_Promise() throws Exception {
226
+		final StackController stackController = newStack();
227
+		stackController.push(child1);
228
+		uut.setRoot(stackController);
229
+
230
+		assertIsChildById(uut.getView(), stackController.getView());
231
+		assertIsChildById(stackController.getView(), child1.getView());
232
+
233
+		uut.push(child1.getId(), child2, new MockPromise() {
234
+			@Override
235
+			public void resolve(@Nullable Object value) {
236
+				assertIsChildById(uut.getView(), stackController.getView());
237
+				assertIsChildById(stackController.getView(), child2.getView());
238
+			}
239
+		});
240
+	}
241
+
242
+	@Test
243
+	public void push_InvalidPushWithoutAStack_DoesNothing_Promise() throws Exception {
244
+		uut.setRoot(child1);
245
+		uut.push(child1.getId(), child2, new MockPromise() {
246
+			@Override
247
+			public void reject(String code, Throwable e) {
248
+				assertIsChildById(uut.getView(), child1.getView());
249
+			}
250
+		});
251
+
252
+	}
253
+
254
+	@Test
255
+	public void pop_InvalidDoesNothing_Promise() throws Exception {
256
+		uut.pop("123");
257
+		uut.setRoot(child1);
258
+		uut.pop(child1.getId(), new MockPromise() {
259
+			@Override
260
+			public void reject(Throwable reason) {
261
+				assertThat(uut.getChildControllers()).hasSize(1);
262
+			}
263
+		});
264
+	}
265
+
266
+	@Test
267
+	public void pop_FromCorrectStackByFindingChildId_Promise() throws Exception {
268
+		BottomTabsController bottomTabsController = newTabs();
269
+		StackController stack1 = newStack();
270
+		final StackController stack2 = newStack();
271
+		stack1.push(child1);
272
+		stack2.push(child2);
273
+		stack2.push(child3);
274
+		stack2.push(child4);
275
+		bottomTabsController.setTabs(Arrays.<ViewController>asList(stack1, stack2));
276
+		uut.setRoot(bottomTabsController);
277
+
278
+		uut.pop("child4", new MockPromise() {
279
+			@Override
280
+			public void resolve(@Nullable Object value) {
281
+				assertThat(stack2.getChildControllers()).containsOnly(child2, child3);
282
+			}
283
+		});
284
+	}
219 285
 }

+ 9
- 18
lib/src/adapters/NativeCommandsSender.js View File

@@ -6,8 +6,7 @@ class NativeCommandsSender {
6 6
   }
7 7
 
8 8
   setRoot(layoutTree) {
9
-    this.nativeCommandsModule.setRoot(layoutTree);
10
-    return Promise.resolve(layoutTree);
9
+    return this.nativeCommandsModule.setRoot(layoutTree);
11 10
   }
12 11
 
13 12
   setOptions(containerId, options) {
@@ -15,38 +14,31 @@ class NativeCommandsSender {
15 14
   }
16 15
 
17 16
   push(onContainerId, layout) {
18
-    this.nativeCommandsModule.push(onContainerId, layout);
19
-    return Promise.resolve(layout);
17
+    return this.nativeCommandsModule.push(onContainerId, layout);
20 18
   }
21 19
 
22 20
   pop(containerId) {
23
-    this.nativeCommandsModule.pop(containerId);
24
-    return Promise.resolve(containerId);
21
+    return this.nativeCommandsModule.pop(containerId);
25 22
   }
26 23
 
27 24
   popTo(containerId) {
28
-    this.nativeCommandsModule.popTo(containerId);
29
-    return Promise.resolve(containerId);
25
+    return this.nativeCommandsModule.popTo(containerId);
30 26
   }
31 27
 
32 28
   popToRoot(containerId) {
33
-    this.nativeCommandsModule.popToRoot(containerId);
34
-    return Promise.resolve(containerId);
29
+    return this.nativeCommandsModule.popToRoot(containerId);
35 30
   }
36 31
 
37 32
   showModal(layout) {
38
-    this.nativeCommandsModule.showModal(layout);
39
-    return Promise.resolve(layout);
33
+    return this.nativeCommandsModule.showModal(layout);
40 34
   }
41 35
 
42 36
   dismissModal(containerId) {
43
-    this.nativeCommandsModule.dismissModal(containerId);
44
-    return Promise.resolve(containerId);
37
+    return this.nativeCommandsModule.dismissModal(containerId);
45 38
   }
46 39
 
47 40
   dismissAllModals() {
48
-    this.nativeCommandsModule.dismissAllModals();
49
-    return Promise.resolve(true);
41
+    return this.nativeCommandsModule.dismissAllModals();
50 42
   }
51 43
 
52 44
   switchToTab(containerId, tabIndex) {
@@ -55,8 +47,7 @@ class NativeCommandsSender {
55 47
   }
56 48
 
57 49
   showOverlay(type, options) {
58
-    this.nativeCommandsModule.showOverlay(type, options);
59
-    return Promise.resolve(type);
50
+    return this.nativeCommandsModule.showOverlay(type, options);
60 51
   }
61 52
 }
62 53
 

+ 2
- 2
playground/src/containers/ModalScreen.js View File

@@ -54,8 +54,8 @@ class ModalScreen extends Component {
54 54
     });
55 55
   }
56 56
 
57
-  onClickDismissModal() {
58
-    Navigation.dismissModal(this.props.containerId);
57
+  async onClickDismissModal() {
58
+    await Navigation.dismissModal(this.props.containerId);
59 59
   }
60 60
 
61 61
   onClickDismissPreviousModal() {

+ 10
- 10
playground/src/containers/PushedScreen.js View File

@@ -33,8 +33,8 @@ class PushedScreen extends Component {
33 33
     );
34 34
   }
35 35
 
36
-  onClickPush() {
37
-    Navigation.push(this.props.containerId, {
36
+  async onClickPush() {
37
+    await Navigation.push(this.props.containerId, {
38 38
       name: 'navigation.playground.PushedScreen',
39 39
       passProps: {
40 40
         stackPosition: this.getStackPosition() + 1,
@@ -43,20 +43,20 @@ class PushedScreen extends Component {
43 43
     });
44 44
   }
45 45
 
46
-  onClickPop() {
47
-    Navigation.pop(this.props.containerId);
46
+  async onClickPop() {
47
+    await Navigation.pop(this.props.containerId);
48 48
   }
49 49
 
50
-  onClickPopPrevious() {
51
-    Navigation.pop(_.last(this.props.previousScreenIds));
50
+  async onClickPopPrevious() {
51
+    await Navigation.pop(_.last(this.props.previousScreenIds));
52 52
   }
53 53
 
54
-  onClickPopToFirstPosition() {
55
-    Navigation.popTo(this.props.previousScreenIds[0]);
54
+  async onClickPopToFirstPosition() {
55
+    await Navigation.popTo(this.props.previousScreenIds[0]);
56 56
   }
57 57
 
58
-  onClickPopToRoot() {
59
-    Navigation.popToRoot(this.props.containerId);
58
+  async onClickPopToRoot() {
59
+    await Navigation.popToRoot(this.props.containerId);
60 60
   }
61 61
 
62 62
   getStackPosition() {

+ 4
- 4
playground/src/containers/WelcomeScreen.js View File

@@ -104,8 +104,8 @@ class WelcomeScreen extends Component {
104 104
     });
105 105
   }
106 106
 
107
-  onClickPush() {
108
-    Navigation.push(this.props.containerId, {
107
+  async onClickPush() {
108
+    await Navigation.push(this.props.containerId, {
109 109
       name: 'navigation.playground.PushedScreen'
110 110
     });
111 111
   }
@@ -116,8 +116,8 @@ class WelcomeScreen extends Component {
116 116
     });
117 117
   }
118 118
 
119
-  onClickShowModal() {
120
-    Navigation.showModal({
119
+  async onClickShowModal() {
120
+    await Navigation.showModal({
121 121
       container: {
122 122
         name: 'navigation.playground.ModalScreen'
123 123
       }