├── .editorconfig ├── .github ├── maven-cd-settings.xml ├── maven-ci-settings.xml └── workflows │ ├── ci-4.x.yml │ ├── ci-5.x-stable.yml │ ├── ci-5.x.yml │ ├── ci-matrix-5.x.yml │ ├── ci.yml │ └── deploy.yml ├── .gitignore ├── .vertx └── debug-js │ └── vertx-js │ ├── async_file.js │ ├── async_map.js │ ├── buffer.js │ ├── context.js │ ├── counter.js │ ├── datagram_packet.js │ ├── datagram_socket.js │ ├── dns_client.js │ ├── event_bus.js │ ├── file_props.js │ ├── file_system.js │ ├── file_system_props.js │ ├── future.js │ ├── http_client.js │ ├── http_client_request.js │ ├── http_client_response.js │ ├── http_connection.js │ ├── http_frame.js │ ├── http_server.js │ ├── http_server_file_upload.js │ ├── http_server_request.js │ ├── http_server_response.js │ ├── local_map.js │ ├── lock.js │ ├── measured.js │ ├── message.js │ ├── message_consumer.js │ ├── message_producer.js │ ├── multi_map.js │ ├── mx_record.js │ ├── net_client.js │ ├── net_server.js │ ├── net_socket.js │ ├── read_stream.js │ ├── send_context.js │ ├── server_web_socket.js │ ├── shared_data.js │ ├── socket_address.js │ ├── srv_record.js │ ├── stream_base.js │ ├── timeout_stream.js │ ├── util │ ├── console.js │ ├── jvm-npm.js │ └── utils.js │ ├── vertx.js │ ├── web_socket.js │ ├── web_socket_base.js │ ├── web_socket_frame.js │ ├── worker_executor.js │ └── write_stream.js ├── LICENSE.txt ├── README.md ├── pom.xml └── src ├── main ├── asciidoc │ └── index.adoc ├── generated │ └── io │ │ └── vertx │ │ └── ext │ │ └── unit │ │ ├── TestOptionsConverter.java │ │ └── report │ │ ├── ReportOptionsConverter.java │ │ └── ReportingOptionsConverter.java └── java │ ├── examples │ ├── Examples.java │ ├── Helper.java │ ├── junit │ │ ├── JUnitTestSuite.java │ │ ├── JunitTestWithTimeout.java │ │ ├── MyTestSuite.java │ │ ├── RepeatingTest.java │ │ ├── RunOnContextJUnitTestSuite.java │ │ ├── SimpleParameterizedTest.java │ │ ├── Snippets.java │ │ ├── TimeoutOverwriteTestSuite.java │ │ ├── TimeoutTestSuite.java │ │ └── package-info.java │ └── package-info.java │ ├── io │ └── vertx │ │ └── ext │ │ └── unit │ │ ├── Async.java │ │ ├── Completion.java │ │ ├── TestCase.java │ │ ├── TestCompletion.java │ │ ├── TestContext.java │ │ ├── TestOptions.java │ │ ├── TestSuite.java │ │ ├── collect │ │ ├── EventBusCollector.java │ │ └── impl │ │ │ └── EventBusCollectorImpl.java │ │ ├── impl │ │ ├── AsyncImpl.java │ │ ├── CompletionImpl.java │ │ ├── ExecutionContext.java │ │ ├── FailureImpl.java │ │ ├── Helper.java │ │ ├── Result.java │ │ ├── Task.java │ │ ├── TestCaseImpl.java │ │ ├── TestCaseReportImpl.java │ │ ├── TestCompletionImpl.java │ │ ├── TestContextImpl.java │ │ ├── TestContextTask.java │ │ ├── TestResultImpl.java │ │ ├── TestSuiteImpl.java │ │ ├── TestSuiteReportImpl.java │ │ └── TestSuiteRunner.java │ │ ├── junit │ │ ├── Repeat.java │ │ ├── RepeatRule.java │ │ ├── RunTestOnContext.java │ │ ├── Timeout.java │ │ ├── VertxUnitRunner.java │ │ ├── VertxUnitRunnerWithParameters.java │ │ └── VertxUnitRunnerWithParametersFactory.java │ │ ├── package-info.java │ │ └── report │ │ ├── Failure.java │ │ ├── ReportOptions.java │ │ ├── Reporter.java │ │ ├── ReporterFactory.java │ │ ├── ReportingOptions.java │ │ ├── TestCaseReport.java │ │ ├── TestResult.java │ │ ├── TestSuiteReport.java │ │ └── impl │ │ ├── DefaultReporterFactory.java │ │ ├── EventBusReporter.java │ │ ├── JunitXmlFormatter.java │ │ ├── ReportStream.java │ │ └── SimpleFormatter.java │ └── module-info.java └── test └── java ├── io └── vertx │ └── ext │ └── unit │ └── tests │ ├── CompletionTest.java │ ├── ConcurrentTest.java │ ├── EventBusTest.java │ ├── ExamplesTest.java │ ├── JUnitParameterizedTest.java │ ├── JUnitTest.java │ ├── JUnitTestSuiteTest.java │ ├── JunitXmlReporterTest.java │ ├── OptionsTest.java │ ├── ReportingTest.java │ ├── TestReporter.java │ ├── TestSuiteNoEventLoopAsyncTest.java │ ├── TestSuiteNoEventLoopTest.java │ ├── TestSuiteNoEventLoopWithVertxTest.java │ ├── TestSuiteObjectTest.java │ ├── TestSuiteTestBase.java │ ├── TestSuiteUseContextualEventLoopTest.java │ ├── TestSuiteUseVertxEventLoopTest.java │ └── UseEventLoopTest.java └── module-info.java /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | trim_trailing_whitespace = true 8 | end_of_line = lf 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.github/maven-cd-settings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | false 20 | 21 | 22 | 23 | vertx-snapshots-repository 24 | ${env.VERTX_NEXUS_USERNAME} 25 | ${env.VERTX_NEXUS_PASSWORD} 26 | 27 | 28 | 29 | 30 | 31 | google-mirror 32 | 33 | true 34 | 35 | 36 | 37 | google-maven-central 38 | GCS Maven Central mirror EU 39 | https://maven-central.storage-download.googleapis.com/maven2/ 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | google-maven-central 51 | GCS Maven Central mirror 52 | https://maven-central.storage-download.googleapis.com/maven2/ 53 | 54 | true 55 | 56 | 57 | false 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /.github/maven-ci-settings.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | false 20 | 21 | 22 | 23 | google-mirror 24 | 25 | true 26 | 27 | 28 | 29 | google-maven-central 30 | GCS Maven Central mirror EU 31 | https://maven-central.storage-download.googleapis.com/maven2/ 32 | 33 | true 34 | 35 | 36 | false 37 | 38 | 39 | 40 | 41 | 42 | google-maven-central 43 | GCS Maven Central mirror 44 | https://maven-central.storage-download.googleapis.com/maven2/ 45 | 46 | true 47 | 48 | 49 | false 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /.github/workflows/ci-4.x.yml: -------------------------------------------------------------------------------- 1 | name: vertx-unit (4.x) 2 | on: 3 | schedule: 4 | - cron: '0 4 * * *' 5 | jobs: 6 | CI: 7 | strategy: 8 | matrix: 9 | include: 10 | - os: ubuntu-latest 11 | jdk: 8 12 | - os: ubuntu-latest 13 | jdk: 17 14 | uses: ./.github/workflows/ci.yml 15 | with: 16 | branch: 4.x 17 | jdk: ${{ matrix.jdk }} 18 | os: ${{ matrix.os }} 19 | secrets: inherit 20 | Deploy: 21 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }} 22 | needs: CI 23 | uses: ./.github/workflows/deploy.yml 24 | with: 25 | branch: 4.x 26 | jdk: 8 27 | secrets: inherit 28 | -------------------------------------------------------------------------------- /.github/workflows/ci-5.x-stable.yml: -------------------------------------------------------------------------------- 1 | name: vertx-unit (5.x-stable) 2 | on: 3 | push: 4 | branches: 5 | - '5.[0-9]+' 6 | pull_request: 7 | branches: 8 | - '5.[0-9]+' 9 | schedule: 10 | - cron: '0 6 * * *' 11 | jobs: 12 | CI-CD: 13 | uses: ./.github/workflows/ci-matrix-5.x.yml 14 | secrets: inherit 15 | with: 16 | branch: ${{ github.event_name == 'schedule' && vars.VERTX_5_STABLE_BRANCH || github.event.pull_request.head.sha || github.ref_name }} 17 | -------------------------------------------------------------------------------- /.github/workflows/ci-5.x.yml: -------------------------------------------------------------------------------- 1 | name: vertx-unit (5.x) 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | schedule: 10 | - cron: '0 5 * * *' 11 | jobs: 12 | CI-CD: 13 | uses: ./.github/workflows/ci-matrix-5.x.yml 14 | secrets: inherit 15 | with: 16 | branch: ${{ github.event.pull_request.head.sha || github.ref_name }} 17 | -------------------------------------------------------------------------------- /.github/workflows/ci-matrix-5.x.yml: -------------------------------------------------------------------------------- 1 | name: CI matrix (5.x) 2 | on: 3 | workflow_call: 4 | inputs: 5 | branch: 6 | required: true 7 | type: string 8 | jobs: 9 | CI: 10 | strategy: 11 | matrix: 12 | include: 13 | - os: ubuntu-latest 14 | jdk: 11 15 | - os: ubuntu-latest 16 | jdk: 21 17 | uses: ./.github/workflows/ci.yml 18 | with: 19 | branch: ${{ inputs.branch }} 20 | jdk: ${{ matrix.jdk }} 21 | os: ${{ matrix.os }} 22 | secrets: inherit 23 | Deploy: 24 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }} 25 | needs: CI 26 | uses: ./.github/workflows/deploy.yml 27 | with: 28 | branch: ${{ inputs.branch }} 29 | jdk: 11 30 | secrets: inherit 31 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | workflow_call: 4 | inputs: 5 | branch: 6 | required: true 7 | type: string 8 | jdk: 9 | default: 8 10 | type: string 11 | os: 12 | default: ubuntu-latest 13 | type: string 14 | jobs: 15 | Test: 16 | name: Run tests 17 | runs-on: ${{ inputs.os }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | with: 22 | ref: ${{ inputs.branch }} 23 | - name: Install JDK 24 | uses: actions/setup-java@v2 25 | with: 26 | java-version: ${{ inputs.jdk }} 27 | distribution: temurin 28 | - name: Run tests 29 | run: mvn -s .github/maven-ci-settings.xml -q clean verify -B 30 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | workflow_call: 4 | inputs: 5 | branch: 6 | required: true 7 | type: string 8 | jdk: 9 | default: 8 10 | type: string 11 | jobs: 12 | Deploy: 13 | name: Deploy to OSSRH 14 | runs-on: ubuntu-latest 15 | env: 16 | VERTX_NEXUS_USERNAME: ${{ secrets.VERTX_NEXUS_USERNAME }} 17 | VERTX_NEXUS_PASSWORD: ${{ secrets.VERTX_NEXUS_PASSWORD }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | with: 22 | ref: ${{ inputs.branch }} 23 | - name: Install JDK 24 | uses: actions/setup-java@v2 25 | with: 26 | java-version: ${{ inputs.jdk }} 27 | distribution: temurin 28 | - name: Get project version 29 | run: echo "PROJECT_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -q -DforceStdout | grep -v '\[')" >> $GITHUB_ENV 30 | - name: Maven deploy 31 | if: ${{ endsWith(env.PROJECT_VERSION, '-SNAPSHOT') }} 32 | run: mvn deploy -s .github/maven-cd-settings.xml -DskipTests -B 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | gi.vertx 2 | .DS_Store 3 | .gradle 4 | .idea 5 | .classpath 6 | .project 7 | .settings 8 | .yardoc 9 | .yardopts 10 | build 11 | target 12 | out 13 | *.iml 14 | *.ipr 15 | *.iws 16 | test-output 17 | Scratch.java 18 | ScratchTest.java 19 | test-results 20 | test-tmp 21 | *.class 22 | ScratchPad.java 23 | src/main/resources/ext-js/*.js 24 | src/main/java/io/vertx/java/**/*.java 25 | *.swp 26 | -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/datagram_packet.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/datagram_packet */ 18 | var utils = require('vertx-js/util/utils'); 19 | var Buffer = require('vertx-js/buffer'); 20 | var SocketAddress = require('vertx-js/socket_address'); 21 | 22 | var io = Packages.io; 23 | var JsonObject = io.vertx.core.json.JsonObject; 24 | var JDatagramPacket = Java.type('io.vertx.core.datagram.DatagramPacket'); 25 | 26 | /** 27 | A received datagram packet (UDP) which contains the data and information about the sender of the data itself. 28 | 29 | @class 30 | */ 31 | var DatagramPacket = function(j_val) { 32 | 33 | var j_datagramPacket = j_val; 34 | var that = this; 35 | 36 | /** 37 | Returns the {@link SocketAddress} of the sender that sent 38 | this {@link DatagramPacket}. 39 | 40 | @public 41 | 42 | @return {SocketAddress} the address of the sender 43 | */ 44 | this.sender = function() { 45 | var __args = arguments; 46 | if (__args.length === 0) { 47 | return utils.convReturnVertxGen(SocketAddress, j_datagramPacket["sender()"]()); 48 | } else throw new TypeError('function invoked with invalid arguments'); 49 | }; 50 | 51 | /** 52 | Returns the data of the {@link DatagramPacket} 53 | 54 | @public 55 | 56 | @return {Buffer} the data 57 | */ 58 | this.data = function() { 59 | var __args = arguments; 60 | if (__args.length === 0) { 61 | return utils.convReturnVertxGen(Buffer, j_datagramPacket["data()"]()); 62 | } else throw new TypeError('function invoked with invalid arguments'); 63 | }; 64 | 65 | // A reference to the underlying Java delegate 66 | // NOTE! This is an internal API and must not be used in user code. 67 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 68 | this._jdel = j_datagramPacket; 69 | }; 70 | 71 | DatagramPacket._jclass = utils.getJavaClass("io.vertx.core.datagram.DatagramPacket"); 72 | DatagramPacket._jtype = { 73 | accept: function(obj) { 74 | return DatagramPacket._jclass.isInstance(obj._jdel); 75 | }, 76 | wrap: function(jdel) { 77 | var obj = Object.create(DatagramPacket.prototype, {}); 78 | DatagramPacket.apply(obj, arguments); 79 | return obj; 80 | }, 81 | unwrap: function(obj) { 82 | return obj._jdel; 83 | } 84 | }; 85 | DatagramPacket._create = function(jdel) { 86 | var obj = Object.create(DatagramPacket.prototype, {}); 87 | DatagramPacket.apply(obj, arguments); 88 | return obj; 89 | } 90 | module.exports = DatagramPacket; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/file_props.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/file_props */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JFileProps = Java.type('io.vertx.core.file.FileProps'); 23 | 24 | /** 25 | Represents properties of a file on the file system. 26 |

