ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.23 by jsr166, Tue Apr 9 07:50:55 2013 UTC vs.
Revision 1.34 by jsr166, Sun Jun 1 21:17:05 2014 UTC

# Line 68 | Line 68 | public class CompletableFutureTest exten
68          } catch (Throwable fail) { threadUnexpectedException(fail); }
69          assertTrue(f.isDone());
70          assertFalse(f.isCancelled());
71 +        assertFalse(f.isCompletedExceptionally());
72          assertTrue(f.toString().contains("[Completed normally]"));
73      }
74  
# Line 101 | Line 102 | public class CompletableFutureTest exten
102          assertTrue(f.toString().contains("[Completed exceptionally]"));
103      }
104  
105 +    void checkCompletedWithWrappedCFException(CompletableFuture<?> f,
106 +                                              CFException ex) {
107 +        try {
108 +            f.get(LONG_DELAY_MS, MILLISECONDS);
109 +            shouldThrow();
110 +        } catch (ExecutionException success) {
111 +            assertSame(ex, success.getCause());
112 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
113 +        try {
114 +            f.join();
115 +            shouldThrow();
116 +        } catch (CompletionException success) {
117 +            assertSame(ex, success.getCause());
118 +        }
119 +        try {
120 +            f.getNow(null);
121 +            shouldThrow();
122 +        } catch (CompletionException success) {
123 +            assertSame(ex, success.getCause());
124 +        }
125 +        try {
126 +            f.get();
127 +            shouldThrow();
128 +        } catch (ExecutionException success) {
129 +            assertSame(ex, success.getCause());
130 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
131 +        assertTrue(f.isDone());
132 +        assertFalse(f.isCancelled());
133 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
134 +    }
135 +
136      void checkCancelled(CompletableFuture<?> f) {
137          try {
138              f.get(LONG_DELAY_MS, MILLISECONDS);
# Line 121 | Line 153 | public class CompletableFutureTest exten
153          } catch (CancellationException success) {
154          } catch (Throwable fail) { threadUnexpectedException(fail); }
155          assertTrue(f.isDone());
156 +        assertTrue(f.isCompletedExceptionally());
157          assertTrue(f.isCancelled());
158          assertTrue(f.toString().contains("[Completed exceptionally]"));
159      }
# Line 152 | Line 185 | public class CompletableFutureTest exten
185          } catch (Throwable fail) { threadUnexpectedException(fail); }
186          assertTrue(f.isDone());
187          assertFalse(f.isCancelled());
188 +        assertTrue(f.isCompletedExceptionally());
189          assertTrue(f.toString().contains("[Completed exceptionally]"));
190      }
191  
# Line 256 | Line 290 | public class CompletableFutureTest exten
290          assertEquals(g.getNumberOfDependents(), 0);
291      }
292  
259
293      /**
294       * toString indicates current completion state
295       */
# Line 371 | Line 404 | public class CompletableFutureTest exten
404          }
405      }
406  
374
407      /**
408       * exceptionally action completes with function value on source
409 <     * exception;  otherwise with source value
409 >     * exception; otherwise with source value
410       */
411      public void testExceptionally() {
412          CompletableFuture<Integer> f = new CompletableFuture<>();
# Line 660 | Line 692 | public class CompletableFutureTest exten
692          checkCompletedWithWrappedCancellationException(g);
693      }
694  
663
695      /**
696       * thenCombine result completes normally after normal completion
697       * of sources
# Line 916 | Line 947 | public class CompletableFutureTest exten
947      }
948  
949      /**
950 +     * Permits the testing of parallel code for the 3 different
951 +     * execution modes without repeating all the testing code.
952 +     */
953 +    enum ExecutionMode {
954 +        DEFAULT {
955 +            public <T,U> CompletableFuture<Void> runAfterBoth
956 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable r) {
957 +                return f.runAfterBoth(g, r);
958 +            }
959 +        },
960 +
961 +        DEFAULT_ASYNC {
962 +            public <T,U> CompletableFuture<Void> runAfterBoth
963 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable r) {
964 +                return f.runAfterBothAsync(g, r);
965 +            }
966 +        },
967 +
968 +        EXECUTOR {
969 +            public <T,U> CompletableFuture<Void> runAfterBoth
970 +                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable r) {
971 +                return f.runAfterBothAsync(g, r, new ThreadExecutor());
972 +            }
973 +        };
974 +
975 +        public abstract <T,U> CompletableFuture<Void> runAfterBoth
976 +            (CompletableFuture<T> f, CompletableFuture<U> g, Runnable r);
977 +    }
978 +
979 +    /**
980       * runAfterBoth result completes normally after normal
981       * completion of sources
982       */
983 <    public void testRunAfterBoth() {
984 <        CompletableFuture<Integer> f, g;
985 <        CompletableFuture<Void> h;
986 <        Noop r;
983 >    public void testRunAfterBoth_normalCompletion1() {
984 >        for (ExecutionMode m : ExecutionMode.values())
985 >        for (Integer v1 : new Integer[] { 1, null })
986 >        for (Integer v2 : new Integer[] { 2, null }) {
987 >
988 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
989 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
990 >        final Noop r = new Noop();
991 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
992  
993 <        f = new CompletableFuture<>();
928 <        g = new CompletableFuture<>();
929 <        h = f.runAfterBoth(g, r = new Noop());
930 <        f.complete(3);
993 >        f.complete(v1);
994          checkIncomplete(h);
995 <        g.complete(1);
995 >        assertFalse(r.ran);
996 >        g.complete(v2);
997 >
998          checkCompletedNormally(h, null);
999          assertTrue(r.ran);
1000 +        checkCompletedNormally(f, v1);
1001 +        checkCompletedNormally(g, v2);
1002 +        }
1003 +    }
1004  
1005 <        f = new CompletableFuture<>();
1006 <        g = new CompletableFuture<>();
1007 <        h = f.runAfterBoth(g, r = new Noop());
1008 <        g.complete(1);
1005 >    public void testRunAfterBoth_normalCompletion2() {
1006 >        for (ExecutionMode m : ExecutionMode.values())
1007 >        for (Integer v1 : new Integer[] { 1, null })
1008 >        for (Integer v2 : new Integer[] { 2, null }) {
1009 >
1010 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1011 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1012 >        final Noop r = new Noop();
1013 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1014 >
1015 >        g.complete(v2);
1016          checkIncomplete(h);
1017 <        f.complete(3);
1017 >        assertFalse(r.ran);
1018 >        f.complete(v1);
1019 >
1020          checkCompletedNormally(h, null);
1021          assertTrue(r.ran);
1022 +        checkCompletedNormally(f, v1);
1023 +        checkCompletedNormally(g, v2);
1024 +        }
1025 +    }
1026 +
1027 +    public void testRunAfterBoth_normalCompletion3() {
1028 +        for (ExecutionMode m : ExecutionMode.values())
1029 +        for (Integer v1 : new Integer[] { 1, null })
1030 +        for (Integer v2 : new Integer[] { 2, null }) {
1031 +
1032 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1033 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1034 +        final Noop r = new Noop();
1035 +
1036 +        g.complete(v2);
1037 +        f.complete(v1);
1038 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1039 +
1040 +        checkCompletedNormally(h, null);
1041 +        assertTrue(r.ran);
1042 +        checkCompletedNormally(f, v1);
1043 +        checkCompletedNormally(g, v2);
1044 +        }
1045 +    }
1046 +
1047 +    public void testRunAfterBoth_normalCompletion4() {
1048 +        for (ExecutionMode m : ExecutionMode.values())
1049 +        for (Integer v1 : new Integer[] { 1, null })
1050 +        for (Integer v2 : new Integer[] { 2, null }) {
1051 +
1052 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1053 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1054 +        final Noop r = new Noop();
1055 +
1056 +        f.complete(v1);
1057 +        g.complete(v2);
1058 +        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1059  
945        f = new CompletableFuture<>();
946        g = new CompletableFuture<>();
947        g.complete(1);
948        f.complete(3);
949        h = f.runAfterBoth(g, r = new Noop());
1060          checkCompletedNormally(h, null);
1061          assertTrue(r.ran);
1062 +        checkCompletedNormally(f, v1);
1063 +        checkCompletedNormally(g, v2);
1064 +        }
1065      }
1066  
1067      /**
1068       * runAfterBoth result completes exceptionally after exceptional
1069       * completion of either source
1070       */
1071 <    public void testRunAfterBoth2() {
1072 <        CompletableFuture<Integer> f, g;
1073 <        CompletableFuture<Void> h;
1074 <        Noop r;
1071 >    public void testRunAfterBoth_exceptionalCompletion1() {
1072 >        for (ExecutionMode m : ExecutionMode.values())
1073 >        for (Integer v1 : new Integer[] { 1, null }) {
1074 >
1075 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1076 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1077 >        final Noop r = new Noop();
1078 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1079 >        final CFException ex = new CFException();
1080  
1081 <        f = new CompletableFuture<>();
964 <        g = new CompletableFuture<>();
965 <        h = f.runAfterBoth(g, r = new Noop());
966 <        f.completeExceptionally(new CFException());
1081 >        f.completeExceptionally(ex);
1082          checkIncomplete(h);
1083 <        g.complete(1);
1084 <        checkCompletedWithWrappedCFException(h);
1083 >        g.complete(v1);
1084 >
1085 >        checkCompletedWithWrappedCFException(h, ex);
1086 >        checkCompletedWithWrappedCFException(f, ex);
1087          assertFalse(r.ran);
1088 +        checkCompletedNormally(g, v1);
1089 +        }
1090 +    }
1091  
1092 <        f = new CompletableFuture<>();
1093 <        g = new CompletableFuture<>();
1094 <        h = f.runAfterBoth(g, r = new Noop());
1095 <        g.completeExceptionally(new CFException());
1092 >    public void testRunAfterBoth_exceptionalCompletion2() {
1093 >        for (ExecutionMode m : ExecutionMode.values())
1094 >        for (Integer v1 : new Integer[] { 1, null }) {
1095 >
1096 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1097 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1098 >        final Noop r = new Noop();
1099 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1100 >        final CFException ex = new CFException();
1101 >
1102 >        g.completeExceptionally(ex);
1103          checkIncomplete(h);
1104 <        f.complete(3);
1105 <        checkCompletedWithWrappedCFException(h);
1104 >        f.complete(v1);
1105 >
1106 >        checkCompletedWithWrappedCFException(h, ex);
1107 >        checkCompletedWithWrappedCFException(g, ex);
1108          assertFalse(r.ran);
1109 +        checkCompletedNormally(f, v1);
1110 +        }
1111 +    }
1112  
1113 <        f = new CompletableFuture<>();
1114 <        g = new CompletableFuture<>();
1115 <        g.completeExceptionally(new CFException());
1116 <        f.complete(3);
1117 <        h = f.runAfterBoth(g, r = new Noop());
1118 <        checkCompletedWithWrappedCFException(h);
1113 >    public void testRunAfterBoth_exceptionalCompletion3() {
1114 >        for (ExecutionMode m : ExecutionMode.values())
1115 >        for (Integer v1 : new Integer[] { 1, null }) {
1116 >
1117 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1118 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1119 >        final Noop r = new Noop();
1120 >        final CFException ex = new CFException();
1121 >
1122 >        g.completeExceptionally(ex);
1123 >        f.complete(v1);
1124 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1125 >
1126 >        checkCompletedWithWrappedCFException(h, ex);
1127 >        checkCompletedWithWrappedCFException(g, ex);
1128          assertFalse(r.ran);
1129 +        checkCompletedNormally(f, v1);
1130 +        }
1131 +    }
1132  
1133 <        f = new CompletableFuture<>();
1134 <        g = new CompletableFuture<>();
1135 <        f.completeExceptionally(new CFException());
1136 <        g.complete(1);
1137 <        h = f.runAfterBoth(g, r = new Noop());
1138 <        checkCompletedWithWrappedCFException(h);
1133 >    public void testRunAfterBoth_exceptionalCompletion4() {
1134 >        for (ExecutionMode m : ExecutionMode.values())
1135 >        for (Integer v1 : new Integer[] { 1, null }) {
1136 >
1137 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1138 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1139 >        final Noop r = new Noop();
1140 >        final CFException ex = new CFException();
1141 >
1142 >        f.completeExceptionally(ex);
1143 >        g.complete(v1);
1144 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1145 >
1146 >        checkCompletedWithWrappedCFException(h, ex);
1147 >        checkCompletedWithWrappedCFException(f, ex);
1148          assertFalse(r.ran);
1149 +        checkCompletedNormally(g, v1);
1150 +        }
1151      }
1152  
1153      /**
1154       * runAfterBoth result completes exceptionally if action does
1155       */
1156 <    public void testRunAfterBoth3() {
1157 <        CompletableFuture<Integer> f = new CompletableFuture<>();
1158 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1159 <        FailingNoop r = new FailingNoop();
1160 <        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
1161 <        f.complete(one);
1162 <        checkIncomplete(g);
1163 <        f2.complete(two);
1164 <        checkCompletedWithWrappedCFException(g);
1156 >    public void testRunAfterBoth_actionFailed1() {
1157 >        for (ExecutionMode m : ExecutionMode.values())
1158 >        for (Integer v1 : new Integer[] { 1, null })
1159 >        for (Integer v2 : new Integer[] { 2, null }) {
1160 >
1161 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1162 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1163 >        final FailingNoop r = new FailingNoop();
1164 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1165 >
1166 >        f.complete(v1);
1167 >        checkIncomplete(h);
1168 >        g.complete(v2);
1169 >
1170 >        checkCompletedWithWrappedCFException(h);
1171 >        checkCompletedNormally(f, v1);
1172 >        checkCompletedNormally(g, v2);
1173 >        }
1174 >    }
1175 >
1176 >    public void testRunAfterBoth_actionFailed2() {
1177 >        for (ExecutionMode m : ExecutionMode.values())
1178 >        for (Integer v1 : new Integer[] { 1, null })
1179 >        for (Integer v2 : new Integer[] { 2, null }) {
1180 >
1181 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1182 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1183 >        final FailingNoop r = new FailingNoop();
1184 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1185 >
1186 >        g.complete(v2);
1187 >        checkIncomplete(h);
1188 >        f.complete(v1);
1189 >
1190 >        checkCompletedWithWrappedCFException(h);
1191 >        checkCompletedNormally(f, v1);
1192 >        checkCompletedNormally(g, v2);
1193 >        }
1194      }
1195  
1196      /**
1197       * runAfterBoth result completes exceptionally if either source cancelled
1198       */
1199 <    public void testRunAfterBoth4() {
1200 <        CompletableFuture<Integer> f = new CompletableFuture<>();
1201 <        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1202 <        Noop r = new Noop();
1203 <        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
1204 <        assertTrue(f.cancel(true));
1205 <        f2.complete(two);
1206 <        checkCompletedWithWrappedCancellationException(g);
1207 <        f = new CompletableFuture<>();
1208 <        f2 = new CompletableFuture<>();
1209 <        r = new Noop();
1210 <        g = f.runAfterBoth(f2, r);
1211 <        f.complete(one);
1212 <        assertTrue(f2.cancel(true));
1213 <        checkCompletedWithWrappedCancellationException(g);
1199 >    public void testRunAfterBoth_sourceCancelled1() {
1200 >        for (ExecutionMode m : ExecutionMode.values())
1201 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1202 >        for (Integer v1 : new Integer[] { 1, null }) {
1203 >
1204 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1205 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1206 >        final Noop r = new Noop();
1207 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1208 >
1209 >        assertTrue(f.cancel(mayInterruptIfRunning));
1210 >        checkIncomplete(h);
1211 >        g.complete(v1);
1212 >
1213 >        checkCompletedWithWrappedCancellationException(h);
1214 >        checkCancelled(f);
1215 >        assertFalse(r.ran);
1216 >        checkCompletedNormally(g, v1);
1217 >        }
1218 >    }
1219 >
1220 >    public void testRunAfterBoth_sourceCancelled2() {
1221 >        for (ExecutionMode m : ExecutionMode.values())
1222 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1223 >        for (Integer v1 : new Integer[] { 1, null }) {
1224 >
1225 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1226 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1227 >        final Noop r = new Noop();
1228 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1229 >
1230 >        assertTrue(g.cancel(mayInterruptIfRunning));
1231 >        checkIncomplete(h);
1232 >        f.complete(v1);
1233 >
1234 >        checkCompletedWithWrappedCancellationException(h);
1235 >        checkCancelled(g);
1236 >        assertFalse(r.ran);
1237 >        checkCompletedNormally(f, v1);
1238 >        }
1239 >    }
1240 >
1241 >    public void testRunAfterBoth_sourceCancelled3() {
1242 >        for (ExecutionMode m : ExecutionMode.values())
1243 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1244 >        for (Integer v1 : new Integer[] { 1, null }) {
1245 >
1246 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1247 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1248 >        final Noop r = new Noop();
1249 >
1250 >        assertTrue(g.cancel(mayInterruptIfRunning));
1251 >        f.complete(v1);
1252 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1253 >
1254 >        checkCompletedWithWrappedCancellationException(h);
1255 >        checkCancelled(g);
1256 >        assertFalse(r.ran);
1257 >        checkCompletedNormally(f, v1);
1258 >        }
1259 >    }
1260 >
1261 >    public void testRunAfterBoth_sourceCancelled4() {
1262 >        for (ExecutionMode m : ExecutionMode.values())
1263 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1264 >        for (Integer v1 : new Integer[] { 1, null }) {
1265 >
1266 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1267 >        final CompletableFuture<Integer> g = new CompletableFuture<>();
1268 >        final Noop r = new Noop();
1269 >
1270 >        assertTrue(f.cancel(mayInterruptIfRunning));
1271 >        g.complete(v1);
1272 >        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1273 >
1274 >        checkCompletedWithWrappedCancellationException(h);
1275 >        checkCancelled(f);
1276 >        assertFalse(r.ran);
1277 >        checkCompletedNormally(g, v1);
1278 >        }
1279      }
1280  
1281      /**
# Line 1168 | Line 1417 | public class CompletableFutureTest exten
1417          checkCompletedWithWrappedCancellationException(g);
1418      }
1419  
1171
1420      /**
1421       * runAfterEither result completes normally after normal completion
1422       * of either source
# Line 1317 | Line 1565 | public class CompletableFutureTest exten
1565          checkCompletedWithWrappedCancellationException(g);
1566      }
1567  
1320
1568      // asyncs
1569  
1570      /**
# Line 1350 | Line 1597 | public class CompletableFutureTest exten
1597          try {
1598              g.join();
1599              shouldThrow();
1600 <        } catch (Exception ok) {
1354 <        }
1600 >        } catch (CompletionException success) {}
1601          checkCompletedWithWrappedCFException(g);
1602      }
1603  
# Line 1721 | Line 1967 | public class CompletableFutureTest exten
1967      }
1968  
1969      /**
1724     * runAfterBothAsync result completes normally after normal
1725     * completion of sources
1726     */
1727    public void testRunAfterBothAsync() {
1728        CompletableFuture<Integer> f = new CompletableFuture<>();
1729        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1730        Noop r = new Noop();
1731        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1732        f.complete(one);
1733        checkIncomplete(g);
1734        f2.complete(two);
1735        checkCompletedNormally(g, null);
1736        assertTrue(r.ran);
1737    }
1738
1739    /**
1740     * runAfterBothAsync result completes exceptionally after exceptional
1741     * completion of source
1742     */
1743    public void testRunAfterBothAsync2() {
1744        CompletableFuture<Integer> f = new CompletableFuture<>();
1745        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1746        Noop r = new Noop();
1747        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1748        f.completeExceptionally(new CFException());
1749        f2.complete(two);
1750        checkCompletedWithWrappedCFException(g);
1751
1752        r = new Noop();
1753        f = new CompletableFuture<>();
1754        f2 = new CompletableFuture<>();
1755        g = f.runAfterBothAsync(f2, r);
1756        f.complete(one);
1757        f2.completeExceptionally(new CFException());
1758        checkCompletedWithWrappedCFException(g);
1759    }
1760
1761    /**
1762     * runAfterBothAsync result completes exceptionally if action does
1763     */
1764    public void testRunAfterBothAsync3() {
1765        CompletableFuture<Integer> f = new CompletableFuture<>();
1766        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1767        FailingNoop r = new FailingNoop();
1768        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1769        f.complete(one);
1770        checkIncomplete(g);
1771        f2.complete(two);
1772        checkCompletedWithWrappedCFException(g);
1773    }
1774
1775    /**
1776     * runAfterBothAsync result completes exceptionally if either source cancelled
1777     */
1778    public void testRunAfterBothAsync4() {
1779        CompletableFuture<Integer> f = new CompletableFuture<>();
1780        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1781        Noop r = new Noop();
1782        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1783        assertTrue(f.cancel(true));
1784        f2.complete(two);
1785        checkCompletedWithWrappedCancellationException(g);
1786
1787        r = new Noop();
1788        f = new CompletableFuture<>();
1789        f2 = new CompletableFuture<>();
1790        g = f.runAfterBothAsync(f2, r);
1791        f.complete(one);
1792        assertTrue(f2.cancel(true));
1793        checkCompletedWithWrappedCancellationException(g);
1794    }
1795
1796    /**
1970       * applyToEitherAsync result completes normally after normal
1971       * completion of sources
1972       */
# Line 2085 | Line 2258 | public class CompletableFutureTest exten
2258          checkCompletedWithWrappedCancellationException(g);
2259      }
2260  
2088
2261      // async with explicit executors
2262  
2263      /**
# Line 2118 | Line 2290 | public class CompletableFutureTest exten
2290          try {
2291              g.join();
2292              shouldThrow();
2293 <        } catch (Exception ok) {
2122 <        }
2293 >        } catch (CompletionException success) {}
2294          checkCompletedWithWrappedCFException(g);
2295      }
2296  
# Line 2515 | Line 2686 | public class CompletableFutureTest exten
2686      }
2687  
2688      /**
2518     * runAfterBothAsync result completes normally after normal
2519     * completion of sources
2520     */
2521    public void testRunAfterBothAsyncE() {
2522        CompletableFuture<Integer> f = new CompletableFuture<>();
2523        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2524        Noop r = new Noop();
2525        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2526        f.complete(one);
2527        checkIncomplete(g);
2528        f2.complete(two);
2529        checkCompletedNormally(g, null);
2530        assertTrue(r.ran);
2531    }
2532
2533    /**
2534     * runAfterBothAsync result completes exceptionally after exceptional
2535     * completion of source
2536     */
2537    public void testRunAfterBothAsync2E() {
2538        CompletableFuture<Integer> f = new CompletableFuture<>();
2539        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2540        Noop r = new Noop();
2541        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2542        f.completeExceptionally(new CFException());
2543        f2.complete(two);
2544        checkCompletedWithWrappedCFException(g);
2545
2546        r = new Noop();
2547        f = new CompletableFuture<>();
2548        f2 = new CompletableFuture<>();
2549        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2550        f.complete(one);
2551        f2.completeExceptionally(new CFException());
2552        checkCompletedWithWrappedCFException(g);
2553    }
2554
2555    /**
2556     * runAfterBothAsync result completes exceptionally if action does
2557     */
2558    public void testRunAfterBothAsync3E() {
2559        CompletableFuture<Integer> f = new CompletableFuture<>();
2560        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2561        FailingNoop r = new FailingNoop();
2562        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2563        f.complete(one);
2564        checkIncomplete(g);
2565        f2.complete(two);
2566        checkCompletedWithWrappedCFException(g);
2567    }
2568
2569    /**
2570     * runAfterBothAsync result completes exceptionally if either source cancelled
2571     */
2572    public void testRunAfterBothAsync4E() {
2573        CompletableFuture<Integer> f = new CompletableFuture<>();
2574        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2575        Noop r = new Noop();
2576        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2577        assertTrue(f.cancel(true));
2578        f2.complete(two);
2579        checkCompletedWithWrappedCancellationException(g);
2580
2581        r = new Noop();
2582        f = new CompletableFuture<>();
2583        f2 = new CompletableFuture<>();
2584        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2585        f.complete(one);
2586        assertTrue(f2.cancel(true));
2587        checkCompletedWithWrappedCancellationException(g);
2588    }
2589
2590    /**
2689       * applyToEitherAsync result completes normally after normal
2690       * completion of sources
2691       */
# Line 2856 | Line 2954 | public class CompletableFutureTest exten
2954       * with the value null
2955       */
2956      public void testAllOf_empty() throws Exception {
2957 <        CompletableFuture<?> f = CompletableFuture.allOf();
2957 >        CompletableFuture<Void> f = CompletableFuture.allOf();
2958          checkCompletedNormally(f, null);
2959      }
2960  
2961      /**
2962 <     * allOf returns a future completed when all components complete
2962 >     * allOf returns a future completed normally with the value null
2963 >     * when all components complete normally
2964       */
2965 <    public void testAllOf() throws Exception {
2965 >    public void testAllOf_normal() throws Exception {
2966          for (int k = 1; k < 20; ++k) {
2967              CompletableFuture<Integer>[] fs = (CompletableFuture<Integer>[]) new CompletableFuture[k];
2968              for (int i = 0; i < k; ++i)
# Line 2871 | Line 2970 | public class CompletableFutureTest exten
2970              CompletableFuture<Void> f = CompletableFuture.allOf(fs);
2971              for (int i = 0; i < k; ++i) {
2972                  checkIncomplete(f);
2973 +                checkIncomplete(CompletableFuture.allOf(fs));
2974                  fs[i].complete(one);
2975              }
2976              checkCompletedNormally(f, null);
2977 +            checkCompletedNormally(CompletableFuture.allOf(fs), null);
2978          }
2979      }
2980  
# Line 2881 | Line 2982 | public class CompletableFutureTest exten
2982       * anyOf(no component futures) returns an incomplete future
2983       */
2984      public void testAnyOf_empty() throws Exception {
2985 <        CompletableFuture<?> f = CompletableFuture.anyOf();
2985 >        CompletableFuture<Object> f = CompletableFuture.anyOf();
2986          checkIncomplete(f);
2987      }
2988  
2989      /**
2990 <     * anyOf returns a future completed when any components complete
2990 >     * anyOf returns a future completed normally with a value when
2991 >     * a component future does
2992       */
2993 <    public void testAnyOf() throws Exception {
2994 <        for (int k = 1; k < 20; ++k) {
2993 >    public void testAnyOf_normal() throws Exception {
2994 >        for (int k = 0; k < 10; ++k) {
2995              CompletableFuture[] fs = new CompletableFuture[k];
2996              for (int i = 0; i < k; ++i)
2997                  fs[i] = new CompletableFuture<>();
# Line 2898 | Line 3000 | public class CompletableFutureTest exten
3000              for (int i = 0; i < k; ++i) {
3001                  fs[i].complete(one);
3002                  checkCompletedNormally(f, one);
3003 +                checkCompletedNormally(CompletableFuture.anyOf(fs), one);
3004 +            }
3005 +        }
3006 +    }
3007 +
3008 +    /**
3009 +     * anyOf result completes exceptionally when any component does.
3010 +     */
3011 +    public void testAnyOf_exceptional() throws Exception {
3012 +        for (int k = 0; k < 10; ++k) {
3013 +            CompletableFuture[] fs = new CompletableFuture[k];
3014 +            for (int i = 0; i < k; ++i)
3015 +                fs[i] = new CompletableFuture<>();
3016 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3017 +            checkIncomplete(f);
3018 +            for (int i = 0; i < k; ++i) {
3019 +                fs[i].completeExceptionally(new CFException());
3020 +                checkCompletedWithWrappedCFException(f);
3021 +                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3022              }
3023          }
3024      }
# Line 2913 | Line 3034 | public class CompletableFutureTest exten
3034          ThreadExecutor exec = new ThreadExecutor();
3035  
3036          Runnable[] throwingActions = {
3037 <            () -> { CompletableFuture.supplyAsync(null); },
3038 <            () -> { CompletableFuture.supplyAsync(null, exec); },
3039 <            () -> { CompletableFuture.supplyAsync(supplyOne, null); },
3040 <
3041 <            () -> { CompletableFuture.runAsync(null); },
3042 <            () -> { CompletableFuture.runAsync(null, exec); },
3043 <            () -> { CompletableFuture.runAsync(() -> {}, null); },
3044 <
3045 <            () -> { f.completeExceptionally(null); },
3046 <
3047 <            () -> { f.thenApply(null); },
3048 <            () -> { f.thenApplyAsync(null); },
3049 <            () -> { f.thenApplyAsync((x) -> x, null); },
3050 <            () -> { f.thenApplyAsync(null, exec); },
3051 <
3052 <            () -> { f.thenAccept(null); },
3053 <            () -> { f.thenAcceptAsync(null); },
3054 <            () -> { f.thenAcceptAsync((x) -> { ; }, null); },
3055 <            () -> { f.thenAcceptAsync(null, exec); },
3056 <
3057 <            () -> { f.thenRun(null); },
3058 <            () -> { f.thenRunAsync(null); },
3059 <            () -> { f.thenRunAsync(() -> { ; }, null); },
3060 <            () -> { f.thenRunAsync(null, exec); },
3061 <
3062 <            () -> { f.thenCombine(g, null); },
3063 <            () -> { f.thenCombineAsync(g, null); },
3064 <            () -> { f.thenCombineAsync(g, null, exec); },
3065 <            () -> { f.thenCombine(nullFuture, (x, y) -> x); },
3066 <            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); },
3067 <            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); },
3068 <            () -> { f.thenCombineAsync(g, (x, y) -> x, null); },
3069 <
3070 <            () -> { f.thenAcceptBoth(g, null); },
3071 <            () -> { f.thenAcceptBothAsync(g, null); },
3072 <            () -> { f.thenAcceptBothAsync(g, null, exec); },
3073 <            () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); },
3074 <            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); },
3075 <            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); },
3076 <            () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); },
3077 <
3078 <            () -> { f.runAfterBoth(g, null); },
3079 <            () -> { f.runAfterBothAsync(g, null); },
3080 <            () -> { f.runAfterBothAsync(g, null, exec); },
3081 <            () -> { f.runAfterBoth(nullFuture, () -> {}); },
3082 <            () -> { f.runAfterBothAsync(nullFuture, () -> {}); },
3083 <            () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); },
3084 <            () -> { f.runAfterBothAsync(g, () -> {}, null); },
3085 <
3086 <            () -> { f.applyToEither(g, null); },
3087 <            () -> { f.applyToEitherAsync(g, null); },
3088 <            () -> { f.applyToEitherAsync(g, null, exec); },
3089 <            () -> { f.applyToEither(nullFuture, (x) -> x); },
3090 <            () -> { f.applyToEitherAsync(nullFuture, (x) -> x); },
3091 <            () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); },
3092 <            () -> { f.applyToEitherAsync(g, (x) -> x, null); },
3093 <
3094 <            () -> { f.acceptEither(g, null); },
3095 <            () -> { f.acceptEitherAsync(g, null); },
3096 <            () -> { f.acceptEitherAsync(g, null, exec); },
3097 <            () -> { f.acceptEither(nullFuture, (x) -> {}); },
3098 <            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); },
3099 <            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); },
3100 <            () -> { f.acceptEitherAsync(g, (x) -> {}, null); },
3101 <
3102 <            () -> { f.runAfterEither(g, null); },
3103 <            () -> { f.runAfterEitherAsync(g, null); },
3104 <            () -> { f.runAfterEitherAsync(g, null, exec); },
3105 <            () -> { f.runAfterEither(nullFuture, () -> {}); },
3106 <            () -> { f.runAfterEitherAsync(nullFuture, () -> {}); },
3107 <            () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); },
3108 <            () -> { f.runAfterEitherAsync(g, () -> {}, null); },
3109 <
3110 <            () -> { f.thenCompose(null); },
3111 <            () -> { f.thenComposeAsync(null); },
3112 <            () -> { f.thenComposeAsync(new CompletableFutureInc(), null); },
3113 <            () -> { f.thenComposeAsync(null, exec); },
3114 <
3115 <            () -> { f.exceptionally(null); },
3116 <
3117 <            () -> { f.handle(null); },
3118 <
3119 <            () -> { CompletableFuture.allOf((CompletableFuture<?>)null); },
3120 <            () -> { CompletableFuture.allOf((CompletableFuture<?>[])null); },
3121 <            () -> { CompletableFuture.allOf(f, null); },
3122 <            () -> { CompletableFuture.allOf(null, f); },
3123 <
3124 <            () -> { CompletableFuture.anyOf((CompletableFuture<?>)null); },
3125 <            () -> { CompletableFuture.anyOf((CompletableFuture<?>[])null); },
3126 <            () -> { CompletableFuture.anyOf(f, null); },
3127 <            () -> { CompletableFuture.anyOf(null, f); },
3037 >            () -> CompletableFuture.supplyAsync(null),
3038 >            () -> CompletableFuture.supplyAsync(null, exec),
3039 >            () -> CompletableFuture.supplyAsync(supplyOne, null),
3040 >
3041 >            () -> CompletableFuture.runAsync(null),
3042 >            () -> CompletableFuture.runAsync(null, exec),
3043 >            () -> CompletableFuture.runAsync(() -> {}, null),
3044 >
3045 >            () -> f.completeExceptionally(null),
3046 >
3047 >            () -> f.thenApply(null),
3048 >            () -> f.thenApplyAsync(null),
3049 >            () -> f.thenApplyAsync((x) -> x, null),
3050 >            () -> f.thenApplyAsync(null, exec),
3051 >
3052 >            () -> f.thenAccept(null),
3053 >            () -> f.thenAcceptAsync(null),
3054 >            () -> f.thenAcceptAsync((x) -> {} , null),
3055 >            () -> f.thenAcceptAsync(null, exec),
3056 >
3057 >            () -> f.thenRun(null),
3058 >            () -> f.thenRunAsync(null),
3059 >            () -> f.thenRunAsync(() -> {} , null),
3060 >            () -> f.thenRunAsync(null, exec),
3061 >
3062 >            () -> f.thenCombine(g, null),
3063 >            () -> f.thenCombineAsync(g, null),
3064 >            () -> f.thenCombineAsync(g, null, exec),
3065 >            () -> f.thenCombine(nullFuture, (x, y) -> x),
3066 >            () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
3067 >            () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
3068 >            () -> f.thenCombineAsync(g, (x, y) -> x, null),
3069 >
3070 >            () -> f.thenAcceptBoth(g, null),
3071 >            () -> f.thenAcceptBothAsync(g, null),
3072 >            () -> f.thenAcceptBothAsync(g, null, exec),
3073 >            () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
3074 >            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
3075 >            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
3076 >            () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
3077 >
3078 >            () -> f.runAfterBoth(g, null),
3079 >            () -> f.runAfterBothAsync(g, null),
3080 >            () -> f.runAfterBothAsync(g, null, exec),
3081 >            () -> f.runAfterBoth(nullFuture, () -> {}),
3082 >            () -> f.runAfterBothAsync(nullFuture, () -> {}),
3083 >            () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
3084 >            () -> f.runAfterBothAsync(g, () -> {}, null),
3085 >
3086 >            () -> f.applyToEither(g, null),
3087 >            () -> f.applyToEitherAsync(g, null),
3088 >            () -> f.applyToEitherAsync(g, null, exec),
3089 >            () -> f.applyToEither(nullFuture, (x) -> x),
3090 >            () -> f.applyToEitherAsync(nullFuture, (x) -> x),
3091 >            () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec),
3092 >            () -> f.applyToEitherAsync(g, (x) -> x, null),
3093 >
3094 >            () -> f.acceptEither(g, null),
3095 >            () -> f.acceptEitherAsync(g, null),
3096 >            () -> f.acceptEitherAsync(g, null, exec),
3097 >            () -> f.acceptEither(nullFuture, (x) -> {}),
3098 >            () -> f.acceptEitherAsync(nullFuture, (x) -> {}),
3099 >            () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec),
3100 >            () -> f.acceptEitherAsync(g, (x) -> {}, null),
3101 >
3102 >            () -> f.runAfterEither(g, null),
3103 >            () -> f.runAfterEitherAsync(g, null),
3104 >            () -> f.runAfterEitherAsync(g, null, exec),
3105 >            () -> f.runAfterEither(nullFuture, () -> {}),
3106 >            () -> f.runAfterEitherAsync(nullFuture, () -> {}),
3107 >            () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
3108 >            () -> f.runAfterEitherAsync(g, () -> {}, null),
3109 >
3110 >            () -> f.thenCompose(null),
3111 >            () -> f.thenComposeAsync(null),
3112 >            () -> f.thenComposeAsync(new CompletableFutureInc(), null),
3113 >            () -> f.thenComposeAsync(null, exec),
3114 >
3115 >            () -> f.exceptionally(null),
3116 >
3117 >            () -> f.handle(null),
3118 >
3119 >            () -> CompletableFuture.allOf((CompletableFuture<?>)null),
3120 >            () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
3121 >            () -> CompletableFuture.allOf(f, null),
3122 >            () -> CompletableFuture.allOf(null, f),
3123 >
3124 >            () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
3125 >            () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
3126 >            () -> CompletableFuture.anyOf(f, null),
3127 >            () -> CompletableFuture.anyOf(null, f),
3128 >
3129 >            () -> f.obtrudeException(null),
3130          };
3131  
3132          assertThrows(NullPointerException.class, throwingActions);
3133          assertEquals(0, exec.count.get());
3134      }
3135  
3136 +    /**
3137 +     * toCompletableFuture returns this CompletableFuture.
3138 +     */
3139 +    public void testToCompletableFuture() {
3140 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3141 +        assertSame(f, f.toCompletableFuture());
3142 +    }
3143 +
3144 +    /**
3145 +     * whenComplete action executes on normal completion, propagating
3146 +     * source result.
3147 +     */
3148 +    public void testWhenComplete1() {
3149 +        final AtomicInteger a = new AtomicInteger();
3150 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3151 +        CompletableFuture<Integer> g =
3152 +            f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement());
3153 +        f.complete(three);
3154 +        checkCompletedNormally(f, three);
3155 +        checkCompletedNormally(g, three);
3156 +        assertEquals(a.get(), 1);
3157 +    }
3158 +
3159 +    /**
3160 +     * whenComplete action executes on exceptional completion, propagating
3161 +     * source result.
3162 +     */
3163 +    public void testWhenComplete2() {
3164 +        final AtomicInteger a = new AtomicInteger();
3165 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3166 +        CompletableFuture<Integer> g =
3167 +            f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement());
3168 +        f.completeExceptionally(new CFException());
3169 +        assertTrue(f.isCompletedExceptionally());
3170 +        assertTrue(g.isCompletedExceptionally());
3171 +        assertEquals(a.get(), 1);
3172 +    }
3173 +
3174 +    /**
3175 +     * If a whenComplete action throws an exception when triggered by
3176 +     * a normal completion, it completes exceptionally
3177 +     */
3178 +    public void testWhenComplete3() {
3179 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3180 +        CompletableFuture<Integer> g =
3181 +            f.whenComplete((Integer x, Throwable t) ->
3182 +                           { throw new CFException(); } );
3183 +        f.complete(three);
3184 +        checkCompletedNormally(f, three);
3185 +        assertTrue(g.isCompletedExceptionally());
3186 +        checkCompletedWithWrappedCFException(g);
3187 +    }
3188 +
3189 +    /**
3190 +     * whenCompleteAsync action executes on normal completion, propagating
3191 +     * source result.
3192 +     */
3193 +    public void testWhenCompleteAsync1() {
3194 +        final AtomicInteger a = new AtomicInteger();
3195 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3196 +        CompletableFuture<Integer> g =
3197 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement());
3198 +        f.complete(three);
3199 +        checkCompletedNormally(f, three);
3200 +        checkCompletedNormally(g, three);
3201 +        assertEquals(a.get(), 1);
3202 +    }
3203 +
3204 +    /**
3205 +     * whenCompleteAsync action executes on exceptional completion, propagating
3206 +     * source result.
3207 +     */
3208 +    public void testWhenCompleteAsync2() {
3209 +        final AtomicInteger a = new AtomicInteger();
3210 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3211 +        CompletableFuture<Integer> g =
3212 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement());
3213 +        f.completeExceptionally(new CFException());
3214 +        checkCompletedWithWrappedCFException(f);
3215 +        checkCompletedWithWrappedCFException(g);
3216 +    }
3217 +
3218 +    /**
3219 +     * If a whenCompleteAsync action throws an exception when
3220 +     * triggered by a normal completion, it completes exceptionally
3221 +     */
3222 +    public void testWhenCompleteAsync3() {
3223 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3224 +        CompletableFuture<Integer> g =
3225 +            f.whenCompleteAsync((Integer x, Throwable t) ->
3226 +                           { throw new CFException(); } );
3227 +        f.complete(three);
3228 +        checkCompletedNormally(f, three);
3229 +        checkCompletedWithWrappedCFException(g);
3230 +    }
3231 +
3232 +    /**
3233 +     * whenCompleteAsync action executes on normal completion, propagating
3234 +     * source result.
3235 +     */
3236 +    public void testWhenCompleteAsync1e() {
3237 +        final AtomicInteger a = new AtomicInteger();
3238 +        ThreadExecutor exec = new ThreadExecutor();
3239 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3240 +        CompletableFuture<Integer> g =
3241 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(),
3242 +                                exec);
3243 +        f.complete(three);
3244 +        checkCompletedNormally(f, three);
3245 +        checkCompletedNormally(g, three);
3246 +        assertEquals(a.get(), 1);
3247 +    }
3248 +
3249 +    /**
3250 +     * whenCompleteAsync action executes on exceptional completion, propagating
3251 +     * source result.
3252 +     */
3253 +    public void testWhenCompleteAsync2e() {
3254 +        final AtomicInteger a = new AtomicInteger();
3255 +        ThreadExecutor exec = new ThreadExecutor();
3256 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3257 +        CompletableFuture<Integer> g =
3258 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(),
3259 +                                exec);
3260 +        f.completeExceptionally(new CFException());
3261 +        checkCompletedWithWrappedCFException(f);
3262 +        checkCompletedWithWrappedCFException(g);
3263 +    }
3264 +
3265 +    /**
3266 +     * If a whenCompleteAsync action throws an exception when triggered
3267 +     * by a normal completion, it completes exceptionally
3268 +     */
3269 +    public void testWhenCompleteAsync3e() {
3270 +        ThreadExecutor exec = new ThreadExecutor();
3271 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3272 +        CompletableFuture<Integer> g =
3273 +            f.whenCompleteAsync((Integer x, Throwable t) ->
3274 +                                { throw new CFException(); },
3275 +                                exec);
3276 +        f.complete(three);
3277 +        checkCompletedNormally(f, three);
3278 +        checkCompletedWithWrappedCFException(g);
3279 +    }
3280 +
3281 +    /**
3282 +     * handleAsync action completes normally with function value on
3283 +     * either normal or exceptional completion of source
3284 +     */
3285 +    public void testHandleAsync() {
3286 +        CompletableFuture<Integer> f, g;
3287 +        IntegerHandler r;
3288 +
3289 +        f = new CompletableFuture<>();
3290 +        g = f.handleAsync(r = new IntegerHandler());
3291 +        assertFalse(r.ran);
3292 +        f.completeExceptionally(new CFException());
3293 +        checkCompletedWithWrappedCFException(f);
3294 +        checkCompletedNormally(g, three);
3295 +        assertTrue(r.ran);
3296 +
3297 +        f = new CompletableFuture<>();
3298 +        g = f.handleAsync(r = new IntegerHandler());
3299 +        assertFalse(r.ran);
3300 +        f.completeExceptionally(new CFException());
3301 +        checkCompletedWithWrappedCFException(f);
3302 +        checkCompletedNormally(g, three);
3303 +        assertTrue(r.ran);
3304 +
3305 +        f = new CompletableFuture<>();
3306 +        g = f.handleAsync(r = new IntegerHandler());
3307 +        assertFalse(r.ran);
3308 +        f.complete(one);
3309 +        checkCompletedNormally(f, one);
3310 +        checkCompletedNormally(g, two);
3311 +        assertTrue(r.ran);
3312 +
3313 +        f = new CompletableFuture<>();
3314 +        g = f.handleAsync(r = new IntegerHandler());
3315 +        assertFalse(r.ran);
3316 +        f.complete(one);
3317 +        checkCompletedNormally(f, one);
3318 +        checkCompletedNormally(g, two);
3319 +        assertTrue(r.ran);
3320 +    }
3321 +
3322 +    /**
3323 +     * handleAsync action with Executor completes normally with
3324 +     * function value on either normal or exceptional completion of
3325 +     * source
3326 +     */
3327 +    public void testHandleAsync2() {
3328 +        CompletableFuture<Integer> f, g;
3329 +        ThreadExecutor exec = new ThreadExecutor();
3330 +        IntegerHandler r;
3331 +
3332 +        f = new CompletableFuture<>();
3333 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3334 +        assertFalse(r.ran);
3335 +        f.completeExceptionally(new CFException());
3336 +        checkCompletedWithWrappedCFException(f);
3337 +        checkCompletedNormally(g, three);
3338 +        assertTrue(r.ran);
3339 +
3340 +        f = new CompletableFuture<>();
3341 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3342 +        assertFalse(r.ran);
3343 +        f.completeExceptionally(new CFException());
3344 +        checkCompletedWithWrappedCFException(f);
3345 +        checkCompletedNormally(g, three);
3346 +        assertTrue(r.ran);
3347 +
3348 +        f = new CompletableFuture<>();
3349 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3350 +        assertFalse(r.ran);
3351 +        f.complete(one);
3352 +        checkCompletedNormally(f, one);
3353 +        checkCompletedNormally(g, two);
3354 +        assertTrue(r.ran);
3355 +
3356 +        f = new CompletableFuture<>();
3357 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3358 +        assertFalse(r.ran);
3359 +        f.complete(one);
3360 +        checkCompletedNormally(f, one);
3361 +        checkCompletedNormally(g, two);
3362 +        assertTrue(r.ran);
3363 +    }
3364 +
3365   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines