├── .gitignore ├── .travis.yml ├── CONTRIBUTE.md ├── LICENSE ├── README.md ├── pom.xml ├── src ├── main │ ├── README.txt │ ├── assembly │ │ └── mod.xml │ ├── java │ │ └── org │ │ │ └── simondean │ │ │ └── vertx │ │ │ └── async │ │ │ ├── Async.java │ │ │ ├── AsyncResultHandlerWrapper.java │ │ │ ├── DefaultAsyncResult.java │ │ │ ├── EachBuilder.java │ │ │ ├── Forever.java │ │ │ ├── ForeverBuilder.java │ │ │ ├── FunctionWrapper.java │ │ │ ├── IterableBuilder.java │ │ │ ├── ObjectWrapper.java │ │ │ ├── Retry.java │ │ │ ├── RetryBuilder.java │ │ │ ├── RetryTimesBuilder.java │ │ │ ├── Series.java │ │ │ ├── Waterfall.java │ │ │ ├── WaterfallBuilder.java │ │ │ └── internal │ │ │ ├── DefaultWaterfall.java │ │ │ ├── EachBuilderImpl.java │ │ │ ├── ForeverBuilderImpl.java │ │ │ ├── ForeverImpl.java │ │ │ ├── IterableBuilderImpl.java │ │ │ ├── NestedWaterfall.java │ │ │ ├── RetryBuilderImpl.java │ │ │ ├── RetryImpl.java │ │ │ ├── RetryTimesBuilderImpl.java │ │ │ ├── SeriesImpl.java │ │ │ └── WaterfallBuilderImpl.java │ ├── platform_lib │ │ └── README.txt │ └── resources │ │ ├── mod.json │ │ └── platform_lib │ │ └── README.txt └── test │ └── java │ └── org │ └── simondean │ └── vertx │ └── async │ ├── integration │ ├── README.txt │ └── java │ │ └── README.txt │ └── unit │ ├── AsyncTest.java │ ├── EachExampleTest.java │ ├── EachTest.java │ ├── ForeverExampleTest.java │ ├── ForeverTest.java │ ├── README.txt │ ├── RetryExampleTest.java │ ├── RetryTest.java │ ├── SeriesExampleTest.java │ ├── SeriesTest.java │ ├── WaterfallExampleTest.java │ ├── WaterfallTest.java │ ├── examples │ ├── BaseExample.java │ ├── EachExample.java │ ├── ForeverExample.java │ ├── RetryExample.java │ ├── SeriesExample.java │ └── WaterfallExample.java │ └── fakes │ ├── FakeAsyncFunction.java │ ├── FakeAsyncSupplier.java │ ├── FakeErrorThrowingAsyncFunction.java │ ├── FakeErrorThrowingAsyncSupplier.java │ ├── FakeFailingAsyncFunction.java │ ├── FakeFailingAsyncSupplier.java │ ├── FakeSuccessfulAsyncFunction.java │ ├── FakeSuccessfulAsyncSupplier.java │ └── FakeVertx.java └── vertx_classpath.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .classpath 6 | .project 7 | .settings/ 8 | 9 | .gradle/ 10 | build/ 11 | target/ 12 | 13 | mods/ 14 | 15 | *.versionsBackup 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | install: 7 | - mvn install -DskipTests=true 8 | 9 | script: 10 | - mvn test 11 | -------------------------------------------------------------------------------- /CONTRIBUTE.md: -------------------------------------------------------------------------------- 1 | ## Release Checklist 2 | 3 | Here are the steps to follow when making a release. 4 | 5 | * Update `HISTORY.md` 6 | * Remove the "-SNAPSHOT" from the version "*0.1.2*-SNAPSHOT" in `pom.xml` (where *0.1.2* is the actual version, of course) 7 | * `$ mvn versions:set -DnewVersion=0.1.2` 8 | * Add new contributors to `pom.xml`, if any 9 | * Commit those changes as "Release 0.1.2" 10 | * `$ git add pom.xml` 11 | * `$ git commit -m "Release 0.1.2"` 12 | * Tag commit as "v0.1.2" with short description of main changes 13 | * `$ git tag -a v0.1.2 -m "Description of changes"` 14 | * Push to main repo on GitHub 15 | * `$ git push origin master` 16 | * `$ git push origin v0.1.2` 17 | * Wait for build to go green 18 | * Publish to Maven Central 19 | * `$ mvn clean deploy -P release` 20 | * Updated the version to "*0.1.3*-SNAPSHOT" in `pom.xml` (where *0.1.3* is the next release version, of course) 21 | * `$ mvn versions:set -DnewVersion=0.1.3-SNAPSHOT` 22 | * Commit those changes as "Preparing for next release" 23 | * `$ git add pom.xml` 24 | * `$ git commit -m "Preparing for next release"` 25 | * Push to main repo on GitHub 26 | * `$ git push origin master` 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Simon Dean 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vertx-async 2 | 3 | vertx-async is a [Vert.x](http://vertx.io/) module that provides helper methods for common async patterns. 4 | It helps avoid call back hell and is inspired by the API of the popular [async](https://www.npmjs.com/package/async) 5 | node.js module. 6 | 7 | ## Using 8 | 9 | The module is available on Maven Central: 10 | 11 | ``` xml 12 | 13 | org.simondean.vertx 14 | vertx-async 15 | 0.1.1 16 | provided 17 | 18 | ``` 19 | 20 | The module then needs to be added to the includes field of your mod.json: 21 | 22 | ``` json 23 | "includes": "org.simondean.vertx~vertx-async~0.1.6" 24 | ``` 25 | 26 | The patterns are all available as static methods on the `org.simondean.vertx.async.Async` class. 27 | 28 | ## Patterns 29 | 30 | ### Series 31 | 32 | ``` java 33 | public void seriesExample(AsyncResultHandler> handler) { 34 | Async.series() 35 | .task(taskHandler -> { 36 | String result = getSomeResult(); 37 | taskHandler.handle(DefaultAsyncResult.succeed(result)); 38 | }) 39 | .task(taskHandler -> { 40 | someAsyncMethodThatTakesAHandler(taskHandler); 41 | }) 42 | .run(result -> { 43 | if (result.failed()) { 44 | handler.handle(DefaultAsyncResult.fail(result.cause())); 45 | return; 46 | } 47 | 48 | List resultList = result.result(); 49 | doSomethingWithTheResults(resultList); 50 | 51 | handler.handle(DefaultAsyncResult.succeed(resultList)); 52 | }); 53 | } 54 | ``` 55 | 56 | ### Waterfall 57 | 58 | ``` java 59 | public void waterfallExample(AsyncResultHandler handler) { 60 | Async.waterfall() 61 | .task(taskHandler -> { 62 | String result = getSomeResult(); 63 | taskHandler.handle(DefaultAsyncResult.succeed(result)); 64 | }) 65 | .task((result, taskHandler) -> { 66 | someAsyncMethodThatTakesAResultAndHandler(result, taskHandler); 67 | }) 68 | .run(result -> { 69 | if (result.failed()) { 70 | handler.handle(DefaultAsyncResult.fail(result.cause())); 71 | return; 72 | } 73 | 74 | Integer resultValue = result.result(); 75 | doSomethingWithTheResults(resultValue); 76 | 77 | handler.handle(DefaultAsyncResult.succeed(resultValue)); 78 | }); 79 | } 80 | ``` 81 | 82 | ### Each 83 | 84 | ``` java 85 | public void eachExample(AsyncResultHandler handler) { 86 | List list = Arrays.asList("one", "two", "three"); 87 | 88 | Async.iterable(list) 89 | .each((item, eachHandler) -> { 90 | doSomethingWithItem(item, eachHandler); 91 | }) 92 | .run(vertx, handler); 93 | } 94 | ``` 95 | 96 | ### Retry 97 | 98 | ``` java 99 | public void retryExample(AsyncResultHandler handler) { 100 | Async.retry() 101 | .task(taskHandler -> { 102 | someAsyncMethodThatTakesAHandler(taskHandler); 103 | }) 104 | .times(5) 105 | .run(result -> { 106 | if (result.failed()) { 107 | handler.handle(DefaultAsyncResult.fail(result)); 108 | return; 109 | } 110 | 111 | String resultValue = result.result(); 112 | 113 | doSomethingWithTheResults(resultValue); 114 | 115 | handler.handle(DefaultAsyncResult.succeed(resultValue)); 116 | }); 117 | } 118 | ``` 119 | 120 | ### Forever 121 | 122 | ``` java 123 | public void foreverExample(AsyncResultHandler handler) { 124 | Async.forever() 125 | .task(taskHandler -> { 126 | someAsyncMethodThatTakesAHandler(taskHandler); 127 | }) 128 | .run(vertx, result -> { 129 | handler.handle(DefaultAsyncResult.fail(result)); 130 | }); 131 | } 132 | ``` 133 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.simondean.vertx 7 | vertx-async 8 | jar 9 | 0.1.8-SNAPSHOT 10 | vertx-async 11 | Async helpers for Vert.x 12 | https://github.com/simondean/vertx-async 13 | 14 | 15 | MIT 16 | http://opensource.org/licenses/MIT 17 | 18 | 19 | 20 | 21 | Simon Dean 22 | simon@simondean.org 23 | simondean 24 | https://github.com/simondean 25 | 26 | 27 | 28 | scm:git:https://github.com/simondean/vertx-async.git 29 | scm:git:git@github.com:simondean/vertx-async.git 30 | https://github.com/simondean/vertx-async.git 31 | 32 | 33 | 34 | UTF-8 35 | 36 | 39 | false 40 | 41 | 43 | false 44 | 45 | 46 | ${project.groupId}~${project.artifactId}~${project.version} 47 | 48 | 50 | target/mods 51 | 52 | 53 | 2.1.5 54 | 2.0.3-final 55 | 4.11 56 | 3.0.0 57 | 58 | 59 | 3.0 60 | 2.6 61 | 2.5 62 | 2.0.11-final 63 | 2.14 64 | 2.14 65 | 2.14 66 | 2.9 67 | 2.7 68 | 69 | 70 | 71 | 72 | 73 | io.vertx 74 | vertx-core 75 | ${vertx.version} 76 | provided 77 | 78 | 79 | io.vertx 80 | vertx-platform 81 | ${vertx.version} 82 | provided 83 | 84 | 85 | io.vertx 86 | vertx-hazelcast 87 | ${vertx.version} 88 | provided 89 | 90 | 91 | 92 | 93 | junit 94 | junit 95 | 4.11 96 | test 97 | 98 | 99 | io.vertx 100 | testtools 101 | ${vertx.testtools.version} 102 | test 103 | 104 | 105 | org.assertj 106 | assertj-core 107 | ${assertj.version} 108 | test 109 | 110 | 111 | 112 | 113 | 114 | 115 | ossrh 116 | https://oss.sonatype.org/content/repositories/snapshots 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | io.vertx 126 | vertx-maven-plugin 127 | ${maven.vertx.plugin.version} 128 | 136 | 137 | 138 | 139 | io.vertx 140 | vertx-platform 141 | ${vertx.version} 142 | 143 | 144 | io.vertx 145 | vertx-core 146 | ${vertx.version} 147 | 148 | 149 | io.vertx 150 | vertx-hazelcast 151 | ${vertx.version} 152 | 153 | 154 | 155 | 156 | PullInDeps 157 | prepare-package 158 | 159 | pullInDeps 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | org.apache.maven.plugins 168 | maven-compiler-plugin 169 | ${maven.compiler.plugin.version} 170 | 171 | 1.8 172 | 1.8 173 | 174 | 175 | 176 | maven-resources-plugin 177 | ${maven.resources.plugin.version} 178 | 179 | 180 | copy-mod-to-target 181 | process-classes 182 | 183 | copy-resources 184 | 185 | 186 | true 187 | ${mods.directory}/${module.name} 188 | 189 | 190 | target/classes 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | org.apache.maven.plugins 199 | maven-dependency-plugin 200 | ${maven.dependency.plugin.version} 201 | 202 | 203 | copy-mod-dependencies-to-target 204 | process-classes 205 | 206 | copy-dependencies 207 | 208 | 209 | ${mods.directory}/${module.name}/lib 210 | runtime 211 | 212 | 213 | 214 | copy-mod-dependencies-to-target-dependencies 215 | process-classes 216 | 217 | copy-dependencies 218 | 219 | 220 | target/dependencies 221 | runtime 222 | 223 | 224 | 225 | 226 | 227 | org.apache.maven.plugins 228 | maven-surefire-plugin 229 | ${maven.surefire.plugin.version} 230 | 231 | 232 | **/unit/*Test*.java 233 | 234 | 235 | 236 | 237 | org.apache.maven.plugins 238 | maven-failsafe-plugin 239 | ${maven.failsafe.plugin.version} 240 | 241 | 242 | 243 | vertx.mods 244 | ${mods.directory} 245 | 246 | 247 | 248 | **/integration/**/*Test* 249 | 250 | 251 | 252 | 253 | 254 | integration-test 255 | verify 256 | 257 | 258 | 259 | 260 | 261 | org.apache.maven.plugins 262 | maven-surefire-report-plugin 263 | ${maven.surefire.report.plugin.version} 264 | 265 | 266 | generate-test-report 267 | test 268 | 269 | report-only 270 | 271 | 272 | 273 | generate-integration-test-report 274 | integration-test 275 | 276 | failsafe-report-only 277 | 278 | 279 | 280 | 281 | 282 | maven-assembly-plugin 283 | 284 | 285 | src/main/assembly/mod.xml 286 | 287 | 288 | 289 | 290 | assemble 291 | package 292 | 293 | single 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | org.apache.maven.plugins 304 | maven-surefire-report-plugin 305 | ${maven.surefire.report.plugin.version} 306 | 307 | 308 | org.apache.maven.plugins 309 | maven-javadoc-plugin 310 | ${maven.javadoc.plugin.version} 311 | 312 | true 313 | 314 | 315 | 316 | 317 | 318 | 319 | release 320 | 321 | 322 | 323 | org.sonatype.plugins 324 | nexus-staging-maven-plugin 325 | 1.6.3 326 | true 327 | 328 | ossrh 329 | https://oss.sonatype.org/ 330 | true 331 | 332 | 333 | 334 | org.apache.maven.plugins 335 | maven-source-plugin 336 | 2.2.1 337 | 338 | 339 | attach-sources 340 | 341 | jar-no-fork 342 | 343 | 344 | 345 | 346 | 347 | org.apache.maven.plugins 348 | maven-javadoc-plugin 349 | 2.9.1 350 | 351 | 352 | attach-javadocs 353 | 354 | jar 355 | 356 | 357 | 358 | 359 | 360 | org.apache.maven.plugins 361 | maven-gpg-plugin 362 | 1.5 363 | 364 | 365 | sign-artifacts 366 | verify 367 | 368 | sign 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | -------------------------------------------------------------------------------- /src/main/README.txt: -------------------------------------------------------------------------------- 1 | Put any Java or Groovy classes used in your module in the java or groovy directories. 2 | 3 | Put any other resources that you want included in your module in the resources directory, this includes any 4 | JavaScript, Ruby, Python, Groovy or CoffeeScript scripts or any other stuff you want in your module. 5 | 6 | The mod.json file also goes in the resources directory so it's copied over too. -------------------------------------------------------------------------------- /src/main/assembly/mod.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | mod 7 | 8 | zip 9 | 10 | 11 | false 12 | 13 | 14 | 15 | 16 | ${mods.directory}/${module.name} 17 | 18 | ** 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/Async.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.simondean.vertx.async.internal.*; 4 | 5 | public final class Async { 6 | private Async() {} 7 | 8 | public static Series series() { 9 | return new SeriesImpl<>(); 10 | } 11 | 12 | public static WaterfallBuilder waterfall() { 13 | return new WaterfallBuilderImpl(); 14 | } 15 | 16 | public static IterableBuilder iterable(Iterable iterable) { 17 | return new IterableBuilderImpl(iterable); 18 | } 19 | 20 | public static RetryBuilder retry() { 21 | return new RetryBuilderImpl(); 22 | } 23 | 24 | public static ForeverBuilder forever() { 25 | return new ForeverBuilderImpl(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/AsyncResultHandlerWrapper.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResult; 4 | import org.vertx.java.core.AsyncResultHandler; 5 | 6 | public class AsyncResultHandlerWrapper implements AsyncResultHandler { 7 | private final AsyncResultHandler handler; 8 | 9 | public AsyncResultHandlerWrapper(AsyncResultHandler handler) { 10 | this.handler = handler; 11 | } 12 | 13 | public static AsyncResultHandler wrap(AsyncResultHandler handler) { 14 | return new AsyncResultHandlerWrapper<>(handler); 15 | } 16 | 17 | @Override 18 | public void handle(AsyncResult asyncResult) { 19 | if (asyncResult.failed()) { 20 | handler.handle(DefaultAsyncResult.fail(asyncResult.cause())); 21 | return; 22 | } 23 | 24 | handler.handle(DefaultAsyncResult.succeed((T) asyncResult.result())); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/DefaultAsyncResult.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResult; 4 | 5 | public class DefaultAsyncResult implements AsyncResult { 6 | private Throwable cause; 7 | private T result; 8 | 9 | public DefaultAsyncResult(Throwable cause, T result) { 10 | this.cause = cause; 11 | this.result = result; 12 | } 13 | 14 | public static AsyncResult succeed(T result) { 15 | return new DefaultAsyncResult<>(null, result); 16 | } 17 | 18 | public static AsyncResult succeed() { 19 | return succeed(null); 20 | } 21 | 22 | public static AsyncResult fail(Throwable cause) { 23 | if (cause == null) { 24 | throw new IllegalArgumentException("cause argument cannot be null"); 25 | } 26 | 27 | return new DefaultAsyncResult<>(cause, null); 28 | } 29 | 30 | public static AsyncResult fail(AsyncResult result) { 31 | return fail(result.cause()); 32 | } 33 | 34 | @Override 35 | public T result() { 36 | return result; 37 | } 38 | 39 | @Override 40 | public Throwable cause() { 41 | return cause; 42 | } 43 | 44 | @Override 45 | public boolean succeeded() { 46 | return cause == null; 47 | } 48 | 49 | @Override 50 | public boolean failed() { 51 | return cause != null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/EachBuilder.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | import org.vertx.java.core.Vertx; 5 | 6 | public interface EachBuilder { 7 | void run(Vertx vertx, AsyncResultHandler handler); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/Forever.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | import org.vertx.java.core.Vertx; 5 | 6 | public interface Forever { 7 | void run(Vertx vertx, AsyncResultHandler handler); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/ForeverBuilder.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface ForeverBuilder { 8 | Forever task(Consumer> task); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/FunctionWrapper.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | public class FunctionWrapper { 4 | private T f; 5 | 6 | public void wrap(T f) { 7 | this.f = f; 8 | } 9 | 10 | public T f() { 11 | return f; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/IterableBuilder.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.function.BiConsumer; 6 | 7 | public interface IterableBuilder { 8 | EachBuilder each(BiConsumer> each); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/ObjectWrapper.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | public class ObjectWrapper { 4 | private T object; 5 | 6 | public ObjectWrapper() { 7 | } 8 | 9 | public ObjectWrapper(T object) { 10 | this.object = object; 11 | } 12 | 13 | public void setObject(T object) { 14 | this.object = object; 15 | } 16 | 17 | public T getObject() { 18 | return object; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/Retry.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | public interface Retry { 6 | void run(AsyncResultHandler handler); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/RetryBuilder.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface RetryBuilder { 8 | RetryTimesBuilder task(Consumer> task); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/RetryTimesBuilder.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | public interface RetryTimesBuilder { 4 | Retry times(int times); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/Series.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.List; 6 | import java.util.function.Consumer; 7 | 8 | public interface Series { 9 | Series task(Consumer> task); 10 | 11 | void run(AsyncResultHandler> handler); 12 | } -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/Waterfall.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.function.BiConsumer; 6 | 7 | public interface Waterfall { 8 | public Waterfall task(BiConsumer> task); 9 | 10 | public void run(AsyncResultHandler handler); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/WaterfallBuilder.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public interface WaterfallBuilder { 8 | public Waterfall task(Consumer> task); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/DefaultWaterfall.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.Waterfall; 4 | import org.vertx.java.core.AsyncResultHandler; 5 | 6 | import java.util.function.BiConsumer; 7 | import java.util.function.Consumer; 8 | 9 | public class DefaultWaterfall implements Waterfall { 10 | private final Consumer> task; 11 | 12 | public DefaultWaterfall(Consumer> task) { 13 | this.task = task; 14 | } 15 | 16 | @Override 17 | public Waterfall task(BiConsumer> task) { 18 | return new NestedWaterfall<>(this, task); 19 | } 20 | 21 | @Override 22 | public void run(AsyncResultHandler handler) { 23 | if (task == null) { 24 | handler.handle(null); 25 | return; 26 | } 27 | 28 | task.accept(handler); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/EachBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.simondean.vertx.async.EachBuilder; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.vertx.java.core.AsyncResultHandler; 7 | import org.vertx.java.core.Vertx; 8 | 9 | import java.util.ArrayList; 10 | import java.util.function.BiConsumer; 11 | 12 | public class EachBuilderImpl implements EachBuilder { 13 | private final Iterable iterable; 14 | private final BiConsumer> each; 15 | 16 | public EachBuilderImpl(Iterable iterable, BiConsumer> each) { 17 | this.iterable = iterable; 18 | this.each = each; 19 | } 20 | 21 | @Override 22 | public void run(Vertx vertx, AsyncResultHandler handler) { 23 | final ObjectWrapper failed = new ObjectWrapper<>(false); 24 | final ObjectWrapper finishedCount = new ObjectWrapper<>(0); 25 | 26 | ArrayList items = new ArrayList(); 27 | 28 | for (T item : iterable) { 29 | items.add(item); 30 | } 31 | 32 | if (items.size() == 0) { 33 | handler.handle(DefaultAsyncResult.succeed()); 34 | return; 35 | } 36 | 37 | for (T item : items) { 38 | vertx.runOnContext(aVoid -> each.accept(item, result -> { 39 | finishedCount.setObject(finishedCount.getObject() + 1); 40 | 41 | if (result.failed()) { 42 | if (!failed.getObject()) { 43 | handler.handle(DefaultAsyncResult.fail(result)); 44 | failed.setObject(true); 45 | } 46 | 47 | return; 48 | } 49 | 50 | if (finishedCount.getObject() == items.size()) { 51 | handler.handle(DefaultAsyncResult.succeed()); 52 | } 53 | })); 54 | 55 | if (failed.getObject()) { 56 | return; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/ForeverBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.Forever; 4 | import org.simondean.vertx.async.ForeverBuilder; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | import java.util.function.Consumer; 8 | 9 | public class ForeverBuilderImpl implements ForeverBuilder { 10 | @Override 11 | public Forever task(Consumer> task) { 12 | return new ForeverImpl(task); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/ForeverImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.simondean.vertx.async.Forever; 5 | import org.simondean.vertx.async.FunctionWrapper; 6 | import org.vertx.java.core.AsyncResultHandler; 7 | import org.vertx.java.core.Vertx; 8 | 9 | import java.util.function.Consumer; 10 | 11 | public class ForeverImpl implements Forever { 12 | private final Consumer> task; 13 | 14 | public ForeverImpl(Consumer> task) { 15 | this.task = task; 16 | } 17 | 18 | @Override 19 | public void run(Vertx vertx, AsyncResultHandler handler) { 20 | FunctionWrapper visitor = new FunctionWrapper<>(); 21 | visitor.wrap(() -> task.accept(result -> { 22 | if (result.failed()) { 23 | handler.handle(DefaultAsyncResult.fail(result)); 24 | return; 25 | } 26 | 27 | vertx.runOnContext(aVoid -> visitor.f().run()); 28 | })); 29 | 30 | visitor.f().run(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/IterableBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.EachBuilder; 4 | import org.simondean.vertx.async.IterableBuilder; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | import java.util.function.BiConsumer; 8 | 9 | public class IterableBuilderImpl implements IterableBuilder { 10 | private final Iterable iterable; 11 | 12 | public IterableBuilderImpl(Iterable iterable) { 13 | this.iterable = iterable; 14 | } 15 | 16 | @Override 17 | public EachBuilder each(BiConsumer> each) { 18 | return new EachBuilderImpl(iterable, each); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/NestedWaterfall.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.simondean.vertx.async.Waterfall; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | import java.util.function.BiConsumer; 8 | 9 | public class NestedWaterfall implements Waterfall { 10 | private final Waterfall parentWaterfall; 11 | private BiConsumer> task; 12 | 13 | public NestedWaterfall(Waterfall parentWaterfall, BiConsumer> task) { 14 | this.parentWaterfall = parentWaterfall; 15 | this.task = task; 16 | } 17 | 18 | @Override 19 | public Waterfall task(BiConsumer> task) { 20 | return new NestedWaterfall<>(this, task); 21 | } 22 | 23 | @Override 24 | public void run(AsyncResultHandler handler) { 25 | parentWaterfall.run(result -> { 26 | if (result.failed()) { 27 | handler.handle(DefaultAsyncResult.fail(result)); 28 | return; 29 | } 30 | 31 | task.accept(result.result(), handler); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/RetryBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.RetryBuilder; 4 | import org.simondean.vertx.async.RetryTimesBuilder; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | import java.util.function.Consumer; 8 | 9 | public class RetryBuilderImpl implements RetryBuilder { 10 | @Override 11 | public RetryTimesBuilder task(Consumer> task) { 12 | return new RetryTimesBuilderImpl<>(task); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/RetryImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.simondean.vertx.async.FunctionWrapper; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.simondean.vertx.async.Retry; 7 | import org.vertx.java.core.AsyncResultHandler; 8 | 9 | import java.util.function.Consumer; 10 | 11 | public class RetryImpl implements Retry { 12 | private final Consumer> task; 13 | private final int times; 14 | 15 | public RetryImpl(Consumer> task, int times) { 16 | this.task = task; 17 | this.times = times; 18 | } 19 | 20 | @Override 21 | public void run(AsyncResultHandler handler) { 22 | ObjectWrapper count = new ObjectWrapper<>(0); 23 | 24 | FunctionWrapper visitor = new FunctionWrapper<>(); 25 | visitor.wrap(() -> task.accept(result -> { 26 | if (result.failed()) { 27 | count.setObject(count.getObject() + 1); 28 | 29 | if (count.getObject() > times) { 30 | handler.handle(DefaultAsyncResult.fail(result)); 31 | return; 32 | } 33 | 34 | visitor.f().run(); 35 | return; 36 | } 37 | 38 | handler.handle(DefaultAsyncResult.succeed(result.result())); 39 | })); 40 | 41 | visitor.f().run(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/RetryTimesBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.Retry; 4 | import org.simondean.vertx.async.RetryTimesBuilder; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | import java.util.function.Consumer; 8 | 9 | public class RetryTimesBuilderImpl implements RetryTimesBuilder { 10 | private final Consumer> task; 11 | 12 | public RetryTimesBuilderImpl(Consumer> task) { 13 | this.task = task; 14 | } 15 | 16 | @Override 17 | public Retry times(int times) { 18 | return new RetryImpl<>(task, times); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/SeriesImpl.java: -------------------------------------------------------------------------------- 1 | 2 | package org.simondean.vertx.async.internal; 3 | 4 | import org.simondean.vertx.async.DefaultAsyncResult; 5 | import org.simondean.vertx.async.FunctionWrapper; 6 | import org.simondean.vertx.async.Series; 7 | import org.vertx.java.core.AsyncResultHandler; 8 | import org.vertx.java.core.impl.DefaultFutureResult; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Iterator; 12 | import java.util.List; 13 | import java.util.function.Consumer; 14 | 15 | public class SeriesImpl implements Series { 16 | private ArrayList>> tasks = new ArrayList<>(); 17 | 18 | @Override 19 | public Series task(Consumer> task) { 20 | tasks.add(task); 21 | return this; 22 | } 23 | 24 | @Override 25 | public void run(AsyncResultHandler> handler) { 26 | Iterator>> iterator = tasks.iterator(); 27 | List results = new ArrayList<>(); 28 | 29 | FunctionWrapper visitor = new FunctionWrapper<>(); 30 | visitor.wrap(() -> { 31 | if (!iterator.hasNext()) { 32 | handler.handle(DefaultAsyncResult.succeed(results)); 33 | return; 34 | } 35 | 36 | Consumer> task = iterator.next(); 37 | 38 | AsyncResultHandler taskHandler = (result) -> { 39 | if (result.failed()) { 40 | handler.handle(DefaultAsyncResult.fail(result)); 41 | return; 42 | } 43 | 44 | results.add(result.result()); 45 | visitor.f().run(); 46 | }; 47 | 48 | task.accept(taskHandler); 49 | }); 50 | 51 | visitor.f().run(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/simondean/vertx/async/internal/WaterfallBuilderImpl.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.internal; 2 | 3 | import org.simondean.vertx.async.WaterfallBuilder; 4 | import org.simondean.vertx.async.Waterfall; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | import java.util.function.Consumer; 8 | 9 | public class WaterfallBuilderImpl implements WaterfallBuilder { 10 | @Override 11 | public Waterfall task(Consumer> task) { 12 | return new DefaultWaterfall<>(task); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/platform_lib/README.txt: -------------------------------------------------------------------------------- 1 | If you want override the default langs.properties, cluster.xml or any other config for the Vert.x platform (i.e. 2 | not for the module!) then you can add them in here and they will be added to the platform classpath when running 3 | your module using Gradle. -------------------------------------------------------------------------------- /src/main/resources/mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "description":"Async helpers for Vert.x", 3 | "licenses": ["MIT"], 4 | "author": "Simon Dean", 5 | 6 | "developers": [], 7 | "keywords": [ 8 | "async", 9 | "vert.x" 10 | ], 11 | "homepage": "https://github.com/simondean/vertx-async", 12 | 13 | "auto-redeploy": true 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/platform_lib/README.txt: -------------------------------------------------------------------------------- 1 | If you are using fatjars and you want override the default langs.properties, cluster.xml or any other config for the Vert.x platform (i.e. 2 | not for the module!) then you can add them in here and they will be added to the platform classpath when running 3 | your module using Gradle. 4 | 5 | The fatjar starter knows to add this directory (and any jars/zips inside it) to the Vert.x platform classpath when executing your module as a fatjar. -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/integration/README.txt: -------------------------------------------------------------------------------- 1 | Your integration tests go in here. 2 | 3 | Integration tests are run inside the Vert.x container -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/integration/java/README.txt: -------------------------------------------------------------------------------- 1 | Put your Java integration tests in here or sub directories. 2 | 3 | To create a Java integration test in Vert.x - that's a test that runs *inside* the Vert.x container, you should 4 | create a class like this which extends `TestVerticle`. 5 | 6 | `TestVerticle` acts as both a Verticle which can run inside the Vert.x container and as a JUnit test. 7 | 8 | We use a custom JUnit test runner so that when this test is run it auto-magically creates a Vert.x container 9 | and runs it in that whilst communicating the test results back to the runner so they can be collated as 10 | normal. 11 | 12 | You should annotate your test methods with @Test as normal, and you can use the standard JUnit API 13 | inside the test to assert stuff. 14 | 15 | @Before and @After annotations currently don't work, but you can put any shared startup code that inside the 16 | standard verticle `start()` method. 17 | 18 | You can use the standard JUnit Assert API in your test by using the VertxAssert class -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/AsyncTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.*; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | public class AsyncTest { 12 | @Test 13 | public void itCreatesANewSeries() { 14 | Series series = Async.series(); 15 | assertThat(series).isNotNull(); 16 | } 17 | 18 | @Test 19 | public void itCreatesANewWaterfall() { 20 | WaterfallBuilder waterfallBuilder = Async.waterfall(); 21 | assertThat(waterfallBuilder).isNotNull(); 22 | } 23 | 24 | @Test 25 | public void itCreatesANewIterable() { 26 | List list = Arrays.asList("One"); 27 | IterableBuilder iterableBuilder = Async.iterable(list); 28 | assertThat(iterableBuilder).isNotNull(); 29 | } 30 | 31 | @Test 32 | public void itCreatesANewRetry() { 33 | RetryBuilder retryBuilder = Async.retry(); 34 | assertThat(retryBuilder).isNotNull(); 35 | } 36 | 37 | @Test 38 | public void itCreatesANewForever() { 39 | ForeverBuilder foreverBuilder = Async.forever(); 40 | assertThat(foreverBuilder).isNotNull(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/EachExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.unit.examples.EachExample; 5 | import org.simondean.vertx.async.unit.examples.SeriesExample; 6 | 7 | import java.util.List; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | public class EachExampleTest { 12 | @Test 13 | public void itHandlesSuccess() { 14 | EachExample example = new EachExample(true); 15 | 16 | example.eachExample(result -> { 17 | assertThat(result).isNotNull(); 18 | assertThat(result.succeeded()).isTrue(); 19 | 20 | assertThat(result.result()).isNull(); 21 | List items = example.items(); 22 | assertThat(items).isNotNull(); 23 | assertThat(items).containsExactly("one", "two", "three"); 24 | }); 25 | } 26 | 27 | @Test 28 | public void itHandlesFailure() { 29 | EachExample example = new EachExample(false); 30 | 31 | example.eachExample(result -> { 32 | assertThat(result).isNotNull(); 33 | assertThat(result.succeeded()).isFalse(); 34 | 35 | assertThat(result.result()).isNull(); 36 | List items = example.items(); 37 | assertThat(items).isNotNull(); 38 | assertThat(items).isEmpty(); 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/EachTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.Async; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.simondean.vertx.async.unit.fakes.*; 7 | 8 | import java.util.ArrayList; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | public class EachTest { 13 | @Test 14 | public void itStillExecutesWhenThereAreNoItems() { 15 | ArrayList items = new ArrayList<>(); 16 | 17 | FakeFailingAsyncFunction each = new FakeFailingAsyncFunction<>(new Throwable("Failed")); 18 | 19 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 20 | 21 | Async.iterable(items) 22 | .each(each) 23 | .run(new FakeVertx(), result -> { 24 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 25 | 26 | assertThat(result).isNotNull(); 27 | assertThat(result.succeeded()).isTrue(); 28 | assertThat(result.result()).isNull(); 29 | 30 | assertThat(each.runCount()).isEqualTo(0); 31 | }); 32 | 33 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 34 | } 35 | 36 | @Test 37 | public void itExecutesForOneItem() { 38 | ArrayList items = new ArrayList<>(); 39 | items.add("One"); 40 | 41 | FakeSuccessfulAsyncFunction each = new FakeSuccessfulAsyncFunction<>(null); 42 | 43 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 44 | 45 | Async.iterable(items) 46 | .each(each) 47 | .run(new FakeVertx(), result -> { 48 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 49 | 50 | assertThat(result).isNotNull(); 51 | assertThat(result.succeeded()).isTrue(); 52 | assertThat(result.result()).isNull(); 53 | 54 | assertThat(each.runCount()).isEqualTo(1); 55 | assertThat(each.consumedValues()).containsExactly("One"); 56 | }); 57 | 58 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 59 | } 60 | 61 | @Test 62 | public void itExecutesForTwoItems() { 63 | ArrayList items = new ArrayList<>(); 64 | items.add("One"); 65 | items.add("Two"); 66 | 67 | FakeSuccessfulAsyncFunction each = new FakeSuccessfulAsyncFunction<>(null); 68 | 69 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 70 | 71 | Async.iterable(items) 72 | .each(each) 73 | .run(new FakeVertx(), result -> { 74 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 75 | 76 | assertThat(result).isNotNull(); 77 | assertThat(result.succeeded()).isTrue(); 78 | assertThat(result.result()).isNull(); 79 | 80 | assertThat(each.runCount()).isEqualTo(2); 81 | assertThat(each.consumedValues()).containsExactly("One", "Two"); 82 | }); 83 | 84 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 85 | } 86 | 87 | @Test 88 | public void itFailsWhenAnItemFails() { 89 | ArrayList items = new ArrayList<>(); 90 | items.add("One"); 91 | 92 | FakeFailingAsyncFunction each = new FakeFailingAsyncFunction<>(new Throwable("Failed")); 93 | 94 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 95 | 96 | Async.iterable(items) 97 | .each(each) 98 | .run(new FakeVertx(), result -> { 99 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 100 | 101 | assertThat(result).isNotNull(); 102 | assertThat(result.succeeded()).isFalse(); 103 | assertThat(result.cause()).isEqualTo(each.cause()); 104 | assertThat(result.result()).isNull(); 105 | 106 | assertThat(each.runCount()).isEqualTo(1); 107 | assertThat(each.consumedValues()).containsExactlyElementsOf(items); 108 | }); 109 | 110 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 111 | } 112 | 113 | @Test 114 | public void itFailsNoMoreThanOnce() { 115 | ArrayList items = new ArrayList<>(); 116 | items.add("One"); 117 | items.add("Two"); 118 | 119 | FakeFailingAsyncFunction each = new FakeFailingAsyncFunction<>(new Throwable("Failed")); 120 | ObjectWrapper resultCount = new ObjectWrapper<>(0); 121 | 122 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 123 | 124 | Async.iterable(items) 125 | .each(each) 126 | .run(new FakeVertx(), result -> { 127 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 128 | 129 | assertThat(result).isNotNull(); 130 | assertThat(result.succeeded()).isFalse(); 131 | assertThat(result.cause()).isEqualTo(each.cause()); 132 | assertThat(result.result()).isNull(); 133 | 134 | resultCount.setObject(resultCount.getObject().intValue() + 1); 135 | 136 | assertThat(resultCount.getObject().intValue()).isEqualTo(1); 137 | }); 138 | 139 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/ForeverExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.unit.examples.ForeverExample; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | public class ForeverExampleTest { 9 | @Test 10 | public void itHandlesFailure() { 11 | ForeverExample example = new ForeverExample(); 12 | 13 | example.foreverExample(result -> { 14 | assertThat(result).isNotNull(); 15 | assertThat(result.succeeded()).isFalse(); 16 | 17 | String resultFromHandler = result.result(); 18 | assertThat(resultFromHandler).isNull(); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/ForeverTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.Async; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.simondean.vertx.async.unit.fakes.FakeFailingAsyncSupplier; 7 | import org.simondean.vertx.async.unit.fakes.FakeSuccessfulAsyncSupplier; 8 | import org.simondean.vertx.async.unit.fakes.FakeVertx; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | public class ForeverTest { 13 | @Test 14 | public void itExecutesTheTaskUntilItFails() { 15 | FakeFailingAsyncSupplier task1 = new FakeFailingAsyncSupplier<>(2, null, new Throwable("Failed")); 16 | 17 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 18 | 19 | Async.forever() 20 | .task(task1) 21 | .run(new FakeVertx(), result -> { 22 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 23 | 24 | assertThat(task1.runCount()).isEqualTo(3); 25 | 26 | assertThat(result).isNotNull(); 27 | assertThat(result.succeeded()).isFalse(); 28 | Object resultValue = result.result(); 29 | assertThat(resultValue).isNull(); 30 | }); 31 | 32 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/README.txt: -------------------------------------------------------------------------------- 1 | Put your unit tests in here. 2 | 3 | Unit tests talk directly to your project test classes and aren't run inside the Vert.x container. -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/RetryExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.unit.examples.RetryExample; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | public class RetryExampleTest { 9 | @Test 10 | public void itHandlesSuccess() { 11 | RetryExample example = new RetryExample(true); 12 | 13 | example.retryExample(result -> { 14 | assertThat(result).isNotNull(); 15 | assertThat(result.succeeded()).isTrue(); 16 | 17 | String resultFromHandler = result.result(); 18 | assertThat(resultFromHandler).isNotNull(); 19 | assertThat(resultFromHandler).isEqualTo("Async result"); 20 | String resultFromExample = example.result(); 21 | assertThat(resultFromExample).isNotNull(); 22 | assertThat(resultFromExample).isEqualTo("Async result"); 23 | }); 24 | } 25 | 26 | @Test 27 | public void itHandlesFailure() { 28 | RetryExample example = new RetryExample(false); 29 | 30 | example.retryExample(result -> { 31 | assertThat(result).isNotNull(); 32 | assertThat(result.succeeded()).isFalse(); 33 | 34 | String resultFromHandler = result.result(); 35 | assertThat(resultFromHandler).isNull(); 36 | String resultFromExample = example.result(); 37 | assertThat(resultFromExample).isNull(); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/RetryTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.Async; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.simondean.vertx.async.unit.fakes.FakeFailingAsyncSupplier; 7 | import org.simondean.vertx.async.unit.fakes.FakeSuccessfulAsyncSupplier; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | public class RetryTest { 12 | @Test 13 | public void itExecutesTheTask() { 14 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 15 | 16 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 17 | 18 | Async.retry() 19 | .task(task1) 20 | .times(1) 21 | .run(result -> { 22 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 23 | 24 | assertThat(task1.runCount()).isEqualTo(1); 25 | 26 | assertThat(result).isNotNull(); 27 | assertThat(result.succeeded()).isTrue(); 28 | String resultValue = result.result(); 29 | assertThat(resultValue).isNotNull(); 30 | assertThat(resultValue).isEqualTo(task1.result()); 31 | }); 32 | 33 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 34 | } 35 | 36 | @Test 37 | public void itExecutesTheTaskAgainAfterAFailure() { 38 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>(1, new Throwable("Failed"), "Task 1"); 39 | 40 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 41 | 42 | Async.retry() 43 | .task(task1) 44 | .times(1) 45 | .run(result -> { 46 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 47 | 48 | assertThat(task1.runCount()).isEqualTo(2); 49 | 50 | assertThat(result).isNotNull(); 51 | assertThat(result.succeeded()).isTrue(); 52 | String resultValue = result.result(); 53 | assertThat(resultValue).isNotNull(); 54 | assertThat(resultValue).isEqualTo(task1.result()); 55 | }); 56 | 57 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 58 | } 59 | 60 | @Test 61 | public void itExecutesTheTaskAgainAfterASecondFailure() { 62 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>(2, new Throwable("Failed"), "Task 1"); 63 | 64 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 65 | 66 | Async.retry() 67 | .task(task1) 68 | .times(2) 69 | .run(result -> { 70 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 71 | 72 | assertThat(task1.runCount()).isEqualTo(3); 73 | 74 | assertThat(result).isNotNull(); 75 | assertThat(result.succeeded()).isTrue(); 76 | String resultValue = result.result(); 77 | assertThat(resultValue).isNotNull(); 78 | assertThat(resultValue).isEqualTo(task1.result()); 79 | }); 80 | 81 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 82 | } 83 | @Test 84 | public void itFailsAfterTheRetryTimes() { 85 | FakeFailingAsyncSupplier task1 = new FakeFailingAsyncSupplier<>(new Throwable("Failed")); 86 | 87 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 88 | 89 | Async.retry() 90 | .task(task1) 91 | .times(1) 92 | .run(result -> { 93 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 94 | 95 | assertThat(task1.runCount()).isEqualTo(2); 96 | 97 | assertThat(result).isNotNull(); 98 | assertThat(result.succeeded()).isFalse(); 99 | assertThat(result.cause()).isEqualTo(task1.cause()); 100 | assertThat(result.result()).isNull(); 101 | }); 102 | 103 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/SeriesExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.unit.examples.SeriesExample; 5 | 6 | import java.util.List; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | public class SeriesExampleTest { 11 | @Test 12 | public void itHandlesSuccess() { 13 | SeriesExample example = new SeriesExample(true); 14 | 15 | example.seriesExample(result -> { 16 | assertThat(result).isNotNull(); 17 | assertThat(result.succeeded()).isTrue(); 18 | 19 | List resultsFromHandler = result.result(); 20 | assertThat(resultsFromHandler).isNotNull(); 21 | assertThat(resultsFromHandler).containsExactly("Result", "Async result"); 22 | List resultsFromExample = example.results(); 23 | assertThat(resultsFromExample).isNotNull(); 24 | assertThat(resultsFromExample).containsExactly("Result", "Async result"); 25 | }); 26 | } 27 | 28 | @Test 29 | public void itHandlesFailure() { 30 | SeriesExample example = new SeriesExample(false); 31 | 32 | example.seriesExample(result -> { 33 | assertThat(result).isNotNull(); 34 | assertThat(result.succeeded()).isFalse(); 35 | 36 | List resultsFromHandler = result.result(); 37 | assertThat(resultsFromHandler).isNull(); 38 | List resultsFromExample = example.results(); 39 | assertThat(resultsFromExample).isNull(); 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/SeriesTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.Async; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.simondean.vertx.async.unit.fakes.FakeFailingAsyncSupplier; 7 | import org.simondean.vertx.async.unit.fakes.FakeSuccessfulAsyncSupplier; 8 | 9 | import java.util.List; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | public class SeriesTest { 14 | @Test 15 | public void itStillExecutesWhenThereAreNoTasks() { 16 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 17 | 18 | Async.series() 19 | .run(result -> { 20 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 21 | 22 | assertThat(result).isNotNull(); 23 | assertThat(result.succeeded()).isTrue(); 24 | List resultList = result.result(); 25 | assertThat(resultList).isNotNull(); 26 | assertThat(resultList).isEmpty(); 27 | }); 28 | 29 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 30 | } 31 | 32 | @Test 33 | public void itExecutesOneTask() { 34 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 35 | 36 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 37 | 38 | Async.series() 39 | .task(task1) 40 | .run(result -> { 41 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 42 | 43 | assertThat(task1.runCount()).isEqualTo(1); 44 | 45 | assertThat(result).isNotNull(); 46 | assertThat(result.succeeded()).isTrue(); 47 | List resultList = result.result(); 48 | assertThat(resultList).isNotNull(); 49 | assertThat(resultList).containsExactly(task1.result()); 50 | }); 51 | 52 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 53 | } 54 | 55 | @Test 56 | public void itExecutesTwoTasks() { 57 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 58 | FakeSuccessfulAsyncSupplier task2 = new FakeSuccessfulAsyncSupplier<>("Task 2"); 59 | 60 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 61 | 62 | Async.series() 63 | .task(task1) 64 | .task(task2) 65 | .run(result -> { 66 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 67 | 68 | assertThat(task1.runCount()).isEqualTo(1); 69 | assertThat(task2.runCount()).isEqualTo(1); 70 | 71 | assertThat(result).isNotNull(); 72 | assertThat(result.succeeded()).isTrue(); 73 | List resultList = result.result(); 74 | assertThat(resultList).isNotNull(); 75 | assertThat(resultList).containsExactly(task1.result(), task2.result()); 76 | }); 77 | 78 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 79 | } 80 | 81 | @Test 82 | public void itFailsWhenATaskFails() { 83 | FakeFailingAsyncSupplier task1 = new FakeFailingAsyncSupplier<>(new Throwable("Failed")); 84 | 85 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 86 | 87 | Async.series() 88 | .task(task1) 89 | .run(result -> { 90 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 91 | 92 | assertThat(task1.runCount()).isEqualTo(1); 93 | 94 | assertThat(result).isNotNull(); 95 | assertThat(result.succeeded()).isFalse(); 96 | assertThat(result.cause()).isEqualTo(task1.cause()); 97 | assertThat(result.result()).isNull(); 98 | }); 99 | 100 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 101 | } 102 | 103 | @Test 104 | public void itExecutesNoMoreTasksWhenATaskFails() { 105 | FakeFailingAsyncSupplier task1 = new FakeFailingAsyncSupplier<>(new Throwable("Failed")); 106 | FakeSuccessfulAsyncSupplier task2 = new FakeSuccessfulAsyncSupplier<>("Task 2"); 107 | 108 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 109 | 110 | Async.series() 111 | .task(task1) 112 | .task(task2) 113 | .run(result -> { 114 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 115 | 116 | assertThat(result).isNotNull(); 117 | assertThat(result.succeeded()).isFalse(); 118 | assertThat(result.cause()).isEqualTo(task1.cause()); 119 | assertThat(result.result()).isNull(); 120 | assertThat(task1.runCount()).isEqualTo(1); 121 | assertThat(task2.runCount()).isEqualTo(0); 122 | }); 123 | 124 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/WaterfallExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.unit.examples.WaterfallExample; 5 | 6 | import java.util.List; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | public class WaterfallExampleTest { 11 | @Test 12 | public void itHandlesSuccess() { 13 | WaterfallExample example = new WaterfallExample(true); 14 | 15 | example.waterfallExample(result -> { 16 | assertThat(result).isNotNull(); 17 | assertThat(result.succeeded()).isTrue(); 18 | 19 | Integer resultsFromHandler = result.result(); 20 | assertThat(resultsFromHandler).isNotNull(); 21 | assertThat(resultsFromHandler).isEqualTo(42); 22 | Integer resultsFromExample = example.result(); 23 | assertThat(resultsFromExample).isNotNull(); 24 | assertThat(resultsFromExample).isEqualTo(42); 25 | }); 26 | } 27 | 28 | @Test 29 | public void itHandlesFailure() { 30 | WaterfallExample example = new WaterfallExample(false); 31 | 32 | example.waterfallExample(result -> { 33 | assertThat(result).isNotNull(); 34 | assertThat(result.succeeded()).isFalse(); 35 | 36 | Integer resultsFromHandler = result.result(); 37 | assertThat(resultsFromHandler).isNull(); 38 | Integer resultsFromExample = example.result(); 39 | assertThat(resultsFromExample).isNull(); 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/WaterfallTest.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit; 2 | 3 | import org.junit.Test; 4 | import org.simondean.vertx.async.Async; 5 | import org.simondean.vertx.async.ObjectWrapper; 6 | import org.simondean.vertx.async.unit.fakes.FakeFailingAsyncFunction; 7 | import org.simondean.vertx.async.unit.fakes.FakeFailingAsyncSupplier; 8 | import org.simondean.vertx.async.unit.fakes.FakeSuccessfulAsyncFunction; 9 | import org.simondean.vertx.async.unit.fakes.FakeSuccessfulAsyncSupplier; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | public class WaterfallTest { 14 | @Test 15 | public void itExecutesOneTask() { 16 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 17 | 18 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 19 | 20 | Async.waterfall() 21 | .task(task1) 22 | .run(result -> { 23 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 24 | 25 | assertThat(task1.runCount()).isEqualTo(1); 26 | 27 | assertThat(result).isNotNull(); 28 | assertThat(result.succeeded()).isTrue(); 29 | String resultValue = result.result(); 30 | assertThat(resultValue).isNotNull(); 31 | assertThat(resultValue).isEqualTo(task1.result()); 32 | }); 33 | } 34 | 35 | @Test 36 | public void itExecutesTwoTasks() { 37 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 38 | FakeSuccessfulAsyncFunction task2 = new FakeSuccessfulAsyncFunction<>(2); 39 | 40 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 41 | 42 | Async.waterfall() 43 | .task(task1) 44 | .task(task2) 45 | .run(result -> { 46 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 47 | 48 | assertThat(task1.runCount()).isEqualTo(1); 49 | assertThat(task2.consumedValue()).isEqualTo(task1.result()); 50 | assertThat(task2.runCount()).isEqualTo(1); 51 | 52 | assertThat(result).isNotNull(); 53 | assertThat(result.succeeded()).isTrue(); 54 | Integer resultValue = result.result(); 55 | assertThat(resultValue).isNotNull(); 56 | assertThat(resultValue).isEqualTo(task2.result()); 57 | }); 58 | 59 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 60 | } 61 | 62 | @Test 63 | public void itFailsWhenATaskFails() { 64 | FakeFailingAsyncSupplier task1 = new FakeFailingAsyncSupplier<>(new Throwable("Failed")); 65 | 66 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 67 | 68 | Async.waterfall() 69 | .task(task1) 70 | .run(result -> { 71 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 72 | 73 | assertThat(task1.runCount()).isEqualTo(1); 74 | 75 | assertThat(result).isNotNull(); 76 | assertThat(result.succeeded()).isFalse(); 77 | assertThat(result.cause()).isEqualTo(task1.cause()); 78 | assertThat(result.result()).isNull(); 79 | }); 80 | 81 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 82 | } 83 | 84 | @Test 85 | public void itExecutesNoMoreTasksWhenATaskFails() { 86 | FakeFailingAsyncSupplier task1 = new FakeFailingAsyncSupplier<>(new Throwable("Failed")); 87 | FakeSuccessfulAsyncFunction task2 = new FakeSuccessfulAsyncFunction<>(2); 88 | 89 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 90 | 91 | Async.waterfall() 92 | .task(task1) 93 | .task(task2) 94 | .run(result -> { 95 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 96 | 97 | assertThat(task1.runCount()).isEqualTo(1); 98 | assertThat(task2.runCount()).isEqualTo(0); 99 | 100 | assertThat(result).isNotNull(); 101 | assertThat(result.succeeded()).isFalse(); 102 | assertThat(result.cause()).isEqualTo(task1.cause()); 103 | assertThat(result.result()).isNull(); 104 | }); 105 | 106 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 107 | } 108 | 109 | @Test 110 | public void itFailsWhenAConsumerTaskFails() { 111 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 112 | FakeFailingAsyncFunction task2 = new FakeFailingAsyncFunction<>(new Throwable("Failed")); 113 | 114 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 115 | 116 | Async.waterfall() 117 | .task(task1) 118 | .task(task2) 119 | .run(result -> { 120 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 121 | 122 | assertThat(task1.runCount()).isEqualTo(1); 123 | assertThat(task2.consumedValue()).isEqualTo(task1.result()); 124 | assertThat(task2.runCount()).isEqualTo(1); 125 | 126 | assertThat(result).isNotNull(); 127 | assertThat(result.succeeded()).isFalse(); 128 | assertThat(result.cause()).isEqualTo(task2.cause()); 129 | assertThat(result.result()).isNull(); 130 | }); 131 | 132 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 133 | } 134 | 135 | @Test 136 | public void itExecutesNoMoreTasksWhenAConsumerTaskFails() { 137 | FakeSuccessfulAsyncSupplier task1 = new FakeSuccessfulAsyncSupplier<>("Task 1"); 138 | FakeFailingAsyncFunction task2 = new FakeFailingAsyncFunction<>(new Throwable("Failed")); 139 | FakeSuccessfulAsyncFunction task3 = new FakeSuccessfulAsyncFunction<>("Task 3"); 140 | 141 | ObjectWrapper handlerCallCount = new ObjectWrapper<>(0); 142 | 143 | Async.waterfall() 144 | .task(task1) 145 | .task(task2) 146 | .task(task3) 147 | .run(result -> { 148 | handlerCallCount.setObject(handlerCallCount.getObject() + 1); 149 | 150 | assertThat(task1.runCount()).isEqualTo(1); 151 | assertThat(task2.consumedValue()).isEqualTo(task1.result()); 152 | assertThat(task2.runCount()).isEqualTo(1); 153 | assertThat(task3.runCount()).isEqualTo(0); 154 | 155 | assertThat(result).isNotNull(); 156 | assertThat(result.succeeded()).isFalse(); 157 | assertThat(result.cause()).isEqualTo(task2.cause()); 158 | assertThat(result.result()).isNull(); 159 | }); 160 | 161 | assertThat(handlerCallCount.getObject()).isEqualTo(1); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/examples/BaseExample.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.examples; 2 | 3 | import org.simondean.vertx.async.unit.fakes.FakeVertx; 4 | import org.vertx.java.core.Vertx; 5 | 6 | public class BaseExample { 7 | protected Vertx vertx; 8 | 9 | public BaseExample() { 10 | this.vertx = new FakeVertx(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/examples/EachExample.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.examples; 2 | 3 | import org.simondean.vertx.async.Async; 4 | import org.simondean.vertx.async.DefaultAsyncResult; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | import org.vertx.java.core.impl.DefaultFutureResult; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | public class EachExample extends BaseExample { 13 | private final boolean succeed; 14 | private ArrayList items = new ArrayList<>(); 15 | 16 | public EachExample(boolean succeed) { 17 | this.succeed = succeed; 18 | } 19 | 20 | public void eachExample(AsyncResultHandler handler) { 21 | List list = Arrays.asList("one", "two", "three"); 22 | 23 | Async.iterable(list) 24 | .each((item, eachHandler) -> { 25 | doSomethingWithItem(item, eachHandler); 26 | }) 27 | .run(vertx, handler); 28 | } 29 | 30 | private void doSomethingWithItem(String item, AsyncResultHandler handler) { 31 | if (!succeed) { 32 | handler.handle(DefaultAsyncResult.fail(new Exception("Fail"))); 33 | return; 34 | } 35 | 36 | items.add(item); 37 | handler.handle(DefaultAsyncResult.succeed()); 38 | } 39 | 40 | public List items() { 41 | return items; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/examples/ForeverExample.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.examples; 2 | 3 | import org.simondean.vertx.async.Async; 4 | import org.simondean.vertx.async.DefaultAsyncResult; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | public class ForeverExample extends BaseExample { 8 | public void foreverExample(AsyncResultHandler handler) { 9 | Async.forever() 10 | .task(taskHandler -> { 11 | someAsyncMethodThatTakesAHandler(taskHandler); 12 | }) 13 | .run(vertx, result -> { 14 | handler.handle(DefaultAsyncResult.fail(result)); 15 | }); 16 | } 17 | 18 | private void someAsyncMethodThatTakesAHandler(AsyncResultHandler handler) { 19 | handler.handle(DefaultAsyncResult.fail(new Exception("Fail"))); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/examples/RetryExample.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.examples; 2 | 3 | import org.simondean.vertx.async.Async; 4 | import org.simondean.vertx.async.DefaultAsyncResult; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | 7 | public class RetryExample extends BaseExample { 8 | private final boolean succeed; 9 | private String result; 10 | 11 | public RetryExample(boolean succeed) { 12 | this.succeed = succeed; 13 | } 14 | 15 | public void retryExample(AsyncResultHandler handler) { 16 | Async.retry() 17 | .task(taskHandler -> { 18 | someAsyncMethodThatTakesAHandler(taskHandler); 19 | }) 20 | .times(5) 21 | .run(result -> { 22 | if (result.failed()) { 23 | handler.handle(DefaultAsyncResult.fail(result)); 24 | return; 25 | } 26 | 27 | String resultValue = result.result(); 28 | 29 | doSomethingWithTheResults(resultValue); 30 | 31 | handler.handle(DefaultAsyncResult.succeed(resultValue)); 32 | }); 33 | } 34 | 35 | private void someAsyncMethodThatTakesAHandler(AsyncResultHandler handler) { 36 | if (!succeed) { 37 | handler.handle(DefaultAsyncResult.fail(new Exception("Fail"))); 38 | return; 39 | } 40 | 41 | handler.handle(DefaultAsyncResult.succeed("Async result")); 42 | } 43 | 44 | private void doSomethingWithTheResults(String result) { 45 | this.result = result; 46 | } 47 | 48 | public String result() { 49 | return result; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/examples/SeriesExample.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.examples; 2 | 3 | import org.simondean.vertx.async.Async; 4 | import org.simondean.vertx.async.DefaultAsyncResult; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | import org.vertx.java.core.impl.DefaultFutureResult; 7 | 8 | import java.util.List; 9 | 10 | public class SeriesExample extends BaseExample { 11 | private final boolean succeed; 12 | private List results; 13 | 14 | public SeriesExample(boolean succeed) { 15 | this.succeed = succeed; 16 | } 17 | 18 | public void seriesExample(AsyncResultHandler> handler) { 19 | Async.series() 20 | .task(taskHandler -> { 21 | String result = getSomeResult(); 22 | taskHandler.handle(DefaultAsyncResult.succeed(result)); 23 | }) 24 | .task(taskHandler -> { 25 | someAsyncMethodThatTakesAHandler(taskHandler); 26 | }) 27 | .run(result -> { 28 | if (result.failed()) { 29 | handler.handle(DefaultAsyncResult.fail(result)); 30 | return; 31 | } 32 | 33 | List resultList = result.result(); 34 | doSomethingWithTheResults(resultList); 35 | 36 | handler.handle(DefaultAsyncResult.succeed(resultList)); 37 | }); 38 | } 39 | 40 | private String getSomeResult() { 41 | return "Result"; 42 | } 43 | 44 | private void someAsyncMethodThatTakesAHandler(AsyncResultHandler handler) { 45 | if (!succeed) { 46 | handler.handle(DefaultAsyncResult.fail(new Exception("Fail"))); 47 | return; 48 | } 49 | 50 | handler.handle(DefaultAsyncResult.succeed("Async result")); 51 | } 52 | 53 | private void doSomethingWithTheResults(List results) { 54 | this.results = results; 55 | } 56 | 57 | public List results() { 58 | return results; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/examples/WaterfallExample.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.examples; 2 | 3 | import org.simondean.vertx.async.Async; 4 | import org.simondean.vertx.async.DefaultAsyncResult; 5 | import org.vertx.java.core.AsyncResultHandler; 6 | import org.vertx.java.core.impl.DefaultFutureResult; 7 | 8 | public class WaterfallExample extends BaseExample { 9 | private final boolean succeed; 10 | private Integer result; 11 | 12 | public WaterfallExample(boolean succeed) { 13 | this.succeed = succeed; 14 | } 15 | 16 | public void waterfallExample(AsyncResultHandler handler) { 17 | Async.waterfall() 18 | .task(taskHandler -> { 19 | String result = getSomeResult(); 20 | taskHandler.handle(DefaultAsyncResult.succeed(result)); 21 | }) 22 | .task((result, taskHandler) -> { 23 | someAsyncMethodThatTakesAResultAndHandler(result, taskHandler); 24 | }) 25 | .run(result -> { 26 | if (result.failed()) { 27 | handler.handle(DefaultAsyncResult.fail(result.cause())); 28 | return; 29 | } 30 | 31 | Integer resultValue = result.result(); 32 | doSomethingWithTheResults(resultValue); 33 | 34 | handler.handle(DefaultAsyncResult.succeed(resultValue)); 35 | }); 36 | } 37 | 38 | private String getSomeResult() { 39 | return "42"; 40 | } 41 | 42 | private void someAsyncMethodThatTakesAResultAndHandler(String result, AsyncResultHandler handler) { 43 | if (!succeed) { 44 | handler.handle(DefaultAsyncResult.fail(new Exception("Fail"))); 45 | return; 46 | } 47 | 48 | handler.handle(DefaultAsyncResult.succeed(Integer.parseInt(result))); 49 | } 50 | 51 | private void doSomethingWithTheResults(Integer result) { 52 | this.result = result; 53 | } 54 | 55 | public Integer result() { 56 | return result; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeAsyncFunction.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.BiConsumer; 8 | 9 | public abstract class FakeAsyncFunction implements BiConsumer> { 10 | private ArrayList consumedValues = new ArrayList<>(); 11 | private int runCount = 0; 12 | 13 | protected void incrementRunCount() { 14 | runCount++; 15 | } 16 | 17 | protected void addConsumedValue(T consumedValue) { 18 | this.consumedValues.add(consumedValue); 19 | } 20 | 21 | public int runCount() { 22 | return runCount; 23 | } 24 | 25 | public T consumedValue() { 26 | return consumedValues.get(consumedValues.size() - 1); 27 | } 28 | 29 | public List consumedValues() { 30 | return consumedValues; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeAsyncSupplier.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public abstract class FakeAsyncSupplier implements Consumer> { 8 | private int runCount = 0; 9 | 10 | protected void incrementRunCount() { 11 | runCount++; 12 | } 13 | 14 | public int runCount() { 15 | return runCount; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeErrorThrowingAsyncFunction.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | public class FakeErrorThrowingAsyncFunction extends FakeAsyncFunction { 6 | private final Error cause; 7 | 8 | public FakeErrorThrowingAsyncFunction(Error cause) { 9 | this.cause = cause; 10 | } 11 | 12 | @Override 13 | public void accept(T value, AsyncResultHandler handler) { 14 | addConsumedValue(value); 15 | incrementRunCount(); 16 | throw cause; 17 | } 18 | 19 | public Error cause() { 20 | return cause; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeErrorThrowingAsyncSupplier.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.vertx.java.core.AsyncResultHandler; 4 | 5 | public class FakeErrorThrowingAsyncSupplier extends FakeAsyncSupplier { 6 | private final Error cause; 7 | 8 | public FakeErrorThrowingAsyncSupplier(Error cause) { 9 | this.cause = cause; 10 | } 11 | 12 | @Override 13 | public void accept(AsyncResultHandler handler) { 14 | incrementRunCount(); 15 | throw cause; 16 | } 17 | 18 | public Error cause() { 19 | return cause; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeFailingAsyncFunction.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.vertx.java.core.AsyncResultHandler; 5 | import org.vertx.java.core.impl.DefaultFutureResult; 6 | 7 | public class FakeFailingAsyncFunction extends FakeAsyncFunction { 8 | private final int successCount; 9 | private final R result; 10 | private final Throwable cause; 11 | 12 | public FakeFailingAsyncFunction(Throwable cause) { 13 | this(0, null, cause); 14 | } 15 | 16 | public FakeFailingAsyncFunction(int successCount, R result, Throwable cause) { 17 | this.successCount = successCount; 18 | this.result = result; 19 | this.cause = cause; 20 | } 21 | 22 | @Override 23 | public void accept(T value, AsyncResultHandler handler) { 24 | addConsumedValue(value); 25 | incrementRunCount(); 26 | 27 | if (runCount() > successCount) { 28 | handler.handle(DefaultAsyncResult.fail(cause)); 29 | } 30 | else { 31 | handler.handle(DefaultAsyncResult.succeed(result)); 32 | } 33 | } 34 | 35 | public Throwable cause() { 36 | return cause; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeFailingAsyncSupplier.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.vertx.java.core.AsyncResultHandler; 5 | import org.vertx.java.core.impl.DefaultFutureResult; 6 | 7 | public class FakeFailingAsyncSupplier extends FakeAsyncSupplier { 8 | private final int successCount; 9 | private final T result; 10 | private final Throwable cause; 11 | 12 | public FakeFailingAsyncSupplier(Throwable cause) { 13 | this(0, null, cause); 14 | } 15 | 16 | public FakeFailingAsyncSupplier(int successCount, T result, Throwable cause) { 17 | this.successCount = successCount; 18 | this.result = result; 19 | this.cause = cause; 20 | } 21 | 22 | @Override 23 | public void accept(AsyncResultHandler handler) { 24 | incrementRunCount(); 25 | 26 | if (runCount() > successCount) { 27 | handler.handle(DefaultAsyncResult.fail(cause)); 28 | } 29 | else { 30 | handler.handle(DefaultAsyncResult.succeed(result)); 31 | } 32 | } 33 | 34 | public Throwable cause() { 35 | return cause; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeSuccessfulAsyncFunction.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.vertx.java.core.AsyncResultHandler; 5 | import org.vertx.java.core.impl.DefaultFutureResult; 6 | 7 | public class FakeSuccessfulAsyncFunction extends FakeAsyncFunction { 8 | private final int failureCount; 9 | private final R result; 10 | private final Throwable cause; 11 | 12 | public FakeSuccessfulAsyncFunction(R result) { 13 | this(0, null, result); 14 | } 15 | 16 | public FakeSuccessfulAsyncFunction(int failureCount, Throwable cause, R result) { 17 | this.failureCount = failureCount; 18 | this.result = result; 19 | this.cause = cause; 20 | } 21 | 22 | @Override 23 | public void accept(T value, AsyncResultHandler handler) { 24 | addConsumedValue(value); 25 | incrementRunCount(); 26 | 27 | if (runCount() > failureCount) { 28 | handler.handle(DefaultAsyncResult.succeed(result)); 29 | } 30 | else { 31 | handler.handle(DefaultAsyncResult.fail(cause)); 32 | } 33 | } 34 | 35 | public R result() { 36 | return result; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeSuccessfulAsyncSupplier.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.simondean.vertx.async.DefaultAsyncResult; 4 | import org.vertx.java.core.AsyncResultHandler; 5 | import org.vertx.java.core.impl.DefaultFutureResult; 6 | 7 | public class FakeSuccessfulAsyncSupplier extends FakeAsyncSupplier { 8 | private final int failureCount; 9 | private final T result; 10 | private final Throwable cause; 11 | 12 | public FakeSuccessfulAsyncSupplier(T result) { 13 | this(0, null, result); 14 | } 15 | 16 | public FakeSuccessfulAsyncSupplier(int failureCount, Throwable cause, T result) { 17 | this.failureCount = failureCount; 18 | this.result = result; 19 | this.cause = cause; 20 | } 21 | 22 | @Override 23 | public void accept(AsyncResultHandler handler) { 24 | incrementRunCount(); 25 | 26 | if (runCount() > failureCount) { 27 | handler.handle(DefaultAsyncResult.succeed(result)); 28 | } 29 | else { 30 | handler.handle(DefaultAsyncResult.fail(cause)); 31 | } 32 | } 33 | 34 | public T result() { 35 | return result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/simondean/vertx/async/unit/fakes/FakeVertx.java: -------------------------------------------------------------------------------- 1 | package org.simondean.vertx.async.unit.fakes; 2 | 3 | import org.vertx.java.core.Context; 4 | import org.vertx.java.core.Handler; 5 | import org.vertx.java.core.Vertx; 6 | import org.vertx.java.core.datagram.DatagramSocket; 7 | import org.vertx.java.core.datagram.InternetProtocolFamily; 8 | import org.vertx.java.core.dns.DnsClient; 9 | import org.vertx.java.core.eventbus.EventBus; 10 | import org.vertx.java.core.file.FileSystem; 11 | import org.vertx.java.core.http.HttpClient; 12 | import org.vertx.java.core.http.HttpServer; 13 | import org.vertx.java.core.net.NetClient; 14 | import org.vertx.java.core.net.NetServer; 15 | import org.vertx.java.core.shareddata.SharedData; 16 | import org.vertx.java.core.sockjs.SockJSServer; 17 | 18 | import java.net.InetSocketAddress; 19 | 20 | public class FakeVertx implements Vertx { 21 | @Override 22 | public NetServer createNetServer() { 23 | return null; 24 | } 25 | 26 | @Override 27 | public NetClient createNetClient() { 28 | return null; 29 | } 30 | 31 | @Override 32 | public HttpServer createHttpServer() { 33 | return null; 34 | } 35 | 36 | @Override 37 | public HttpClient createHttpClient() { 38 | return null; 39 | } 40 | 41 | @Override 42 | public DatagramSocket createDatagramSocket(InternetProtocolFamily internetProtocolFamily) { 43 | return null; 44 | } 45 | 46 | @Override 47 | public SockJSServer createSockJSServer(HttpServer httpServer) { 48 | return null; 49 | } 50 | 51 | @Override 52 | public FileSystem fileSystem() { 53 | return null; 54 | } 55 | 56 | @Override 57 | public EventBus eventBus() { 58 | return null; 59 | } 60 | 61 | @Override 62 | public DnsClient createDnsClient(InetSocketAddress... inetSocketAddresses) { 63 | return null; 64 | } 65 | 66 | @Override 67 | public SharedData sharedData() { 68 | return null; 69 | } 70 | 71 | @Override 72 | public long setTimer(long l, Handler handler) { 73 | return 0; 74 | } 75 | 76 | @Override 77 | public long setPeriodic(long l, Handler handler) { 78 | return 0; 79 | } 80 | 81 | @Override 82 | public boolean cancelTimer(long l) { 83 | return false; 84 | } 85 | 86 | @Override 87 | public Context currentContext() { 88 | return null; 89 | } 90 | 91 | @Override 92 | public void runOnContext(Handler handler) { 93 | handler.handle(null); 94 | } 95 | 96 | @Override 97 | public boolean isEventLoop() { 98 | return false; 99 | } 100 | 101 | @Override 102 | public boolean isWorker() { 103 | return false; 104 | } 105 | 106 | @Override 107 | public void stop() { 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /vertx_classpath.txt: -------------------------------------------------------------------------------- 1 | # This file contains information on where to find the resources of your module during development 2 | # This file is used when running your module as you develop - it tells Vert.x where to find 3 | # the resources of your module 4 | 5 | # Feel free to edit it if you have a non standard project structure and put the resources of your 6 | # module elsewhere 7 | 8 | src/main/resources 9 | target/classes 10 | target/dependencies 11 | bin --------------------------------------------------------------------------------