3030package com .google .api .core ;
3131
3232import com .google .common .truth .Truth ;
33+ import java .util .concurrent .CancellationException ;
34+ import java .util .concurrent .CompletableFuture ;
3335import java .util .concurrent .ExecutionException ;
3436import java .util .concurrent .Executor ;
3537import java .util .concurrent .TimeUnit ;
38+ import java .util .concurrent .atomic .AtomicBoolean ;
3639import java .util .concurrent .atomic .AtomicInteger ;
3740import java .util .function .BiFunction ;
3841
@@ -93,7 +96,7 @@ public void execute(Runnable r) {
9396 }
9497
9598 @ Test
96- void testCompletable () {
99+ void testCompletableApplied () {
97100 final AtomicInteger flag = new AtomicInteger ();
98101 SettableApiFuture <Integer > future = SettableApiFuture .<Integer >create ();
99102 future .completable (
@@ -113,4 +116,108 @@ public Object apply(Integer integer, Throwable throwable) {
113116 future .set (0 );
114117 Truth .assertThat (flag .get ()).isEqualTo (1 );
115118 }
119+
120+ @ Test
121+ void testCompletableSuccess () throws Exception {
122+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
123+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
124+
125+ Truth .assertThat (completable .isDone ()).isFalse ();
126+ future .set (42 );
127+ Truth .assertThat (completable .isDone ()).isTrue ();
128+ Truth .assertThat (completable .get ()).isEqualTo (42 );
129+ }
130+
131+ @ Test
132+ void testCompletableException () {
133+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
134+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
135+
136+ Exception expectedException = new IllegalArgumentException ("something failed" );
137+ future .setException (expectedException );
138+
139+ Truth .assertThat (completable .isDone ()).isTrue ();
140+ Truth .assertThat (completable .isCompletedExceptionally ()).isTrue ();
141+ ExecutionException thrown =
142+ Assertions .assertThrows (ExecutionException .class , completable ::get );
143+ Truth .assertThat (thrown .getCause ()).isSameInstanceAs (expectedException );
144+ }
145+
146+ @ Test
147+ void testCompletableCancelApiFutureCancelsCompletableFuture () {
148+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
149+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
150+
151+ future .cancel (false );
152+
153+ Truth .assertThat (completable .isDone ()).isTrue ();
154+ Truth .assertThat (completable .isCancelled ()).isTrue ();
155+ Assertions .assertThrows (CancellationException .class , completable ::get );
156+ }
157+
158+ @ Test
159+ void testCompletableCancelCompletableFutureCancelsApiFuture () {
160+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
161+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
162+
163+ completable .cancel (true );
164+
165+ Truth .assertThat (future .isDone ()).isTrue ();
166+ Truth .assertThat (future .isCancelled ()).isTrue ();
167+ Assertions .assertThrows (CancellationException .class , future ::get );
168+ }
169+
170+ @ Test
171+ void testCompletableAlreadyCompleted () throws Exception {
172+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
173+ future .set (100 );
174+
175+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
176+
177+ Truth .assertThat (completable .isDone ()).isTrue ();
178+ Truth .assertThat (completable .get ()).isEqualTo (100 );
179+ }
180+
181+ @ Test
182+ void testCompletableAlreadyFailed () {
183+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
184+ RuntimeException expectedException = new RuntimeException ("pre-failed" );
185+ future .setException (expectedException );
186+
187+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
188+
189+ Truth .assertThat (completable .isDone ()).isTrue ();
190+ Truth .assertThat (completable .isCompletedExceptionally ()).isTrue ();
191+ ExecutionException thrown =
192+ Assertions .assertThrows (ExecutionException .class , completable ::get );
193+ Truth .assertThat (thrown .getCause ()).isSameInstanceAs (expectedException );
194+ }
195+
196+ @ Test
197+ void testCompletableAlreadyCancelled () {
198+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
199+ future .cancel (false );
200+
201+ CompletableFuture <Integer > completable = future .completable (Runnable ::run );
202+
203+ Truth .assertThat (completable .isDone ()).isTrue ();
204+ Truth .assertThat (completable .isCancelled ()).isTrue ();
205+ }
206+
207+ @ Test
208+ void testCompletableUsesExecutor () {
209+ AtomicBoolean executorRan = new AtomicBoolean (false );
210+ SettableApiFuture <Integer > future = SettableApiFuture .create ();
211+ CompletableFuture <Integer > completable =
212+ future .completable (
213+ command -> {
214+ executorRan .set (true );
215+ command .run ();
216+ });
217+
218+ Truth .assertThat (executorRan .get ()).isFalse ();
219+ future .set (7 );
220+ Truth .assertThat (executorRan .get ()).isTrue ();
221+ Truth .assertThat (completable .isDone ()).isTrue ();
222+ }
116223}
0 commit comments