27 | 28 | @class 29 | */ 30 | var FileProps = function(j_val) { 31 | 32 | var j_fileProps = j_val; 33 | var that = this; 34 | 35 | /** 36 | The date the file was created 37 | 38 | @public 39 | 40 | @return {number} 41 | */ 42 | this.creationTime = function() { 43 | var __args = arguments; 44 | if (__args.length === 0) { 45 | return j_fileProps["creationTime()"](); 46 | } else throw new TypeError('function invoked with invalid arguments'); 47 | }; 48 | 49 | /** 50 | The date the file was last accessed 51 | 52 | @public 53 | 54 | @return {number} 55 | */ 56 | this.lastAccessTime = function() { 57 | var __args = arguments; 58 | if (__args.length === 0) { 59 | return j_fileProps["lastAccessTime()"](); 60 | } else throw new TypeError('function invoked with invalid arguments'); 61 | }; 62 | 63 | /** 64 | The date the file was last modified 65 | 66 | @public 67 | 68 | @return {number} 69 | */ 70 | this.lastModifiedTime = function() { 71 | var __args = arguments; 72 | if (__args.length === 0) { 73 | return j_fileProps["lastModifiedTime()"](); 74 | } else throw new TypeError('function invoked with invalid arguments'); 75 | }; 76 | 77 | /** 78 | Is the file a directory? 79 | 80 | @public 81 | 82 | @return {boolean} 83 | */ 84 | this.isDirectory = function() { 85 | var __args = arguments; 86 | if (__args.length === 0) { 87 | return j_fileProps["isDirectory()"](); 88 | } else throw new TypeError('function invoked with invalid arguments'); 89 | }; 90 | 91 | /** 92 | Is the file some other type? (I.e. not a directory, regular file or symbolic link) 93 | 94 | @public 95 | 96 | @return {boolean} 97 | */ 98 | this.isOther = function() { 99 | var __args = arguments; 100 | if (__args.length === 0) { 101 | return j_fileProps["isOther()"](); 102 | } else throw new TypeError('function invoked with invalid arguments'); 103 | }; 104 | 105 | /** 106 | Is the file a regular file? 107 | 108 | @public 109 | 110 | @return {boolean} 111 | */ 112 | this.isRegularFile = function() { 113 | var __args = arguments; 114 | if (__args.length === 0) { 115 | return j_fileProps["isRegularFile()"](); 116 | } else throw new TypeError('function invoked with invalid arguments'); 117 | }; 118 | 119 | /** 120 | Is the file a symbolic link? 121 | 122 | @public 123 | 124 | @return {boolean} 125 | */ 126 | this.isSymbolicLink = function() { 127 | var __args = arguments; 128 | if (__args.length === 0) { 129 | return j_fileProps["isSymbolicLink()"](); 130 | } else throw new TypeError('function invoked with invalid arguments'); 131 | }; 132 | 133 | /** 134 | The size of the file, in bytes 135 | 136 | @public 137 | 138 | @return {number} 139 | */ 140 | this.size = function() { 141 | var __args = arguments; 142 | if (__args.length === 0) { 143 | return j_fileProps["size()"](); 144 | } else throw new TypeError('function invoked with invalid arguments'); 145 | }; 146 | 147 | // A reference to the underlying Java delegate 148 | // NOTE! This is an internal API and must not be used in user code. 149 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 150 | this._jdel = j_fileProps; 151 | }; 152 | 153 | FileProps._jclass = utils.getJavaClass("io.vertx.core.file.FileProps"); 154 | FileProps._jtype = { 155 | accept: function(obj) { 156 | return FileProps._jclass.isInstance(obj._jdel); 157 | }, 158 | wrap: function(jdel) { 159 | var obj = Object.create(FileProps.prototype, {}); 160 | FileProps.apply(obj, arguments); 161 | return obj; 162 | }, 163 | unwrap: function(obj) { 164 | return obj._jdel; 165 | } 166 | }; 167 | FileProps._create = function(jdel) { 168 | var obj = Object.create(FileProps.prototype, {}); 169 | FileProps.apply(obj, arguments); 170 | return obj; 171 | } 172 | module.exports = FileProps; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/file_system_props.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/file_system_props */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JFileSystemProps = Java.type('io.vertx.core.file.FileSystemProps'); 23 | 24 | /** 25 | Represents properties of the file system. 26 | 27 | 28 | @class 29 | */ 30 | var FileSystemProps = function(j_val) { 31 | 32 | var j_fileSystemProps = j_val; 33 | var that = this; 34 | 35 | /** 36 | 37 | @public 38 | 39 | @return {number} The total space on the file system, in bytes 40 | */ 41 | this.totalSpace = function() { 42 | var __args = arguments; 43 | if (__args.length === 0) { 44 | return j_fileSystemProps["totalSpace()"](); 45 | } else throw new TypeError('function invoked with invalid arguments'); 46 | }; 47 | 48 | /** 49 | 50 | @public 51 | 52 | @return {number} The total un-allocated space on the file system, in bytes 53 | */ 54 | this.unallocatedSpace = function() { 55 | var __args = arguments; 56 | if (__args.length === 0) { 57 | return j_fileSystemProps["unallocatedSpace()"](); 58 | } else throw new TypeError('function invoked with invalid arguments'); 59 | }; 60 | 61 | /** 62 | 63 | @public 64 | 65 | @return {number} The total usable space on the file system, in bytes 66 | */ 67 | this.usableSpace = function() { 68 | var __args = arguments; 69 | if (__args.length === 0) { 70 | return j_fileSystemProps["usableSpace()"](); 71 | } else throw new TypeError('function invoked with invalid arguments'); 72 | }; 73 | 74 | // A reference to the underlying Java delegate 75 | // NOTE! This is an internal API and must not be used in user code. 76 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 77 | this._jdel = j_fileSystemProps; 78 | }; 79 | 80 | FileSystemProps._jclass = utils.getJavaClass("io.vertx.core.file.FileSystemProps"); 81 | FileSystemProps._jtype = { 82 | accept: function(obj) { 83 | return FileSystemProps._jclass.isInstance(obj._jdel); 84 | }, 85 | wrap: function(jdel) { 86 | var obj = Object.create(FileSystemProps.prototype, {}); 87 | FileSystemProps.apply(obj, arguments); 88 | return obj; 89 | }, 90 | unwrap: function(obj) { 91 | return obj._jdel; 92 | } 93 | }; 94 | FileSystemProps._create = function(jdel) { 95 | var obj = Object.create(FileSystemProps.prototype, {}); 96 | FileSystemProps.apply(obj, arguments); 97 | return obj; 98 | } 99 | module.exports = FileSystemProps; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/http_frame.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/http_frame */ 18 | var utils = require('vertx-js/util/utils'); 19 | var Buffer = require('vertx-js/buffer'); 20 | 21 | var io = Packages.io; 22 | var JsonObject = io.vertx.core.json.JsonObject; 23 | var JHttpFrame = Java.type('io.vertx.core.http.HttpFrame'); 24 | 25 | /** 26 | An HTTP/2 frame. 27 | 28 | @class 29 | */ 30 | var HttpFrame = function(j_val) { 31 | 32 | var j_httpFrame = j_val; 33 | var that = this; 34 | 35 | /** 36 | 37 | @public 38 | 39 | @return {number} the 8-bit type of the frame 40 | */ 41 | this.type = function() { 42 | var __args = arguments; 43 | if (__args.length === 0) { 44 | if (that.cachedtype == null) { 45 | that.cachedtype = j_httpFrame["type()"](); 46 | } 47 | return that.cachedtype; 48 | } else throw new TypeError('function invoked with invalid arguments'); 49 | }; 50 | 51 | /** 52 | 53 | @public 54 | 55 | @return {number} the 8-bit flags specific to the frame 56 | */ 57 | this.flags = function() { 58 | var __args = arguments; 59 | if (__args.length === 0) { 60 | if (that.cachedflags == null) { 61 | that.cachedflags = j_httpFrame["flags()"](); 62 | } 63 | return that.cachedflags; 64 | } else throw new TypeError('function invoked with invalid arguments'); 65 | }; 66 | 67 | /** 68 | 69 | @public 70 | 71 | @return {Buffer} the frame payload 72 | */ 73 | this.payload = function() { 74 | var __args = arguments; 75 | if (__args.length === 0) { 76 | if (that.cachedpayload == null) { 77 | that.cachedpayload = utils.convReturnVertxGen(Buffer, j_httpFrame["payload()"]()); 78 | } 79 | return that.cachedpayload; 80 | } else throw new TypeError('function invoked with invalid arguments'); 81 | }; 82 | 83 | // A reference to the underlying Java delegate 84 | // NOTE! This is an internal API and must not be used in user code. 85 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 86 | this._jdel = j_httpFrame; 87 | }; 88 | 89 | HttpFrame._jclass = utils.getJavaClass("io.vertx.core.http.HttpFrame"); 90 | HttpFrame._jtype = { 91 | accept: function(obj) { 92 | return HttpFrame._jclass.isInstance(obj._jdel); 93 | }, 94 | wrap: function(jdel) { 95 | var obj = Object.create(HttpFrame.prototype, {}); 96 | HttpFrame.apply(obj, arguments); 97 | return obj; 98 | }, 99 | unwrap: function(obj) { 100 | return obj._jdel; 101 | } 102 | }; 103 | HttpFrame._create = function(jdel) { 104 | var obj = Object.create(HttpFrame.prototype, {}); 105 | HttpFrame.apply(obj, arguments); 106 | return obj; 107 | } 108 | module.exports = HttpFrame; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/lock.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/lock */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JLock = Java.type('io.vertx.core.shareddata.Lock'); 23 | 24 | /** 25 | An asynchronous exclusive lock which can be obtained from any node in the cluster. 26 |

27 | When the lock is obtained, no-one else in the cluster can obtain the lock with the same name until the lock 28 | is released. 29 | 30 | @class 31 | */ 32 | var Lock = function(j_val) { 33 | 34 | var j_lock = j_val; 35 | var that = this; 36 | 37 | /** 38 | Release the lock. Once the lock is released another will be able to obtain the lock. 39 | 40 | @public 41 | 42 | */ 43 | this.release = function() { 44 | var __args = arguments; 45 | if (__args.length === 0) { 46 | j_lock["release()"](); 47 | } else throw new TypeError('function invoked with invalid arguments'); 48 | }; 49 | 50 | // A reference to the underlying Java delegate 51 | // NOTE! This is an internal API and must not be used in user code. 52 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 53 | this._jdel = j_lock; 54 | }; 55 | 56 | Lock._jclass = utils.getJavaClass("io.vertx.core.shareddata.Lock"); 57 | Lock._jtype = { 58 | accept: function(obj) { 59 | return Lock._jclass.isInstance(obj._jdel); 60 | }, 61 | wrap: function(jdel) { 62 | var obj = Object.create(Lock.prototype, {}); 63 | Lock.apply(obj, arguments); 64 | return obj; 65 | }, 66 | unwrap: function(obj) { 67 | return obj._jdel; 68 | } 69 | }; 70 | Lock._create = function(jdel) { 71 | var obj = Object.create(Lock.prototype, {}); 72 | Lock.apply(obj, arguments); 73 | return obj; 74 | } 75 | module.exports = Lock; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/measured.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/measured */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JMeasured = Java.type('io.vertx.core.metrics.Measured'); 23 | 24 | /** 25 | 26 | @class 27 | */ 28 | var Measured = function(j_val) { 29 | 30 | var j_measured = j_val; 31 | var that = this; 32 | 33 | /** 34 | Whether the metrics are enabled for this measured object 35 | 36 | @public 37 | 38 | @return {boolean} true if the metrics are enabled 39 | */ 40 | this.isMetricsEnabled = function() { 41 | var __args = arguments; 42 | if (__args.length === 0) { 43 | return j_measured["isMetricsEnabled()"](); 44 | } else throw new TypeError('function invoked with invalid arguments'); 45 | }; 46 | 47 | // A reference to the underlying Java delegate 48 | // NOTE! This is an internal API and must not be used in user code. 49 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 50 | this._jdel = j_measured; 51 | }; 52 | 53 | Measured._jclass = utils.getJavaClass("io.vertx.core.metrics.Measured"); 54 | Measured._jtype = { 55 | accept: function(obj) { 56 | return Measured._jclass.isInstance(obj._jdel); 57 | }, 58 | wrap: function(jdel) { 59 | var obj = Object.create(Measured.prototype, {}); 60 | Measured.apply(obj, arguments); 61 | return obj; 62 | }, 63 | unwrap: function(obj) { 64 | return obj._jdel; 65 | } 66 | }; 67 | Measured._create = function(jdel) { 68 | var obj = Object.create(Measured.prototype, {}); 69 | Measured.apply(obj, arguments); 70 | return obj; 71 | } 72 | module.exports = Measured; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/mx_record.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/mx_record */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JMxRecord = Java.type('io.vertx.core.dns.MxRecord'); 23 | 24 | /** 25 | Represent a Mail-Exchange-Record (MX) which was resolved for a domain. 26 | 27 | @class 28 | */ 29 | var MxRecord = function(j_val) { 30 | 31 | var j_mxRecord = j_val; 32 | var that = this; 33 | 34 | /** 35 | The priority of the MX record. 36 | 37 | @public 38 | 39 | @return {number} 40 | */ 41 | this.priority = function() { 42 | var __args = arguments; 43 | if (__args.length === 0) { 44 | return j_mxRecord["priority()"](); 45 | } else throw new TypeError('function invoked with invalid arguments'); 46 | }; 47 | 48 | /** 49 | The name of the MX record 50 | 51 | @public 52 | 53 | @return {string} 54 | */ 55 | this.name = function() { 56 | var __args = arguments; 57 | if (__args.length === 0) { 58 | return j_mxRecord["name()"](); 59 | } else throw new TypeError('function invoked with invalid arguments'); 60 | }; 61 | 62 | // A reference to the underlying Java delegate 63 | // NOTE! This is an internal API and must not be used in user code. 64 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 65 | this._jdel = j_mxRecord; 66 | }; 67 | 68 | MxRecord._jclass = utils.getJavaClass("io.vertx.core.dns.MxRecord"); 69 | MxRecord._jtype = { 70 | accept: function(obj) { 71 | return MxRecord._jclass.isInstance(obj._jdel); 72 | }, 73 | wrap: function(jdel) { 74 | var obj = Object.create(MxRecord.prototype, {}); 75 | MxRecord.apply(obj, arguments); 76 | return obj; 77 | }, 78 | unwrap: function(obj) { 79 | return obj._jdel; 80 | } 81 | }; 82 | MxRecord._create = function(jdel) { 83 | var obj = Object.create(MxRecord.prototype, {}); 84 | MxRecord.apply(obj, arguments); 85 | return obj; 86 | } 87 | module.exports = MxRecord; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/read_stream.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/read_stream */ 18 | var utils = require('vertx-js/util/utils'); 19 | var StreamBase = require('vertx-js/stream_base'); 20 | 21 | var io = Packages.io; 22 | var JsonObject = io.vertx.core.json.JsonObject; 23 | var JReadStream = Java.type('io.vertx.core.streams.ReadStream'); 24 | 25 | /** 26 | Represents a stream of items that can be read from. 27 |

28 | @class 29 | */ 30 | var ReadStream = function(j_val, j_arg_0) { 31 | 32 | var j_readStream = j_val; 33 | var that = this; 34 | var j_T = typeof j_arg_0 !== 'undefined' ? j_arg_0 : utils.unknown_jtype; 35 | StreamBase.call(this, j_val); 36 | 37 | /** 38 | Set an exception handler on the read stream. 39 | 40 | @public 41 | @param handler {function} the exception handler 42 | @return {ReadStream} a reference to this, so the API can be used fluently 43 | */ 44 | this.exceptionHandler = function(handler) { 45 | var __args = arguments; 46 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 47 | j_readStream["exceptionHandler(io.vertx.core.Handler)"](handler == null ? null : function(jVal) { 48 | handler(utils.convReturnThrowable(jVal)); 49 | }); 50 | return that; 51 | } else throw new TypeError('function invoked with invalid arguments'); 52 | }; 53 | 54 | /** 55 | Set a data handler. As data is read, the handler will be called with the data. 56 | 57 | @public 58 | @param handler {function} 59 | @return {ReadStream} a reference to this, so the API can be used fluently 60 | */ 61 | this.handler = function(handler) { 62 | var __args = arguments; 63 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 64 | j_readStream["handler(io.vertx.core.Handler)"](handler == null ? null : function(jVal) { 65 | handler(j_T.wrap(jVal)); 66 | }); 67 | return that; 68 | } else throw new TypeError('function invoked with invalid arguments'); 69 | }; 70 | 71 | /** 72 | Pause the ReadSupport. While it's paused, no data will be sent to the dataHandler 73 | 74 | @public 75 | 76 | @return {ReadStream} a reference to this, so the API can be used fluently 77 | */ 78 | this.pause = function() { 79 | var __args = arguments; 80 | if (__args.length === 0) { 81 | j_readStream["pause()"](); 82 | return that; 83 | } else throw new TypeError('function invoked with invalid arguments'); 84 | }; 85 | 86 | /** 87 | Resume reading. If the ReadSupport has been paused, reading will recommence on it. 88 | 89 | @public 90 | 91 | @return {ReadStream} a reference to this, so the API can be used fluently 92 | */ 93 | this.resume = function() { 94 | var __args = arguments; 95 | if (__args.length === 0) { 96 | j_readStream["resume()"](); 97 | return that; 98 | } else throw new TypeError('function invoked with invalid arguments'); 99 | }; 100 | 101 | /** 102 | Set an end handler. Once the stream has ended, and there is no more data to be read, this handler will be called. 103 | 104 | @public 105 | @param endHandler {function} 106 | @return {ReadStream} a reference to this, so the API can be used fluently 107 | */ 108 | this.endHandler = function(endHandler) { 109 | var __args = arguments; 110 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 111 | j_readStream["endHandler(io.vertx.core.Handler)"](endHandler); 112 | return that; 113 | } else throw new TypeError('function invoked with invalid arguments'); 114 | }; 115 | 116 | // A reference to the underlying Java delegate 117 | // NOTE! This is an internal API and must not be used in user code. 118 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 119 | this._jdel = j_readStream; 120 | }; 121 | 122 | ReadStream._jclass = utils.getJavaClass("io.vertx.core.streams.ReadStream"); 123 | ReadStream._jtype = { 124 | accept: function(obj) { 125 | return ReadStream._jclass.isInstance(obj._jdel); 126 | }, 127 | wrap: function(jdel) { 128 | var obj = Object.create(ReadStream.prototype, {}); 129 | ReadStream.apply(obj, arguments); 130 | return obj; 131 | }, 132 | unwrap: function(obj) { 133 | return obj._jdel; 134 | } 135 | }; 136 | ReadStream._create = function(jdel) { 137 | var obj = Object.create(ReadStream.prototype, {}); 138 | ReadStream.apply(obj, arguments); 139 | return obj; 140 | } 141 | module.exports = ReadStream; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/send_context.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/send_context */ 18 | var utils = require('vertx-js/util/utils'); 19 | var Message = require('vertx-js/message'); 20 | 21 | var io = Packages.io; 22 | var JsonObject = io.vertx.core.json.JsonObject; 23 | var JSendContext = Java.type('io.vertx.core.eventbus.SendContext'); 24 | 25 | /** 26 | 27 | Encapsulates a message being sent from Vert.x. Used with event bus interceptors 28 | 29 | @class 30 | */ 31 | var SendContext = function(j_val, j_arg_0) { 32 | 33 | var j_sendContext = j_val; 34 | var that = this; 35 | var j_T = typeof j_arg_0 !== 'undefined' ? j_arg_0 : utils.unknown_jtype; 36 | 37 | /** 38 | 39 | @public 40 | 41 | @return {Message} The message being sent 42 | */ 43 | this.message = function() { 44 | var __args = arguments; 45 | if (__args.length === 0) { 46 | return utils.convReturnVertxGen(Message, j_sendContext["message()"](), undefined); 47 | } else throw new TypeError('function invoked with invalid arguments'); 48 | }; 49 | 50 | /** 51 | Call the next interceptor 52 | 53 | @public 54 | 55 | */ 56 | this.next = function() { 57 | var __args = arguments; 58 | if (__args.length === 0) { 59 | j_sendContext["next()"](); 60 | } else throw new TypeError('function invoked with invalid arguments'); 61 | }; 62 | 63 | /** 64 | 65 | @public 66 | 67 | @return {boolean} true if the message is being sent (point to point) or False if the message is being published 68 | */ 69 | this.send = function() { 70 | var __args = arguments; 71 | if (__args.length === 0) { 72 | return j_sendContext["send()"](); 73 | } else throw new TypeError('function invoked with invalid arguments'); 74 | }; 75 | 76 | /** 77 | 78 | @public 79 | 80 | @return {Object} the value sent or published (before being processed by the codec) 81 | */ 82 | this.sentBody = function() { 83 | var __args = arguments; 84 | if (__args.length === 0) { 85 | return utils.convReturnTypeUnknown(j_sendContext["sentBody()"]()); 86 | } else throw new TypeError('function invoked with invalid arguments'); 87 | }; 88 | 89 | // A reference to the underlying Java delegate 90 | // NOTE! This is an internal API and must not be used in user code. 91 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 92 | this._jdel = j_sendContext; 93 | }; 94 | 95 | SendContext._jclass = utils.getJavaClass("io.vertx.core.eventbus.SendContext"); 96 | SendContext._jtype = { 97 | accept: function(obj) { 98 | return SendContext._jclass.isInstance(obj._jdel); 99 | }, 100 | wrap: function(jdel) { 101 | var obj = Object.create(SendContext.prototype, {}); 102 | SendContext.apply(obj, arguments); 103 | return obj; 104 | }, 105 | unwrap: function(obj) { 106 | return obj._jdel; 107 | } 108 | }; 109 | SendContext._create = function(jdel) { 110 | var obj = Object.create(SendContext.prototype, {}); 111 | SendContext.apply(obj, arguments); 112 | return obj; 113 | } 114 | module.exports = SendContext; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/socket_address.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/socket_address */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JSocketAddress = Java.type('io.vertx.core.net.SocketAddress'); 23 | 24 | /** 25 | The address of a socket, an inet socket address or a domain socket address. 26 |

