Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: base/android/junit/src/org/chromium/base/PromiseTest.java

Issue 1885463002: Create a Promise class to simplify dealing with async results. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove IntDef Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.base;
6
7 import static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertFalse;
9 import static org.junit.Assert.assertTrue;
10
11 import org.chromium.base.Promise.UnhandledRejectionException;
12 import org.chromium.testing.local.LocalRobolectricTestRunner;
13 import org.junit.Test;
14 import org.junit.runner.RunWith;
15 import org.robolectric.annotation.Config;
16 import org.robolectric.shadows.ShadowHandler;
17
18 /** Unit tests for {@link Promise}. */
19 @RunWith(LocalRobolectricTestRunner.class)
20 @Config(manifest = Config.NONE)
21 public class PromiseTest {
22 // We need a simple mutable reference type for testing.
23 private static class Value {
24 private int mValue;
25
26 public int get() {
27 return mValue;
28 }
29
30 public void set(int value) {
31 mValue = value;
32 }
33 }
34
35 /** Tests that the callback is called on fulfillment. */
36 @Test
37 public void callback() {
38 final Value value = new Value();
39
40 Promise<Integer> promise = new Promise<Integer>();
41 promise.then(this.<Integer>setValue(value, 1));
42
43 assertEquals(value.get(), 0);
44
45 promise.fulfill(new Integer(1));
46 assertEquals(value.get(), 1);
47 }
48
49 /** Tests that multiple callbacks are called. */
50 @Test
51 public void multipleCallbacks() {
52 final Value value = new Value();
53
54 Promise<Integer> promise = new Promise<Integer>();
55 Callback<Integer> callback = new Callback<Integer>() {
56 @Override
57 public void onResult(Integer result) {
58 value.set(value.get() + 1);
59 }
60 };
61 promise.then(callback);
62 promise.then(callback);
63
64 assertEquals(value.get(), 0);
65
66 promise.fulfill(new Integer(0));
67 assertEquals(value.get(), 2);
68 }
69
70 /** Tests that a callback is called immediately when given to a fulfilled Pr omise. */
71 @Test
72 public void callbackOnFulfilled() {
73 final Value value = new Value();
74
75 Promise<Integer> promise = Promise.fulfilled(new Integer(0));
76 assertEquals(value.get(), 0);
77
78 promise.then(this.<Integer>setValue(value, 1));
79
80 assertEquals(value.get(), 1);
81 }
82
83 /** Tests that promises can chain synchronous functions correctly. */
84 @Test
85 public void promiseChaining() {
86 Promise<Integer> promise = new Promise<Integer>();
87 final Value value = new Value();
88
89 promise.then(new Promise.Function<Integer, String>(){
90 @Override
91 public String apply(Integer arg) {
92 return arg.toString();
93 }
94 }).then(new Promise.Function<String, String>(){
95 @Override
96 public String apply(String arg) {
97 return arg + arg;
98 }
99 }).then(new Callback<String>() {
100 @Override
101 public void onResult(String result) {
102 value.set(result.length());
103 }
104 });
105
106 promise.fulfill(new Integer(123));
107 ShadowHandler.runMainLooperToEndOfTasks();
108 assertEquals(6, value.get());
109 }
110
111 /** Tests that promises can chain asynchronous functions correctly. */
112 @Test
113 public void promiseChainingAsyncFunctions() {
114 Promise<Integer> promise = new Promise<Integer>();
115 final Value value = new Value();
116
117 final Promise<String> innerPromise = new Promise<String>();
118
119 promise.then(new Promise.AsyncFunction<Integer, String>() {
120 @Override
121 public Promise<String> apply(Integer arg) {
122 return innerPromise;
123 }
124 }).then(new Callback<String>(){
125 @Override
126 public void onResult(String result) {
127 value.set(result.length());
128 }
129 });
130
131 assertEquals(0, value.get());
132
133 promise.fulfill(5);
134 ShadowHandler.runMainLooperToEndOfTasks();
135 assertEquals(0, value.get());
136
137 innerPromise.fulfill("abc");
138 ShadowHandler.runMainLooperToEndOfTasks();
139 assertEquals(3, value.get());
140 }
141
142 /** Tests that a Promise that does not use its result does not throw on reje ction. */
143 @Test
144 public void rejectPromiseNoCallbacks() {
145 Promise<Integer> promise = new Promise<Integer>();
146
147 boolean caught = false;
148 try {
149 promise.reject();
150 ShadowHandler.runMainLooperToEndOfTasks();
151 } catch (UnhandledRejectionException e) {
152 caught = true;
153 }
154 assertFalse(caught);
155 }
156
157 /** Tests that a Promise that uses its result throws on rejection if it has no handler. */
158 @Test
159 public void rejectPromiseNoHandler() {
160 Promise<Integer> promise = new Promise<Integer>();
161 promise.then(this.<Integer>identity()).then(this.<Integer>pass());
162
163 boolean caught = false;
164 try {
165 promise.reject();
166 ShadowHandler.runMainLooperToEndOfTasks();
167 } catch (UnhandledRejectionException e) {
168 caught = true;
169 }
170 assertTrue(caught);
171 }
172
173 /** Tests that a Promise that handles rejection does not throw on rejection. */
174 @Test
175 public void rejectPromiseHandled() {
176 Promise<Integer> promise = new Promise<Integer>();
177 promise.then(this.<Integer>identity()).then(this.<Integer>pass(), this.< Exception>pass());
178
179 boolean caught = false;
180 try {
181 promise.reject();
182 ShadowHandler.runMainLooperToEndOfTasks();
183 } catch (UnhandledRejectionException e) {
184 caught = true;
185 }
186 assertFalse(caught);
187 }
188
189 /** Tests that rejections carry the exception information. */
190 @Test
191 public void rejectionInformation() {
192 Promise<Integer> promise = new Promise<Integer>();
193 promise.then(this.<Integer>pass());
194
195 String message = "Promise Test";
196 try {
197 promise.reject(new NegativeArraySizeException(message));
198 ShadowHandler.runMainLooperToEndOfTasks();
199 } catch (UnhandledRejectionException e) {
200 assertTrue(e.getCause() instanceof NegativeArraySizeException);
201 assertEquals(e.getCause().getMessage(), message);
202 }
203 }
204
205 /** Tests that rejections propagate. */
206 @Test
207 public void rejectionChaining() {
208 final Value value = new Value();
209 Promise<Integer> promise = new Promise<Integer>();
210
211 Promise<Integer> result =
212 promise.then(this.<Integer>identity()).then(this.<Integer>identi ty());
213
214 result.then(this.<Integer>pass(), this.<Exception>setValue(value, 5));
215
216 promise.reject(new Exception());
217 ShadowHandler.runMainLooperToEndOfTasks();
218
219 assertEquals(value.get(), 5);
220 assertTrue(result.isRejected());
221 }
222
223 /** Tests that Promises get rejected if a Function throws. */
224 @Test
225 public void rejectOnThrow() {
226 Value value = new Value();
227 Promise<Integer> promise = new Promise<Integer>();
228 promise.then(new Promise.Function<Integer, Integer>() {
229 @Override
230 public Integer apply(Integer argument) {
231 throw new IllegalArgumentException();
232 }
233 }).then(this.<Integer>pass(), this.<Exception>setValue(value, 5));
234
235 promise.fulfill(0);
236
237 ShadowHandler.runMainLooperToEndOfTasks();
238 assertEquals(value.get(), 5);
239 }
240
241 /** Tests that Promises get rejected if an AsyncFunction throws. */
242 @Test
243 public void rejectOnAsyncThrow() {
244 Value value = new Value();
245 Promise<Integer> promise = new Promise<Integer>();
246
247 promise.then(new Promise.AsyncFunction<Integer, Integer>() {
248 @Override
249 public Promise<Integer> apply(Integer argument) {
250 throw new IllegalArgumentException();
251 }
252 }).then(this.<Integer>pass(), this.<Exception>setValue(value, 5));
253
254 promise.fulfill(0);
255
256 ShadowHandler.runMainLooperToEndOfTasks();
257 assertEquals(value.get(), 5);
258 }
259
260 /** Tests that Promises get rejected if an AsyncFunction rejects. */
261 @Test
262 public void rejectOnAsyncReject() {
263 Value value = new Value();
264 Promise<Integer> promise = new Promise<Integer>();
265 final Promise<Integer> inner = new Promise<Integer>();
266
267 promise.then(new Promise.AsyncFunction<Integer, Integer>() {
268 @Override
269 public Promise<Integer> apply(Integer argument) {
270 return inner;
271 }
272 }).then(this.<Integer>pass(), this.<Exception>setValue(value, 5));
273
274 promise.fulfill(0);
275
276 ShadowHandler.runMainLooperToEndOfTasks();
277 assertEquals(value.get(), 0);
278
279 inner.reject();
280
281 ShadowHandler.runMainLooperToEndOfTasks();
282 assertEquals(value.get(), 5);
283 }
284
285 /** Convenience method that returns a Callback that does nothing with its re sult. */
286 private static <T> Callback<T> pass() {
287 return new Callback<T>() {
288 @Override
289 public void onResult(T result) {}
290 };
291 }
292
293 /** Convenience method that returns a Function that just passes through its argument. */
294 private static <T> Promise.Function<T, T> identity() {
295 return new Promise.Function<T, T>() {
296 @Override
297 public T apply(T argument) {
298 return argument;
299 }
300 };
301 }
302
303 /** Convenience method that returns a Callback that sets the given Value on execution. */
304 private static <T> Callback<T> setValue(final Value toSet, final int value) {
305 return new Callback<T>() {
306 @Override
307 public void onResult(T result) {
308 toSet.set(value);
309 }
310 };
311 }
312 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698