27 | @class 28 | */ 29 | var SocketAddress = function(j_val) { 30 | 31 | var j_socketAddress = j_val; 32 | var that = this; 33 | 34 | /** 35 | 36 | @public 37 | 38 | @return {string} the address host or null for a domain socket 39 | */ 40 | this.host = function() { 41 | var __args = arguments; 42 | if (__args.length === 0) { 43 | return j_socketAddress["host()"](); 44 | } else throw new TypeError('function invoked with invalid arguments'); 45 | }; 46 | 47 | /** 48 | 49 | @public 50 | 51 | @return {number} the address port or -1 for a domain socket 52 | */ 53 | this.port = function() { 54 | var __args = arguments; 55 | if (__args.length === 0) { 56 | return j_socketAddress["port()"](); 57 | } else throw new TypeError('function invoked with invalid arguments'); 58 | }; 59 | 60 | /** 61 | 62 | @public 63 | 64 | @return {string} the address path or null for a inet socket 65 | */ 66 | this.path = function() { 67 | var __args = arguments; 68 | if (__args.length === 0) { 69 | return j_socketAddress["path()"](); 70 | } else throw new TypeError('function invoked with invalid arguments'); 71 | }; 72 | 73 | // A reference to the underlying Java delegate 74 | // NOTE! This is an internal API and must not be used in user code. 75 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 76 | this._jdel = j_socketAddress; 77 | }; 78 | 79 | SocketAddress._jclass = utils.getJavaClass("io.vertx.core.net.SocketAddress"); 80 | SocketAddress._jtype = { 81 | accept: function(obj) { 82 | return SocketAddress._jclass.isInstance(obj._jdel); 83 | }, 84 | wrap: function(jdel) { 85 | var obj = Object.create(SocketAddress.prototype, {}); 86 | SocketAddress.apply(obj, arguments); 87 | return obj; 88 | }, 89 | unwrap: function(obj) { 90 | return obj._jdel; 91 | } 92 | }; 93 | SocketAddress._create = function(jdel) { 94 | var obj = Object.create(SocketAddress.prototype, {}); 95 | SocketAddress.apply(obj, arguments); 96 | return obj; 97 | } 98 | /** 99 | Create a inet socket address, host must be non null and port must be between 0 100 | and 65536. 101 | 102 | @memberof module:vertx-js/socket_address 103 | @param port {number} the address port 104 | @param host {string} the address host 105 | @return {SocketAddress} the created socket address 106 | */ 107 | SocketAddress.inetSocketAddress = function(port, host) { 108 | var __args = arguments; 109 | if (__args.length === 2 && typeof __args[0] ==='number' && typeof __args[1] === 'string') { 110 | return utils.convReturnVertxGen(SocketAddress, JSocketAddress["inetSocketAddress(int,java.lang.String)"](port, host)); 111 | } else throw new TypeError('function invoked with invalid arguments'); 112 | }; 113 | 114 | /** 115 | Create a domain socket address. 116 | 117 | @memberof module:vertx-js/socket_address 118 | @param path {string} the address path 119 | @return {SocketAddress} the created socket address 120 | */ 121 | SocketAddress.domainSocketAddress = function(path) { 122 | var __args = arguments; 123 | if (__args.length === 1 && typeof __args[0] === 'string') { 124 | return utils.convReturnVertxGen(SocketAddress, JSocketAddress["domainSocketAddress(java.lang.String)"](path)); 125 | } else throw new TypeError('function invoked with invalid arguments'); 126 | }; 127 | 128 | module.exports = SocketAddress; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/srv_record.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/srv_record */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JSrvRecord = Java.type('io.vertx.core.dns.SrvRecord'); 23 | 24 | /** 25 | Represent a Service-Record (SRV) which was resolved for a domain. 26 | 27 | @class 28 | */ 29 | var SrvRecord = function(j_val) { 30 | 31 | var j_srvRecord = j_val; 32 | var that = this; 33 | 34 | /** 35 | Returns the priority for this service record. 36 | 37 | @public 38 | 39 | @return {number} 40 | */ 41 | this.priority = function() { 42 | var __args = arguments; 43 | if (__args.length === 0) { 44 | return j_srvRecord["priority()"](); 45 | } else throw new TypeError('function invoked with invalid arguments'); 46 | }; 47 | 48 | /** 49 | Returns the weight of this service record. 50 | 51 | @public 52 | 53 | @return {number} 54 | */ 55 | this.weight = function() { 56 | var __args = arguments; 57 | if (__args.length === 0) { 58 | return j_srvRecord["weight()"](); 59 | } else throw new TypeError('function invoked with invalid arguments'); 60 | }; 61 | 62 | /** 63 | Returns the port the service is running on. 64 | 65 | @public 66 | 67 | @return {number} 68 | */ 69 | this.port = function() { 70 | var __args = arguments; 71 | if (__args.length === 0) { 72 | return j_srvRecord["port()"](); 73 | } else throw new TypeError('function invoked with invalid arguments'); 74 | }; 75 | 76 | /** 77 | Returns the name for the server being queried. 78 | 79 | @public 80 | 81 | @return {string} 82 | */ 83 | this.name = function() { 84 | var __args = arguments; 85 | if (__args.length === 0) { 86 | return j_srvRecord["name()"](); 87 | } else throw new TypeError('function invoked with invalid arguments'); 88 | }; 89 | 90 | /** 91 | Returns the protocol for the service being queried (i.e. "_tcp"). 92 | 93 | @public 94 | 95 | @return {string} 96 | */ 97 | this.protocol = function() { 98 | var __args = arguments; 99 | if (__args.length === 0) { 100 | return j_srvRecord["protocol()"](); 101 | } else throw new TypeError('function invoked with invalid arguments'); 102 | }; 103 | 104 | /** 105 | Returns the service's name (i.e. "_http"). 106 | 107 | @public 108 | 109 | @return {string} 110 | */ 111 | this.service = function() { 112 | var __args = arguments; 113 | if (__args.length === 0) { 114 | return j_srvRecord["service()"](); 115 | } else throw new TypeError('function invoked with invalid arguments'); 116 | }; 117 | 118 | /** 119 | Returns the name of the host for the service. 120 | 121 | @public 122 | 123 | @return {string} 124 | */ 125 | this.target = function() { 126 | var __args = arguments; 127 | if (__args.length === 0) { 128 | return j_srvRecord["target()"](); 129 | } else throw new TypeError('function invoked with invalid arguments'); 130 | }; 131 | 132 | // A reference to the underlying Java delegate 133 | // NOTE! This is an internal API and must not be used in user code. 134 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 135 | this._jdel = j_srvRecord; 136 | }; 137 | 138 | SrvRecord._jclass = utils.getJavaClass("io.vertx.core.dns.SrvRecord"); 139 | SrvRecord._jtype = { 140 | accept: function(obj) { 141 | return SrvRecord._jclass.isInstance(obj._jdel); 142 | }, 143 | wrap: function(jdel) { 144 | var obj = Object.create(SrvRecord.prototype, {}); 145 | SrvRecord.apply(obj, arguments); 146 | return obj; 147 | }, 148 | unwrap: function(obj) { 149 | return obj._jdel; 150 | } 151 | }; 152 | SrvRecord._create = function(jdel) { 153 | var obj = Object.create(SrvRecord.prototype, {}); 154 | SrvRecord.apply(obj, arguments); 155 | return obj; 156 | } 157 | module.exports = SrvRecord; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/stream_base.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/stream_base */ 18 | var utils = require('vertx-js/util/utils'); 19 | 20 | var io = Packages.io; 21 | var JsonObject = io.vertx.core.json.JsonObject; 22 | var JStreamBase = Java.type('io.vertx.core.streams.StreamBase'); 23 | 24 | /** 25 | Base interface for a stream. 26 | 27 | @class 28 | */ 29 | var StreamBase = function(j_val) { 30 | 31 | var j_streamBase = j_val; 32 | var that = this; 33 | 34 | /** 35 | Set an exception handler. 36 | 37 | @public 38 | @param handler {function} the handler 39 | @return {StreamBase} a reference to this, so the API can be used fluently 40 | */ 41 | this.exceptionHandler = function(handler) { 42 | var __args = arguments; 43 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 44 | j_streamBase["exceptionHandler(io.vertx.core.Handler)"](handler == null ? null : function(jVal) { 45 | handler(utils.convReturnThrowable(jVal)); 46 | }); 47 | return that; 48 | } else throw new TypeError('function invoked with invalid arguments'); 49 | }; 50 | 51 | // A reference to the underlying Java delegate 52 | // NOTE! This is an internal API and must not be used in user code. 53 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 54 | this._jdel = j_streamBase; 55 | }; 56 | 57 | StreamBase._jclass = utils.getJavaClass("io.vertx.core.streams.StreamBase"); 58 | StreamBase._jtype = { 59 | accept: function(obj) { 60 | return StreamBase._jclass.isInstance(obj._jdel); 61 | }, 62 | wrap: function(jdel) { 63 | var obj = Object.create(StreamBase.prototype, {}); 64 | StreamBase.apply(obj, arguments); 65 | return obj; 66 | }, 67 | unwrap: function(obj) { 68 | return obj._jdel; 69 | } 70 | }; 71 | StreamBase._create = function(jdel) { 72 | var obj = Object.create(StreamBase.prototype, {}); 73 | StreamBase.apply(obj, arguments); 74 | return obj; 75 | } 76 | module.exports = StreamBase; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/timeout_stream.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/timeout_stream */ 18 | var utils = require('vertx-js/util/utils'); 19 | var ReadStream = require('vertx-js/read_stream'); 20 | 21 | var io = Packages.io; 22 | var JsonObject = io.vertx.core.json.JsonObject; 23 | var JTimeoutStream = Java.type('io.vertx.core.TimeoutStream'); 24 | 25 | /** 26 | 27 | @class 28 | */ 29 | var TimeoutStream = function(j_val) { 30 | 31 | var j_timeoutStream = j_val; 32 | var that = this; 33 | ReadStream.call(this, j_val); 34 | 35 | /** 36 | 37 | @public 38 | @param handler {function} 39 | @return {TimeoutStream} 40 | */ 41 | this.exceptionHandler = function(handler) { 42 | var __args = arguments; 43 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 44 | j_timeoutStream["exceptionHandler(io.vertx.core.Handler)"](handler == null ? null : function(jVal) { 45 | handler(utils.convReturnThrowable(jVal)); 46 | }); 47 | return that; 48 | } else throw new TypeError('function invoked with invalid arguments'); 49 | }; 50 | 51 | /** 52 | 53 | @public 54 | @param handler {function} 55 | @return {TimeoutStream} 56 | */ 57 | this.handler = function(handler) { 58 | var __args = arguments; 59 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 60 | j_timeoutStream["handler(io.vertx.core.Handler)"](handler == null ? null : function(jVal) { 61 | handler(utils.convReturnLong(jVal)); 62 | }); 63 | return that; 64 | } else throw new TypeError('function invoked with invalid arguments'); 65 | }; 66 | 67 | /** 68 | 69 | @public 70 | 71 | @return {TimeoutStream} 72 | */ 73 | this.pause = function() { 74 | var __args = arguments; 75 | if (__args.length === 0) { 76 | j_timeoutStream["pause()"](); 77 | return that; 78 | } else throw new TypeError('function invoked with invalid arguments'); 79 | }; 80 | 81 | /** 82 | 83 | @public 84 | 85 | @return {TimeoutStream} 86 | */ 87 | this.resume = function() { 88 | var __args = arguments; 89 | if (__args.length === 0) { 90 | j_timeoutStream["resume()"](); 91 | return that; 92 | } else throw new TypeError('function invoked with invalid arguments'); 93 | }; 94 | 95 | /** 96 | 97 | @public 98 | @param endHandler {function} 99 | @return {TimeoutStream} 100 | */ 101 | this.endHandler = function(endHandler) { 102 | var __args = arguments; 103 | if (__args.length === 1 && (typeof __args[0] === 'function' || __args[0] == null)) { 104 | j_timeoutStream["endHandler(io.vertx.core.Handler)"](endHandler); 105 | return that; 106 | } else throw new TypeError('function invoked with invalid arguments'); 107 | }; 108 | 109 | /** 110 | Cancels the timeout. Note this has the same effect as calling {@link TimeoutStream#handler} with a null 111 | argument. 112 | 113 | @public 114 | 115 | */ 116 | this.cancel = function() { 117 | var __args = arguments; 118 | if (__args.length === 0) { 119 | j_timeoutStream["cancel()"](); 120 | } else throw new TypeError('function invoked with invalid arguments'); 121 | }; 122 | 123 | // A reference to the underlying Java delegate 124 | // NOTE! This is an internal API and must not be used in user code. 125 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 126 | this._jdel = j_timeoutStream; 127 | }; 128 | 129 | TimeoutStream._jclass = utils.getJavaClass("io.vertx.core.TimeoutStream"); 130 | TimeoutStream._jtype = { 131 | accept: function(obj) { 132 | return TimeoutStream._jclass.isInstance(obj._jdel); 133 | }, 134 | wrap: function(jdel) { 135 | var obj = Object.create(TimeoutStream.prototype, {}); 136 | TimeoutStream.apply(obj, arguments); 137 | return obj; 138 | }, 139 | unwrap: function(obj) { 140 | return obj._jdel; 141 | } 142 | }; 143 | TimeoutStream._create = function(jdel) { 144 | var obj = Object.create(TimeoutStream.prototype, {}); 145 | TimeoutStream.apply(obj, arguments); 146 | return obj; 147 | } 148 | module.exports = TimeoutStream; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/util/console.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var formatRegExp = /%[sdj%]/g; 4 | 5 | function format(f) { 6 | if (typeof f !== 'string') { 7 | var objects = []; 8 | for (var index = 0; index < arguments.length; index++) { 9 | objects.push(JSON.stringify(arguments[index])); 10 | } 11 | return objects.join(' '); 12 | } 13 | 14 | if (arguments.length === 1) return f; 15 | 16 | var i = 1; 17 | var args = arguments; 18 | var len = args.length; 19 | var str = String(f).replace(formatRegExp, function(x) { 20 | if (x === '%%') return '%'; 21 | if (i >= len) return x; 22 | switch (x) { 23 | case '%s': return String(args[i++]); 24 | case '%d': return Number(args[i++]); 25 | case '%j': 26 | try { 27 | return JSON.stringify(args[i++]); 28 | } catch (_) { 29 | return '[Circular]'; 30 | } 31 | // falls through 32 | default: 33 | return x; 34 | } 35 | }); 36 | for (var x = args[i]; i < len; x = args[++i]) { 37 | if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { 38 | str += ' ' + x; 39 | } else { 40 | str += ' ' + JSON.stringify(x); 41 | } 42 | } 43 | return str; 44 | } 45 | 46 | function Console(stdout, stderr) { 47 | if (!(this instanceof Console)) { 48 | return new Console(stdout, stderr); 49 | } 50 | if (!stdout || !(stdout instanceof java.io.PrintStream)) { 51 | throw new TypeError('Console expects a java.io.PrintStream instance'); 52 | } 53 | if (!stderr) { 54 | stderr = stdout; 55 | } else if (!(stderr instanceof java.io.PrintStream)) { 56 | throw new TypeError('Console expects java.io.PrintStream instances'); 57 | } 58 | 59 | var prop = { 60 | writable: true, 61 | enumerable: false, 62 | configurable: true 63 | }; 64 | prop.value = stdout; 65 | Object.defineProperty(this, '_stdout', prop); 66 | prop.value = stderr; 67 | Object.defineProperty(this, '_stderr', prop); 68 | prop.value = {}; 69 | Object.defineProperty(this, '_times', prop); 70 | 71 | // bind the prototype functions to this Console instance 72 | var keys = Object.keys(Console.prototype); 73 | for (var v = 0; v < keys.length; v++) { 74 | var k = keys[v]; 75 | this[k] = this[k].bind(this); 76 | } 77 | } 78 | 79 | Console.prototype.log = function() { 80 | this._stdout.println(format.apply(null, arguments)); 81 | }; 82 | 83 | 84 | Console.prototype.info = Console.prototype.log; 85 | 86 | 87 | Console.prototype.warn = function() { 88 | this._stderr.println(format.apply(null, arguments)); 89 | }; 90 | 91 | 92 | Console.prototype.error = Console.prototype.warn; 93 | 94 | 95 | module.exports = new Console(java.lang.System.out, java.lang.System.err); 96 | module.exports.Console = Console; -------------------------------------------------------------------------------- /.vertx/debug-js/vertx-js/worker_executor.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | /** @module vertx-js/worker_executor */ 18 | var utils = require('vertx-js/util/utils'); 19 | var Measured = require('vertx-js/measured'); 20 | var Future = require('vertx-js/future'); 21 | 22 | var io = Packages.io; 23 | var JsonObject = io.vertx.core.json.JsonObject; 24 | var JWorkerExecutor = Java.type('io.vertx.core.WorkerExecutor'); 25 | 26 | /** 27 | An executor for executing blocking code in Vert.x .

28 | 29 | @class 30 | */ 31 | var WorkerExecutor = function(j_val) { 32 | 33 | var j_workerExecutor = j_val; 34 | var that = this; 35 | Measured.call(this, j_val); 36 | 37 | /** 38 | Whether the metrics are enabled for this measured object 39 | 40 | @public 41 | 42 | @return {boolean} true if the metrics are enabled 43 | */ 44 | this.isMetricsEnabled = function() { 45 | var __args = arguments; 46 | if (__args.length === 0) { 47 | return j_workerExecutor["isMetricsEnabled()"](); 48 | } else throw new TypeError('function invoked with invalid arguments'); 49 | }; 50 | 51 | /** 52 | Safely execute some blocking code. 53 |

54 | Executes the blocking code in the handler blockingCodeHandler using a thread from the worker pool. 55 |

56 | When the code is complete the handler resultHandler will be called with the result on the original context 57 | (i.e. on the original event loop of the caller). 58 |

59 | A Future instance is passed into blockingCodeHandler. When the blocking code successfully completes, 60 | the handler should call the {@link Future#complete} or {@link Future#complete} method, or the {@link Future#fail} 61 | method if it failed. 62 |

63 | In the blockingCodeHandler the current context remains the original context and therefore any task 64 | scheduled in the blockingCodeHandler will be executed on the this context and not on the worker thread. 65 | 66 | @public 67 | @param blockingCodeHandler {function} handler representing the blocking code to run 68 | @param ordered {boolean} if true then if executeBlocking is called several times on the same context, the executions for that context will be executed serially, not in parallel. if false then they will be no ordering guarantees 69 | @param resultHandler {function} handler that will be called when the blocking code is complete 70 | */ 71 | this.executeBlocking = function() { 72 | var __args = arguments; 73 | if (__args.length === 2 && typeof __args[0] === 'function' && typeof __args[1] === 'function') { 74 | j_workerExecutor["executeBlocking(io.vertx.core.Handler,io.vertx.core.Handler)"](function(jVal) { 75 | __args[0](utils.convReturnVertxGen(Future, jVal, undefined)); 76 | }, function(ar) { 77 | if (ar.succeeded()) { 78 | __args[1](utils.convReturnTypeUnknown(ar.result()), null); 79 | } else { 80 | __args[1](null, ar.cause()); 81 | } 82 | }); 83 | } else if (__args.length === 3 && typeof __args[0] === 'function' && typeof __args[1] ==='boolean' && typeof __args[2] === 'function') { 84 | j_workerExecutor["executeBlocking(io.vertx.core.Handler,boolean,io.vertx.core.Handler)"](function(jVal) { 85 | __args[0](utils.convReturnVertxGen(Future, jVal, undefined)); 86 | }, __args[1], function(ar) { 87 | if (ar.succeeded()) { 88 | __args[2](utils.convReturnTypeUnknown(ar.result()), null); 89 | } else { 90 | __args[2](null, ar.cause()); 91 | } 92 | }); 93 | } else throw new TypeError('function invoked with invalid arguments'); 94 | }; 95 | 96 | /** 97 | Close the executor. 98 | 99 | @public 100 | 101 | */ 102 | this.close = function() { 103 | var __args = arguments; 104 | if (__args.length === 0) { 105 | j_workerExecutor["close()"](); 106 | } else throw new TypeError('function invoked with invalid arguments'); 107 | }; 108 | 109 | // A reference to the underlying Java delegate 110 | // NOTE! This is an internal API and must not be used in user code. 111 | // If you rely on this property your code is likely to break if we change it / remove it without warning. 112 | this._jdel = j_workerExecutor; 113 | }; 114 | 115 | WorkerExecutor._jclass = utils.getJavaClass("io.vertx.core.WorkerExecutor"); 116 | WorkerExecutor._jtype = { 117 | accept: function(obj) { 118 | return WorkerExecutor._jclass.isInstance(obj._jdel); 119 | }, 120 | wrap: function(jdel) { 121 | var obj = Object.create(WorkerExecutor.prototype, {}); 122 | WorkerExecutor.apply(obj, arguments); 123 | return obj; 124 | }, 125 | unwrap: function(obj) { 126 | return obj._jdel; 127 | } 128 | }; 129 | WorkerExecutor._create = function(jdel) { 130 | var obj = Object.create(WorkerExecutor.prototype, {}); 131 | WorkerExecutor.apply(obj, arguments); 132 | return obj; 133 | } 134 | module.exports = WorkerExecutor; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Asynchronous Unit Test 2 | 3 | [![Build Status (5.x)](https://github.com/vert-x3/vertx-unit/actions/workflows/ci-5.x.yml/badge.svg)](https://github.com/vert-x3/vertx-unit/actions/workflows/ci-5.x.yml) 4 | [![Build Status (4.x)](https://github.com/vert-x3/vertx-unit/actions/workflows/ci-4.x.yml/badge.svg)](https://github.com/eclipse-vertx/vertx-codegen/actions/workflows/ci-4.x.yml) 5 | 6 | Async unit testing for Vert.x. 7 | 8 | ## Documentation 9 | 10 | * [Java documentation](http://vertx.io/docs/vertx-unit/java/) 11 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | 21 | io.vertx 22 | vertx5-parent 23 | 12 24 | 25 | 26 | vertx-unit 27 | 5.1.0-SNAPSHOT 28 | 29 | Vert.x Unit 30 | 31 | 32 | scm:git:git@github.com:vert-x3/vertx-unit.git 33 | scm:git:git@github.com:vert-x3/vertx-unit.git 34 | git@github.com:vert-x3/vertx-unit.git 35 | 36 | 37 | 38 | 39 | 40 | io.vertx 41 | vertx-dependencies 42 | ${project.version} 43 | pom 44 | import 45 | 46 | 47 | 48 | 49 | 50 | 51 | io.vertx 52 | vertx-core 53 | 54 | 55 | 56 | 57 | junit 58 | junit 59 | 4.13.1 60 | true 61 | 62 | 63 | 64 | io.vertx 65 | vertx-codegen-api 66 | true 67 | 68 | 69 | io.vertx 70 | vertx-codegen-json 71 | true 72 | 73 | 74 | io.vertx 75 | vertx-docgen-api 76 | true 77 | 78 | 79 | io.vertx 80 | vertx-core 81 | test-jar 82 | test 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | maven-compiler-plugin 92 | 93 | 94 | default-compile 95 | 96 | 97 | 98 | io.vertx 99 | vertx-codegen 100 | processor 101 | 102 | 103 | io.vertx 104 | vertx-docgen-processor 105 | processor 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | maven-resources-plugin 119 | 120 | 121 | default-resources 122 | process-classes 123 | 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-surefire-plugin 129 | 130 | 131 | 60 132 | PARANOID 133 | 134 | 135 | 136 | 137 | maven-assembly-plugin 138 | 139 | 140 | package-docs 141 | 142 | single 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/ext/unit/TestOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.ext.unit.TestOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.ext.unit.TestOptions} original class using Vert.x codegen. 11 | */ 12 | public class TestOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, TestOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "timeout": 18 | if (member.getValue() instanceof Number) { 19 | obj.setTimeout(((Number)member.getValue()).longValue()); 20 | } 21 | break; 22 | case "useEventLoop": 23 | if (member.getValue() instanceof Boolean) { 24 | obj.setUseEventLoop((Boolean)member.getValue()); 25 | } 26 | break; 27 | } 28 | } 29 | } 30 | 31 | static void toJson(TestOptions obj, JsonObject json) { 32 | toJson(obj, json.getMap()); 33 | } 34 | 35 | static void toJson(TestOptions obj, java.util.Map json) { 36 | json.put("timeout", obj.getTimeout()); 37 | if (obj.isUseEventLoop() != null) { 38 | json.put("useEventLoop", obj.isUseEventLoop()); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/ext/unit/report/ReportOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.ext.unit.report.ReportOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.ext.unit.report.ReportOptions} original class using Vert.x codegen. 11 | */ 12 | public class ReportOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, ReportOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "to": 18 | if (member.getValue() instanceof String) { 19 | obj.setTo((String)member.getValue()); 20 | } 21 | break; 22 | case "format": 23 | if (member.getValue() instanceof String) { 24 | obj.setFormat((String)member.getValue()); 25 | } 26 | break; 27 | } 28 | } 29 | } 30 | 31 | static void toJson(ReportOptions obj, JsonObject json) { 32 | toJson(obj, json.getMap()); 33 | } 34 | 35 | static void toJson(ReportOptions obj, java.util.Map json) { 36 | if (obj.getTo() != null) { 37 | json.put("to", obj.getTo()); 38 | } 39 | if (obj.getFormat() != null) { 40 | json.put("format", obj.getFormat()); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/ext/unit/report/ReportingOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.ext.unit.report.ReportingOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.ext.unit.report.ReportingOptions} original class using Vert.x codegen. 11 | */ 12 | public class ReportingOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, ReportingOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "reporters": 18 | if (member.getValue() instanceof JsonArray) { 19 | java.util.ArrayList list = new java.util.ArrayList<>(); 20 | ((Iterable)member.getValue()).forEach( item -> { 21 | if (item instanceof JsonObject) 22 | list.add(new io.vertx.ext.unit.report.ReportOptions((io.vertx.core.json.JsonObject)item)); 23 | }); 24 | obj.setReporters(list); 25 | } 26 | break; 27 | } 28 | } 29 | } 30 | 31 | static void toJson(ReportingOptions obj, JsonObject json) { 32 | toJson(obj, json.getMap()); 33 | } 34 | 35 | static void toJson(ReportingOptions obj, java.util.Map json) { 36 | if (obj.getReporters() != null) { 37 | JsonArray array = new JsonArray(); 38 | obj.getReporters().forEach(item -> array.add(item.toJson())); 39 | json.put("reporters", array); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/examples/Helper.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | /** 4 | * @author Julien Viet 5 | */ 6 | public class Helper { 7 | 8 | public int randomPort() { 9 | throw new UnsupportedOperationException(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/JUnitTestSuite.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | import io.vertx.ext.unit.junit.VertxUnitRunner; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | 8 | @RunWith(VertxUnitRunner.class) 9 | public class JUnitTestSuite { 10 | @Test 11 | public void testSomething(TestContext context) { 12 | context.assertFalse(false); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/JunitTestWithTimeout.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | 4 | import io.vertx.ext.unit.TestContext; 5 | import org.junit.Test; 6 | 7 | public class JunitTestWithTimeout { 8 | 9 | @Test(timeout = 1000l) 10 | public void testSomething(TestContext context) { 11 | //... 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/MyTestSuite.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | 5 | public class MyTestSuite { 6 | 7 | public void testSomething(TestContext context) { 8 | context.assertFalse(false); 9 | } 10 | } -------------------------------------------------------------------------------- /src/main/java/examples/junit/RepeatingTest.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | import io.vertx.ext.unit.junit.Repeat; 5 | import io.vertx.ext.unit.junit.RepeatRule; 6 | import io.vertx.ext.unit.junit.VertxUnitRunner; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | @RunWith(VertxUnitRunner.class) 12 | public class RepeatingTest { 13 | 14 | @Rule 15 | public RepeatRule rule = new RepeatRule(); 16 | 17 | @Repeat(1000) 18 | @Test 19 | public void testSomething(TestContext context) { 20 | // This will be executed 1000 times 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/RunOnContextJUnitTestSuite.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.TestContext; 5 | import io.vertx.ext.unit.junit.RunTestOnContext; 6 | import io.vertx.ext.unit.junit.VertxUnitRunner; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | @RunWith(VertxUnitRunner.class) 12 | public class RunOnContextJUnitTestSuite { 13 | 14 | @Rule 15 | public RunTestOnContext rule = new RunTestOnContext(); 16 | 17 | @Test 18 | public void testSomething(TestContext context) { 19 | // Use the underlying vertx instance 20 | Vertx vertx = rule.vertx(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/SimpleParameterizedTest.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | import io.vertx.ext.unit.junit.VertxUnitRunnerWithParametersFactory; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.junit.runners.Parameterized; 8 | 9 | import java.util.Arrays; 10 | 11 | @RunWith(Parameterized.class) 12 | @Parameterized.UseParametersRunnerFactory(VertxUnitRunnerWithParametersFactory.class) 13 | public class SimpleParameterizedTest { 14 | 15 | @Parameterized.Parameters 16 | public static Iterable data() { 17 | return Arrays.asList(0, 1, 2); 18 | } 19 | 20 | public SimpleParameterizedTest(int value) { 21 | //... 22 | } 23 | 24 | @Test 25 | public void testSomething(TestContext context) { 26 | // Execute test with the current value 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/Snippets.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.ext.unit.TestSuite; 4 | 5 | public class Snippets { 6 | 7 | 8 | public void testSuite() { 9 | TestSuite suite = TestSuite.create(new MyTestSuite()); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/TimeoutOverwriteTestSuite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License 2.0 which is available at 6 | * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 7 | * which is available at https://www.apache.org/licenses/LICENSE-2.0. 8 | * 9 | * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 10 | */ 11 | 12 | package examples.junit; 13 | 14 | import io.vertx.ext.unit.TestContext; 15 | import io.vertx.ext.unit.junit.Timeout; 16 | import io.vertx.ext.unit.junit.VertxUnitRunner; 17 | import org.junit.Rule; 18 | import org.junit.Test; 19 | import org.junit.runner.RunWith; 20 | 21 | @RunWith(VertxUnitRunner.class) 22 | public class TimeoutOverwriteTestSuite { 23 | 24 | @Rule 25 | public Timeout rule = Timeout.millis(5_000L); 26 | 27 | @Test 28 | public void testQuick(TestContext context) { 29 | //... 30 | } 31 | 32 | @Test(timeout = 30_000L) 33 | public void testSlow(TestContext context) { 34 | //... 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/TimeoutTestSuite.java: -------------------------------------------------------------------------------- 1 | package examples.junit; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | import io.vertx.ext.unit.junit.Timeout; 5 | import io.vertx.ext.unit.junit.VertxUnitRunner; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(VertxUnitRunner.class) 11 | public class TimeoutTestSuite { 12 | 13 | @Rule 14 | public Timeout rule = Timeout.seconds(1); 15 | 16 | @Test 17 | public void testSomething(TestContext context) { 18 | //... 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/examples/junit/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Julien Viet 3 | */ 4 | @Source(translate = false) 5 | package examples.junit; 6 | 7 | import io.vertx.docgen.Source; -------------------------------------------------------------------------------- /src/main/java/examples/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Julien Viet 3 | */ 4 | @Source 5 | package examples; 6 | 7 | import io.vertx.codegen.annotations.ModuleGen; 8 | import io.vertx.docgen.Source; -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/Async.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit; 2 | 3 | import io.vertx.codegen.annotations.VertxGen; 4 | 5 | /** 6 | * An asynchronous exit point for a test.

7 | * 8 | * @author Julien Viet 9 | */ 10 | @VertxGen 11 | public interface Async extends Completion { 12 | 13 | /** 14 | * @return the current count 15 | */ 16 | int count(); 17 | 18 | /** 19 | * Count down the async. 20 | * 21 | * @throws IllegalStateException in strict mode if invoked more than the initial count 22 | */ 23 | void countDown(); 24 | 25 | /** 26 | * Signals the asynchronous operation is done, this method must be called with a count greater than {@code 0}, 27 | * otherwise it throws an {@code IllegalStateException} to signal the error. 28 | */ 29 | void complete(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/Completion.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit; 2 | 3 | import io.vertx.codegen.annotations.GenIgnore; 4 | import io.vertx.codegen.annotations.Nullable; 5 | import io.vertx.codegen.annotations.VertxGen; 6 | import io.vertx.core.AsyncResult; 7 | import io.vertx.core.Future; 8 | import io.vertx.core.Handler; 9 | import io.vertx.core.Promise; 10 | 11 | /** 12 | * A completion object that emits completion notifications either succeeded or failed. 13 | * 14 | * @author Julien Viet 15 | */ 16 | @VertxGen 17 | public interface Completion { 18 | 19 | /** 20 | * Completes the future upon completion, otherwise fails it. 21 | * 22 | * @param future the future to resolve 23 | */ 24 | void resolve(Promise future); 25 | 26 | /** 27 | * @return true if this completion is completed 28 | */ 29 | boolean isCompleted(); 30 | 31 | /** 32 | * @return true if this completion is completed and succeeded 33 | */ 34 | boolean isSucceeded(); 35 | 36 | /** 37 | * @return true if the this completion is completed and failed 38 | */ 39 | boolean isFailed(); 40 | 41 | /** 42 | * Completion handler to receive a completion signal when this completions completes. 43 | * 44 | * @param completionHandler the completion handler 45 | */ 46 | @GenIgnore(GenIgnore.PERMITTED_TYPE) 47 | void handler(Handler> completionHandler); 48 | 49 | /** 50 | * Cause the current thread to wait until this completion completes.

51 | * 52 | * If the current thread is interrupted, an exception will be thrown. 53 | */ 54 | void await(); 55 | 56 | /** 57 | * Cause the current thread to wait until this completion completes with a configurable timeout.

58 | * 59 | * If completion times out or the current thread is interrupted, an exception will be thrown. 60 | * 61 | * @param timeoutMillis the timeout in milliseconds 62 | */ 63 | void await(long timeoutMillis); 64 | 65 | /** 66 | * Cause the current thread to wait until this completion completes and succeeds.

67 | * 68 | * If the current thread is interrupted or the suite fails, an exception will be thrown. 69 | */ 70 | void awaitSuccess(); 71 | 72 | /** 73 | * Cause the current thread to wait until this completion completes and succeeds with a configurable timeout.

74 | * 75 | * If completion times out or the current thread is interrupted or the suite fails, an exception will be thrown. 76 | * 77 | * @param timeoutMillis the timeout in milliseconds 78 | */ 79 | void awaitSuccess(long timeoutMillis); 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/TestCase.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit; 2 | 3 | import io.vertx.codegen.annotations.GenIgnore; 4 | import io.vertx.codegen.annotations.VertxGen; 5 | import io.vertx.core.Handler; 6 | import io.vertx.core.Vertx; 7 | import io.vertx.ext.unit.impl.TestCaseImpl; 8 | 9 | import java.util.concurrent.TimeUnit; 10 | 11 | /** 12 | * A test case object can be used to create a single test. 13 | * 14 | * @author Julien Viet 15 | */ 16 | @VertxGen 17 | public interface TestCase { 18 | 19 | /** 20 | * Create a test case. 21 | * 22 | * @param name the test case name 23 | * @param testCase the test case 24 | * @return the created test case 25 | */ 26 | static TestCase create(String name, Handler testCase) { 27 | return new TestCaseImpl(name, 1, testCase); 28 | } 29 | 30 | /** 31 | * Assert the test case passes and block until it is executed. This method should be used from a non Vert.x 32 | * context, like a Junit test. 33 | */ 34 | @GenIgnore 35 | void awaitSuccess(); 36 | 37 | /** 38 | * Assert the test case passes and block until it is executed. This method should be used from a non Vert.x 39 | * context, like a Junit test. 40 | * 41 | * @param timeout the suite timeout expressed in the {@code unit} argument 42 | * @param unit the suite {@code timeout} unit 43 | */ 44 | @GenIgnore 45 | void awaitSuccess(long timeout, TimeUnit unit); 46 | 47 | /** 48 | * Assert the test case passes and block until it is executed. This method should be used from a non Vert.x 49 | * context, like a Junit test. 50 | * 51 | * @param vertx the vert.x instance 52 | */ 53 | @GenIgnore 54 | void awaitSuccess(Vertx vertx); 55 | 56 | /** 57 | * Assert the test case passes and block until it is executed. This method should be used from a non Vert.x 58 | * 59 | * @param vertx the vert.x instance 60 | * @param timeout the suite timeout expressed in the {@code unit} argument 61 | * @param unit the suite {@code timeout} unit 62 | */ 63 | @GenIgnore 64 | void awaitSuccess(Vertx vertx, long timeout, TimeUnit unit); 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/TestCompletion.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit; 2 | 3 | import io.vertx.codegen.annotations.VertxGen; 4 | import io.vertx.ext.unit.report.TestSuiteReport; 5 | 6 | /** 7 | * This object provides callback-ability for the end of a test suite, the completion succeeds 8 | * when all tests pass otherwise it fails. 9 | * 10 | * @author Julien Viet 11 | */ 12 | @VertxGen 13 | public interface TestCompletion extends Completion { 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/TestOptions.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.codegen.annotations.Fluent; 5 | import io.vertx.codegen.json.annotations.JsonGen; 6 | import io.vertx.core.json.JsonObject; 7 | import io.vertx.ext.unit.report.ReportOptions; 8 | import io.vertx.ext.unit.report.ReportingOptions; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Test execution options: 14 | * 15 | *

    16 | *
  • the {@code timeout} in milliseconds, the default value is 2 minutes
  • 17 | *
  • the {@code useEventLoop}
  • configures the event loop usage 18 | *
      19 | *
    • {@code true} always runs with an event loop
    • 20 | *
    • {@code false} never runs with an event loop
    • 21 | *
    • {@code null} uses an event loop if there is one (provided by {@link io.vertx.core.Vertx#currentContext()}) 22 | * otherwise run without
    • 23 | *
    24 | * 25 | *
  • the {@code reporters} is an array of reporter configurations
  • 26 | *
27 | * 28 | * @author Julien Viet 29 | */ 30 | @DataObject 31 | @JsonGen(publicConverter = false) 32 | public class TestOptions extends ReportingOptions { 33 | 34 | /** 35 | * The default time out value in milliseconds: 2 minutes. 36 | */ 37 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000; 38 | 39 | /** 40 | * The default value for using or not the event loop: {@code null}. 41 | */ 42 | public static final Boolean DEFAULT_USE_EVENT_LOOP = null; 43 | 44 | private long timeout = DEFAULT_TIMEOUT; 45 | private Boolean useEventLoop = DEFAULT_USE_EVENT_LOOP; 46 | 47 | /** 48 | * Create a new empty options, with the default time out and no reporters. 49 | */ 50 | public TestOptions() { 51 | } 52 | 53 | /** 54 | * Copy constructor. 55 | * 56 | * @param other the options to copy 57 | */ 58 | public TestOptions(TestOptions other) { 59 | super(other); 60 | setTimeout(other.timeout); 61 | setUseEventLoop(other.useEventLoop); 62 | } 63 | 64 | /** 65 | * Create a new options from the specified json. 66 | * 67 | * @param json the json to create from 68 | */ 69 | public TestOptions(JsonObject json) { 70 | super(json); 71 | TestOptionsConverter.fromJson(json, this); 72 | } 73 | 74 | /** 75 | * @return the current timeout in milliseconds. 76 | */ 77 | public long getTimeout() { 78 | return timeout; 79 | } 80 | 81 | /** 82 | * Set the test timeout. 83 | * 84 | * @param timeout the timeout value in milliseconds. 85 | * @return a reference to this, so the API can be used fluently 86 | */ 87 | @Fluent 88 | public TestOptions setTimeout(long timeout) { 89 | this.timeout = timeout; 90 | return this; 91 | } 92 | 93 | /** 94 | * @return true if the execution should use an event loop when there is no one existing 95 | */ 96 | public Boolean isUseEventLoop() { 97 | return useEventLoop; 98 | } 99 | 100 | /** 101 | * Configure the execution to use an event loop when there is no one existing. 102 | * 103 | * @param useEventLoop the even loop usage 104 | * @return a reference to this, so the API can be used fluently 105 | */ 106 | @Fluent 107 | public TestOptions setUseEventLoop(Boolean useEventLoop) { 108 | this.useEventLoop = useEventLoop; 109 | return this; 110 | } 111 | 112 | @Override 113 | public TestOptions addReporter(ReportOptions reportOptions) { 114 | return (TestOptions) super.addReporter(reportOptions); 115 | } 116 | 117 | @Override 118 | public TestOptions setReporters(List reporters) { 119 | return (TestOptions) super.setReporters(reporters); 120 | } 121 | 122 | /** 123 | * @return the json modelling the current configuration 124 | */ 125 | public JsonObject toJson() { 126 | JsonObject json = super.toJson(); 127 | TestOptionsConverter.toJson(this, json); 128 | return json; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/collect/EventBusCollector.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.collect; 2 | 3 | import io.vertx.codegen.annotations.GenIgnore; 4 | import io.vertx.codegen.annotations.VertxGen; 5 | import io.vertx.core.Handler; 6 | import io.vertx.core.Vertx; 7 | import io.vertx.core.eventbus.Message; 8 | import io.vertx.core.eventbus.MessageConsumer; 9 | import io.vertx.core.json.JsonObject; 10 | import io.vertx.ext.unit.collect.impl.EventBusCollectorImpl; 11 | import io.vertx.ext.unit.impl.TestCompletionImpl; 12 | import io.vertx.ext.unit.report.Reporter; 13 | import io.vertx.ext.unit.report.ReportingOptions; 14 | import io.vertx.ext.unit.report.TestSuiteReport; 15 | 16 | /** 17 | * The event bus collector listen to events on the Vert.x event bus and translate them 18 | * into reports. 19 | * 20 | * @author Julien Viet 21 | */ 22 | @VertxGen 23 | public interface EventBusCollector { 24 | 25 | /** 26 | * Json {@code type} field value that signals a test suite begins, used as part of the test reporting 27 | * protocol for the event bus. 28 | */ 29 | String EVENT_TEST_SUITE_BEGIN = "testSuiteBegin"; 30 | 31 | /** 32 | * Json {@code type} field value that signals a test suite ends, used as part of the test reporting 33 | * protocol for the event bus. 34 | */ 35 | String EVENT_TEST_SUITE_END = "testSuiteEnd"; 36 | 37 | /** 38 | * Json {@code type} field value that reports a test suite error, used as part of the test reporting 39 | * protocol for the event bus. 40 | */ 41 | String EVENT_TEST_SUITE_ERROR = "testSuiteError"; 42 | 43 | /** 44 | * Json {@code type} field value that signals a test case begins, used as part of the test reporting 45 | * protocol for the event bus. 46 | */ 47 | String EVENT_TEST_CASE_BEGIN = "testCaseBegin"; 48 | 49 | /** 50 | * Json {@code type} field value that signals a test case ends, used as part of the test reporting 51 | * protocol for the event bus. 52 | */ 53 | String EVENT_TEST_CASE_END = "testCaseEnd"; 54 | 55 | /** 56 | * Create a message handler reporting with the specified options. The returned 57 | * message handler can be registered to an event bus. 58 | * 59 | * @param options the reporting options 60 | * @return the message handler 61 | */ 62 | static EventBusCollector create(Vertx vertx, ReportingOptions options) { 63 | Reporter[] reporters = options.getReporters().stream().map(reportOptions -> Reporter.reporter(vertx, reportOptions)).toArray(Reporter[]::new); 64 | TestCompletionImpl reporter = new TestCompletionImpl(reporters); 65 | return new EventBusCollectorImpl(vertx, reporter); 66 | } 67 | 68 | static EventBusCollector create(Vertx vertx, Handler reporter) { 69 | return new EventBusCollectorImpl(vertx, reporter); 70 | } 71 | 72 | /** 73 | * Register the collector as a consumer of the event bus with the specified address. 74 | * 75 | * @param address the registration address 76 | * @return the subscribed message consumer 77 | */ 78 | MessageConsumer register(String address); 79 | 80 | @GenIgnore 81 | Handler> asMessageHandler(); 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/collect/impl/EventBusCollectorImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.collect.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.core.eventbus.Message; 6 | import io.vertx.core.eventbus.MessageConsumer; 7 | import io.vertx.core.json.JsonObject; 8 | import io.vertx.core.streams.ReadStream; 9 | import io.vertx.ext.unit.collect.EventBusCollector; 10 | import io.vertx.ext.unit.impl.FailureImpl; 11 | import io.vertx.ext.unit.impl.TestResultImpl; 12 | import io.vertx.ext.unit.report.Failure; 13 | import io.vertx.ext.unit.report.TestCaseReport; 14 | import io.vertx.ext.unit.report.TestResult; 15 | import io.vertx.ext.unit.report.TestSuiteReport; 16 | 17 | /** 18 | * @author Julien Viet 19 | */ 20 | public class EventBusCollectorImpl implements EventBusCollector, Handler> { 21 | 22 | private final Vertx vertx; 23 | private final Handler reporter; 24 | private Handler testCaseRunnerHandler; 25 | private Handler exceptionHandler; 26 | private Handler endHandler; 27 | private TestSuiteReport runner; 28 | private Handler testCaseHandler; 29 | 30 | public EventBusCollectorImpl(Vertx vertx, Handler reporter) { 31 | this.reporter = reporter; 32 | this.vertx = vertx; 33 | } 34 | 35 | @Override 36 | public void handle(Message event) { 37 | JsonObject body = event.body(); 38 | String type = body.getString("type", ""); 39 | String name = body.getString("name"); 40 | switch (type) { 41 | case EVENT_TEST_SUITE_BEGIN: { 42 | runner = new TestSuiteReport() { 43 | @Override 44 | public String name() { 45 | return name; 46 | } 47 | @Override 48 | public TestSuiteReport exceptionHandler(Handler handler) { 49 | exceptionHandler = handler; 50 | return this; 51 | } 52 | @Override 53 | public TestSuiteReport handler(Handler handler) { 54 | testCaseRunnerHandler = handler; 55 | return this; 56 | } 57 | @Override 58 | public ReadStream fetch(long amount) { 59 | return this; 60 | } 61 | @Override 62 | public TestSuiteReport pause() { 63 | return this; 64 | } 65 | @Override 66 | public TestSuiteReport resume() { 67 | return this; 68 | } 69 | @Override 70 | public TestSuiteReport endHandler(Handler handler) { 71 | endHandler = handler; 72 | return this; 73 | } 74 | }; 75 | reporter.handle(runner); 76 | break; 77 | } 78 | case EVENT_TEST_CASE_BEGIN: { 79 | if (testCaseRunnerHandler != null) { 80 | testCaseRunnerHandler.handle(new TestCaseReport() { 81 | @Override 82 | public String name() { 83 | return name; 84 | } 85 | @Override 86 | public TestCaseReport endHandler(Handler handler) { 87 | testCaseHandler = handler; 88 | return this; 89 | } 90 | }); 91 | } 92 | break; 93 | } 94 | case EVENT_TEST_SUITE_ERROR: { 95 | JsonObject failureJson = body.getJsonObject("failure"); 96 | if (failureJson != null && exceptionHandler != null) { 97 | FailureImpl failure = new FailureImpl(failureJson); 98 | Throwable cause = failure.cause(); 99 | if (cause == null) { 100 | // Best effort 101 | cause = new Exception(failureJson.getString("message")); 102 | } 103 | exceptionHandler.handle(cause); 104 | } 105 | break; 106 | } 107 | case EVENT_TEST_CASE_END: { 108 | if (testCaseHandler != null) { 109 | JsonObject failureJson = body.getJsonObject("failure"); 110 | Failure failure = null; 111 | if (failureJson != null) { 112 | failure = new FailureImpl(failureJson); 113 | } 114 | TestResult result = new TestResultImpl(name, body.getLong("beginTime", 0L), body.getLong("durationTime", 0L), failure); 115 | testCaseHandler.handle(result); 116 | testCaseHandler = null; 117 | } 118 | break; 119 | } 120 | case EVENT_TEST_SUITE_END: { 121 | if (endHandler != null) { 122 | endHandler.handle(null); 123 | } 124 | break; 125 | } 126 | } 127 | } 128 | 129 | @Override 130 | public MessageConsumer register(String address) { 131 | return vertx.eventBus().consumer(address, this); 132 | } 133 | 134 | @Override 135 | public Handler> asMessageHandler() { 136 | return this; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/AsyncImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.ext.unit.Async; 4 | 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | 7 | class AsyncImpl extends CompletionImpl implements Async { 8 | 9 | private final int initialCount; 10 | private final AtomicInteger count; 11 | private final boolean strict; 12 | 13 | AsyncImpl(int initialCount, boolean strict) { 14 | this.initialCount = initialCount; 15 | this.strict = strict; 16 | this.count = new AtomicInteger(initialCount); 17 | } 18 | 19 | @Override 20 | public int count() { 21 | return count.get(); 22 | } 23 | 24 | @Override 25 | public void countDown() { 26 | int oldValue, newValue; 27 | do { 28 | oldValue = count.get(); 29 | if (oldValue == 0) { 30 | newValue = 0; 31 | if (strict) { 32 | String msg; 33 | if (initialCount == 1) { 34 | msg = "Countdown invoked more than once"; 35 | } else if (initialCount == 2) { 36 | msg = "Countdown invoked more than twice"; 37 | } else { 38 | msg = "Countdown invoked more than " + initialCount + " times"; 39 | } 40 | throw new IllegalStateException(msg); 41 | } 42 | } else { 43 | newValue = oldValue - 1; 44 | } 45 | } while (!count.compareAndSet(oldValue, newValue)); 46 | if (newValue == 0) { 47 | release(null); 48 | } 49 | } 50 | 51 | @Override 52 | public void complete() { 53 | int value = count.getAndSet(0); 54 | if (value > 0) { 55 | release(null); 56 | } else { 57 | throw new IllegalStateException("The Async complete method has been called more than " + initialCount + " times, check your test."); 58 | } 59 | } 60 | 61 | void release(Throwable failure) { 62 | if (failure != null) { 63 | completable.completeExceptionally(failure); 64 | } else { 65 | completable.complete(null); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/CompletionImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.AsyncResult; 4 | import io.vertx.core.Handler; 5 | import io.vertx.core.Promise; 6 | import io.vertx.ext.unit.Completion; 7 | 8 | import java.util.concurrent.CompletableFuture; 9 | import java.util.concurrent.ExecutionException; 10 | import java.util.concurrent.TimeUnit; 11 | import java.util.concurrent.TimeoutException; 12 | 13 | /** 14 | * @author Julien Viet 15 | */ 16 | public class CompletionImpl implements Completion { 17 | 18 | protected final CompletableFuture completable = new CompletableFuture<>(); 19 | 20 | @Override 21 | public void resolve(Promise future) { 22 | completable.whenComplete((done, err) -> { 23 | if (err != null) { 24 | future.fail(err); 25 | } else { 26 | future.complete(); 27 | } 28 | }); 29 | } 30 | 31 | @Override 32 | public boolean isCompleted() { 33 | return completable.isDone(); 34 | } 35 | 36 | @Override 37 | public boolean isSucceeded() { 38 | return isCompleted() && !isFailed(); 39 | } 40 | 41 | @Override 42 | public boolean isFailed() { 43 | return completable.isCompletedExceptionally(); 44 | } 45 | 46 | @Override 47 | public void handler(Handler> completionHandler) { 48 | Promise completion = Promise.promise(); 49 | completion.future().onComplete(completionHandler); 50 | resolve(completion); 51 | } 52 | 53 | @Override 54 | public void await() { 55 | try { 56 | completable.get(); 57 | } catch (ExecutionException ignore) { 58 | } catch (InterruptedException e) { 59 | Thread.currentThread().interrupt(); 60 | Helper.uncheckedThrow(e); 61 | } 62 | } 63 | 64 | @Override 65 | public void await(long timeoutMillis) { 66 | try { 67 | completable.get(timeoutMillis, TimeUnit.MILLISECONDS); 68 | } catch (ExecutionException ignore) { 69 | } catch (InterruptedException e) { 70 | Thread.currentThread().interrupt(); 71 | Helper.uncheckedThrow(e); 72 | } catch (TimeoutException e) { 73 | Helper.uncheckedThrow(new TimeoutException("Timed out")); 74 | } 75 | } 76 | 77 | @Override 78 | public void awaitSuccess() { 79 | try { 80 | completable.get(); 81 | } catch (ExecutionException result) { 82 | Helper.uncheckedThrow(result.getCause()); 83 | } catch (InterruptedException e) { 84 | Thread.currentThread().interrupt(); 85 | Helper.uncheckedThrow(e); 86 | } 87 | } 88 | 89 | @Override 90 | public void awaitSuccess(long timeoutMillis) { 91 | try { 92 | completable.get(timeoutMillis, TimeUnit.MILLISECONDS); 93 | } catch (ExecutionException result) { 94 | Helper.uncheckedThrow(result.getCause()); 95 | } catch (InterruptedException e) { 96 | Thread.currentThread().interrupt(); 97 | Helper.uncheckedThrow(e); 98 | } catch (TimeoutException e) { 99 | Helper.uncheckedThrow(new TimeoutException("Timed out")); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/ExecutionContext.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Context; 4 | 5 | /** 6 | * The test suite global context. 7 | * 8 | * @author Julien Viet 9 | */ 10 | public class ExecutionContext { 11 | 12 | private final Context context; 13 | 14 | public ExecutionContext(Context context) { 15 | this.context = context; 16 | } 17 | 18 | public void run(Task task, T value) { 19 | if (context != null) { 20 | context.runOnContext(v -> task.execute(value, this)); 21 | } else { 22 | task.execute(value, this); 23 | } 24 | } 25 | 26 | public void run(Task task) { 27 | run(task, null); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/FailureImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.ext.unit.report.Failure; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.ObjectInputStream; 9 | import java.io.ObjectOutputStream; 10 | import java.io.PrintWriter; 11 | import java.io.StringWriter; 12 | 13 | /** 14 | * @author Julien Viet 15 | */ 16 | public class FailureImpl implements Failure { 17 | 18 | private final boolean error; 19 | private final String message; 20 | private final String stackTrace; 21 | private final Throwable cause; 22 | 23 | public FailureImpl(JsonObject json) { 24 | byte[] tmp = json.getBinary("cause"); 25 | Throwable t = null; 26 | if (tmp != null) { 27 | try { 28 | ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(tmp)); 29 | t = (Throwable) ois.readObject(); 30 | } catch (Exception ignore) { 31 | } 32 | } 33 | error = json.getBoolean("error"); 34 | message = json.getString("message"); 35 | stackTrace = json.getString("stackTrace"); 36 | cause = t; 37 | } 38 | 39 | public FailureImpl(boolean error, String message, String stackTrace, Throwable cause) { 40 | this.error = error; 41 | this.message = message; 42 | this.stackTrace = stackTrace; 43 | this.cause = cause; 44 | } 45 | 46 | public FailureImpl(Throwable t) { 47 | StringWriter buffer = new StringWriter(); 48 | PrintWriter writer = new PrintWriter(buffer); 49 | t.printStackTrace(writer); 50 | writer.close(); 51 | error = t instanceof AssertionError ? false : true; 52 | stackTrace = buffer.toString(); 53 | cause = t; 54 | message = t.getMessage(); 55 | } 56 | 57 | @Override 58 | public boolean isError() { 59 | return error; 60 | } 61 | 62 | @Override 63 | public String message() { 64 | return message; 65 | } 66 | 67 | @Override 68 | public String stackTrace() { 69 | return stackTrace; 70 | } 71 | 72 | @Override 73 | public Throwable cause() { 74 | return cause; 75 | } 76 | 77 | public JsonObject toJson() { 78 | JsonObject json = new JsonObject(). 79 | put("error", error). 80 | put("message", message). 81 | put("stackTrace", stackTrace); 82 | if (cause != null) { 83 | // Attempt to marshall the cause since it is Serializable 84 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 85 | try(ObjectOutputStream oos = new ObjectOutputStream(buffer)) { 86 | oos.flush(); 87 | oos.writeObject(cause); 88 | json.put("cause", buffer.toByteArray()); 89 | } catch (Exception ignore) { 90 | } 91 | } 92 | return json; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/Helper.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.ext.unit.TestContext; 5 | 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.util.function.Supplier; 9 | 10 | /** 11 | * @author Julien Viet 12 | */ 13 | public class Helper { 14 | 15 | /** 16 | * JVM hack to throw a throwable as unchecked. 17 | * 18 | * @param throwable the throwable to throw 19 | */ 20 | public static void uncheckedThrow(Throwable throwable) { 21 | Helper.throwIt(throwable); 22 | } 23 | 24 | private static void throwIt(Throwable throwable) throws T { 25 | throw (T)throwable; 26 | } 27 | 28 | public static Handler invoker(Method method, Supplier instance) { 29 | Class[] paramTypes = method.getParameterTypes(); 30 | if (!(paramTypes.length == 0 || (paramTypes.length == 1 && paramTypes[0].equals(TestContext.class)))) { 31 | throw new IllegalArgumentException("Incorrect method handler mapping " + method); 32 | } 33 | return context -> { 34 | try { 35 | Object o = instance.get(); 36 | if (paramTypes.length == 0) { 37 | method.invoke(o); 38 | } else { 39 | method.invoke(o, context); 40 | } 41 | } catch (IllegalAccessException e) { 42 | Helper.uncheckedThrow(e); 43 | } catch (InvocationTargetException e) { 44 | Helper.uncheckedThrow(e.getCause()); 45 | } 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/Result.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * @author Julien Viet 7 | */ 8 | public class Result { 9 | 10 | final long beginTime; 11 | final long endTime; 12 | final Throwable failure; 13 | 14 | Result(long beginTime, long endTime, Throwable failure) { 15 | this.beginTime = beginTime; 16 | this.endTime = endTime; 17 | this.failure = failure; 18 | } 19 | 20 | long duration() { 21 | return endTime - beginTime; 22 | } 23 | 24 | public Throwable getFailure() { 25 | return failure; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/Task.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | /** 4 | * @author Julien Viet 5 | */ 6 | public interface Task { 7 | 8 | void execute(T t, ExecutionContext context); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestCaseImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.ext.unit.TestContext; 6 | import io.vertx.ext.unit.TestCase; 7 | import io.vertx.ext.unit.report.TestCaseReport; 8 | import io.vertx.ext.unit.report.TestResult; 9 | 10 | import java.util.HashMap; 11 | import java.util.concurrent.CountDownLatch; 12 | import java.util.concurrent.TimeUnit; 13 | import java.util.concurrent.atomic.AtomicReference; 14 | 15 | /** 16 | * @author Julien Viet 17 | */ 18 | public class TestCaseImpl implements TestCase { 19 | 20 | final String name; 21 | final int repeat; 22 | final Handler handler; 23 | 24 | public TestCaseImpl(String name, int repeat, Handler handler) { 25 | if (name == null) { 26 | throw new IllegalArgumentException("Test name cannot be null"); 27 | } 28 | if (repeat < 1) { 29 | throw new IllegalArgumentException("Repeat count must be >= 1"); 30 | } 31 | if (handler == null) { 32 | throw new IllegalArgumentException("Test cannot be null"); 33 | } 34 | this.name = name; 35 | this.repeat = repeat; 36 | this.handler = handler; 37 | } 38 | 39 | private TestCaseReport runner() { 40 | return new TestCaseReportImpl(name, 0, 1, new HashMap<>(), null, handler, null, null); 41 | } 42 | 43 | public String name() { 44 | return name; 45 | } 46 | 47 | @Override 48 | public void awaitSuccess() { 49 | awaitSuccess(2, TimeUnit.MINUTES); 50 | } 51 | 52 | @Override 53 | public void awaitSuccess(long timeout, TimeUnit unit) { 54 | awaitSuccess(new ExecutionContext(Vertx.currentContext()), timeout, unit); 55 | } 56 | 57 | @Override 58 | public void awaitSuccess(Vertx vertx, long timeout, TimeUnit unit) { 59 | awaitSuccess(new ExecutionContext(vertx.getOrCreateContext()), timeout, unit); 60 | } 61 | 62 | @Override 63 | public void awaitSuccess(Vertx vertx) { 64 | awaitSuccess(new ExecutionContext(vertx.getOrCreateContext()), 2, TimeUnit.MINUTES); 65 | } 66 | 67 | private void awaitSuccess(ExecutionContext context, long timeout, TimeUnit unit) { 68 | CountDownLatch latch = new CountDownLatch(1); 69 | TestCaseReportImpl testCase = (TestCaseReportImpl) runner(); 70 | AtomicReference resultRef = new AtomicReference<>(); 71 | testCase.endHandler(result ->{ 72 | resultRef.set(result); 73 | latch.countDown(); 74 | }); 75 | Task task = testCase.buildTask((v, executor) -> {}); 76 | context.run(task); 77 | try { 78 | latch.await(timeout, unit); 79 | } catch (InterruptedException e) { 80 | throw new IllegalStateException(e); 81 | } 82 | TestResult result = resultRef.get(); 83 | if (result == null) { 84 | throw new IllegalStateException("Time out"); 85 | } else if (result.failed()) { 86 | Throwable failure = result.failure().cause(); 87 | if (failure instanceof Error) { 88 | throw (Error) failure; 89 | } else if (failure instanceof RuntimeException) { 90 | throw (RuntimeException) failure; 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestCaseReportImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.ext.unit.TestContext; 5 | import io.vertx.ext.unit.report.TestResult; 6 | import io.vertx.ext.unit.report.TestCaseReport; 7 | 8 | import java.util.Map; 9 | import java.util.function.Function; 10 | 11 | /** 12 | * @author Julien Viet 13 | */ 14 | public class TestCaseReportImpl implements TestCaseReport { 15 | 16 | private final String name; 17 | private final long timeout; 18 | private final int repeat; 19 | private final Map attributes; 20 | private final Handler before; 21 | private final Handler test; 22 | private final Handler after; 23 | private final Handler unhandledFailureHandler; 24 | private volatile Handler completionHandler; 25 | 26 | public TestCaseReportImpl(String name, 27 | long timeout, 28 | int repeat, 29 | Map attributes, 30 | Handler before, 31 | Handler test, 32 | Handler after, 33 | Handler unhandledFailureHandler) { 34 | 35 | this.attributes = attributes; 36 | this.timeout = timeout; 37 | this.repeat = repeat; 38 | this.name = name; 39 | this.before = before; 40 | this.test = test; 41 | this.after = after; 42 | this.unhandledFailureHandler = unhandledFailureHandler; 43 | } 44 | 45 | Task buildTask(Task nextTask) { 46 | // Build task assemblies for the test case 47 | Task task = (result, context) -> { 48 | if (completionHandler != null) { 49 | completionHandler.handle(new TestResultImpl(name, result.beginTime, result.duration(), result.failure)); 50 | } 51 | nextTask.execute(null, context); 52 | }; 53 | for (int count = 0;count < repeat;count++) { 54 | task = runTask(task); 55 | } 56 | return task; 57 | } 58 | 59 | private Task runTask(Task next) { 60 | TestContextImpl testContext = new TestContextImpl(attributes, unhandledFailureHandler); 61 | Task afterHandler; 62 | if (after != null) { 63 | afterHandler = new TestContextTask(testContext, after, next, timeout); 64 | } else { 65 | afterHandler = next; 66 | } 67 | Task testHandler = new TestContextTask(testContext, test, afterHandler, timeout); 68 | if (before != null) { 69 | Function> tmp = result -> { 70 | if (result.failure != null) { 71 | return next; 72 | } else { 73 | return testHandler; 74 | } 75 | }; 76 | return new TestContextTask(testContext, before, tmp, timeout); 77 | } else { 78 | return testHandler; 79 | } 80 | } 81 | 82 | @Override 83 | public String name() { 84 | return name; 85 | } 86 | 87 | @Override 88 | public TestCaseReport endHandler(Handler handler) { 89 | completionHandler = handler; 90 | return this; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestCompletionImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.ext.unit.TestCompletion; 5 | import io.vertx.ext.unit.report.TestSuiteReport; 6 | import io.vertx.ext.unit.report.Reporter; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | import java.util.concurrent.atomic.AtomicReference; 12 | 13 | /** 14 | * @author Julien Viet 15 | */ 16 | public class TestCompletionImpl extends CompletionImpl implements TestCompletion, Handler { 17 | 18 | private final AtomicReference report = new AtomicReference<>(); 19 | private final List reporters = Collections.synchronizedList(new ArrayList<>()); 20 | private final AtomicReference failure = new AtomicReference<>(); 21 | 22 | public TestCompletionImpl(Reporter... reporters) { 23 | Collections.addAll(this.reporters, reporters); 24 | } 25 | 26 | public void addReporter(Reporter reporter) { 27 | reporters.add(reporter); 28 | } 29 | 30 | @Override 31 | public void handle(TestSuiteReport report) { 32 | Reporter[] reporters = this.reporters.toArray(new Reporter[this.reporters.size()]); 33 | Object[] reports = new Object[reporters.length]; 34 | for (int i = 0;i < reporters.length;i++) { 35 | reports[i] = reporters[i].reportBeginTestSuite(report.name()); 36 | } 37 | report.handler(testcase -> { 38 | for (int i = 0; i < reporters.length; i++) { 39 | reporters[i].reportBeginTestCase(reports[i], testcase.name()); 40 | } 41 | testcase.endHandler(result -> { 42 | if (result.failed()) { 43 | failure.compareAndSet(null, result.failure().cause()); 44 | } 45 | for (int i = 0; i < reporters.length; i++) { 46 | reporters[i].reportEndTestCase(reports[i], testcase.name(), result); 47 | } 48 | }); 49 | }); 50 | AtomicReference err = new AtomicReference<>(); 51 | report.exceptionHandler(t -> { 52 | failure.compareAndSet(null, t); 53 | err.set(t); 54 | for (int i = 0; i < reporters.length; i++) { 55 | reporters[i].reportError(reports[i], t); 56 | } 57 | }); 58 | report.endHandler(v -> { 59 | this.report.set(report); 60 | for (int i = 0; i < reporters.length; i++) { 61 | reporters[i].reportEndTestSuite(reports[i]); 62 | } 63 | if (failure.get() != null) { 64 | completable.completeExceptionally(failure.get()); 65 | } else { 66 | completable.complete(null); 67 | } 68 | }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestContextTask.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.ext.unit.TestContext; 5 | 6 | import java.util.Map; 7 | import java.util.function.Function; 8 | 9 | /** 10 | * @author Julien Viet 11 | */ 12 | public class TestContextTask implements Task { 13 | 14 | private final TestContextImpl testContext; 15 | private final Handler callback; 16 | private Function> next; 17 | private final long timeout; 18 | 19 | public TestContextTask(TestContextImpl testContext, Handler callback, Task next, long timeout) { 20 | this.testContext = testContext; 21 | this.callback = callback; 22 | this.next = result -> next; 23 | this.timeout = timeout; 24 | } 25 | 26 | public TestContextTask(TestContextImpl testContext, Handler callback, Function> next, long timeout) { 27 | this.testContext = testContext; 28 | this.callback = callback; 29 | this.next = next; 30 | this.timeout = timeout; 31 | } 32 | 33 | @Override 34 | public void execute(Result prev, ExecutionContext context) { 35 | long beginTime; 36 | if (prev != null) { 37 | beginTime = prev.beginTime; 38 | } else { 39 | beginTime = System.currentTimeMillis(); 40 | } 41 | testContext.run(prev != null ? prev.failure : null, timeout, callback, failed -> { 42 | long endTime = System.currentTimeMillis(); 43 | Result result = new Result(beginTime, endTime, failed); 44 | context.run(next.apply(result), result); 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestResultImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.ext.unit.report.Failure; 4 | import io.vertx.ext.unit.report.TestResult; 5 | 6 | /** 7 | * @author Julien Viet 8 | */ 9 | public class TestResultImpl implements TestResult { 10 | 11 | private final String name; 12 | private final long beginTime; 13 | private final long durationTime; 14 | private final Failure failure; 15 | 16 | public TestResultImpl(String name, long beginTime, long durationTime, Failure failure) { 17 | this.name = name; 18 | this.beginTime = beginTime; 19 | this.durationTime = durationTime; 20 | this.failure = failure; 21 | } 22 | 23 | public TestResultImpl(String name, long beginTime, long durationTime, Throwable failure) { 24 | this(name, beginTime, durationTime, failure != null ? new FailureImpl(failure) : null); 25 | } 26 | 27 | @Override 28 | public String name() { 29 | return name; 30 | } 31 | 32 | @Override 33 | public long beginTime() { 34 | return beginTime; 35 | } 36 | 37 | @Override 38 | public long durationTime() { 39 | return durationTime; 40 | } 41 | 42 | @Override 43 | public Failure failure() { 44 | return failure; 45 | } 46 | 47 | @Override 48 | public boolean succeeded() { 49 | return failure == null; 50 | } 51 | 52 | @Override 53 | public boolean failed() { 54 | return failure != null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestSuiteImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.ext.unit.TestCompletion; 6 | import io.vertx.ext.unit.TestOptions; 7 | import io.vertx.ext.unit.TestSuite; 8 | import io.vertx.ext.unit.TestContext; 9 | import io.vertx.ext.unit.report.Reporter; 10 | 11 | import java.lang.reflect.InvocationTargetException; 12 | import java.lang.reflect.Method; 13 | import java.lang.reflect.Modifier; 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.List; 17 | 18 | /** 19 | * @author Julien Viet 20 | */ 21 | public class TestSuiteImpl implements TestSuite { 22 | 23 | private static volatile Handler defaultRunner; 24 | 25 | /** 26 | * Internal hook for launcher test command 27 | * @param runner the runner 28 | */ 29 | static void setDefaultRunner(Handler runner) { 30 | defaultRunner = runner; 31 | } 32 | 33 | private final String name; 34 | private volatile Handler before; 35 | private volatile Handler beforeEach; 36 | private volatile Handler after; 37 | private volatile Handler afterEach; 38 | private final List testCases = new ArrayList<>(); 39 | 40 | public TestSuiteImpl(String name) { 41 | this.name = name; 42 | } 43 | 44 | public TestSuiteImpl(Object testSuiteObject) { 45 | Class suiteClass = testSuiteObject.getClass(); 46 | name = suiteClass.getName(); 47 | for (Method method : suiteClass.getMethods()) { 48 | int modifiers = method.getModifiers(); 49 | String methodName = method.getName(); 50 | if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && 51 | Arrays.equals(method.getParameterTypes(), new Class[]{TestContext.class})) { 52 | Handler handler = context -> { 53 | try { 54 | method.invoke(testSuiteObject, context); 55 | } catch (IllegalAccessException e) { 56 | Helper.uncheckedThrow(e); 57 | } catch (InvocationTargetException e) { 58 | Helper.uncheckedThrow(e.getCause()); 59 | } 60 | }; 61 | switch (methodName) { 62 | case "before": 63 | before(handler); 64 | break; 65 | case "after": 66 | after(handler); 67 | break; 68 | case "beforeEach": 69 | beforeEach(handler); 70 | break; 71 | case "afterEach": 72 | afterEach(handler); 73 | break; 74 | default: 75 | if (methodName.startsWith("test") && methodName.length() > 4) { 76 | test(methodName, handler); 77 | } 78 | break; 79 | } 80 | } 81 | } 82 | } 83 | 84 | public List testCases() { 85 | return testCases; 86 | } 87 | 88 | @Override 89 | public TestSuite before(Handler callback) { 90 | this.before = callback; 91 | return this; 92 | } 93 | 94 | @Override 95 | public TestSuite beforeEach(Handler callback) { 96 | beforeEach = callback; 97 | return this; 98 | } 99 | 100 | @Override 101 | public TestSuite after(Handler handler) { 102 | this.after = handler; 103 | return this; 104 | } 105 | 106 | @Override 107 | public TestSuite afterEach(Handler handler) { 108 | afterEach = handler; 109 | return this; 110 | } 111 | 112 | @Override 113 | public TestSuite test(String name, Handler testCase) { 114 | return test(name, 1, testCase); 115 | } 116 | 117 | @Override 118 | public TestSuite test(String name, int repeat, Handler testCase) { 119 | testCases.add(new TestCaseImpl(name, repeat, testCase)); 120 | return this; 121 | } 122 | 123 | @Override 124 | public TestCompletion run() { 125 | return run(null, new TestOptions()); 126 | } 127 | 128 | @Override 129 | public TestCompletion run(Vertx vertx) { 130 | return run(vertx, new TestOptions()); 131 | } 132 | 133 | @Override 134 | public TestCompletion run(TestOptions options) { 135 | return run(null, options); 136 | } 137 | 138 | @Override 139 | public TestCompletion run(Vertx vertx, TestOptions options) { 140 | Reporter[] reporters = options.getReporters().stream().map(reportOptions -> Reporter.reporter(vertx, reportOptions)).toArray(Reporter[]::new); 141 | TestCompletionImpl completion = new TestCompletionImpl(reporters); 142 | TestSuiteRunner runner = runner(). 143 | setVertx(vertx). 144 | setTimeout(options.getTimeout()). 145 | setUseEventLoop(options.isUseEventLoop()). 146 | setReporter(completion); 147 | if (defaultRunner != null) { 148 | defaultRunner.handle(runner); 149 | } else { 150 | runner.run(); 151 | } 152 | return completion; 153 | } 154 | 155 | public TestSuiteRunner runner() { 156 | return new TestSuiteRunner(name, before, after, beforeEach, afterEach, new ArrayList<>(testCases)); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestSuiteReportImpl.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Context; 4 | import io.vertx.core.Handler; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.core.streams.ReadStream; 7 | import io.vertx.ext.unit.report.TestSuiteReport; 8 | import io.vertx.ext.unit.TestContext; 9 | import io.vertx.ext.unit.report.TestCaseReport; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * @author Julien Viet 16 | */ 17 | class TestSuiteReportImpl implements TestSuiteReport { 18 | 19 | private final String name; 20 | private final long timeout; 21 | private final Handler before; 22 | private final Handler after; 23 | private final Handler beforeEach; 24 | private final Handler afterEach; 25 | private final TestCaseImpl[] tests; 26 | private Handler endHandler; 27 | private Handler exceptionHandler; 28 | private Handler handler; 29 | 30 | TestSuiteReportImpl(String name, long timeout, Handler before, Handler after, 31 | Handler beforeEach, Handler afterEach, 32 | TestCaseImpl[] tests) { 33 | this.name = name; 34 | this.timeout = timeout; 35 | this.before = before; 36 | this.after = after; 37 | this.beforeEach = beforeEach; 38 | this.afterEach = afterEach; 39 | this.tests = tests; 40 | } 41 | 42 | @Override 43 | public String name() { 44 | return name; 45 | } 46 | 47 | @Override 48 | public TestSuiteReport exceptionHandler(Handler handler) { 49 | exceptionHandler = handler; 50 | return this; 51 | } 52 | 53 | @Override 54 | public TestSuiteReport handler(Handler handler) { 55 | this.handler = handler; 56 | return this; 57 | } 58 | 59 | @Override 60 | public TestSuiteReport pause() { 61 | return this; 62 | } 63 | 64 | @Override 65 | public TestSuiteReport resume() { 66 | return this; 67 | } 68 | 69 | @Override 70 | public ReadStream fetch(long amount) { 71 | return this; 72 | } 73 | 74 | @Override 75 | public TestSuiteReport endHandler(Handler handler) { 76 | endHandler = handler; 77 | return this; 78 | } 79 | 80 | private Task buildTestCasesTasks(Map attributes, TestCaseImpl[] tests, int index, Task endTask) { 81 | if (tests.length > index) { 82 | TestCaseImpl test = tests[index]; 83 | Task nextTask = buildTestCasesTasks(attributes, tests, index + 1, endTask); 84 | return (v, context) -> { 85 | TestCaseReportImpl testReport = new TestCaseReportImpl(test.name, timeout, test.repeat, new HashMap<>(attributes), beforeEach, test.handler, afterEach, exceptionHandler); 86 | if (handler != null) { 87 | handler.handle(testReport); 88 | } 89 | Task task = testReport.buildTask(nextTask); 90 | task.execute(null, context); 91 | }; 92 | } else { 93 | if (after != null) { 94 | return new TestContextTask(new TestContextImpl(new HashMap<>(attributes), exceptionHandler), after, endTask, 0); 95 | } else { 96 | return endTask; 97 | } 98 | } 99 | } 100 | 101 | private Task buildTask() { 102 | Task endTask = (result, context) -> { 103 | if (result != null && result.failure != null && exceptionHandler != null) { 104 | exceptionHandler.handle(result.failure); 105 | } 106 | if (endHandler != null) { 107 | endHandler.handle(null); 108 | } 109 | }; 110 | if (before != null) { 111 | HashMap attributes = new HashMap<>(); 112 | return new TestContextTask(new TestContextImpl(attributes, exceptionHandler), before, result -> { 113 | if (result.failure == null) { 114 | Task runTask = buildTestCasesTasks(attributes, tests, 0, endTask); 115 | return (result_, context) -> runTask.execute(null, context); 116 | } else { 117 | return endTask; 118 | } 119 | }, 0); 120 | } else { 121 | return buildTestCasesTasks(new HashMap<>(), tests, 0, endTask); 122 | } 123 | } 124 | 125 | // For unit testing 126 | public void run(ExecutionContext context) { 127 | context.run(buildTask()); 128 | } 129 | 130 | public void run(Boolean useEventLoop) { 131 | Context context = null; 132 | if (useEventLoop == null) { 133 | context = Vertx.currentContext(); 134 | } else if (useEventLoop) { 135 | context = Vertx.currentContext(); 136 | if (context == null) { 137 | throw new IllegalStateException("No event loop, your test should either provide a Vertx instance or " + 138 | "be executed in a Verticle"); 139 | } 140 | } 141 | new ExecutionContext(context).run(buildTask()); 142 | } 143 | 144 | public void run(Vertx vertx, Boolean useEventLoop) { 145 | Context context = Boolean.FALSE.equals(useEventLoop) ? null : vertx.getOrCreateContext(); 146 | Task task = buildTask(); 147 | new ExecutionContext(context).run(task); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/impl/TestSuiteRunner.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.ext.unit.TestContext; 6 | import io.vertx.ext.unit.report.TestSuiteReport; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * The test suite runner. 12 | * 13 | * @author Julien Viet 14 | */ 15 | public class TestSuiteRunner { 16 | 17 | private final String name; 18 | private final Handler before; 19 | private final Handler after; 20 | private final Handler beforeEach; 21 | private final Handler afterEach; 22 | private final List tests; 23 | private Vertx vertx; 24 | private Handler handler; 25 | private long timeout; 26 | private Boolean useEventLoop; 27 | 28 | public TestSuiteRunner(String name, Handler before, Handler after, Handler beforeEach, 29 | Handler afterEach, List tests) { 30 | this.name = name; 31 | this.timeout = 0; 32 | this.before = before; 33 | this.after = after; 34 | this.beforeEach = beforeEach; 35 | this.afterEach = afterEach; 36 | this.tests = tests; 37 | } 38 | 39 | public List getTests() { 40 | return tests; 41 | } 42 | 43 | public Boolean isUseEventLoop() { 44 | return useEventLoop; 45 | } 46 | 47 | public TestSuiteRunner setUseEventLoop(Boolean useEventLoop) { 48 | this.useEventLoop = useEventLoop; 49 | return this; 50 | } 51 | 52 | /** 53 | * @return the current runner vertx instance 54 | */ 55 | public Vertx getVertx() { 56 | return vertx; 57 | } 58 | 59 | /** 60 | * Set a vertx instance of the runner. 61 | * 62 | * @param vertx the vertx instance 63 | * @return a reference to this, so the API can be used fluently 64 | */ 65 | public TestSuiteRunner setVertx(Vertx vertx) { 66 | this.vertx = vertx; 67 | return this; 68 | } 69 | 70 | /** 71 | * @return the current runner timeout 72 | */ 73 | public long getTimeout() { 74 | return timeout; 75 | } 76 | 77 | /** 78 | * Set a timeout on the runner, zero or a negative value means no timeout. 79 | * 80 | * @param timeout the timeout in millis 81 | * @return a reference to this, so the API can be used fluently 82 | */ 83 | public TestSuiteRunner setTimeout(long timeout) { 84 | this.timeout = timeout; 85 | return this; 86 | } 87 | 88 | public Handler getReporter() { 89 | return handler; 90 | } 91 | 92 | /** 93 | * Set a reporter for handling the events emitted by the test suite. 94 | * 95 | * @param reporter the reporter 96 | * @return a reference to this, so the API can be used fluently 97 | */ 98 | public TestSuiteRunner setReporter(Handler reporter) { 99 | handler = reporter; 100 | return this; 101 | } 102 | 103 | /** 104 | * Run the testsuite with the current {@code timeout}, {@code vertx} and {@code reporter}. 105 | */ 106 | public void run() { 107 | TestSuiteReportImpl runner = new TestSuiteReportImpl(name, timeout, before, after, beforeEach, 108 | afterEach, tests.toArray(new TestCaseImpl[tests.size()])); 109 | handler.handle(runner); 110 | if (vertx != null) { 111 | runner.run(vertx, useEventLoop); 112 | } else { 113 | runner.run(useEventLoop); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/junit/Repeat.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.junit; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | import java.lang.annotation.Target; 6 | 7 | /** 8 | * Annotates a test method to repeat this test several times. This can be useful when a test fails randomly and 9 | * not often. 10 | * 11 | * @author Tim Fox 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({java.lang.annotation.ElementType.METHOD}) 15 | public @interface Repeat { 16 | 17 | int value(); 18 | 19 | /** 20 | * @return true if Vertx Unit repeat test in silent mode 21 | */ 22 | boolean silent() default false; 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/junit/RepeatRule.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.junit; 2 | 3 | import org.junit.rules.TestRule; 4 | import org.junit.runner.Description; 5 | import org.junit.runners.model.Statement; 6 | 7 | /** 8 | * @author Tim Fox 9 | */ 10 | public class RepeatRule implements TestRule { 11 | 12 | private static class RepeatStatement extends Statement { 13 | 14 | private final int times; 15 | private final Statement statement; 16 | private final Description description; 17 | private final boolean silent; 18 | 19 | private RepeatStatement(int times, Statement statement, Description description, boolean silent) { 20 | this.times = times; 21 | this.statement = statement; 22 | this.description = description; 23 | this.silent = silent; 24 | } 25 | 26 | @Override 27 | public void evaluate() throws Throwable { 28 | for( int i = 0; i < times; i++ ) { 29 | if(!silent) { 30 | System.out.println("*** Iteration " + (i + 1) + "/" + times + " of test " + description.getDisplayName()); 31 | } 32 | statement.evaluate(); 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | public Statement apply( Statement statement, Description description ) { 39 | Statement result = statement; 40 | Repeat repeat = description.getAnnotation(Repeat.class); 41 | if( repeat != null ) { 42 | final int times = repeat.value(); 43 | final boolean silent = repeat.silent(); 44 | result = new RepeatStatement(times, statement, description, silent); 45 | } 46 | return result; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/junit/RunTestOnContext.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.junit; 2 | 3 | import io.vertx.core.*; 4 | import io.vertx.core.internal.logging.Logger; 5 | import io.vertx.core.internal.logging.LoggerFactory; 6 | import org.junit.rules.TestRule; 7 | import org.junit.runner.Description; 8 | import org.junit.runners.model.Statement; 9 | 10 | import java.util.concurrent.CountDownLatch; 11 | import java.util.concurrent.TimeUnit; 12 | import java.util.function.BiConsumer; 13 | import java.util.function.Consumer; 14 | import java.util.function.Supplier; 15 | 16 | /** 17 | * A JUnit rule that runs tests on a Vert.x context.

18 | * 19 | * When used as a {@link org.junit.Rule} a new context is created for each tested method, the context will be same 20 | * for the before and after method, but different for all the tested methods.

21 | * 22 | * When used as a {@link org.junit.ClassRule}, a single context is created for all the tested method, the beforeClass 23 | * and afterClass method will also executed in this context. 24 | * 25 | * @author Julien Viet 26 | */ 27 | public class RunTestOnContext implements TestRule { 28 | 29 | private volatile Vertx vertx; 30 | private final Supplier createVertx; 31 | private final BiConsumer closeVertx; 32 | 33 | /** 34 | * Create a new rule managing a Vertx instance created with default options. The Vert.x instance 35 | * is created and closed for each test. 36 | */ 37 | public RunTestOnContext() { 38 | this(new VertxOptions()); 39 | } 40 | 41 | /** 42 | * Create a new rule managing a Vertx instance created with specified options. The Vert.x instance 43 | * is created and closed for each test. 44 | * 45 | * @param options the vertx options 46 | */ 47 | public RunTestOnContext(VertxOptions options) { 48 | this(Future.succeededFuture(Vertx.vertx(options))); 49 | } 50 | 51 | /** 52 | * Create a new rule with supplier for creating a Vert.x instance. The lambda are invoked for each 53 | * test. 54 | * 55 | * @param createVertx the create Vert.x supplier 56 | */ 57 | public RunTestOnContext(Supplier createVertx) { 58 | this(createVertx, (vertx, latch) -> vertx.close().onComplete(ar -> latch.accept(null))); 59 | } 60 | 61 | /** 62 | * Create a new rule with supplier/consumer for creating/closing a Vert.x instance. The lambda are invoked for each 63 | * test. The {@code closeVertx} lambda should invoke the consumer with null when the {@code vertx} instance is closed. 64 | * 65 | * @param createVertx the create Vert.x supplier 66 | * @param closeVertx the close Vert.x consumer 67 | */ 68 | public RunTestOnContext(Supplier createVertx, BiConsumer> closeVertx) { 69 | this.createVertx = createVertx; 70 | this.closeVertx = (vertx, latch) -> closeVertx.accept(vertx, v -> latch.countDown()); 71 | } 72 | 73 | /** 74 | * Create a new rule with an asynchronous supplier for creating a Vert.x instance. The lambda are invoked for each 75 | * test. 76 | * 77 | * @param createVertx the asynchronous create Vert.x supplier 78 | */ 79 | public RunTestOnContext(Future createVertx) { 80 | this(createVertx, (vertx, latch) -> vertx.close().onComplete(ar -> latch.accept(null))); 81 | } 82 | 83 | /** 84 | * Create a new rule with an asynchronous supplier and consumer for creating and closing a Vert.x instance. The 85 | * lambda are invoked for each test. The {@code closeVertx} lambda should invoke the consumer with null when the 86 | * {@code vertx} instance is closed. 87 | * 88 | * @param createVertx the asynchronous Vert.x supplier 89 | * @param closeVertx the close Vert.x consumer 90 | */ 91 | public RunTestOnContext(Future createVertx, BiConsumer> closeVertx) { 92 | this.createVertx = () -> { 93 | try { 94 | return createVertx.toCompletionStage().toCompletableFuture().get(60, TimeUnit.SECONDS); 95 | } catch (Exception e) { 96 | throw new AssertionError(e); 97 | } 98 | }; 99 | this.closeVertx = (vertx, latch) -> closeVertx.accept(vertx, v -> latch.countDown()); 100 | } 101 | 102 | /** 103 | * Retrieves the current Vert.x instance, this value varies according to the test life cycle. 104 | * 105 | * @return the vertx object 106 | */ 107 | public Vertx vertx() { 108 | return vertx; 109 | } 110 | 111 | @Override 112 | public Statement apply(Statement base, Description description) { 113 | return new Statement() { 114 | @Override 115 | public void evaluate() throws Throwable { 116 | vertx = createVertx.get(); 117 | try { 118 | Context context = vertx != null ? vertx.getOrCreateContext() : null; 119 | VertxUnitRunner.pushContext(context); 120 | base.evaluate(); 121 | } finally { 122 | VertxUnitRunner.popContext(); 123 | CountDownLatch latch = new CountDownLatch(1); 124 | closeVertx.accept(vertx, latch); 125 | try { 126 | if (!latch.await(30 * 1000, TimeUnit.MILLISECONDS)) { 127 | Logger logger = LoggerFactory.getLogger(description.getTestClass()); 128 | logger.warn("Could not close Vert.x in time."); 129 | } 130 | } catch (InterruptedException e) { 131 | Thread.currentThread().interrupt(); 132 | } 133 | } 134 | } 135 | }; 136 | } 137 | } 138 | 139 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/junit/Timeout.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.junit; 2 | 3 | import org.junit.rules.TestRule; 4 | import org.junit.runner.Description; 5 | import org.junit.runners.model.Statement; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * A rule for configuring the tests timeout. 11 | * 12 | * @author Julien Viet 13 | */ 14 | public class Timeout implements TestRule { 15 | 16 | /** 17 | * @param millis the timeout value in milli seconds 18 | * @return a new timeout rule 19 | */ 20 | public static Timeout millis(long millis) { 21 | return new Timeout(millis, TimeUnit.MILLISECONDS); 22 | } 23 | 24 | /** 25 | * @param seconds the timeout value in seconds 26 | * @return a new timeout rule 27 | */ 28 | public static Timeout seconds(long seconds) { 29 | return new Timeout(seconds, TimeUnit.SECONDS); 30 | } 31 | 32 | private final long value; 33 | 34 | public Timeout(long value, TimeUnit unit) { 35 | this.value = unit.toMillis(value); 36 | } 37 | 38 | @Override 39 | public Statement apply(Statement base, Description description) { 40 | return new Statement() { 41 | @Override 42 | public void evaluate() throws Throwable { 43 | VertxUnitRunner.pushTimeout(value); 44 | try { 45 | base.evaluate(); 46 | } finally { 47 | VertxUnitRunner.popTimeout(); 48 | } 49 | } 50 | }; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/junit/VertxUnitRunnerWithParameters.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.junit; 2 | 3 | import org.junit.runner.notification.RunNotifier; 4 | import org.junit.runners.Parameterized; 5 | import org.junit.runners.model.FrameworkField; 6 | import org.junit.runners.model.FrameworkMethod; 7 | import org.junit.runners.model.InitializationError; 8 | import org.junit.runners.model.Statement; 9 | import org.junit.runners.parameterized.TestWithParameters; 10 | 11 | import java.lang.annotation.Annotation; 12 | import java.lang.reflect.Field; 13 | import java.util.List; 14 | 15 | /** 16 | * @author Julien Viet 17 | */ 18 | public class VertxUnitRunnerWithParameters extends VertxUnitRunner { 19 | 20 | private final Object[] parameters; 21 | 22 | private final String name; 23 | 24 | protected VertxUnitRunnerWithParameters(TestWithParameters test) throws InitializationError { 25 | super(test.getTestClass().getJavaClass()); 26 | parameters = test.getParameters().toArray( 27 | new Object[test.getParameters().size()]); 28 | name = test.getName(); 29 | } 30 | 31 | @Override 32 | public Object createTest() throws Exception { 33 | if (fieldsAreAnnotated()) { 34 | return createTestUsingFieldInjection(); 35 | } else { 36 | return createTestUsingConstructorInjection(); 37 | } 38 | } 39 | 40 | private Object createTestUsingConstructorInjection() throws Exception { 41 | return getTestClass().getOnlyConstructor().newInstance(parameters); 42 | } 43 | 44 | private Object createTestUsingFieldInjection() throws Exception { 45 | List annotatedFieldsByParameter = getAnnotatedFieldsByParameter(); 46 | if (annotatedFieldsByParameter.size() != parameters.length) { 47 | throw new Exception( 48 | "Wrong number of parameters and @Parameter fields." 49 | + " @Parameter fields counted: " 50 | + annotatedFieldsByParameter.size() 51 | + ", available parameters: " + parameters.length 52 | + "."); 53 | } 54 | Object testClassInstance = getTestClass().getJavaClass().newInstance(); 55 | for (FrameworkField each : annotatedFieldsByParameter) { 56 | Field field = each.getField(); 57 | Parameterized.Parameter annotation = field.getAnnotation(Parameterized.Parameter.class); 58 | int index = annotation.value(); 59 | try { 60 | field.set(testClassInstance, parameters[index]); 61 | } catch (IllegalArgumentException iare) { 62 | throw new Exception(getTestClass().getName() 63 | + ": Trying to set " + field.getName() 64 | + " with the value " + parameters[index] 65 | + " that is not the right type (" 66 | + parameters[index].getClass().getSimpleName() 67 | + " instead of " + field.getType().getSimpleName() 68 | + ").", iare); 69 | } 70 | } 71 | return testClassInstance; 72 | } 73 | 74 | @Override 75 | protected String getName() { 76 | return name; 77 | } 78 | 79 | @Override 80 | protected void validateConstructor(List errors) { 81 | validateOnlyOneConstructor(errors); 82 | if (fieldsAreAnnotated()) { 83 | validateZeroArgConstructor(errors); 84 | } 85 | } 86 | 87 | @Override 88 | protected void validateFields(List errors) { 89 | super.validateFields(errors); 90 | if (fieldsAreAnnotated()) { 91 | List annotatedFieldsByParameter = getAnnotatedFieldsByParameter(); 92 | int[] usedIndices = new int[annotatedFieldsByParameter.size()]; 93 | for (FrameworkField each : annotatedFieldsByParameter) { 94 | int index = each.getField().getAnnotation(Parameterized.Parameter.class) 95 | .value(); 96 | if (index < 0 || index > annotatedFieldsByParameter.size() - 1) { 97 | errors.add(new Exception("Invalid @Parameter value: " 98 | + index + ". @Parameter fields counted: " 99 | + annotatedFieldsByParameter.size() 100 | + ". Please use an index between 0 and " 101 | + (annotatedFieldsByParameter.size() - 1) + ".")); 102 | } else { 103 | usedIndices[index]++; 104 | } 105 | } 106 | for (int index = 0; index < usedIndices.length; index++) { 107 | int numberOfUse = usedIndices[index]; 108 | if (numberOfUse == 0) { 109 | errors.add(new Exception("@Parameter(" + index 110 | + ") is never used.")); 111 | } else if (numberOfUse > 1) { 112 | errors.add(new Exception("@Parameter(" + index 113 | + ") is used more than once (" + numberOfUse + ").")); 114 | } 115 | } 116 | } 117 | } 118 | 119 | @Override 120 | protected Statement classBlock(RunNotifier notifier) { 121 | return childrenInvoker(notifier); 122 | } 123 | 124 | @Override 125 | protected Annotation[] getRunnerAnnotations() { 126 | return new Annotation[0]; 127 | } 128 | 129 | private List getAnnotatedFieldsByParameter() { 130 | return getTestClass().getAnnotatedFields(Parameterized.Parameter.class); 131 | } 132 | 133 | private boolean fieldsAreAnnotated() { 134 | return !getAnnotatedFieldsByParameter().isEmpty(); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/junit/VertxUnitRunnerWithParametersFactory.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.junit; 2 | 3 | import org.junit.runner.Runner; 4 | import org.junit.runners.model.InitializationError; 5 | import org.junit.runners.parameterized.ParametersRunnerFactory; 6 | import org.junit.runners.parameterized.TestWithParameters; 7 | 8 | /** 9 | * A {@link org.junit.runners.parameterized.ParametersRunnerFactory} for a {@link io.vertx.ext.unit.junit.VertxUnitRunner} 10 | * for enabling Vert.x Unit parameterized tests. 11 | * 12 | * @author Julien Viet 13 | */ 14 | public class VertxUnitRunnerWithParametersFactory implements ParametersRunnerFactory { 15 | 16 | @Override 17 | public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError { 18 | return new VertxUnitRunnerWithParameters(test); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/package-info.java: -------------------------------------------------------------------------------- 1 | @ModuleGen(name = "vertx-unit", groupPackage = "io.vertx") 2 | package io.vertx.ext.unit; 3 | 4 | import io.vertx.codegen.annotations.ModuleGen; 5 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/Failure.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.codegen.annotations.CacheReturn; 4 | import io.vertx.codegen.annotations.GenIgnore; 5 | import io.vertx.codegen.annotations.VertxGen; 6 | 7 | /** 8 | * A failure provides the details of a failure that happened during the execution of a test case.

9 | * 10 | * The failure can be: 11 | *

    12 | *
  • an assertion failure: an assertion failed
  • 13 | *
  • an error failure: an expected error occured
  • 14 | *
15 | * 16 | * 17 | * @author Julien Viet 18 | */ 19 | @VertxGen 20 | public interface Failure { 21 | 22 | /** 23 | * @return true if the failure is an error failure otherwise it is an assertion failure 24 | */ 25 | @CacheReturn 26 | boolean isError(); 27 | 28 | /** 29 | * @return the error message 30 | */ 31 | @CacheReturn 32 | String message(); 33 | 34 | /** 35 | * @return the stack trace 36 | */ 37 | @CacheReturn 38 | String stackTrace(); 39 | 40 | /** 41 | * @return the underlying exception causing this failure, it may be null 42 | */ 43 | @GenIgnore 44 | Throwable cause(); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/ReportOptions.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.codegen.annotations.Fluent; 5 | import io.vertx.codegen.json.annotations.JsonGen; 6 | import io.vertx.core.json.JsonObject; 7 | 8 | /** 9 | * Configures a reporter consisting in a name {@code to}, an address {@code at} and an optional {@code format}. 10 | * 11 | * @author Julien Viet 12 | */ 13 | @DataObject 14 | @JsonGen(publicConverter = false) 15 | public class ReportOptions { 16 | 17 | /** 18 | * The {@code console} is the default {@code to} value. 19 | */ 20 | public static final String DEFAULT_TO = "console"; 21 | 22 | /** 23 | * The {@code simple} format is the default {@code format} value. 24 | */ 25 | public static final String DEFAULT_FORMAT = "simple"; 26 | 27 | private String to = DEFAULT_TO; 28 | private String format = DEFAULT_FORMAT; 29 | 30 | public ReportOptions() { 31 | } 32 | 33 | public ReportOptions(ReportOptions other) { 34 | to = other.to; 35 | format = other.format; 36 | } 37 | 38 | public ReportOptions(JsonObject json) { 39 | ReportOptionsConverter.fromJson(json, this); 40 | } 41 | 42 | /** 43 | * @return the current reporter name 44 | */ 45 | public String getTo() { 46 | return to; 47 | } 48 | 49 | /** 50 | * Set the current reporter name. 51 | * 52 | * @param to the new reporter name 53 | * @return a reference to this, so the API can be used fluently 54 | */ 55 | @Fluent 56 | public ReportOptions setTo(String to) { 57 | this.to = to; 58 | return this; 59 | } 60 | 61 | /** 62 | * @return the current reporter format 63 | */ 64 | public String getFormat() { 65 | return format; 66 | } 67 | 68 | /** 69 | * Set the current reporter format. 70 | * 71 | * @param format the format 72 | * @return a reference to this, so the API can be used fluently 73 | a */ 74 | @Fluent 75 | public ReportOptions setFormat(String format) { 76 | this.format = format; 77 | return this; 78 | } 79 | 80 | public JsonObject toJson() { 81 | JsonObject json = new JsonObject(); 82 | ReportOptionsConverter.toJson(this, json); 83 | return json; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/Reporter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.report.impl.DefaultReporterFactory; 5 | 6 | /** 7 | * The reporter defines a set of callback for the life cycle events. 8 | * 9 | * @author Julien Viet 10 | * @param the report generic type 11 | */ 12 | public interface Reporter { 13 | 14 | static final ReporterFactory factory = new DefaultReporterFactory(); 15 | 16 | static Reporter reporter(Vertx vertx, ReportOptions options) { 17 | return factory.reporter(vertx, options); 18 | } 19 | 20 | /** 21 | * Signals the test suite began. 22 | * 23 | * @param name the test suite name 24 | * @return the report object 25 | */ 26 | R reportBeginTestSuite(String name); 27 | 28 | /** 29 | * Signals a test case began. 30 | * 31 | * @param report the report 32 | * @param name the test case name 33 | */ 34 | void reportBeginTestCase(R report, String name); 35 | 36 | /** 37 | * Signals a test case ended. 38 | * 39 | * @param report the report 40 | * @param name the test case name 41 | * @param result the test case result 42 | */ 43 | void reportEndTestCase(R report, String name, TestResult result); 44 | 45 | /** 46 | * Report a global test suite error, it can be called mulitple times between the {@link #reportBeginTestSuite} 47 | * and the {@link #reportEndTestSuite}. 48 | * 49 | * @param report the report 50 | * @param err the test suite error 51 | */ 52 | void reportError(R report, Throwable err); 53 | 54 | /** 55 | * Signals a test suite ended. 56 | * 57 | * @param report the report 58 | */ 59 | void reportEndTestSuite(R report); 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/ReporterFactory.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.core.Vertx; 4 | 5 | /** 6 | * @author Julien Viet 7 | */ 8 | public interface ReporterFactory { 9 | 10 | Reporter reporter(Vertx vertx, ReportOptions options); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/ReportingOptions.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.codegen.annotations.Fluent; 5 | import io.vertx.codegen.json.annotations.JsonGen; 6 | import io.vertx.core.json.JsonArray; 7 | import io.vertx.core.json.JsonObject; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Reporting options: 14 | * 15 | *
    16 | *
  • the {@code reporters} is an array of reporter configurations
  • 17 | *
18 | * 19 | * @author Julien Viet 20 | */ 21 | @DataObject 22 | @JsonGen(publicConverter = false) 23 | public class ReportingOptions { 24 | 25 | private List reporters = new ArrayList<>(); 26 | 27 | /** 28 | * Create a new empty options, with the default address out and no reporters. 29 | */ 30 | public ReportingOptions() { 31 | } 32 | 33 | /** 34 | * Copy constructor. 35 | * 36 | * @param other the options to copy 37 | */ 38 | public ReportingOptions(ReportingOptions other) { 39 | other.reporters.stream(). 40 | map(ReportOptions::new). 41 | forEach(reporters::add); 42 | } 43 | 44 | /** 45 | * Create a new options from the specified json. 46 | * 47 | * @param json the json to create from 48 | */ 49 | public ReportingOptions(JsonObject json) { 50 | ReportingOptionsConverter.fromJson(json, this); 51 | } 52 | 53 | /** 54 | * @return the current reporters options 55 | */ 56 | public List getReporters() { 57 | return reporters; 58 | } 59 | 60 | /** 61 | * Add a reporter to the current list. 62 | * 63 | * @param reportOptions the options of the reporter to use 64 | * @return a reference to this, so the API can be used fluently 65 | */ 66 | @Fluent 67 | public ReportingOptions addReporter(ReportOptions reportOptions) { 68 | reporters.add(reportOptions); 69 | return this; 70 | } 71 | 72 | /** 73 | * Replace the current list of reporters with a new one. 74 | * 75 | * @param reporters the new reporters 76 | * @return a reference to this, so the API can be used fluently 77 | */ 78 | @Fluent 79 | public ReportingOptions setReporters(List reporters) { 80 | this.reporters = reporters; 81 | return this; 82 | } 83 | 84 | /** 85 | * @return the json modelling the current configuration 86 | */ 87 | public JsonObject toJson() { 88 | JsonObject json = new JsonObject(); 89 | ReportingOptionsConverter.toJson(this, json); 90 | return json; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/TestCaseReport.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.codegen.annotations.CacheReturn; 4 | import io.vertx.codegen.annotations.Fluent; 5 | import io.vertx.codegen.annotations.VertxGen; 6 | import io.vertx.core.Handler; 7 | 8 | /** 9 | * Report the execution of a test case. 10 | * 11 | * @author Julien Viet 12 | */ 13 | @VertxGen 14 | public interface TestCaseReport { 15 | 16 | /** 17 | * @return the test case name 18 | */ 19 | @CacheReturn 20 | String name(); 21 | 22 | /** 23 | * Set a callback for completion, the specified {@code handler} is invoked when the test exec has completed. 24 | * 25 | * @param handler the completion handler 26 | * @return a reference to this, so the API can be used fluently 27 | */ 28 | @Fluent 29 | TestCaseReport endHandler(Handler handler); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/TestResult.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.codegen.annotations.CacheReturn; 4 | import io.vertx.codegen.annotations.VertxGen; 5 | 6 | /** 7 | * The result of a test. 8 | * 9 | * @author Julien Viet 10 | */ 11 | @VertxGen 12 | public interface TestResult { 13 | 14 | /** 15 | * The test description, may be null if none was provided. 16 | */ 17 | @CacheReturn 18 | String name(); 19 | 20 | /** 21 | * The time at which the test began in millis. 22 | */ 23 | @CacheReturn 24 | long beginTime(); 25 | 26 | /** 27 | * How long the test lasted in millis. 28 | */ 29 | @CacheReturn 30 | long durationTime(); 31 | 32 | /** 33 | * Did it succeed? 34 | */ 35 | @CacheReturn 36 | boolean succeeded(); 37 | 38 | /** 39 | * Did it fail? 40 | */ 41 | @CacheReturn 42 | boolean failed(); 43 | 44 | /** 45 | * An exception describing failure, null if the test succeeded. 46 | */ 47 | @CacheReturn 48 | Failure failure(); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/TestSuiteReport.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report; 2 | 3 | import io.vertx.codegen.annotations.CacheReturn; 4 | import io.vertx.codegen.annotations.VertxGen; 5 | import io.vertx.core.Handler; 6 | import io.vertx.core.streams.ReadStream; 7 | 8 | /** 9 | * The test suite reports is basically a stream of events reporting the test suite execution. 10 | * 11 | * @author Julien Viet 12 | */ 13 | @VertxGen 14 | public interface TestSuiteReport extends ReadStream { 15 | 16 | /** 17 | * @return the test suite name 18 | */ 19 | @CacheReturn 20 | String name(); 21 | 22 | /** 23 | * Set an exception handler, the exception handler reports the test suite errors, it can be called mulitple 24 | * times before the test ends. 25 | * 26 | * @param handler the exception handler 27 | * @return a reference to this, so the API can be used fluently 28 | */ 29 | @Override 30 | TestSuiteReport exceptionHandler(Handler handler); 31 | 32 | @Override 33 | TestSuiteReport handler(Handler handler); 34 | 35 | @Override 36 | TestSuiteReport pause(); 37 | 38 | @Override 39 | TestSuiteReport resume(); 40 | 41 | @Override 42 | TestSuiteReport endHandler(Handler endHandler); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/impl/DefaultReporterFactory.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report.impl; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.core.buffer.Buffer; 6 | import io.vertx.core.file.AsyncFile; 7 | import io.vertx.core.file.OpenOptions; 8 | import io.vertx.core.internal.logging.Logger; 9 | import io.vertx.core.internal.logging.LoggerFactory; 10 | import io.vertx.ext.unit.report.ReportOptions; 11 | import io.vertx.ext.unit.report.Reporter; 12 | import io.vertx.ext.unit.report.ReporterFactory; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | import java.io.PrintWriter; 17 | import java.io.Writer; 18 | import java.util.function.BiConsumer; 19 | import java.util.function.BiFunction; 20 | import java.util.function.Consumer; 21 | import java.util.function.Function; 22 | 23 | /** 24 | * @author Julien Viet 25 | */ 26 | public class DefaultReporterFactory implements ReporterFactory { 27 | 28 | @Override 29 | public Reporter reporter(Vertx vertx, ReportOptions options) { 30 | String to = options.getTo(); 31 | String prefix; 32 | String location; 33 | int pos = to.indexOf(':'); 34 | if (pos != -1) { 35 | prefix = to.substring(0, pos); 36 | location = to.substring(pos + 1); 37 | } else { 38 | prefix = to; 39 | location = null; 40 | } 41 | if (prefix.equals("bus")) { 42 | if (location == null) { 43 | throw new IllegalArgumentException("Invalid bus report configuration: " + to + " must follow bus: + address"); 44 | } 45 | if (vertx == null) { 46 | throw new IllegalArgumentException("No vertx provided for event bus reporting"); 47 | } 48 | return new EventBusReporter(vertx, location); 49 | } else { 50 | BiFunction streamFactory; 51 | switch (prefix) { 52 | case "console": 53 | streamFactory = (name, ext) -> new ReportStream() { 54 | @Override 55 | public void info(Buffer msg) { 56 | System.out.print(msg.toString("UTF-8")); 57 | } 58 | @Override 59 | public void error(Buffer msg, Throwable cause) { 60 | System.err.print(msg.toString("UTF-8")); 61 | cause.printStackTrace(System.err); 62 | } 63 | }; 64 | break; 65 | case "log": 66 | if (location == null) { 67 | throw new IllegalArgumentException("Invalid log report configuration: " + to + " must follow log: + address"); 68 | } 69 | Logger log = LoggerFactory.getLogger(location); 70 | streamFactory = (name, ext) -> new ReportStream() { 71 | @Override 72 | public void info(Buffer msg) { 73 | log.info(msg.toString("UTF-8")); 74 | } 75 | @Override 76 | public void error(Buffer msg, Throwable cause) { 77 | log.error(msg.toString("UTF-8"), cause); 78 | } 79 | }; 80 | break; 81 | case "file": { 82 | if (location == null) { 83 | throw new IllegalArgumentException("Invalid file report configuration: " + to + " must follow file: + address"); 84 | } 85 | if (vertx == null) { 86 | throw new IllegalArgumentException("No vertx provided for filesystem reporting"); 87 | } 88 | streamFactory = (name, ext) -> { 89 | String fileName = location + File.separator + name + "." + ext; 90 | AsyncFile file = vertx.fileSystem().openBlocking(fileName, new OpenOptions()); 91 | PrintWriter writer = new PrintWriter(new Writer() { 92 | public void write(char[] cbuf, int off, int len) throws IOException { 93 | file.write(Buffer.buffer(new String(cbuf, off, len))); 94 | } 95 | public void flush() throws IOException { 96 | file.flush(); 97 | } 98 | public void close() throws IOException { 99 | file.close(); 100 | } 101 | }); 102 | return new ReportStream() { 103 | @Override 104 | public void info(Buffer msg) { 105 | file.write(msg); 106 | } 107 | @Override 108 | public void error(Buffer msg, Throwable cause) { 109 | writer.println(msg.toString("UTF-8")); 110 | cause.printStackTrace(writer); 111 | } 112 | @Override 113 | public void end() { 114 | writer.close(); 115 | } 116 | }; 117 | }; 118 | break; 119 | } 120 | default: 121 | throw new IllegalArgumentException("Illegal reporter name <" + to + ">"); 122 | } 123 | String format = options.getFormat(); 124 | switch (format) { 125 | case "simple": 126 | return new SimpleFormatter(name -> streamFactory.apply(name, "txt")); 127 | case "junit": 128 | return new JunitXmlFormatter(name -> streamFactory.apply(name, "xml")); 129 | default: 130 | throw new IllegalArgumentException("Invalid format <" + format + ">"); 131 | } 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/impl/EventBusReporter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report.impl; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.core.json.JsonObject; 5 | import io.vertx.ext.unit.collect.EventBusCollector; 6 | import io.vertx.ext.unit.report.Failure; 7 | import io.vertx.ext.unit.report.TestResult; 8 | import io.vertx.ext.unit.impl.FailureImpl; 9 | import io.vertx.ext.unit.report.Reporter; 10 | 11 | /** 12 | * @author Julien Viet 13 | */ 14 | public class EventBusReporter implements Reporter { 15 | 16 | public static class EventBusReport { 17 | final String name; 18 | public EventBusReport(String name) { 19 | this.name = name; 20 | } 21 | } 22 | 23 | private final Vertx vertx; 24 | private final String address; 25 | 26 | public EventBusReporter(Vertx vertx, String address) { 27 | this.vertx = vertx; 28 | this.address = address; 29 | } 30 | 31 | @Override 32 | public EventBusReport reportBeginTestSuite(String name) { 33 | EventBusReport report = new EventBusReport(name); 34 | vertx.eventBus().publish(address, new JsonObject(). 35 | put("type", EventBusCollector.EVENT_TEST_SUITE_BEGIN). 36 | put("name", name)); 37 | return report; 38 | } 39 | 40 | @Override 41 | public void reportBeginTestCase(EventBusReport report, String name) { 42 | vertx.eventBus().publish(address, new JsonObject(). 43 | put("type", EventBusCollector.EVENT_TEST_CASE_BEGIN). 44 | put("name", name)); 45 | } 46 | 47 | @Override 48 | public void reportEndTestCase(EventBusReport report, String name, TestResult result) { 49 | JsonObject json = new JsonObject(). 50 | put("type", EventBusCollector.EVENT_TEST_CASE_END). 51 | put("name", result.name()). 52 | put("beginTime", result.beginTime()). 53 | put("durationTime", result.durationTime()); 54 | if (result.failed()) { 55 | Failure failure = result.failure(); 56 | json.put("failure", ((FailureImpl) failure).toJson()); 57 | } 58 | vertx.eventBus().publish(address, json); 59 | } 60 | 61 | @Override 62 | public void reportError(EventBusReport report, Throwable err) { 63 | JsonObject msg = new JsonObject().put("type", EventBusCollector.EVENT_TEST_SUITE_ERROR); 64 | msg.put("failure", new FailureImpl(err).toJson()); 65 | vertx.eventBus().publish(address, msg); 66 | } 67 | 68 | @Override 69 | public void reportEndTestSuite(EventBusReport report) { 70 | JsonObject msg = new JsonObject().put("type", EventBusCollector.EVENT_TEST_SUITE_END). 71 | put("name", report.name); 72 | vertx.eventBus().publish(address, msg); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/impl/JunitXmlFormatter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report.impl; 2 | 3 | import io.vertx.core.buffer.Buffer; 4 | import io.vertx.ext.unit.report.TestResult; 5 | import io.vertx.ext.unit.impl.TestResultImpl; 6 | import io.vertx.ext.unit.report.Reporter; 7 | 8 | import javax.xml.stream.XMLOutputFactory; 9 | import javax.xml.stream.XMLStreamWriter; 10 | import javax.xml.transform.OutputKeys; 11 | import javax.xml.transform.Transformer; 12 | import javax.xml.transform.TransformerFactory; 13 | import javax.xml.transform.stream.StreamResult; 14 | import javax.xml.transform.stream.StreamSource; 15 | import java.io.StringReader; 16 | import java.io.StringWriter; 17 | import java.text.NumberFormat; 18 | import java.text.SimpleDateFormat; 19 | import java.time.format.DateTimeFormatter; 20 | import java.util.ArrayList; 21 | import java.util.Date; 22 | import java.util.List; 23 | import java.util.Locale; 24 | import java.util.TimeZone; 25 | import java.util.concurrent.atomic.AtomicInteger; 26 | import java.util.concurrent.atomic.AtomicLong; 27 | import java.util.function.Function; 28 | 29 | /** 30 | * @author Julien Viet 31 | */ 32 | public class JunitXmlFormatter implements Reporter { 33 | 34 | public static class XmlReport { 35 | final Date timestamp; 36 | final String name; 37 | List results = new ArrayList<>(); 38 | AtomicInteger errors = new AtomicInteger(); 39 | AtomicInteger failures = new AtomicInteger(); 40 | AtomicLong time = new AtomicLong(); 41 | private XmlReport(Date timestamp, String name) { 42 | this.timestamp = timestamp; 43 | this.name = name; 44 | } 45 | } 46 | 47 | private final NumberFormat numberFormat = NumberFormat.getInstance(Locale.ENGLISH); 48 | private final Function streamFactory; 49 | 50 | public JunitXmlFormatter(Function streamFactory) { 51 | this.streamFactory = streamFactory; 52 | } 53 | 54 | @Override 55 | public XmlReport reportBeginTestSuite(String name) { 56 | return new XmlReport(new Date(), name); 57 | } 58 | 59 | @Override 60 | public void reportBeginTestCase(XmlReport report, String name) { 61 | } 62 | 63 | @Override 64 | public void reportEndTestCase(XmlReport report, String name, TestResult result) { 65 | report.results.add(result); 66 | if (result.failed()) { 67 | if (result.failure().isError()) { 68 | report.errors.incrementAndGet(); 69 | } else { 70 | report.failures.incrementAndGet(); 71 | } 72 | } 73 | report.time.addAndGet(result.durationTime()); 74 | } 75 | 76 | @Override 77 | public void reportError(XmlReport report, Throwable err) { 78 | report.results.add(new TestResultImpl(report.name, 0, 0, err)); 79 | report.errors.incrementAndGet(); 80 | } 81 | 82 | @Override 83 | public void reportEndTestSuite(XmlReport report) { 84 | // Create xml and send it 85 | ReportStream stream = streamFactory.apply(report.name); 86 | try { 87 | StringWriter buffer = new StringWriter(); 88 | XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newInstance(); 89 | XMLStreamWriter writer = xmlOutputFactory.createXMLStreamWriter(buffer); 90 | writer.writeStartDocument("UTF-8", "1.0"); 91 | writer.writeStartElement("testsuite"); 92 | writer.writeAttribute("name", report.name); 93 | SimpleDateFormat sdf; 94 | sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); 95 | sdf.setTimeZone(TimeZone.getTimeZone("CET")); 96 | writer.writeAttribute("timestamp", sdf.format(report.timestamp)); 97 | writer.writeAttribute("time", "" + formatTimeMillis(report.time.get())); 98 | writer.writeAttribute("tests", "" + report.results.size()); 99 | writer.writeAttribute("errors", "" + report.errors.get()); 100 | writer.writeAttribute("failures", "" + report.failures.get()); 101 | writer.writeAttribute("skipped", "0"); 102 | for (TestResult result : report.results) { 103 | writer.writeStartElement("testcase"); 104 | writer.writeAttribute("name", result.name()); 105 | writer.writeAttribute("time", "" + formatTimeMillis(result.durationTime())); 106 | if (result.failed()) { 107 | writer.writeStartElement("failure"); 108 | writer.writeAttribute("type", result.failure().isError() ? "Error" : "AssertionError"); 109 | String msg = result.failure().message(); 110 | writer.writeAttribute("message", msg != null ? msg : ""); 111 | writer.writeCharacters(result.failure().stackTrace()); 112 | writer.writeEndElement(); 113 | } 114 | writer.writeEndElement(); 115 | } 116 | writer.writeEndElement(); 117 | writer.writeEndDocument(); 118 | writer.close(); 119 | TransformerFactory factory = TransformerFactory.newInstance(); 120 | Transformer transformer = factory.newTransformer(); 121 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 122 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); 123 | StreamSource source = new StreamSource(new StringReader(buffer.toString())); 124 | buffer.getBuffer().setLength(0); 125 | StreamResult result = new StreamResult(buffer); 126 | transformer.transform(source, result); 127 | stream.info(Buffer.buffer(buffer.toString(), "UTF-8")); 128 | } catch (Exception e) { 129 | e.printStackTrace(); 130 | } finally { 131 | stream.end(); 132 | } 133 | } 134 | 135 | private String formatTimeMillis(long timeMillis) { 136 | return numberFormat.format((((double)timeMillis) / 1000)); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/impl/ReportStream.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report.impl; 2 | 3 | import io.vertx.core.buffer.Buffer; 4 | 5 | /** 6 | * @author Julien Viet 7 | */ 8 | public interface ReportStream { 9 | 10 | default void info(Buffer msg) {} 11 | 12 | default void error(Buffer msg, Throwable cause) {} 13 | 14 | default void end() {} 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/ext/unit/report/impl/SimpleFormatter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.report.impl; 2 | 3 | import io.vertx.core.buffer.Buffer; 4 | import io.vertx.ext.unit.report.TestResult; 5 | import io.vertx.ext.unit.report.Reporter; 6 | 7 | import java.util.function.Function; 8 | 9 | /** 10 | * @author Julien Viet 11 | */ 12 | public class SimpleFormatter implements Reporter { 13 | 14 | private final String sep = System.lineSeparator(); 15 | private final Function streamFactory; 16 | 17 | public SimpleFormatter(Function streamFactory) { 18 | this.streamFactory = streamFactory; 19 | } 20 | 21 | public static class ReportImpl { 22 | private final ReportStream stream; 23 | private final String name; 24 | private int run; 25 | private int failures; 26 | private int errors; 27 | public ReportImpl(ReportStream stream, String name) { 28 | this.stream = stream; 29 | this.name = name; 30 | } 31 | } 32 | 33 | @Override 34 | public ReportImpl reportBeginTestSuite(String name) { 35 | ReportImpl report = new ReportImpl(streamFactory.apply(name), name); 36 | report.stream.info(Buffer.buffer("Begin test suite " + name + sep)); 37 | return report; 38 | } 39 | 40 | @Override 41 | public void reportBeginTestCase(ReportImpl report, String name) { 42 | report.stream.info(Buffer.buffer("Begin test " + name + sep)); 43 | report.run++; 44 | } 45 | 46 | @Override 47 | public void reportEndTestCase(ReportImpl report, String name, TestResult result) { 48 | if (result.succeeded()) { 49 | report.stream.info(Buffer.buffer("Passed " + result.name() + sep)); 50 | } else { 51 | if (result.failure().isError()) { 52 | report.errors++; 53 | } else { 54 | report.failures++; 55 | } 56 | report.stream.error(Buffer.buffer("Failed " + result.name() + sep), result.failure().cause()); 57 | } 58 | } 59 | 60 | @Override 61 | public void reportError(ReportImpl report, Throwable err) { 62 | report.stream.error(Buffer.buffer("Test suite " + report.name + " failure" + sep), err); 63 | } 64 | 65 | @Override 66 | public void reportEndTestSuite(ReportImpl report) { 67 | String msg = "End test suite " + report.name + " , run: " + report.run + ", Failures: " + report.failures + 68 | ", Errors: " + report.errors + sep; 69 | report.stream.info(Buffer.buffer(msg)); 70 | report.stream.end(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module io.vertx.testing.unit { 2 | requires static io.vertx.docgen; 3 | requires static io.vertx.codegen.api; 4 | requires static io.vertx.codegen.json; 5 | requires io.vertx.core; 6 | requires io.vertx.core.logging; 7 | requires java.xml; 8 | requires junit; 9 | exports io.vertx.ext.unit; 10 | exports io.vertx.ext.unit.report; 11 | exports io.vertx.ext.unit.collect; 12 | exports io.vertx.ext.unit.junit; 13 | exports io.vertx.ext.unit.impl to io.vertx.testing.unit.tests; 14 | exports io.vertx.ext.unit.report.impl to io.vertx.testing.unit.tests; 15 | exports io.vertx.ext.unit.collect.impl to io.vertx.testing.unit.tests; 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/CompletionTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.Completion; 5 | import io.vertx.ext.unit.TestSuite; 6 | import org.junit.Test; 7 | 8 | import java.util.concurrent.TimeoutException; 9 | import java.util.concurrent.atomic.AtomicReference; 10 | import java.util.function.Consumer; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * @author Julien Viet 16 | */ 17 | public class CompletionTest { 18 | 19 | @Test 20 | public void testAwaitSucceeded() { 21 | testSucceeded(completion -> completion.await()); 22 | testSucceeded(completion -> completion.await(2000)); 23 | } 24 | 25 | @Test 26 | public void testAwaitSuccessSucceeded() { 27 | testSucceeded(completion -> completion.awaitSuccess()); 28 | testSucceeded(completion -> completion.awaitSuccess(2000)); 29 | } 30 | 31 | private void testSucceeded(Consumer consumer) { 32 | TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { 33 | }); 34 | Completion completion = suite.run(Vertx.vertx()); 35 | consumer.accept(completion); 36 | assertTrue(completion.isCompleted()); 37 | assertTrue(completion.isSucceeded()); 38 | assertFalse(completion.isFailed()); 39 | } 40 | 41 | @Test 42 | public void testAwaitFailed() { 43 | testAwaitFailed(completion -> completion.await()); 44 | testAwaitFailed(completion -> completion.await(2000)); 45 | } 46 | 47 | private void testAwaitFailed(Consumer consumer) { 48 | TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { 49 | context.fail(); 50 | }); 51 | Completion completion = suite.run(Vertx.vertx()); 52 | consumer.accept(completion); 53 | assertTrue(completion.isCompleted()); 54 | assertFalse(completion.isSucceeded()); 55 | assertTrue(completion.isFailed()); 56 | } 57 | 58 | @Test 59 | public void testAwaitSuccessFailed() throws Exception { 60 | testAwaitSuccessFailed(completion -> completion.awaitSuccess()); 61 | testAwaitSuccessFailed(completion -> completion.awaitSuccess(2000)); 62 | } 63 | 64 | private void testAwaitSuccessFailed(Consumer consumer) throws Exception { 65 | AtomicReference expected = new AtomicReference<>(); 66 | TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { 67 | try { 68 | context.fail(); 69 | } catch (AssertionError ae) { 70 | expected.set(ae); 71 | throw ae; 72 | } 73 | }); 74 | Completion completion = suite.run(Vertx.vertx()); 75 | try { 76 | consumer.accept(completion); 77 | fail(); 78 | } catch (AssertionError ae) { 79 | assertSame(expected.get(), ae); 80 | } 81 | assertTrue(completion.isCompleted()); 82 | assertFalse(completion.isSucceeded()); 83 | assertTrue(completion.isFailed()); 84 | } 85 | 86 | @Test 87 | public void testAwaitTimeout() { 88 | testTimeout(completion -> completion.await(10)); 89 | } 90 | 91 | @Test 92 | public void testAwaitSuccessTimeout() { 93 | testTimeout(completion -> completion.awaitSuccess(10)); 94 | } 95 | 96 | private void testTimeout(Consumer consumer) { 97 | TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { 98 | context.async(); 99 | }); 100 | Completion completion = suite.run(Vertx.vertx()); 101 | try { 102 | consumer.accept(completion); 103 | fail(); 104 | } catch (Exception e) { 105 | assertTrue(e instanceof TimeoutException); 106 | assertFalse(completion.isCompleted()); 107 | assertFalse(completion.isSucceeded()); 108 | assertFalse(completion.isFailed()); 109 | } 110 | } 111 | 112 | @Test 113 | public void testAwaitInterruption() { 114 | testAwaitSuccess(completion -> completion.await(), Thread.State.WAITING); 115 | testAwaitSuccess(completion -> completion.await(2000), Thread.State.TIMED_WAITING); 116 | } 117 | 118 | @Test 119 | public void testAwaitSuccessInterruption() { 120 | testAwaitSuccess(completion -> completion.awaitSuccess(), Thread.State.WAITING); 121 | testAwaitSuccess(completion -> completion.awaitSuccess(2000), Thread.State.TIMED_WAITING); 122 | } 123 | 124 | private void testAwaitSuccess(Consumer consumer, Thread.State expectedState) { 125 | TestSuite suite = TestSuite.create("my_suite").test("my_test", context -> { 126 | context.async(); 127 | }); 128 | Thread thread = Thread.currentThread(); 129 | Completion completion = suite.run(Vertx.vertx()); 130 | new Thread(() -> { 131 | while (thread.getState() != expectedState) { 132 | try { 133 | Thread.sleep(1); 134 | } catch (InterruptedException ignore) { 135 | } 136 | } 137 | thread.interrupt(); 138 | }).start(); 139 | try { 140 | consumer.accept(completion); 141 | fail(); 142 | } catch (Exception e) { 143 | assertTrue(Thread.interrupted()); // Check and clear status 144 | assertTrue(e instanceof InterruptedException); 145 | assertFalse(completion.isCompleted()); 146 | assertFalse(completion.isSucceeded()); 147 | assertFalse(completion.isFailed()); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/ConcurrentTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.ext.unit.Async; 4 | import io.vertx.ext.unit.TestSuite; 5 | import io.vertx.test.core.VertxTestBase; 6 | import org.junit.Test; 7 | 8 | public class ConcurrentTest extends VertxTestBase { 9 | 10 | @Test 11 | public void testAsyncCompletion() { 12 | for (int i = 0;i < 128;i++) { 13 | TestSuite suite = TestSuite.create("the-suite").test("the-test", ctx -> { 14 | // Try to create an async asynchronously 15 | // this might succeed or not depending on race agains the testsuite runner thread 16 | // which is fine, but we want to check that when it wins the race there 17 | // are no deadlocks (which is why we repeat this test several times) 18 | new Thread(() -> { 19 | Async async = ctx.async(); 20 | sleepQuietly(10); 21 | async.complete(); 22 | sleepQuietly(10); 23 | }).start(); 24 | sleepQuietly(10); 25 | }); 26 | suite.run().await(1000); 27 | } 28 | } 29 | 30 | private static void sleepQuietly(long millis) { 31 | try { 32 | Thread.sleep(millis); 33 | } catch (InterruptedException e) { 34 | Thread.currentThread().interrupt(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/ExamplesTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.ext.unit.TestOptions; 4 | import io.vertx.ext.unit.TestSuite; 5 | import io.vertx.ext.unit.report.ReportOptions; 6 | 7 | /** 8 | * @author Julien Viet 9 | */ 10 | public class ExamplesTest { 11 | 12 | @org.junit.Test 13 | public void testExample2() { 14 | // Run it to get the output and copy in the docs 15 | System.out.println("------ begin example 2"); 16 | TestSuite suite = TestSuite.create("the_test_suite"); 17 | suite.test("my_test_case", context -> { 18 | String s = "value"; 19 | context.assertEquals("value", s); 20 | }); 21 | suite.run(new TestOptions().addReporter(new ReportOptions().setTo("console"))); 22 | System.out.println("------ end example 2"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/JUnitParameterizedTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.ext.unit.Async; 4 | import io.vertx.ext.unit.TestContext; 5 | import io.vertx.ext.unit.junit.VertxUnitRunnerWithParametersFactory; 6 | import org.junit.Test; 7 | import org.junit.runner.JUnitCore; 8 | import org.junit.runner.Result; 9 | import org.junit.runner.RunWith; 10 | import org.junit.runners.Parameterized; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.concurrent.ConcurrentLinkedDeque; 17 | 18 | /** 19 | * @author Julien Viet 20 | */ 21 | public class JUnitParameterizedTest { 22 | 23 | @RunWith(Parameterized.class) 24 | @Parameterized.UseParametersRunnerFactory(VertxUnitRunnerWithParametersFactory.class) 25 | public static class SimpleParameterizedTestSuite { 26 | 27 | @Parameterized.Parameters 28 | public static Iterable data() { 29 | return Arrays.asList(false, true); 30 | } 31 | 32 | static final ConcurrentLinkedDeque params = new ConcurrentLinkedDeque(); 33 | private boolean pass; 34 | 35 | public SimpleParameterizedTestSuite(boolean pass) { 36 | params.add(pass); 37 | this.pass = pass; 38 | } 39 | 40 | @Test 41 | public void theTest(TestContext context) { 42 | Async async = context.async(); 43 | new Thread() { 44 | @Override 45 | public void run() { 46 | try { 47 | Thread.sleep(200); 48 | } catch (InterruptedException e) { 49 | Thread.currentThread().interrupt(); 50 | } finally { 51 | if (pass) { 52 | async.complete(); 53 | } else { 54 | context.fail(); 55 | } 56 | } 57 | } 58 | }.start(); 59 | } 60 | } 61 | 62 | @org.junit.Test 63 | public void testSuiteRun() { 64 | Result result = run(SimpleParameterizedTestSuite.class); 65 | assertEquals(Arrays.asList(false, true), new ArrayList<>(SimpleParameterizedTestSuite.params)); 66 | assertEquals(2, result.getRunCount()); 67 | assertEquals(1, result.getFailureCount()); 68 | } 69 | 70 | static Result run(Class testClass) { 71 | try { 72 | return new JUnitCore().run(new Parameterized(testClass)); 73 | } catch (Throwable initializationError) { 74 | throw new AssertionError(initializationError); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/JUnitTestSuiteTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | import io.vertx.ext.unit.junit.VertxUnitRunner; 5 | import org.junit.After; 6 | import org.junit.AfterClass; 7 | import org.junit.Before; 8 | import org.junit.BeforeClass; 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | 12 | /** 13 | * Junit integration example. 14 | * 15 | * @author Julien Viet 16 | */ 17 | @RunWith(VertxUnitRunner.class) 18 | public class JUnitTestSuiteTest { 19 | 20 | @BeforeClass 21 | public static void before(TestContext context) { 22 | System.out.println("before"); 23 | } 24 | 25 | @Before 26 | public void beforeEach(TestContext context) { 27 | System.out.println("beforeEach"); 28 | } 29 | 30 | @Test 31 | public void testSomething(TestContext context) { 32 | System.out.println("testSomething"); 33 | } 34 | 35 | @Test 36 | public void testSomethingElse(TestContext context) { 37 | System.out.println("testSomethingElse"); 38 | } 39 | 40 | @After 41 | public void afterEach(TestContext context) { 42 | System.out.println("afterEach"); 43 | } 44 | 45 | @AfterClass 46 | public static void after(TestContext context) { 47 | System.out.println("after"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/OptionsTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.json.JsonArray; 4 | import io.vertx.core.json.JsonObject; 5 | import io.vertx.ext.unit.TestOptions; 6 | import io.vertx.ext.unit.report.ReportOptions; 7 | import io.vertx.test.core.TestUtils; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | /** 17 | * @author Julien Viet 18 | */ 19 | public class OptionsTest { 20 | 21 | private Boolean randomBoolean() { 22 | switch (TestUtils.randomInt() % 3) { 23 | case 0: 24 | return false; 25 | case 1: 26 | return true; 27 | default: 28 | return null; 29 | } 30 | } 31 | 32 | @org.junit.Test 33 | public void testTestOptions() { 34 | TestOptions options = new TestOptions(); 35 | assertEquals(TestOptions.DEFAULT_TIMEOUT, options.getTimeout()); 36 | assertEquals(TestOptions.DEFAULT_USE_EVENT_LOOP, options.isUseEventLoop()); 37 | assertEquals(Collections.emptyList(), options.getReporters()); 38 | long timeout = TestUtils.randomLong(); 39 | Boolean useEventLoop = randomBoolean(); 40 | assertSame(options, options.setTimeout(timeout)); 41 | assertSame(options, options.setUseEventLoop(useEventLoop)); 42 | assertEquals(timeout, options.getTimeout()); 43 | assertEquals(useEventLoop, options.isUseEventLoop()); 44 | List reporters = new ArrayList<>(); 45 | ReportOptions reporter1 = new ReportOptions(); 46 | reporters.add(reporter1); 47 | assertSame(options, options.setReporters(reporters)); 48 | assertEquals(reporters, options.getReporters()); 49 | ReportOptions reporter2 = new ReportOptions(); 50 | assertSame(options, options.addReporter(reporter2)); 51 | assertEquals(reporters, options.getReporters()); 52 | assertEquals(2, reporters.size()); 53 | assertEquals(Arrays.asList(reporter1, reporter2), reporters); 54 | } 55 | 56 | @org.junit.Test 57 | public void testReportOptions() { 58 | ReportOptions options = new ReportOptions(); 59 | assertEquals(ReportOptions.DEFAULT_TO, options.getTo()); 60 | assertEquals(ReportOptions.DEFAULT_FORMAT, options.getFormat()); 61 | String to = TestUtils.randomAlphaString(10); 62 | assertSame(options, options.setTo(to)); 63 | assertEquals(to, options.getTo()); 64 | String at = TestUtils.randomAlphaString(10); 65 | String format = TestUtils.randomAlphaString(10); 66 | assertSame(options, options.setFormat(format)); 67 | assertEquals(format, options.getFormat()); 68 | } 69 | 70 | @org.junit.Test 71 | public void testCopyOptions() { 72 | TestOptions options = new TestOptions(); 73 | long timeout = TestUtils.randomLong(); 74 | Boolean useEventLoop = randomBoolean(); 75 | String to = TestUtils.randomAlphaString(10); 76 | String at = TestUtils.randomAlphaString(10); 77 | String format = TestUtils.randomAlphaString(10); 78 | ReportOptions reporter = new ReportOptions().setTo(to).setFormat(format); 79 | options.setUseEventLoop(useEventLoop).setTimeout(timeout).addReporter(reporter); 80 | TestOptions copy = new TestOptions(options); 81 | options.setTimeout(TestUtils.randomLong()); 82 | options.setUseEventLoop(randomBoolean()); 83 | reporter.setTo(TestUtils.randomAlphaString(10)); 84 | reporter.setFormat(TestUtils.randomAlphaString(10)); 85 | options.getReporters().clear(); 86 | assertEquals(timeout, copy.getTimeout()); 87 | assertEquals(useEventLoop, copy.isUseEventLoop()); 88 | assertEquals(1, copy.getReporters().size()); 89 | assertEquals(to, copy.getReporters().get(0).getTo()); 90 | assertEquals(format, copy.getReporters().get(0).getFormat()); 91 | } 92 | 93 | @org.junit.Test 94 | public void testDefaultJsonTestOptions() { 95 | TestOptions def = new TestOptions(); 96 | TestOptions json = new TestOptions(new JsonObject()); 97 | assertEquals(json.getTimeout(), def.getTimeout()); 98 | assertEquals(json.isUseEventLoop(), def.isUseEventLoop()); 99 | assertEquals(json.getReporters(), def.getReporters()); 100 | } 101 | 102 | @org.junit.Test 103 | public void testDefaultJsonReportOptions() { 104 | ReportOptions def = new ReportOptions(); 105 | ReportOptions json = new ReportOptions(new JsonObject()); 106 | assertEquals(json.getTo(), def.getTo()); 107 | assertEquals(json.getFormat(), def.getFormat()); 108 | } 109 | 110 | @org.junit.Test 111 | public void testJsonOptions() { 112 | JsonObject json = new JsonObject(); 113 | long timeout = TestUtils.randomLong(); 114 | Boolean useEventLoop = randomBoolean(); 115 | String to = TestUtils.randomAlphaString(10); 116 | String at = TestUtils.randomAlphaString(10); 117 | String format = TestUtils.randomAlphaString(10); 118 | json.put("timeout", timeout); 119 | if (useEventLoop != null) { 120 | json.put("useEventLoop", useEventLoop); 121 | } 122 | json.put("reporters", new JsonArray(). 123 | add(new JsonObject(). 124 | put("to", to). 125 | put("at", at). 126 | put("format", format))); 127 | TestOptions options = new TestOptions(json); 128 | assertEquals(timeout, options.getTimeout()); 129 | assertEquals(useEventLoop, options.isUseEventLoop()); 130 | assertEquals(1, options.getReporters().size()); 131 | assertEquals(to, options.getReporters().get(0).getTo()); 132 | assertEquals(format, options.getReporters().get(0).getFormat()); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestReporter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Handler; 4 | import io.vertx.ext.unit.report.TestResult; 5 | import io.vertx.ext.unit.report.TestSuiteReport; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.concurrent.CountDownLatch; 11 | import java.util.concurrent.TimeUnit; 12 | import java.util.concurrent.atomic.AtomicReference; 13 | 14 | /** 15 | * @author Julien Viet 16 | */ 17 | class TestReporter implements Handler { 18 | 19 | private final CountDownLatch latch = new CountDownLatch(1); 20 | final AtomicReference name = new AtomicReference<>(); 21 | final List exceptions = Collections.synchronizedList(new ArrayList<>()); 22 | final List results = Collections.synchronizedList(new ArrayList<>()); 23 | 24 | @Override 25 | public void handle(TestSuiteReport report) { 26 | name.set(report.name()); 27 | report.handler(testExec -> { 28 | testExec.endHandler(results::add); 29 | }); 30 | report.exceptionHandler(err -> { 31 | exceptions.add(err); 32 | }); 33 | report.endHandler(done -> { 34 | latch.countDown(); 35 | }); 36 | } 37 | 38 | void await() { 39 | try { 40 | latch.await(10, TimeUnit.SECONDS); 41 | } catch (InterruptedException e) { 42 | throw new AssertionError(e); 43 | } 44 | } 45 | boolean completed() { 46 | return latch.getCount() == 0; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestSuiteNoEventLoopAsyncTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.TestContext; 5 | 6 | /** 7 | * @author Julien Viet 8 | */ 9 | public class TestSuiteNoEventLoopAsyncTest extends TestSuiteTestBase { 10 | 11 | public TestSuiteNoEventLoopAsyncTest() { 12 | super(); 13 | getRunner = testsuite -> testsuite.runner(); 14 | run = (runner) -> new Thread() { 15 | @Override 16 | public void run() { 17 | runner.setUseEventLoop(false).run(); 18 | } 19 | }.start(); 20 | operateOnAsync = (async,action) -> action.accept(async); 21 | } 22 | 23 | @Override 24 | protected boolean checkTest(TestContext test) { 25 | return Vertx.currentContext() == null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestSuiteNoEventLoopTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.TestContext; 5 | import io.vertx.ext.unit.impl.TestSuiteImpl; 6 | 7 | import static org.junit.Assert.*; 8 | 9 | /** 10 | * @author Julien Viet 11 | */ 12 | public class TestSuiteNoEventLoopTest extends TestSuiteTestBase { 13 | 14 | public TestSuiteNoEventLoopTest() { 15 | super(); 16 | getRunner = TestSuiteImpl::runner; 17 | run = runner -> { 18 | assertNull(Vertx.currentContext()); 19 | runner.setUseEventLoop(false).run(); 20 | }; 21 | operateOnAsync = (async,action) -> action.accept(async); 22 | } 23 | 24 | @Override 25 | protected boolean checkTest(TestContext test) { 26 | return Vertx.currentContext() == null; 27 | } 28 | 29 | /* 30 | @org.junit.Test 31 | public void testEndsAfterCallback() throws Exception { 32 | AtomicBoolean ok = new AtomicBoolean(); 33 | AtomicBoolean after = new AtomicBoolean(); 34 | TestSuite suite = TestSuite.create("my_suite"). 35 | test("my_test", context -> { 36 | try { 37 | context.fail(); 38 | } catch (AssertionError e) { 39 | } 40 | if (!after.get()) { 41 | ok.set(true); 42 | } 43 | }).after(context -> { 44 | after.set(true); 45 | }); 46 | TestReporter reporter = new TestReporter(); 47 | run(suite, reporter); 48 | reporter.await(); 49 | assertTrue(ok.get()); 50 | assertTrue(reporter.completed()); 51 | assertEquals(0, reporter.exceptions.size()); 52 | assertEquals(1, reporter.results.size()); 53 | TestResult result = reporter.results.get(0); 54 | assertEquals("my_test", result.name()); 55 | assertTrue(result.failed()); 56 | } 57 | */ 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestSuiteNoEventLoopWithVertxTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.TestContext; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | 8 | import java.util.concurrent.CountDownLatch; 9 | 10 | import static org.junit.Assert.assertNull; 11 | 12 | /** 13 | * 14 | * 15 | * @author Julien Viet 16 | */ 17 | public class TestSuiteNoEventLoopWithVertxTest extends TestSuiteTestBase { 18 | 19 | private Vertx vertx; 20 | 21 | public TestSuiteNoEventLoopWithVertxTest() { 22 | super(); 23 | getRunner = (suite) -> suite.runner().setUseEventLoop(false).setVertx(vertx); 24 | run = runner -> { 25 | assertNull(Vertx.currentContext()); 26 | runner.run(); 27 | }; 28 | operateOnAsync = (async, action) -> { 29 | assertNull(Vertx.currentContext()); 30 | action.accept(async); 31 | }; 32 | } 33 | 34 | @Override 35 | protected boolean checkTest(TestContext test) { 36 | return Vertx.currentContext() == null; 37 | } 38 | 39 | @Before 40 | public void setUp() { 41 | vertx = Vertx.vertx(); 42 | } 43 | 44 | @After 45 | public void tearDown() throws Exception { 46 | CountDownLatch latch = new CountDownLatch(1); 47 | if (vertx != null) { 48 | vertx.close().onComplete(ar -> { 49 | latch.countDown(); 50 | }); 51 | vertx = null; 52 | latch.await(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestSuiteObjectTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.ext.unit.TestContext; 4 | import io.vertx.ext.unit.TestSuite; 5 | import io.vertx.ext.unit.impl.TestSuiteImpl; 6 | 7 | import java.io.IOException; 8 | import java.util.concurrent.atomic.AtomicInteger; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * @author Julien Viet 14 | */ 15 | public class TestSuiteObjectTest { 16 | 17 | public class MySuite1 { 18 | AtomicInteger count = new AtomicInteger(); 19 | public void testSomething(TestContext test) { 20 | count.incrementAndGet(); 21 | } 22 | } 23 | 24 | @org.junit.Test 25 | public void runTest() { 26 | MySuite1 obj = new MySuite1(); 27 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(obj); 28 | TestReporter reporter = new TestReporter(); 29 | suite.runner().setReporter(reporter).run(); 30 | reporter.await(); 31 | assertEquals(1, obj.count.get()); 32 | assertEquals(MySuite1.class.getName(), reporter.name.get()); 33 | assertEquals(0, reporter.exceptions.size()); 34 | assertEquals(1, reporter.results.size()); 35 | assertEquals("testSomething", reporter.results.get(0).name()); 36 | assertTrue(reporter.results.get(0).succeeded()); 37 | } 38 | 39 | public class MySuite2 { 40 | public void testSomething(TestContext test) { 41 | test.fail("the_message"); 42 | } 43 | } 44 | 45 | @org.junit.Test 46 | public void runTestFailure() { 47 | MySuite2 obj = new MySuite2(); 48 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(obj); 49 | TestReporter reporter = new TestReporter(); 50 | suite.runner().setReporter(reporter).run(); 51 | reporter.await(); 52 | assertEquals(MySuite2.class.getName(), reporter.name.get()); 53 | assertEquals(0, reporter.exceptions.size()); 54 | assertEquals(1, reporter.results.size()); 55 | assertEquals("testSomething", reporter.results.get(0).name()); 56 | assertTrue(reporter.results.get(0).failed()); 57 | assertEquals("the_message", reporter.results.get(0).failure().message()); 58 | assertTrue(reporter.results.get(0).failure().cause() instanceof AssertionError); 59 | } 60 | 61 | public class MySuite3 { 62 | final Throwable error; 63 | public MySuite3(Throwable error) { 64 | this.error = error; 65 | } 66 | public void testSomething(TestContext test) throws Throwable { 67 | throw error; 68 | } 69 | } 70 | 71 | @org.junit.Test 72 | public void runTestError() { 73 | Throwable[] errors = {new IOException(),new RuntimeException(),new AssertionError()}; 74 | for (Throwable error : errors) { 75 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(new MySuite3(error)); 76 | TestReporter reporter = new TestReporter(); 77 | suite.runner().setReporter(reporter).run(); 78 | reporter.await(); 79 | assertEquals(MySuite3.class.getName(), reporter.name.get()); 80 | assertEquals(0, reporter.exceptions.size()); 81 | assertEquals(1, reporter.results.size()); 82 | assertEquals("testSomething", reporter.results.get(0).name()); 83 | assertTrue(reporter.results.get(0).failed()); 84 | assertSame(error, reporter.results.get(0).failure().cause()); 85 | } 86 | } 87 | 88 | public class MySuite4 { 89 | AtomicInteger count = new AtomicInteger(); 90 | public void before(TestContext test) { 91 | count.compareAndSet(0, 1); 92 | } 93 | public void testSomething(TestContext test) { 94 | count.compareAndSet(1, 2); 95 | } 96 | } 97 | 98 | @org.junit.Test 99 | public void runBefore() { 100 | MySuite4 obj = new MySuite4(); 101 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(obj); 102 | TestReporter reporter = new TestReporter(); 103 | suite.runner().setReporter(reporter).run(); 104 | reporter.await(); 105 | assertEquals(2, obj.count.get()); 106 | } 107 | 108 | public class MySuite5 { 109 | AtomicInteger count = new AtomicInteger(); 110 | public void after(TestContext test) { 111 | count.compareAndSet(1, 2); 112 | } 113 | public void testSomething(TestContext test) { 114 | count.compareAndSet(0, 1); 115 | } 116 | } 117 | 118 | @org.junit.Test 119 | public void runAfter() { 120 | MySuite5 obj = new MySuite5(); 121 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(obj); 122 | TestReporter reporter = new TestReporter(); 123 | suite.runner().setReporter(reporter).run(); 124 | reporter.await(); 125 | assertEquals(2, obj.count.get()); 126 | } 127 | 128 | public class MySuite6 { 129 | AtomicInteger count = new AtomicInteger(); 130 | public void beforeEach(TestContext test) { 131 | count.compareAndSet(0, 1); 132 | } 133 | public void testSomething(TestContext test) { 134 | count.compareAndSet(1, 2); 135 | } 136 | } 137 | 138 | @org.junit.Test 139 | public void runBeforeEach() { 140 | MySuite6 obj = new MySuite6(); 141 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(obj); 142 | TestReporter reporter = new TestReporter(); 143 | suite.runner().setReporter(reporter).run(); 144 | reporter.await(); 145 | assertEquals(2, obj.count.get()); 146 | } 147 | 148 | public class MySuite7 { 149 | AtomicInteger count = new AtomicInteger(); 150 | public void afterEach(TestContext test) { 151 | count.compareAndSet(1, 2); 152 | } 153 | public void testSomething(TestContext test) { 154 | count.compareAndSet(0, 1); 155 | } 156 | } 157 | 158 | @org.junit.Test 159 | public void runAfterEach() { 160 | MySuite7 obj = new MySuite7(); 161 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create(obj); 162 | TestReporter reporter = new TestReporter(); 163 | suite.runner().setReporter(reporter).run(); 164 | reporter.await(); 165 | assertEquals(2, obj.count.get()); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestSuiteUseContextualEventLoopTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.TestContext; 5 | import io.vertx.ext.unit.impl.TestSuiteImpl; 6 | import org.junit.After; 7 | import org.junit.Before; 8 | 9 | import java.util.concurrent.CountDownLatch; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * @author Julien Viet 16 | */ 17 | public class TestSuiteUseContextualEventLoopTest extends TestSuiteTestBase { 18 | 19 | private Vertx vertx; 20 | 21 | public TestSuiteUseContextualEventLoopTest() { 22 | super(); 23 | getRunner = TestSuiteImpl::runner; 24 | run = (runner) -> { 25 | assertNull(Vertx.currentContext()); 26 | vertx.runOnContext(v -> runner.setUseEventLoop(true).run()); 27 | }; 28 | operateOnAsync = (async, action) -> { 29 | CountDownLatch latch = new CountDownLatch(1); 30 | assertNull(Vertx.currentContext()); 31 | vertx.runOnContext(v -> { 32 | action.accept(async); 33 | latch.countDown(); 34 | }); 35 | try { 36 | latch.await(10, TimeUnit.SECONDS); 37 | } catch (InterruptedException e) { 38 | Thread.currentThread().interrupt(); 39 | } 40 | }; 41 | } 42 | 43 | @Override 44 | protected boolean checkTest(TestContext test) { 45 | return Vertx.currentContext() != null; 46 | } 47 | 48 | @Before 49 | public void setUp() { 50 | vertx = Vertx.vertx(); 51 | } 52 | 53 | @After 54 | public void tearDown() throws Exception { 55 | CountDownLatch latch = new CountDownLatch(1); 56 | if (vertx != null) { 57 | vertx.close().onComplete(ar -> { 58 | latch.countDown(); 59 | }); 60 | vertx = null; 61 | latch.await(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/TestSuiteUseVertxEventLoopTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.ext.unit.TestContext; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | 8 | import java.util.concurrent.CountDownLatch; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * 14 | * 15 | * @author Julien Viet 16 | */ 17 | public class TestSuiteUseVertxEventLoopTest extends TestSuiteTestBase { 18 | 19 | private Vertx vertx; 20 | 21 | public TestSuiteUseVertxEventLoopTest() { 22 | super(); 23 | getRunner = (suite) -> suite.runner().setUseEventLoop(true).setVertx(vertx); 24 | run = runner -> { 25 | assertNull(Vertx.currentContext()); 26 | runner.run(); 27 | }; 28 | operateOnAsync = (async, action) -> { 29 | assertNull(Vertx.currentContext()); 30 | action.accept(async); 31 | }; 32 | } 33 | 34 | @Override 35 | protected boolean checkTest(TestContext test) { 36 | return Vertx.currentContext() != null; 37 | } 38 | 39 | @Before 40 | public void setUp() { 41 | vertx = Vertx.vertx(); 42 | } 43 | 44 | @After 45 | public void tearDown() throws Exception { 46 | CountDownLatch latch = new CountDownLatch(1); 47 | if (vertx != null) { 48 | vertx.close().onComplete(ar -> { 49 | latch.countDown(); 50 | }); 51 | vertx = null; 52 | latch.await(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/unit/tests/UseEventLoopTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.ext.unit.tests; 2 | 3 | import io.vertx.core.Context; 4 | import io.vertx.core.Vertx; 5 | import io.vertx.ext.unit.TestSuite; 6 | import io.vertx.ext.unit.impl.TestSuiteImpl; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | import static org.junit.Assert.*; 14 | 15 | /** 16 | * @author Julien Viet 17 | */ 18 | public class UseEventLoopTest { 19 | 20 | @org.junit.Test 21 | public void testWithoutVertx() { 22 | List contexts = Collections.synchronizedList(new ArrayList<>()); 23 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create("my_suite").test("my_test", context -> { 24 | contexts.add(Vertx.currentContext()); 25 | }); 26 | try { 27 | suite.runner().setReporter(new TestReporter()).setUseEventLoop(true).run(); 28 | fail(); 29 | } catch (IllegalStateException expected) { 30 | } 31 | assertEquals(Collections.emptyList(), contexts); 32 | TestReporter reporter = new TestReporter(); 33 | suite.runner().setReporter(reporter).setUseEventLoop(false).run(); 34 | reporter.await(); 35 | assertEquals(0, reporter.exceptions.size()); 36 | assertEquals(1, reporter.results.size()); 37 | assertTrue(reporter.results.get(0).succeeded()); 38 | assertEquals(Collections.singletonList(null), contexts); 39 | reporter = new TestReporter(); 40 | suite.runner().setReporter(reporter).setUseEventLoop(null).run(); 41 | reporter.await(); 42 | assertEquals(0, reporter.exceptions.size()); 43 | assertEquals(1, reporter.results.size()); 44 | assertTrue(reporter.results.get(0).succeeded()); 45 | assertEquals(Arrays.asList(null, null), contexts); 46 | } 47 | 48 | @org.junit.Test 49 | public void testWitVertx() { 50 | Vertx vertx = Vertx.vertx(); 51 | List contexts = Collections.synchronizedList(new ArrayList<>()); 52 | TestSuiteImpl suite = (TestSuiteImpl) TestSuite.create("my_suite").test("my_test", context -> { 53 | contexts.add(Vertx.currentContext()); 54 | }); 55 | TestReporter reporter = new TestReporter(); 56 | suite.runner().setReporter(reporter).setUseEventLoop(true).setVertx(vertx).run(); 57 | reporter.await(); 58 | assertEquals(0, reporter.exceptions.size()); 59 | assertEquals(1, reporter.results.size()); 60 | assertTrue(reporter.results.get(0).succeeded()); 61 | assertEquals(1, contexts.size()); 62 | assertNotNull(contexts.get(0)); 63 | reporter = new TestReporter(); 64 | suite.runner().setReporter(reporter).setUseEventLoop(false).setVertx(vertx).run(); 65 | reporter.await(); 66 | assertEquals(0, reporter.exceptions.size()); 67 | assertEquals(1, reporter.results.size()); 68 | assertTrue(reporter.results.get(0).succeeded()); 69 | assertEquals(2, contexts.size()); 70 | assertNull(contexts.get(1)); 71 | reporter = new TestReporter(); 72 | suite.runner().setReporter(reporter).setUseEventLoop(null).setVertx(vertx).run(); 73 | reporter.await(); 74 | assertEquals(0, reporter.exceptions.size()); 75 | assertEquals(1, reporter.results.size()); 76 | assertTrue(reporter.results.get(0).succeeded()); 77 | assertEquals(3, contexts.size()); 78 | assertNotNull(contexts.get(2)); 79 | vertx.close(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/module-info.java: -------------------------------------------------------------------------------- 1 | open module io.vertx.testing.unit.tests { 2 | requires io.vertx.core; 3 | requires io.vertx.core.tests; 4 | requires io.vertx.testing.unit; 5 | requires java.logging; 6 | requires java.xml; 7 | requires junit; 8 | requires hamcrest.core; 9 | } 10 | --------------------------------------------------------------------------------