├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── dependabot.yml ├── issue_template.md └── workflows │ ├── codeql-analysis.yml │ ├── release_on_pr.yml │ └── tests.yml ├── .gitignore ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── build └── make.go ├── checkstyle.xml ├── gauge-java.go ├── genproto.sh ├── go.mod ├── java.json ├── notice.md ├── pom.xml └── src ├── META-INF └── MANIFEST.MF ├── main └── java │ ├── com │ └── thoughtworks │ │ └── gauge │ │ ├── AfterClassSteps.java │ │ ├── AfterScenario.java │ │ ├── AfterSpec.java │ │ ├── AfterStep.java │ │ ├── AfterSuite.java │ │ ├── BeforeClassSteps.java │ │ ├── BeforeScenario.java │ │ ├── BeforeSpec.java │ │ ├── BeforeStep.java │ │ ├── BeforeSuite.java │ │ ├── ClassInitializer.java │ │ ├── ClassInstanceManager.java │ │ ├── ClasspathHelper.java │ │ ├── ContinueOnFailure.java │ │ ├── DefaultClassInitializer.java │ │ ├── ExecutionContext.java │ │ ├── FileHelper.java │ │ ├── Gauge.java │ │ ├── GaugeConstant.java │ │ ├── GaugeRuntime.java │ │ ├── Logger.java │ │ ├── MessageCollector.java │ │ ├── Operator.java │ │ ├── RowSizeMismatchException.java │ │ ├── RunnerServiceHandler.java │ │ ├── Scenario.java │ │ ├── ScreenshotCollector.java │ │ ├── SkipScenarioException.java │ │ ├── Specification.java │ │ ├── Step.java │ │ ├── StepDetails.java │ │ ├── StepRegistryEntry.java │ │ ├── StepValue.java │ │ ├── Table.java │ │ ├── TableCell.java │ │ ├── TableRow.java │ │ ├── Util.java │ │ ├── command │ │ ├── GaugeCommandFactory.java │ │ ├── GaugeJavaCommand.java │ │ ├── SetupCommand.java │ │ └── StartCommand.java │ │ ├── connection │ │ ├── MessageProcessorFactory.java │ │ └── StubImplementationCodeProcessor.java │ │ ├── datastore │ │ ├── DataStore.java │ │ ├── DataStoreFactory.java │ │ ├── DataStoreInitializer.java │ │ ├── ScenarioDataStore.java │ │ ├── SpecDataStore.java │ │ └── SuiteDataStore.java │ │ ├── execution │ │ ├── AbstractExecutionStage.java │ │ ├── ExecutionInfoMapper.java │ │ ├── ExecutionPipeline.java │ │ ├── ExecutionStage.java │ │ ├── ExecutorPool.java │ │ ├── HookExecutionStage.java │ │ ├── HooksExecutor.java │ │ ├── MethodExecutor.java │ │ ├── StepExecutionStage.java │ │ └── parameters │ │ │ ├── DynamicParametersReplacer.java │ │ │ ├── ParametersExtractor.java │ │ │ ├── ParsingException.java │ │ │ └── parsers │ │ │ ├── base │ │ │ ├── CustomParameterParser.java │ │ │ ├── ParameterParser.java │ │ │ └── ParameterParsingChain.java │ │ │ ├── converters │ │ │ ├── StringToPrimitiveConverter.java │ │ │ └── TableConverter.java │ │ │ └── types │ │ │ ├── EnumParameterParser.java │ │ │ ├── PrimitiveParameterParser.java │ │ │ ├── PrimitivesConverter.java │ │ │ └── TableParameterParser.java │ │ ├── hook │ │ └── Hook.java │ │ ├── processor │ │ ├── CacheFileRequestProcessor.java │ │ ├── ClearObjectCache.java │ │ ├── DefaultMessageProcessor.java │ │ ├── ExecuteStepProcessor.java │ │ ├── IMessageProcessor.java │ │ ├── KillProcessProcessor.java │ │ ├── MethodExecutionMessageProcessor.java │ │ ├── RefactorRequestProcessor.java │ │ ├── ScenarioExecutionEndingProcessor.java │ │ ├── ScenarioExecutionStartingProcessor.java │ │ ├── SpecExecutionEndingProcessor.java │ │ ├── SpecExecutionStartingProcessor.java │ │ ├── StepExecutionEndingProcessor.java │ │ ├── StepExecutionStartingProcessor.java │ │ ├── StepNameRequestProcessor.java │ │ ├── StepNamesRequestProcessor.java │ │ ├── StepPositionsRequestProcessor.java │ │ ├── SuiteExecutionEndingProcessor.java │ │ ├── SuiteExecutionStartingProcessor.java │ │ └── ValidateStepProcessor.java │ │ ├── refactor │ │ ├── Diff.java │ │ ├── FileModifier.java │ │ ├── JavaParseWorker.java │ │ ├── JavaRefactoring.java │ │ ├── JavaRefactoringElement.java │ │ ├── RefactoringException.java │ │ ├── RefactoringMethodVisitor.java │ │ └── RefactoringResult.java │ │ ├── registry │ │ ├── ClassInitializerRegistry.java │ │ ├── HooksRegistry.java │ │ └── StepRegistry.java │ │ ├── scan │ │ ├── ClasspathScanner.java │ │ ├── CustomClassInitializerScanner.java │ │ ├── HooksScanner.java │ │ ├── IScanner.java │ │ ├── RegistryMethodVisitor.java │ │ ├── StaticScanner.java │ │ ├── StepsScanner.java │ │ └── StepsUtil.java │ │ ├── screenshot │ │ ├── CustomScreenshot.java │ │ ├── CustomScreenshotScanner.java │ │ ├── CustomScreenshotWriter.java │ │ ├── ICustomScreenshotGrabber.java │ │ └── ScreenshotFactory.java │ │ └── tag │ │ ├── AndMatcher.java │ │ ├── OrMatcher.java │ │ ├── SimpleTagMatcher.java │ │ └── TagMatcher.java │ └── gauge │ └── messages │ ├── Messages.java │ ├── RunnerGrpc.java │ ├── Services.java │ └── Spec.java └── test ├── java └── com │ └── thoughtworks │ └── gauge │ ├── ClassInstanceManagerTest.java │ ├── ExecutionContextTest.java │ ├── FileHelperTest.java │ ├── MessageCollectorTest.java │ ├── ScreenshotCollectorTest.java │ ├── TableRowTest.java │ ├── TableTest.java │ ├── TestStepImplClass.java │ ├── UtilTest.java │ ├── execution │ ├── AbstractExecutionStageTest.java │ ├── ExecutionInfoMapperTest.java │ ├── ExecutionPipelineTest.java │ ├── HooksExecutorTest.java │ ├── ParameterTestHelpers.java │ ├── StepExecutionStageTest.java │ └── parameters │ │ ├── DynamicParametersReplacerTest.java │ │ ├── ParametersExtractorTest.java │ │ └── parsers │ │ └── types │ │ ├── EnumParameterParserTest.java │ │ ├── PrimitiveParameterParserTest.java │ │ └── TableParameterParserTest.java │ ├── hook │ └── HookTest.java │ ├── processor │ ├── CacheFileRequestProcessorTest.java │ ├── DefaultMessageProcessorTest.java │ ├── StepNameRequestProcessorTest.java │ ├── StepPositionsRequestProcessorTest.java │ ├── StubImplementationCodeProcessorTest.java │ └── ValidateStepProcessorTest.java │ ├── refactor │ └── JavaRefactoringTest.java │ ├── registry │ ├── HooksRegistryTest.java │ └── StepRegistryTest.java │ ├── scan │ ├── StaticScannerTest.java │ └── StepsScannerTest.java │ ├── tag │ ├── AndMatcherTest.java │ └── OrMatcherTest.java │ └── test │ ├── AnEnum.java │ └── TestValues.java └── resources └── test └── files ├── Empty.java ├── foo.java ├── fooAliases.java ├── formatted ├── StepImpl.java └── StepImplWithComments.java └── unformatted └── UnFormattedStepImpl.java /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps (or project) to reproduce the behavior: 15 | 1. Initialise a gauge project 16 | 2. Use the following piece of code 17 | 3. Run the gauge command 18 | 5. See error 19 | 20 | ``` 21 | $ gauge init java 22 | $ gauge run specs 23 | ``` 24 | 25 | **Logs** 26 | 27 | ``` 28 | Paste any log or error messages here 29 | ``` 30 | 31 | **Expected behavior** 32 | A clear and concise description of what you expected to happen. 33 | 34 | **Screenshots** 35 | If applicable, add screenshots to help explain your problem. 36 | 37 | 38 | **Versions:** 39 | - OS [e.g. 10.15.6 (19G2021) please be specific ] 40 | - Java version 41 | - Maven/Gradle version 42 | 43 | 44 | 45 | ``` 46 | gauge -v 47 | ``` 48 | 49 | 50 | **Additional context** 51 | Add any other context about the problem here. 52 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Gauge Community Support 4 | url: https://spectrum.chat/gauge 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gomod 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | allow: 8 | - dependency-type: all 9 | groups: 10 | go: 11 | patterns: 12 | - "*" 13 | - package-ecosystem: "github-actions" 14 | directory: "/" 15 | schedule: 16 | interval: monthly 17 | groups: 18 | github-actions: 19 | patterns: 20 | - "*" 21 | - package-ecosystem: maven 22 | directory: "/" 23 | schedule: 24 | interval: monthly 25 | groups: 26 | maven-dependencies: 27 | patterns: 28 | - "*" 29 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ### Expected behavior 12 | Tell us what should happen 13 | 14 | ### Actual behavior 15 | Tell us what happens instead 16 | 17 | ### Steps to reproduce 18 | 1. 19 | 2. 20 | 3. 21 | 22 | ### Gauge version 23 | ``` 24 | Run gauge -v on your system and paste the results here. 25 | ``` 26 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '16 22 * * 2' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'go', 'java' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v4 42 | 43 | - name: Set up Go 44 | uses: actions/setup-go@v5 45 | if: matrix.language == 'go' 46 | with: 47 | check-latest: true 48 | go-version-file: 'go.mod' 49 | 50 | # Initializes the CodeQL tools for scanning. 51 | - name: Initialize CodeQL 52 | uses: github/codeql-action/init@v3 53 | with: 54 | languages: ${{ matrix.language }} 55 | # If you wish to specify custom queries, you can do so here or in a config file. 56 | # By default, queries listed here will override any specified in a config file. 57 | # Prefix the list here with "+" to use these queries and those in the config file. 58 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 59 | 60 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 61 | # If this step fails, then you should remove it and run the build manually (see below) 62 | - name: Autobuild 63 | uses: github/codeql-action/autobuild@v3 64 | 65 | # ℹ️ Command-line programs to run using the OS shell. 66 | # 📚 https://git.io/JvXDl 67 | 68 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 69 | # and modify them (or add more) to build your code if your project 70 | # uses a compiled language 71 | 72 | #- run: | 73 | # make bootstrap 74 | # make release 75 | 76 | - name: Perform CodeQL Analysis 77 | uses: github/codeql-action/analyze@v3 78 | -------------------------------------------------------------------------------- /.github/workflows/release_on_pr.yml: -------------------------------------------------------------------------------- 1 | name: Release on PR Merge 2 | 3 | on: deployment 4 | 5 | jobs: 6 | deploy: 7 | if: github.event.deployment.environment == 'production' 8 | runs-on: ubuntu-latest 9 | env: 10 | MAVEN_GPG_SIGN_KEY: '${{ secrets.MAVEN_GPG_SIGN_KEY }}' 11 | username: '${{ secrets.maven_deploy_username }}' 12 | password: '${{ secrets.maven_deploy_password }}' 13 | passphrase: '${{ secrets.gpg_passphrase }}' 14 | GITHUB_TOKEN: '${{ secrets.GAUGEBOT_GITHUB_TOKEN }}' 15 | CI: true 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Set up JDK 20 | uses: actions/setup-java@v4 21 | with: 22 | distribution: 'temurin' 23 | java-version: '21' 24 | 25 | - name: Set up Maven 26 | uses: stCarolas/setup-maven@v5 27 | with: 28 | maven-version: 3.9.9 29 | 30 | - name: Setup maven 31 | run: | 32 | echo -e "$MAVEN_GPG_SIGN_KEY" | gpg --import --batch - 33 | gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys $gpgkey 34 | rm -rf $HOME/.m2 35 | mkdir -p $HOME/.m2 36 | echo -e "\n\n\ncentral\n$username\n$password\n\n\n" > $HOME/.m2/settings.xml 37 | 38 | - name: Setup git 39 | run: | 40 | git config --global user.name "$(git --no-pager log --format=format:'%an' -n 1)" 41 | git config --global user.email "$(git --no-pager log --format=format:'%ae' -n 1)" 42 | 43 | - name: Set up Go 44 | uses: actions/setup-go@v5 45 | with: 46 | check-latest: true 47 | go-version-file: 'go.mod' 48 | 49 | - name: Build artifacts 50 | run: go run build/make.go --all-platforms && go run build/make.go --all-platforms --distro 51 | shell: bash 52 | 53 | - name: Deploy on github 54 | run: | 55 | if [ -z "$version" ]; then 56 | version=$(cd deploy && ls gauge-java* | head -1 | sed "s/\.[^\.]*$//" | sed "s/gauge-java-//" | sed "s/-[a-z]*\.[a-z0-9_]*$//") 57 | fi 58 | echo "VERSION=$version" >> $GITHUB_ENV 59 | 60 | echo "---------------------------" 61 | echo "Updating release v$version" 62 | echo "---------------------------" 63 | echo -e "Gauge Java v$version\n\n" >desc.txt 64 | release_description=$(ruby -e "$(curl -sSfL https://github.com/getgauge/gauge/raw/master/build/create_release_text.rb)" getgauge gauge-java) 65 | echo "$release_description" >> desc.txt 66 | gh release create --title "Gauge Java v${version}" --notes-file ./desc.txt "v${version}" deploy/gauge-java* 67 | 68 | - name: Deploy on maven central 69 | run: | 70 | mvn -q clean deploy -Dgpg.passphrase=$passphrase 71 | 72 | 73 | - name: Update metadata in gauge-repository 74 | run: | 75 | git clone https://github.com/getgauge/gauge-repository.git 76 | cd gauge-repository 77 | python update_metadata.py java $VERSION 78 | commit_message=$(echo -e "Update java to v$VERSION") 79 | git commit -am "$commit_message" 80 | git push "https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/getgauge/gauge-repository.git" master 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | 8 | libs 9 | .idea/workspace.xml 10 | 11 | gauge-java 12 | tags 13 | src/src 14 | *.exe 15 | target 16 | out 17 | .idea/ 18 | 19 | #go deps 20 | src/github.com 21 | tmp 22 | deploy 23 | artifacts 24 | *.iml 25 | 26 | bin 27 | 28 | .DS_Store 29 | .classpath 30 | .project 31 | .settings/ 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gauge-proto"] 2 | path = gauge-proto 3 | url = https://github.com/getgauge/gauge-proto 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to Gauge 2 | 3 | Contributions to Gauge are welcome and appreciated. Please read this document to understand the process for contributing. 4 | 5 | ## Gauge Core v/s Plugins 6 | 7 | Gauge Core is a project that has features that would reflect across all Gauge use cases. These features are typically agnostic of the user's choice of implementation language. 8 | 9 | Plugins are meant to do something specific. These could be adding support for a new language, or have a new report etc. 10 | 11 | So, depending on where you see your contribution fit, please focus on the respective repository. 12 | 13 | ## Contribution process 14 | 15 | Please read about the Contribution Process [here](https://github.com/getgauge/gauge/blob/master/CONTRIBUTING.md), if you are happy please sign the [Contributor's License Agreement](https://gauge-bot.herokuapp.com/cla/). 16 | 17 | ## How can I contribute 18 | 19 | Contributions can be of many forms: 20 | 21 | - Open an issue, or participate in an existing one. 22 | - Write some code, and send us a pull request. 23 | - Enhance the documentation 24 | - Participate in design discussions on Google Groups 25 | 26 | If you need help in getting started with contribution, feel free to reach out on the [Google Groups](https://groups.google.com/forum/#!forum/getgauge) or [Gitter](https://gitter.im/getgauge/chat). 27 | 28 | 29 | ## Bump up gauge-java version 30 | 31 | * Update the version in `java.json` file. 32 | 33 | Ex: 34 | ```diff 35 | "id": "java", 36 | - "version": "0.7.5", 37 | + "version": "0.7.6", 38 | ``` 39 | 40 | * Update the productVersion property in `pom.xml`. 41 | 42 | Ex: 43 | 44 | 45 | * Update the version in `pom.xml`. 46 | 47 | Ex: 48 | 49 | ```diff 50 | gauge-java 51 | - 0.11.3 52 | + 0.11.4 53 | Java plugin for Gauge 54 | ``` 55 | -------------------------------------------------------------------------------- /genproto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # *---------------------------------------------------------------- 4 | # * Copyright (c) ThoughtWorks, Inc. 5 | # * Licensed under the Apache License, Version 2.0 6 | # * See LICENSE.txt in the project root for license information. 7 | # *----------------------------------------------------------------*/ 8 | 9 | #Using protoc version 2.6.1 10 | for filename in gauge-proto/*.proto; do 11 | newName="$filename-bkp" 12 | sed 's/option java_package = "com.thoughtworks.gauge";/option java_package = "gauge.messages";/' "$filename" > "$newName" 13 | rm "$filename" 14 | cp "$newName" "$filename" 15 | rm "$newName" 16 | done 17 | mvn protobuf:compile-custom protobuf:compile 18 | 19 | 20 | cp target/generated-sources/protobuf/java/gauge/messages/Messages.java src/main/java/gauge/messages 21 | cp target/generated-sources/protobuf/java/gauge/messages/Spec.java src/main/java/gauge/messages 22 | cp target/generated-sources/protobuf/java/gauge/messages/Services.java src/main/java/gauge/messages 23 | 24 | cp target/generated-sources/protobuf/grpc-java/gauge/messages/RunnerGrpc.java src/main/java/gauge/messages 25 | 26 | cd gauge-proto && git checkout . && cd .. 27 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/getgauge/gauge-java 2 | 3 | go 1.24 4 | -------------------------------------------------------------------------------- /java.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "java", 3 | "version": "0.12.0", 4 | "description": "Java support for gauge", 5 | "install": { 6 | "windows": [], 7 | "linux": [], 8 | "darwin": [] 9 | }, 10 | "run": { 11 | "windows": [ 12 | "gauge-java", 13 | "--start" 14 | ], 15 | "linux": [ 16 | "gauge-java", 17 | "--start" 18 | ], 19 | "darwin": [ 20 | "gauge-java", 21 | "--start" 22 | ] 23 | }, 24 | "init": { 25 | "windows": [ 26 | "gauge-java", 27 | "--init" 28 | ], 29 | "linux": [ 30 | "gauge-java", 31 | "--init" 32 | ], 33 | "darwin": [ 34 | "gauge-java", 35 | "--init" 36 | ] 37 | }, 38 | "lib": "libs", 39 | "multithreaded": true, 40 | "gaugeVersionSupport": { 41 | "minimum": "1.6.7", 42 | "maximum": "" 43 | }, 44 | "lspLangId": "java", 45 | "gRPCSupport": true 46 | } 47 | -------------------------------------------------------------------------------- /notice.md: -------------------------------------------------------------------------------- 1 | 2 | | Dependency Name | Copyright Information | Description | Repo URL | License Type | License URL | 3 | |-----------------|-----------------------|-------------|----------|--------------|-------------| 4 | |guava|Copyright (C) 2012 The Guava Authors|"Google Core Libraries for Java 6+|https://code.google.com/p/guava-libraries/|Apache 2.0|http://www.apache.org/licenses/LICENSE-2.0| 5 | |javassist|Copyright (C) 1999-2015 Shigeru Chiba.|Java bytecode engineering toolkit|http://www.javassist.org/ |Triple License: MPL 1.1, LGPL 2.1, Apache 2.0|| 6 | |reflections|Copyright (C) 2004 Sam Hocevar|Java runtime metadata analysis|https://github.com/ronmamo/reflections|wtfpl version 2 |https://code.google.com/p/reflections/source/browse/trunk/COPYING.txt| 7 | |protobuf-java| Copyright 2008 Google Inc.|Java Protocol Buffers runtime library|https://github.com/google/protobuf/tree/master/java|BSD 2 clause license|http://www.opensource.org/licenses/bsd-license.php| 8 | -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/AfterClassSteps.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, will be executed after every step in that particular class. 15 | *

16 | * If there is more than one method annotated with @AfterClassSteps the order of execution is as follows: 17 | *

21 | * If there is more than one hook of these categories, they are executed in reverse alphabetical order based on method names. 22 | *

23 | */ 24 | @Target(ElementType.METHOD) 25 | @Deprecated 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface AfterClassSteps { 28 | 29 | /** 30 | * @return Array of tags to filter which steps the hook executes after based on the tags in the current scenario and spec. 31 | */ 32 | String[] tags() default {}; 33 | 34 | /** 35 | * @return OR: if hook should execute for the current execution context (spec and scenario) containing any of the tags provided 36 | * AND: if hook should execute for the current execution context (spec and scenario) containing all of the tags provided 37 | * Default is AND 38 | */ 39 | Operator tagAggregation() default Operator.AND; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/AfterScenario.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute after every scenario execution completes. 15 | * The scenario can be filtered by passing additional attributes. 16 | *

17 | * If there is more than one method annotated with @AfterScenario, the order of execution is as follows: 18 | *

22 | * If there is more than one hook of these categories, they are executed in reverse alphabetical order based on method names. 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | public @interface AfterScenario { 27 | 28 | /** 29 | * @return Array of tags to filter which scenarios the hook runs after. 30 | */ 31 | String[] tags() default {}; 32 | 33 | /** 34 | * @return OR: if hook should run for a scenario containing any of the tags provided 35 | * AND: if hook should run for a scenario containing all of the tags provided 36 | * Default is AND 37 | */ 38 | Operator tagAggregation() default Operator.AND; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/AfterSpec.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute after every Specification execution completes. 15 | * The specification can be filtered by passing additional attributes. 16 | *

17 | * If there is more than one method annotated with @AfterSpec, the order of execution is as follows: 18 | *

22 | * If there is more than one hook of these categories, they are executed in reverse alphabetical order based on method names. 23 | *

24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface AfterSpec { 28 | 29 | /** 30 | * @return Array of tags to filter which specifications the hook runs after. 31 | */ 32 | String[] tags() default {}; 33 | 34 | /** 35 | * @return OR: if hook should run for a specification containing any of the tags provided 36 | * AND: if hook should run for a specification containing all of the tags provided 37 | * Default is AND 38 | */ 39 | Operator tagAggregation() default Operator.AND; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/AfterStep.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute after every Step execution completes. 15 | * The steps for which the hook executes can be filtered by passing additional attributes. 16 | *

17 | * If there is more than one method annotated with @AfterStep, the order of execution is as follows: 18 | *

22 | * If there is more than one hook of these categories, they are executed in reverse alphabetical order based on method names. 23 | *

24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface AfterStep { 28 | 29 | /** 30 | * @return Array of tags to filter which steps the hook runs after. 31 | */ 32 | String[] tags() default {}; 33 | 34 | /** 35 | * @return OR: if hook should execute for the current execution context (spec and scenario) containing any of the tags provided 36 | * AND: if hook should execute for the current execution context (spec and scenario) containing all of the tags provided 37 | * Default is AND 38 | */ 39 | Operator tagAggregation() default Operator.AND; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/AfterSuite.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute after the entire suite (all specs) execution completes. 15 |

If there is more than one method annotated with @AfterSuite, they are executed in reverse alphabetical order of their method names.

16 | */ 17 | @Target(ElementType.METHOD) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface AfterSuite { 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/BeforeClassSteps.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, will execute before every step in that particular class. 15 | *

16 | * If there is more than one method annotated with @BeforeClassSteps the order of execution is as follows: 17 | *

21 | * If there is more than one hook of these categories, they are alphabetically sorted based on method names. 22 | *

23 | */ 24 | @Target(ElementType.METHOD) 25 | @Deprecated 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface BeforeClassSteps { 28 | 29 | /** 30 | * @return Array of tags to filter which steps the hook executes before based on the tags in the current scenario and spec. 31 | */ 32 | String[] tags() default {}; 33 | 34 | /** 35 | * @return OR: if hook should execute for the current execution context (spec and scenario) containing any of the tags provided 36 | * AND: if hook should execute for the current execution context (spec and scenario) containing all of the tags provided 37 | * Default is AND 38 | */ 39 | Operator tagAggregation() default Operator.AND; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/BeforeScenario.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute before every scenario execution completes. 15 | * The scenario can be filtered by passing additional attributes. 16 | *

17 | * If there is more than one method annotated with @BeforeScenario, the order of execution is as follows: 18 | *

22 | * If there is more than one hook of these categories, they are executed in alphabetical order based on method names. 23 | *

24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface BeforeScenario { 28 | 29 | /** 30 | * @return Array of tags to filter which scenarios the hook runs before. 31 | */ 32 | String[] tags() default {}; 33 | 34 | /** 35 | * @return OR: if hook should run for a scenario containing any of the tags provided 36 | * AND: if hook should run for a scenario containing all of the tags provided 37 | * Default is AND 38 | */ 39 | Operator tagAggregation() default Operator.AND; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/BeforeSpec.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute before every Specification execution completes. 15 | * The specification can be filtered by passing additional attributes. 16 | *

If there is more than one method annotated with @BeforeSpec, the order of execution is as follows: 17 | *

21 | * If there is more than one hook of these categories, they are executed in alphabetical order based on method names. 22 | *

23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | public @interface BeforeSpec { 27 | 28 | /** 29 | * @return Array of tags to filter which specifications the hook runs before. 30 | */ 31 | String[] tags() default {}; 32 | 33 | /** 34 | * @return OR: if hook should run for a specification containing any of the tags provided 35 | * AND: if hook should run for a specification containing all of the tags provided 36 | * Default is AND 37 | */ 38 | Operator tagAggregation() default Operator.AND; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/BeforeStep.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute before every Step execution completes. 15 | * The steps for which the hook executes can be filtered by passing additional attributes 16 | *

17 | * If there is more than one method annotated with @BeforeStep, the order of execution is as follows: 18 | *

22 | * If there is more than one hook of these categories, they are executed in alphabetical order based on method names. 23 | *

24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface BeforeStep { 28 | 29 | /** 30 | * @return Array of tags to filter which steps the hook runs before. 31 | */ 32 | String[] tags() default {}; 33 | 34 | /** 35 | * @return OR: if hook should execute for the current execution context (spec and scenario) containing any of the tags provided 36 | * AND: if hook should execute for the current execution context (spec and scenario) containing all of the tags provided 37 | * Default is AND 38 | */ 39 | Operator tagAggregation() default Operator.AND; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/BeforeSuite.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Methods annotated with this hook, execute before the entire suite (all specs) execution completes. 15 | * If there is more than one method annotated with @BeforeSuite, they are executed in alphabetical order based on method names. 16 | */ 17 | @Target(ElementType.METHOD) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface BeforeSuite { 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/ClassInitializer.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | /** 9 | * Interface to provide a Custom Class Initializer for managing Class Objects. 10 | */ 11 | public interface ClassInitializer { 12 | Object initialize(Class classToInitialize) throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/ClassInstanceManager.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * Manages class instance creation, lifetime and caching. 13 | */ 14 | public class ClassInstanceManager { 15 | private final Map, Object> classInstanceMap = new HashMap<>(); 16 | private static final ThreadLocal INITIALIZER = new InheritableThreadLocal<>(); 17 | 18 | public ClassInstanceManager() { 19 | INITIALIZER.set(new DefaultClassInitializer()); 20 | } 21 | 22 | public ClassInstanceManager(ClassInitializer classInitializer) { 23 | INITIALIZER.set(classInitializer); 24 | } 25 | 26 | public Object get(Class declaringClass) throws Exception { 27 | Object classInstance = classInstanceMap.get(declaringClass); 28 | if (classInstance == null) { 29 | classInstance = getInitializer().initialize(declaringClass); 30 | classInstanceMap.put(declaringClass, classInstance); 31 | } 32 | return classInstance; 33 | } 34 | 35 | public static void setClassInitializer(ClassInitializer classInitializer) { 36 | INITIALIZER.set(classInitializer); 37 | } 38 | 39 | public void clearCache() { 40 | this.classInstanceMap.clear(); 41 | } 42 | 43 | private static ClassInitializer getInitializer() { 44 | return INITIALIZER.get(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/ClasspathHelper.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.net.URL; 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | 12 | public class ClasspathHelper { 13 | 14 | public static Collection getUrls() { 15 | final String packagesToScan = System.getenv(GaugeConstant.PACKAGE_TO_SCAN); 16 | if (packagesToScan != null) { 17 | Collection urls = new ArrayList<>(); 18 | for (String packageToScan : packagesToScan.split(",")) { 19 | urls.addAll(org.reflections.util.ClasspathHelper.forPackage(packageToScan.trim())); 20 | } 21 | return urls; 22 | } 23 | return org.reflections.util.ClasspathHelper.forJavaClassPath(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/ContinueOnFailure.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Annotation added to methods which are Gauge Step implementations. 15 | */ 16 | @Target(ElementType.METHOD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface ContinueOnFailure { 19 | Class[] value() default Throwable.class; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/DefaultClassInitializer.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | public class DefaultClassInitializer implements ClassInitializer { 9 | 10 | @Override 11 | public Object initialize(Class classToInitialize) throws Exception { 12 | return Class.forName(classToInitialize.getName()).newInstance(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/ExecutionContext.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | 12 | /** 13 | * Gives the information about the current execution at runtime - spec, scenario, step that is running. 14 | */ 15 | public class ExecutionContext { 16 | private final Specification currentSpecification; 17 | private final Scenario currentScenario; 18 | private final StepDetails currentStep; 19 | 20 | public ExecutionContext(Specification specification, Scenario scenario, StepDetails stepDetails) { 21 | this.currentSpecification = specification; 22 | this.currentScenario = scenario; 23 | this.currentStep = stepDetails; 24 | } 25 | 26 | public ExecutionContext() { 27 | this.currentSpecification = new Specification(); 28 | this.currentScenario = new Scenario(); 29 | this.currentStep = new StepDetails(); 30 | } 31 | 32 | /** 33 | * @return - The Current Specification that is executing. 34 | * Returns null in BeforeSuite and AfterSuite levels as no spec is executing then. 35 | */ 36 | public Specification getCurrentSpecification() { 37 | return currentSpecification; 38 | } 39 | 40 | /** 41 | * @return - The Current Scenario that is executing. 42 | * Returns null in BeforeSuite, AfterSuite, BeforeSpec levels as no scenario is executing then. 43 | */ 44 | public Scenario getCurrentScenario() { 45 | return currentScenario; 46 | } 47 | 48 | /** 49 | * @return - The Current Step that is executing. 50 | * Returns null in BeforeSuite, AfterSuite, BeforeSpec, AfterSpec, BeforeScenario levels as no step is executing then. 51 | */ 52 | public StepDetails getCurrentStep() { 53 | return currentStep; 54 | } 55 | 56 | /** 57 | * @return - All the valid tags (including scenario and spec tags) at the execution level. 58 | */ 59 | public List getAllTags() { 60 | HashSet specTags = new HashSet<>(currentSpecification.getTags()); 61 | specTags.addAll(currentScenario.getTags()); 62 | return new ArrayList<>(specTags); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Gauge.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import com.thoughtworks.gauge.screenshot.ScreenshotFactory; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class Gauge { 14 | 15 | private static final ThreadLocal> MESSAGES = new InheritableThreadLocal<>() { 16 | @Override 17 | protected List initialValue() { 18 | return new ArrayList<>(); 19 | } 20 | }; 21 | private static ClassInstanceManager instanceManager; 22 | private static final ThreadLocal> SCREENSHOTS = new InheritableThreadLocal<>() { 23 | @Override 24 | protected List initialValue() { 25 | return new ArrayList<>(); 26 | } 27 | }; 28 | 29 | public static void setInstanceManager(ClassInstanceManager instanceManager) { 30 | Gauge.instanceManager = instanceManager; 31 | } 32 | 33 | /** 34 | * @param message - Custom message that can be added at runtime that will be visible in reports. 35 | */ 36 | public static void writeMessage(String message) { 37 | getMessages().add(message); 38 | } 39 | 40 | /** 41 | * @param format - Custom messages that can be added at runtime that will be visible in reports. 42 | * Format of the string message 43 | * @param args - Arguments for the format string as passed into String.format() 44 | */ 45 | public static void writeMessage(String format, String... args) { 46 | getMessages().add(String.format(format, args)); 47 | } 48 | 49 | static List getMessages() { 50 | return MESSAGES.get(); 51 | } 52 | 53 | public static void captureScreenshot() { 54 | String screenshotFileName = new ScreenshotFactory(instanceManager).getScreenshotBytes(); 55 | getScreenshots().add(screenshotFileName); 56 | } 57 | 58 | static List getScreenshots() { 59 | return SCREENSHOTS.get(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/GaugeConstant.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | public class GaugeConstant { 9 | public static final String SCREENSHOT_ON_FAILURE_ENABLED = "screenshot_on_failure"; 10 | public static final String PACKAGE_TO_SCAN = "package_to_scan"; 11 | public static final String GAUGE_PROJECT_ROOT = "GAUGE_PROJECT_ROOT"; 12 | public static final String GAUGE_CUSTOM_COMPILE_DIR = "gauge_custom_compile_dir"; 13 | public static final String DEFAULT_SRC_DIR = "src/test/java"; 14 | public static final String[] DEFAULT_SRC_DIRS = {"src/main/java", DEFAULT_SRC_DIR}; 15 | public static final String SCREENSHOTS_DIR_ENV = "gauge_screenshots_dir"; 16 | public static final String STREAMS_COUNT_ENV = "GAUGE_PARALLEL_STREAMS_COUNT"; 17 | public static final String ENABLE_MULTITHREADING_ENV = "enable_multithreading"; 18 | public static final String SCAN_EXTERNAL_LIBS = "scan_external_dependencies"; 19 | public static final String LOCALHOST = "127.0.0.1"; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/GaugeRuntime.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import com.thoughtworks.gauge.command.GaugeCommandFactory; 9 | 10 | /** 11 | * Holds Main for starting Gauge-java 1. Makes connections to gauge 2. Scans 12 | * Classpath 3. Dispatched all message responses 13 | */ 14 | public class GaugeRuntime { 15 | public static void main(String[] args) throws Exception { 16 | Thread.setDefaultUncaughtExceptionHandler((t, e) -> Logger.fatal("Error in thread " + t.getId(), e)); 17 | if (args.length == 0) { 18 | System.out.println("usage: GaugeJava --"); 19 | System.exit(1); 20 | } 21 | String phase = args[0]; 22 | GaugeCommandFactory gaugeCommandFactory = new GaugeCommandFactory(); 23 | gaugeCommandFactory.getExecutor(phase).execute(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Logger.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import org.assertj.core.util.Throwables; 9 | import org.json.JSONObject; 10 | 11 | public class Logger { 12 | public static void info(String message) { 13 | logToStdout("info", message); 14 | } 15 | 16 | public static void error(String message) { 17 | logToStdErr("error", message); 18 | } 19 | 20 | public static void error(String message, Throwable t) { 21 | error(String.format("%s\n%s\n%s", message, t.getMessage(), Throwables.getStackTrace(t))); 22 | } 23 | 24 | public static void warning(String message) { 25 | logToStdout("warning", message); 26 | } 27 | 28 | public static void warning(String message, Throwable t) { 29 | warning(String.format("%s\n%s\n%s", message, t.getMessage(), Throwables.getStackTrace(t))); 30 | } 31 | 32 | public static void debug(String message) { 33 | logToStdout("debug", message); 34 | } 35 | 36 | public static void fatal(String message) { 37 | logToStdErr("fatal", message); 38 | System.exit(1); 39 | } 40 | 41 | public static void fatal(String message, Throwable t) { 42 | fatal(String.format("%s\n%s\n%s", message, t.getMessage(), Throwables.getStackTrace(t))); 43 | 44 | } 45 | 46 | private static void logToStdout(String level, String message) { 47 | System.out.println(getJsonObject(level, message)); 48 | } 49 | 50 | private static JSONObject getJsonObject(String level, String message) { 51 | JSONObject jsonObj = new JSONObject(); 52 | jsonObj.put("logLevel", level); 53 | jsonObj.put("message", message); 54 | return jsonObj; 55 | } 56 | 57 | private static void logToStdErr(String level, String message) { 58 | System.err.println(getJsonObject(level, message)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/MessageCollector.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import gauge.messages.Spec; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Objects; 13 | 14 | import static com.thoughtworks.gauge.Gauge.getMessages; 15 | 16 | public class MessageCollector { 17 | public Spec.ProtoExecutionResult addPendingMessagesTo(Spec.ProtoExecutionResult result) { 18 | List messages = getPendingMessages(); 19 | return addPendingMessages(result, messages); 20 | } 21 | 22 | Spec.ProtoExecutionResult addPendingMessages(Spec.ProtoExecutionResult result, List messages) { 23 | Spec.ProtoExecutionResult.Builder builder = Spec.ProtoExecutionResult.newBuilder(result); 24 | messages.stream().filter(Objects::nonNull).forEach(builder::addMessage); 25 | return builder.build(); 26 | } 27 | 28 | private static List getPendingMessages() { 29 | List pendingMessages = new ArrayList<>(getMessages()); 30 | clear(); 31 | return pendingMessages; 32 | } 33 | 34 | private static void clear() { 35 | getMessages().clear(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Operator.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | /** 9 | * Operator for performing Tag aggregation mechanism in Execution Hooks. 10 | */ 11 | public enum Operator { 12 | AND, OR 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/RowSizeMismatchException.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | public class RowSizeMismatchException extends RuntimeException { 9 | public RowSizeMismatchException(String error) { 10 | super(error); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Scenario.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Holds the information about the current Scenario executing at Runtime. 13 | */ 14 | public class Scenario { 15 | private String name = ""; 16 | private Boolean isFailing = false; 17 | private List tags = new ArrayList<>(); 18 | 19 | public Scenario(String name, boolean isFailing, List tags) { 20 | this.name = name; 21 | this.isFailing = isFailing; 22 | this.tags = tags; 23 | } 24 | 25 | public Scenario() { 26 | } 27 | 28 | /** 29 | * @return List of all tags in just the scenario 30 | */ 31 | public List getTags() { 32 | return tags; 33 | } 34 | 35 | /** 36 | * @return True if the scenario or spec is failing 37 | */ 38 | public Boolean getIsFailing() { 39 | return isFailing; 40 | } 41 | 42 | /** 43 | * @return Name of the Scenario as mentioned in the scenario heading 44 | */ 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/ScreenshotCollector.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import gauge.messages.Spec; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import static com.thoughtworks.gauge.Gauge.getScreenshots; 14 | 15 | public class ScreenshotCollector { 16 | public Spec.ProtoExecutionResult addPendingScreenshotTo(Spec.ProtoExecutionResult result) { 17 | ArrayList screenshots = getAllPendingScreenshots(); 18 | return addPendingScreenshot(result, screenshots); 19 | } 20 | 21 | Spec.ProtoExecutionResult addPendingScreenshot(Spec.ProtoExecutionResult result, List screenshotsFileName) { 22 | Spec.ProtoExecutionResult.Builder builder = Spec.ProtoExecutionResult.newBuilder(result); 23 | builder.addAllScreenshotFiles(screenshotsFileName); 24 | return builder.build(); 25 | } 26 | 27 | private ArrayList getAllPendingScreenshots() { 28 | ArrayList pendingScreenshots = new ArrayList<>(getScreenshots()); 29 | clear(); 30 | return pendingScreenshots; 31 | } 32 | 33 | private void clear() { 34 | getScreenshots().clear(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/SkipScenarioException.java: -------------------------------------------------------------------------------- 1 | package com.thoughtworks.gauge; 2 | 3 | public class SkipScenarioException extends RuntimeException { 4 | public SkipScenarioException(String message) { 5 | super(message); 6 | } 7 | 8 | @SuppressWarnings("unused") 9 | public SkipScenarioException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Specification.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Holds the information about the current Specification executing at runtime. 13 | */ 14 | public class Specification { 15 | private String name = ""; 16 | private String fileName = ""; 17 | private Boolean isFailing = false; 18 | private List tags = new ArrayList<>(); 19 | 20 | public Specification(String name, String fileName, boolean isFailing, List tags) { 21 | this.name = name; 22 | this.fileName = fileName; 23 | this.isFailing = isFailing; 24 | this.tags = tags; 25 | } 26 | 27 | public Specification() { 28 | } 29 | 30 | /** 31 | * @return List of all the tags in the Spec 32 | */ 33 | public List getTags() { 34 | return tags; 35 | } 36 | 37 | /** 38 | * @return True if the current spec is failing. 39 | */ 40 | public Boolean getIsFailing() { 41 | return isFailing; 42 | } 43 | 44 | /** 45 | * @return Full path to the Spec 46 | */ 47 | public String getFileName() { 48 | return fileName; 49 | } 50 | 51 | /** 52 | * @return The name of the Specification as mentioned in the Spec heading 53 | */ 54 | public String getName() { 55 | return name; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Step.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Annotation added to methods which are Gauge Step implementations. 15 | */ 16 | @Target(ElementType.METHOD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface Step { 19 | String[] value(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/StepDetails.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | /** 9 | * Holds the information about the current step executing at runtime. 10 | */ 11 | public class StepDetails { 12 | private String text = ""; 13 | private String dynamicText = ""; 14 | private String stackTrace = ""; 15 | private String errorMessage = ""; 16 | private Boolean isFailing = false; 17 | 18 | public StepDetails(String text, boolean isFailing, String stackTrace, String errorMessage) { 19 | this(text, text, isFailing, stackTrace, errorMessage); 20 | } 21 | 22 | public StepDetails(String text, String dynamicText, boolean isFailing, String stackTrace, String errorMessage) { 23 | this.text = text; 24 | this.dynamicText = dynamicText; 25 | this.isFailing = isFailing; 26 | this.stackTrace = stackTrace; 27 | this.errorMessage = errorMessage; 28 | } 29 | 30 | public StepDetails() { 31 | } 32 | 33 | /** 34 | * @return True if the current spec or scenario or step is failing due to error. 35 | */ 36 | public Boolean getIsFailing() { 37 | return isFailing; 38 | } 39 | 40 | /** 41 | * @return The name of the step as given in the spec file. 42 | */ 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | /** 48 | * @return The step text with values of dynamic parameters instead of placeholders. 49 | * Return the same value as {@link #text} in case of static parameters. 50 | */ 51 | public String getDynamicText() { 52 | return dynamicText; 53 | } 54 | 55 | public String getStackTrace() { 56 | return stackTrace; 57 | } 58 | 59 | public String getErrorMessage() { 60 | return errorMessage; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/StepValue.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import gauge.messages.Spec; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Objects; 13 | 14 | public class StepValue { 15 | private final String stepText; 16 | private final String parameterizedStepText; 17 | private final List parameters; 18 | 19 | public StepValue(String stepText, String parameterizedStepText, List parameters) { 20 | this.stepText = stepText; 21 | this.parameterizedStepText = parameterizedStepText; 22 | this.parameters = parameters; 23 | } 24 | 25 | public StepValue(String stepTemplateText, String parameterizedStepText) { 26 | this.stepText = stepTemplateText; 27 | this.parameterizedStepText = parameterizedStepText; 28 | this.parameters = new ArrayList<>(); 29 | } 30 | 31 | public static StepValue from(Spec.ProtoStepValue protoStepValue) { 32 | return new StepValue(protoStepValue.getStepValue(), protoStepValue.getParameterizedStepValue(), protoStepValue.getParametersList()); 33 | } 34 | 35 | public String getStepText() { 36 | return stepText; 37 | } 38 | 39 | public List getParameters() { 40 | return parameters; 41 | } 42 | 43 | public String getStepAnnotationText() { 44 | return parameterizedStepText; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object o) { 49 | if (this == o) { 50 | return true; 51 | } 52 | 53 | if (!(o instanceof StepValue)) { 54 | return false; 55 | } 56 | 57 | StepValue stepValue = (StepValue) o; 58 | return Objects.equals(parameterizedStepText, stepValue.parameterizedStepText) 59 | && Objects.equals(parameters, stepValue.parameters) 60 | && Objects.equals(stepText, stepValue.stepText); 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | int result = stepText != null ? stepText.hashCode() : 0; 66 | result = 31 * result + (parameterizedStepText != null ? parameterizedStepText.hashCode() : 0); // SUPPRESS CHECKSTYLE 67 | result = 31 * result + (parameters != null ? parameters.hashCode() : 0); // SUPPRESS CHECKSTYLE 68 | return result; 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return "StepValue{" 74 | + "stepText='" + stepText + '\'' 75 | + ", parameterizedStepText='" + parameterizedStepText + '\'' 76 | + ", parameters=" + parameters 77 | + '}'; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/TableCell.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | /** 9 | * This class represents a single table cell object containing 10 | * the cell's column name and its associated value. 11 | */ 12 | public class TableCell { 13 | private final String columnName; 14 | private final String value; 15 | 16 | public TableCell(String columnName, String value) { 17 | this.columnName = columnName; 18 | this.value = value; 19 | } 20 | 21 | public String getColumnName() { 22 | return columnName; 23 | } 24 | 25 | public String getValue() { 26 | return value; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "TableCell{" 32 | + "columnName=" + columnName 33 | + ", " 34 | + "value=" + value 35 | + '}'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/TableRow.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.util.*; 9 | 10 | /** 11 | * Represents a Row of Data in a Table. 12 | */ 13 | public class TableRow { 14 | private final Map cells = new LinkedHashMap<>(); 15 | 16 | /** 17 | * Get the value of cell corresponding to a column name. 18 | * 19 | * @param columnName 20 | * - The column name of TableRow. 21 | * @return The value of cell corresponding to a column name. 22 | */ 23 | public String getCell(String columnName) { 24 | if (!cells.containsKey(columnName)) { 25 | return ""; 26 | } 27 | return cells.get(columnName); 28 | } 29 | 30 | /** 31 | * Add a cell to the TableRow. 32 | * 33 | * @param columnName 34 | * The column name against which the cell is added. 35 | * @param value 36 | * The value to be stored in the cell. 37 | */ 38 | public void addCell(String columnName, String value) { 39 | cells.put(columnName, value); 40 | } 41 | 42 | /** 43 | * Get the number of cells in TableRow. 44 | * 45 | * @return The number of cells in TableRow. 46 | */ 47 | public int size() { 48 | return cells.size(); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "TableRow{" + "cells=" + cells + '}'; 54 | } 55 | 56 | /** 57 | * Returns a list containing the values of each cell in the table row. 58 | * 59 | * @return a list of the values of each cell in the table row. 60 | */ 61 | public List getCellValues() { 62 | // Since we have a LinkedHashMap, the order of values() is guaranteed. 63 | return new ArrayList<>(cells.values()); 64 | } 65 | 66 | /** 67 | * Returns a list of TableCells representing each cell in the table row. 68 | * 69 | * @return a list of TableCells. 70 | */ 71 | public List getTableCells() { 72 | List listOfCells = new ArrayList<>(); 73 | 74 | // Since we have a LinkedHashMap, the order of entrySet() is guaranteed. 75 | for (Map.Entry mapEntry : cells.entrySet()) { 76 | TableCell cell = new TableCell(mapEntry.getKey(), mapEntry.getValue()); 77 | listOfCells.add(cell); 78 | } 79 | 80 | return listOfCells; 81 | } 82 | 83 | @Override 84 | public int hashCode() { 85 | final int prime = 31; 86 | int result = 1; 87 | result = prime * result + cells.hashCode(); 88 | return result; 89 | } 90 | 91 | @Override 92 | public boolean equals(Object obj) { 93 | if (this == obj) { 94 | return true; 95 | } 96 | if (obj == null) { 97 | return false; 98 | } 99 | if (getClass() != obj.getClass()) { 100 | return false; 101 | } 102 | TableRow other = (TableRow) obj; 103 | return Objects.equals(cells, other.cells); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/Util.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import java.io.File; 9 | 10 | public class Util { 11 | public static File workingDir() { 12 | String wd = System.getenv(GaugeConstant.GAUGE_PROJECT_ROOT); 13 | if (wd != null && !wd.isEmpty()) { 14 | return new File(wd); 15 | } 16 | return new File(System.getProperty("user.dir")); 17 | } 18 | 19 | public static String convertToCamelCase(String s) { 20 | String[] words = s.trim().split(" "); 21 | String text = words[0].toLowerCase(); 22 | for (int i = 1, wordsLength = words.length; i < wordsLength; i++) { 23 | String word = words[i].trim(); 24 | if (!word.isEmpty()) { 25 | text += words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase(); 26 | } 27 | } 28 | return text; 29 | } 30 | 31 | public static String getValidJavaIdentifier(String s) { 32 | StringBuilder builder = new StringBuilder(); 33 | for (int i = 0; i < s.length(); i++) { 34 | if (Character.isJavaIdentifierPart(s.charAt(i))) { 35 | builder.append(s.charAt(i)); 36 | } 37 | } 38 | return builder.toString(); 39 | } 40 | 41 | public static String trimQuotes(String text) { 42 | return text == null ? null : text.replaceFirst("^\"", "").replaceFirst("\"$", ""); 43 | } 44 | 45 | public static boolean shouldTakeFailureScreenshot() { 46 | String screenshotOnFailureEnabled = System.getenv(GaugeConstant.SCREENSHOT_ON_FAILURE_ENABLED); 47 | return !(screenshotOnFailureEnabled == null || screenshotOnFailureEnabled.equalsIgnoreCase("false")); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/command/GaugeCommandFactory.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.command; 7 | 8 | public class GaugeCommandFactory { 9 | public GaugeJavaCommand getExecutor(String phase) { 10 | if ("--init".equals(phase)) { 11 | return new SetupCommand(); 12 | } 13 | return new StartCommand(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/command/GaugeJavaCommand.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.command; 7 | 8 | public interface GaugeJavaCommand { 9 | void execute() throws Exception; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/command/StartCommand.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.command; 7 | 8 | import com.thoughtworks.gauge.Logger; 9 | import com.thoughtworks.gauge.RunnerServiceHandler; 10 | import com.thoughtworks.gauge.connection.MessageProcessorFactory; 11 | import com.thoughtworks.gauge.scan.StaticScanner; 12 | import io.grpc.Server; 13 | import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder; 14 | 15 | import java.net.InetSocketAddress; 16 | 17 | import static com.thoughtworks.gauge.GaugeConstant.*; 18 | 19 | public class StartCommand implements GaugeJavaCommand { 20 | 21 | @Override 22 | public void execute() throws Exception { 23 | boolean multithreading = Boolean.parseBoolean(System.getenv(ENABLE_MULTITHREADING_ENV)); 24 | Logger.debug("multithreading is set to " + multithreading); 25 | int numberOfStreams = 1; 26 | 27 | if (multithreading) { 28 | String streamsCount = System.getenv(STREAMS_COUNT_ENV); 29 | try { 30 | numberOfStreams = Integer.parseInt(streamsCount); 31 | Logger.debug("multithreading enabled, number of threads=" + numberOfStreams); 32 | } catch (NumberFormatException e) { 33 | Logger.debug("multithreading enabled, but could not read " + STREAMS_COUNT_ENV + " as int. Got " + STREAMS_COUNT_ENV + "=" + streamsCount); 34 | Logger.debug("using numberOfStreams=1, err: " + e.getMessage()); 35 | } 36 | } 37 | 38 | long start = System.currentTimeMillis(); 39 | StaticScanner staticScanner = new StaticScanner(); 40 | staticScanner.addStepsToRegistry(); 41 | Server server; 42 | MessageProcessorFactory messageProcessorFactory = new MessageProcessorFactory(staticScanner); 43 | RunnerServiceHandler runnerServiceHandler = new RunnerServiceHandler(messageProcessorFactory, multithreading, numberOfStreams); 44 | server = NettyServerBuilder 45 | .forAddress(new InetSocketAddress(LOCALHOST, 0)) 46 | .addService(runnerServiceHandler) 47 | .executor(Runnable::run) 48 | .build(); 49 | runnerServiceHandler.addServer(server); 50 | long elapsed = System.currentTimeMillis() - start; 51 | Logger.debug("gauge-java took " + elapsed + "milliseconds to load and scan. This should be less than 'runner_connection_timeout' config value."); 52 | Logger.debug("run 'gauge config runner_connection_timeout' and verify that it is < " + elapsed); 53 | Logger.debug("starting gRPC server..."); 54 | server.start(); 55 | int port = server.getPort(); 56 | Logger.debug("started gRPC server on port " + port); 57 | Logger.info("Listening on port:" + port); 58 | server.awaitTermination(); 59 | Logger.debug("Runner killed gracefully."); 60 | System.exit(0); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/datastore/DataStore.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.datastore; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Set; 11 | /** 12 | * @deprecated DataStore is no longer valid. The usage together with DataStoreFactory API will throw an Exception in multithreaded execution. 13 | *

Use specific data stores instead.

14 | * @see com.thoughtworks.gauge.datastore.SuiteDataStore 15 | * @see com.thoughtworks.gauge.datastore.SpecDataStore 16 | * @see com.thoughtworks.gauge.datastore.ScenarioDataStore 17 | */ 18 | @Deprecated 19 | public class DataStore { 20 | 21 | private final HashMap map = new HashMap<>(); 22 | 23 | /** 24 | * @param key - Key of the data entry 25 | * @param value - value of the Data entry 26 | */ 27 | public void put(Object key, Object value) { 28 | map.put(key, value); 29 | } 30 | 31 | /** 32 | * @param key - Key of the data entry to remove 33 | * @return The value of the entry removed. Null if no entry. 34 | */ 35 | public Object remove(Object key) { 36 | return map.remove(key); 37 | } 38 | 39 | /** 40 | * @param key - Key of the data entry whose value is needed 41 | * @return The value corresponding to the key. null if there is no value stored 42 | */ 43 | public Object get(Object key) { 44 | return map.get(key); 45 | } 46 | 47 | void clear() { 48 | map.clear(); 49 | } 50 | 51 | public Set> entrySet() { 52 | return map.entrySet(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/datastore/DataStoreFactory.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.datastore; 7 | 8 | import static com.thoughtworks.gauge.GaugeConstant.ENABLE_MULTITHREADING_ENV; 9 | 10 | 11 | /** 12 | * @deprecated DataStoreFactory is no longer valid. This API will throw an Exception in multithreaded execution. 13 | *

Use specific data stores instead.

14 | * @see com.thoughtworks.gauge.datastore.SuiteDataStore 15 | * @see com.thoughtworks.gauge.datastore.SpecDataStore 16 | * @see com.thoughtworks.gauge.datastore.ScenarioDataStore 17 | */ 18 | @Deprecated 19 | public class DataStoreFactory { 20 | private static final ThreadLocal SUITE_DATA_STORE = new InheritableThreadLocal<>() { 21 | @Override 22 | protected DataStore initialValue() { 23 | return new DataStore(); 24 | } 25 | }; 26 | private static final ThreadLocal SPEC_DATA_STORE = new InheritableThreadLocal<>() { 27 | @Override 28 | protected DataStore initialValue() { 29 | return new DataStore(); 30 | } 31 | }; 32 | private static final ThreadLocal SCENARIO_DATA_STORE = new InheritableThreadLocal<>() { 33 | @Override 34 | protected DataStore initialValue() { 35 | return new DataStore(); 36 | } 37 | }; 38 | 39 | 40 | /** 41 | * @return The current instance of the SuiteDataStore 42 | */ 43 | public static DataStore getSuiteDataStore() { 44 | if (isMultithreadingExecution()) { 45 | throw new RuntimeException("DataStoreFactory cannot be used for multithreaded execution. Use SuiteDataStore."); 46 | } 47 | return SUITE_DATA_STORE.get(); 48 | } 49 | 50 | /** 51 | * @return The current instance of the SpecDataStore 52 | */ 53 | public static DataStore getSpecDataStore() { 54 | if (isMultithreadingExecution()) { 55 | throw new RuntimeException("DataStoreFactory cannot be used for multithreaded execution. Use SpecDataStore."); 56 | } 57 | return SPEC_DATA_STORE.get(); 58 | } 59 | 60 | 61 | /** 62 | * @return The current instance of the ScenarioDataStore 63 | */ 64 | public static DataStore getScenarioDataStore() { 65 | if (isMultithreadingExecution()) { 66 | throw new RuntimeException("DataStoreFactory cannot be used for multithreaded execution. Use ScenarioDataStore."); 67 | } 68 | return SCENARIO_DATA_STORE.get(); 69 | } 70 | 71 | static void clearSuiteDataStore() { 72 | SUITE_DATA_STORE.get().clear(); 73 | } 74 | 75 | static void clearSpecDataStore() { 76 | SPEC_DATA_STORE.get().clear(); 77 | } 78 | 79 | static void clearScenarioDataStore() { 80 | SCENARIO_DATA_STORE.get().clear(); 81 | } 82 | 83 | private static boolean isMultithreadingExecution() { 84 | return Boolean.parseBoolean(System.getenv(ENABLE_MULTITHREADING_ENV)); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/datastore/DataStoreInitializer.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.datastore; 7 | 8 | 9 | 10 | import com.thoughtworks.gauge.processor.IMessageProcessor; 11 | import gauge.messages.Messages; 12 | import gauge.messages.Spec; 13 | 14 | public class DataStoreInitializer implements IMessageProcessor { 15 | 16 | public Messages.Message process(Messages.Message message) { 17 | switch (message.getMessageType()) { // SUPPRESS CHECKSTYLE 18 | case SuiteDataStoreInit: 19 | DataStoreFactory.clearSuiteDataStore(); 20 | SuiteDataStore.clear(); 21 | break; 22 | case SpecDataStoreInit: 23 | DataStoreFactory.clearSpecDataStore(); 24 | SpecDataStore.clear(); 25 | break; 26 | case ScenarioDataStoreInit: 27 | DataStoreFactory.clearScenarioDataStore(); 28 | ScenarioDataStore.clear(); 29 | break; 30 | } 31 | return createMessageWithExecutionStatusResponse(message, Spec.ProtoExecutionResult.newBuilder().setExecutionTime(0).setFailed(false).build()); 32 | } 33 | 34 | private Messages.Message createMessageWithExecutionStatusResponse(Messages.Message receivedMessage, Spec.ProtoExecutionResult result) { 35 | return Messages.Message.newBuilder() 36 | .setMessageId(receivedMessage.getMessageId()) 37 | .setMessageType(Messages.Message.MessageType.ExecutionStatusResponse) 38 | .setExecutionStatusResponse(Messages.ExecutionStatusResponse.newBuilder().setExecutionResult(result).build()) 39 | .build(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/datastore/ScenarioDataStore.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | 7 | package com.thoughtworks.gauge.datastore; 8 | 9 | import java.util.Collections; 10 | import java.util.Set; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | public class ScenarioDataStore { 14 | private static final InheritableThreadLocal> MAP = new InheritableThreadLocal<>() { 15 | @Override 16 | protected ConcurrentHashMap initialValue() { 17 | return new ConcurrentHashMap<>(); 18 | } 19 | }; 20 | 21 | /** 22 | * @param key - Key of the data entry 23 | * @param value - value of the Data entry 24 | */ 25 | public static synchronized void put(Object key, Object value) { 26 | if (key != null && value != null) { 27 | MAP.get().put(key, value); 28 | } 29 | } 30 | 31 | /** 32 | * @param key - Key of the data entry to remove 33 | * @return The value of the entry removed. Null if no entry. 34 | */ 35 | public static synchronized Object remove(Object key) { 36 | if (key != null) { 37 | return MAP.get().remove(key); 38 | } 39 | return null; 40 | } 41 | 42 | /** 43 | * @param key - Key of the data entry whose value is needed 44 | * @return The value corresponding to the key. null if there is no value stored 45 | */ 46 | public static synchronized Object get(Object key) { 47 | if (key != null) { 48 | return MAP.get().get(key); 49 | } 50 | return null; 51 | } 52 | 53 | /** 54 | * Returns a {@link Set} view of the keys in datastore. 55 | * @return A set of keys stored in datastore 56 | */ 57 | public static synchronized Set items() { 58 | return Collections.unmodifiableSet(MAP.get().keySet()); 59 | } 60 | 61 | static synchronized void clear() { 62 | MAP.get().clear(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/datastore/SpecDataStore.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | 7 | package com.thoughtworks.gauge.datastore; 8 | 9 | import java.util.Collections; 10 | import java.util.Set; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | public class SpecDataStore { 14 | private static final InheritableThreadLocal> MAP = new InheritableThreadLocal<>() { 15 | @Override 16 | protected ConcurrentHashMap initialValue() { 17 | return new ConcurrentHashMap<>(); 18 | } 19 | }; 20 | /** 21 | * @param key - Key of the data entry 22 | * @param value - value of the Data entry 23 | */ 24 | public static synchronized void put(Object key, Object value) { 25 | if (key != null && value != null) { 26 | MAP.get().put(key, value); 27 | } 28 | } 29 | 30 | /** 31 | * @param key - Key of the data entry to remove 32 | * @return The value of the entry removed. Null if no entry. 33 | */ 34 | public static synchronized Object remove(Object key) { 35 | if (key != null) { 36 | return MAP.get().remove(key); 37 | } 38 | return null; 39 | } 40 | 41 | /** 42 | * @param key - Key of the data entry whose value is needed 43 | * @return The value corresponding to the key. null if there is no value stored 44 | */ 45 | public static synchronized Object get(Object key) { 46 | if (key != null) { 47 | return MAP.get().get(key); 48 | } 49 | return null; 50 | } 51 | 52 | /** 53 | * Returns a {@link Set} view of the keys in datastore. 54 | * @return A set of keys stored in datastore 55 | */ 56 | public static synchronized Set items() { 57 | return Collections.unmodifiableSet(MAP.get().keySet()); 58 | } 59 | 60 | static synchronized void clear() { 61 | MAP.get().clear(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/datastore/SuiteDataStore.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | 7 | package com.thoughtworks.gauge.datastore; 8 | 9 | import java.util.Collections; 10 | import java.util.Set; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | public class SuiteDataStore { 14 | private static final InheritableThreadLocal> MAP = new InheritableThreadLocal<>() { 15 | @Override 16 | protected ConcurrentHashMap initialValue() { 17 | return new ConcurrentHashMap<>(); 18 | } 19 | }; 20 | 21 | /** 22 | * @param key - Key of the data entry 23 | * @param value - value of the Data entry 24 | */ 25 | public static synchronized void put(Object key, Object value) { 26 | if (key != null && value != null) { 27 | MAP.get().put(key, value); 28 | } 29 | } 30 | 31 | /** 32 | * @param key - Key of the data entry to remove 33 | * @return The value of the entry removed. Null if no entry. 34 | */ 35 | public static synchronized Object remove(Object key) { 36 | if (key != null) { 37 | return MAP.get().remove(key); 38 | } 39 | return null; 40 | } 41 | 42 | /** 43 | * @param key - Key of the data entry whose value is needed 44 | * @return The value corresponding to the key. null if there is no value stored 45 | */ 46 | public static synchronized Object get(Object key) { 47 | if (key != null) { 48 | return MAP.get().get(key); 49 | } 50 | return null; 51 | } 52 | 53 | /** 54 | * Returns a {@link Set} view of the keys in datastore. 55 | * @return A set of keys stored in datastore 56 | */ 57 | public static synchronized Set items() { 58 | return Collections.unmodifiableSet(MAP.get().keySet()); 59 | } 60 | 61 | static synchronized void clear() { 62 | MAP.get().clear(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/AbstractExecutionStage.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import gauge.messages.Spec; 9 | 10 | public abstract class AbstractExecutionStage implements ExecutionStage { 11 | 12 | public Spec.ProtoExecutionResult executeNext(Spec.ProtoExecutionResult previousStageResult) { 13 | if (next() != null) { 14 | return next().execute(previousStageResult); 15 | } else { 16 | return previousStageResult; 17 | } 18 | } 19 | 20 | protected Spec.ProtoExecutionResult mergeExecResults(Spec.ProtoExecutionResult previousStageResult, Spec.ProtoExecutionResult execResult) { 21 | long execTime = execResult.getExecutionTime() + previousStageResult.getExecutionTime(); 22 | boolean failed = execResult.getFailed() | previousStageResult.getFailed(); 23 | boolean skipped = execResult.getSkipScenario() | previousStageResult.getSkipScenario(); 24 | 25 | Spec.ProtoExecutionResult.Builder builder = Spec.ProtoExecutionResult.newBuilder(); 26 | builder.setExecutionTime(execTime); 27 | builder.setFailed(failed); 28 | builder.setSkipScenario(skipped); 29 | if (previousStageResult.getFailed()) { 30 | builder.setErrorMessage(previousStageResult.getErrorMessage()); 31 | builder.setErrorType(previousStageResult.getErrorType()); 32 | builder.setFailureScreenshotFile(previousStageResult.getFailureScreenshotFile()); 33 | builder.setStackTrace(previousStageResult.getStackTrace()); 34 | builder.setRecoverableError(previousStageResult.getRecoverableError()); 35 | } else if (execResult.getFailed()) { 36 | builder.setErrorType(execResult.getErrorType()); 37 | builder.setErrorMessage(execResult.getErrorMessage()); 38 | builder.setFailureScreenshotFile(execResult.getFailureScreenshotFile()); 39 | builder.setStackTrace(execResult.getStackTrace()); 40 | builder.setRecoverableError(execResult.getRecoverableError()); 41 | } 42 | if (previousStageResult.getRecoverableError() && execResult.getFailed()) { 43 | builder.setRecoverableError(execResult.getRecoverableError()); 44 | } 45 | return builder.build(); 46 | } 47 | 48 | protected abstract ExecutionStage next(); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/ExecutionInfoMapper.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import com.thoughtworks.gauge.Scenario; 9 | import com.thoughtworks.gauge.Specification; 10 | import com.thoughtworks.gauge.ExecutionContext; 11 | import com.thoughtworks.gauge.StepDetails; 12 | import com.thoughtworks.gauge.execution.parameters.DynamicParametersReplacer; 13 | import gauge.messages.Messages; 14 | import gauge.messages.Spec; 15 | 16 | import java.util.List; 17 | 18 | public class ExecutionInfoMapper { 19 | public ExecutionContext executionInfoFrom(Messages.ExecutionInfo currentExecutionInfo) { 20 | if (!currentExecutionInfo.isInitialized()) { 21 | return new ExecutionContext(); 22 | } 23 | return new ExecutionContext(specificationFrom(currentExecutionInfo.getCurrentSpec()), scenarioFrom(currentExecutionInfo.getCurrentScenario()), 24 | stepFrom(currentExecutionInfo.getCurrentStep())); 25 | } 26 | 27 | private Specification specificationFrom(Messages.SpecInfo currentSpec) { 28 | if (currentSpec.isInitialized()) { 29 | return new Specification(currentSpec.getName(), currentSpec.getFileName(), currentSpec.getIsFailed(), currentSpec.getTagsList()); 30 | } 31 | return new Specification(); 32 | } 33 | 34 | Scenario scenarioFrom(Messages.ScenarioInfo currentScenario) { 35 | if (currentScenario.isInitialized()) { 36 | return new Scenario(currentScenario.getName(), currentScenario.getIsFailed(), currentScenario.getTagsList()); 37 | } 38 | return new Scenario(); 39 | } 40 | 41 | public StepDetails stepFrom(Messages.StepInfo currentStep) { 42 | if (currentStep.isInitialized()) { 43 | List parameters = currentStep.getStep().getParametersList(); 44 | String actualStepText = currentStep.getStep().getActualStepText(); 45 | 46 | if (parameters.isEmpty()) { 47 | return new StepDetails(actualStepText, currentStep.getIsFailed(), currentStep.getStackTrace(), currentStep.getErrorMessage()); 48 | } else { 49 | String dynamicStepText = DynamicParametersReplacer.replacePlaceholders(actualStepText, parameters); 50 | return new StepDetails(actualStepText, dynamicStepText, currentStep.getIsFailed(), currentStep.getStackTrace(), currentStep.getErrorMessage()); 51 | } 52 | } 53 | return new StepDetails(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/ExecutionPipeline.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import gauge.messages.Spec; 9 | 10 | public class ExecutionPipeline { 11 | private final ExecutionStage firstStage; 12 | 13 | public ExecutionPipeline(ExecutionStage firstStage) { 14 | this.firstStage = firstStage; 15 | } 16 | 17 | public Spec.ProtoExecutionResult start() { 18 | Spec.ProtoExecutionResult result = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(0).build(); 19 | return firstStage.execute(result); 20 | } 21 | 22 | public void addStages(ExecutionStage... stages) { 23 | ExecutionStage currentStage = this.firstStage; 24 | for (ExecutionStage stage : stages) { 25 | currentStage.setNextStage(stage); 26 | currentStage = stage; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/ExecutionStage.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import gauge.messages.Spec; 9 | 10 | public interface ExecutionStage { 11 | 12 | void setNextStage(ExecutionStage stage); 13 | 14 | Spec.ProtoExecutionResult execute(Spec.ProtoExecutionResult result); 15 | 16 | Spec.ProtoExecutionResult executeNext(Spec.ProtoExecutionResult stageResult); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/ExecutorPool.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | import java.util.concurrent.ExecutorService; 12 | import java.util.concurrent.Executors; 13 | 14 | public class ExecutorPool { 15 | private final Map executors = new ConcurrentHashMap<>(); 16 | 17 | public ExecutorPool(int size) { 18 | for (int count = 1; count <= size; count++) { 19 | executors.put(getName(count), Executors.newSingleThreadExecutor()); 20 | } 21 | } 22 | 23 | private String getName(int count) { 24 | return "Executor-" + count; 25 | } 26 | 27 | public void execute(int stream, Runnable task) { 28 | executors.get(getName(stream)).execute(task); 29 | } 30 | 31 | public void stopAfterCompletion() { 32 | for (Map.Entry entry : executors.entrySet()) { 33 | entry.getValue().shutdown(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/HookExecutionStage.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.hook.Hook; 11 | import gauge.messages.Spec; 12 | 13 | import java.util.List; 14 | 15 | 16 | public class HookExecutionStage extends AbstractExecutionStage { 17 | private final List execHooks; 18 | private final ClassInstanceManager manager; 19 | private ExecutionStage next; 20 | 21 | public HookExecutionStage(List execHooks, ClassInstanceManager manager) { 22 | this.execHooks = execHooks; 23 | this.manager = manager; 24 | } 25 | 26 | public void setNextStage(ExecutionStage stage) { 27 | this.next = stage; 28 | } 29 | 30 | public Spec.ProtoExecutionResult execute(Spec.ProtoExecutionResult result) { 31 | Spec.ProtoExecutionResult execResult = execute(); 32 | Spec.ProtoExecutionResult stageResult = mergeExecResults(result, execResult); 33 | return executeNext(stageResult); 34 | } 35 | 36 | protected ExecutionStage next() { 37 | return next; 38 | } 39 | 40 | private Spec.ProtoExecutionResult execute() { 41 | return new HooksExecutor(execHooks, new ExecutionContext(), manager).execute(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/DynamicParametersReplacer.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters; 7 | 8 | import com.google.common.base.Strings; 9 | import gauge.messages.Spec; 10 | 11 | import java.util.List; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | 15 | public final class DynamicParametersReplacer { 16 | 17 | private static final Pattern REPLACER_PATTERN = Pattern.compile("<(.*?)>"); 18 | 19 | private DynamicParametersReplacer() { 20 | 21 | } 22 | 23 | public static String replacePlaceholders(String stepText, List parameters) { 24 | if (Strings.isNullOrEmpty(stepText) || parameters == null || parameters.isEmpty()) { 25 | return stepText; 26 | } 27 | 28 | for (Spec.Parameter parameter : parameters) { 29 | if (parameter.getParameterType() == Spec.Parameter.ParameterType.Dynamic) { 30 | stepText = findAndReplacePlaceholder(stepText, parameter.getValue()); 31 | } 32 | } 33 | 34 | return stepText; 35 | } 36 | 37 | private static String findAndReplacePlaceholder(String stepText, String parameterValue) { 38 | Matcher matcher = REPLACER_PATTERN.matcher(stepText); 39 | if (matcher.find()) { 40 | return matcher.replaceFirst(Matcher.quoteReplacement("\"" + parameterValue + "\"")); 41 | } 42 | return stepText; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/ParametersExtractor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters; 7 | 8 | import com.thoughtworks.gauge.execution.parameters.parsers.base.ParameterParser; 9 | import gauge.messages.Spec; 10 | 11 | import java.util.List; 12 | 13 | public class ParametersExtractor { 14 | 15 | private final ParameterParser parameterParser; 16 | 17 | public ParametersExtractor(ParameterParser parameterParser) { 18 | this.parameterParser = parameterParser; 19 | } 20 | 21 | public Object[] extract(List arguments, Class[] parameterTypes) throws ParsingException { 22 | Object[] parameters = new Object[arguments == null ? 0 : arguments.size()]; 23 | 24 | for (int i = 0; i < parameters.length; i++) { 25 | parameters[i] = parameterParser.parse(parameterTypes[i], arguments.get(i)); 26 | } 27 | 28 | return parameters; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/ParsingException.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters; 7 | 8 | import gauge.messages.Spec.ProtoExecutionResult; 9 | 10 | public class ParsingException extends Exception { 11 | private static final long serialVersionUID = -4205182693938362914L; 12 | 13 | private final ProtoExecutionResult executionResult; 14 | 15 | public ParsingException(ProtoExecutionResult executionResult) { 16 | this.executionResult = executionResult; 17 | } 18 | 19 | public ProtoExecutionResult getExecutionResult() { 20 | return executionResult; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/base/CustomParameterParser.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.base; 7 | 8 | import com.google.common.base.Throwables; 9 | import com.thoughtworks.gauge.execution.parameters.ParsingException; 10 | import gauge.messages.Spec; 11 | 12 | /** 13 | * Extension hook for custom parameter parser implementations. 14 | * 15 | * An example: 16 | * 17 | * Given the following custom model class 18 | * 19 | * public class Person { 20 | * private String name; 21 | * 22 | * public Person(String name) { 23 | * this.name = name; 24 | * } 25 | * } 26 | * 27 | * 28 | * One can create a CustomParameterParser like 29 | * 30 | * public class PersonGaugeParser extends CustomParameterParser { 31 | * @Override 32 | * public boolean canParse(Class aClass, Spec.Parameter parameter) { 33 | * return aClass.equals(Person.class); 34 | * } 35 | * 36 | * 37 | * @Override 38 | * protected Person customParse(Class aClass, Spec.Parameter parameter) { 39 | * return new Person(parameter.getValue()); 40 | * } 41 | * } 42 | * 43 | * 44 | * and then use in a step implementation 45 | * 46 | * 47 | * @Step("Create user ") 48 | * public void createUser(Person person) { 49 | * Assert.assertEquals(person.getUserName(), "John Doe"); 50 | * } 51 | * 52 | */ 53 | public abstract class CustomParameterParser implements ParameterParser { 54 | @Override 55 | public final T parse(Class parameterType, Spec.Parameter parameter) throws ParsingException { 56 | try { 57 | return customParse(parameterType, parameter); 58 | } catch (Throwable e) { 59 | throw new ParsingException(Spec.ProtoExecutionResult.newBuilder().setFailed(true).setExecutionTime(0) 60 | .setStackTrace(Throwables.getStackTraceAsString(e)) 61 | .setErrorMessage(String.format("Failed to convert argument from type String to type %s. %s", 62 | parameterType.toString(), e.getMessage())) 63 | .build()); 64 | } 65 | } 66 | 67 | protected abstract T customParse(Class parameterType, Spec.Parameter parameter); 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/base/ParameterParser.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.base; 7 | 8 | import com.thoughtworks.gauge.execution.parameters.ParsingException; 9 | import gauge.messages.Spec.Parameter; 10 | 11 | public interface ParameterParser { 12 | boolean canParse(Class parameterType, Parameter parameter); 13 | 14 | Object parse(Class parameterType, Parameter parameter) throws ParsingException; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/converters/StringToPrimitiveConverter.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.converters; 7 | 8 | import gauge.messages.Spec; 9 | 10 | public interface StringToPrimitiveConverter { 11 | Object convert(Spec.Parameter source) throws Exception; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/converters/TableConverter.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.converters; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import com.thoughtworks.gauge.Table; 12 | 13 | import gauge.messages.Spec; 14 | 15 | public class TableConverter implements StringToPrimitiveConverter { 16 | 17 | public Object convert(Spec.Parameter source) { 18 | Spec.ProtoTable protoTable = source.getTable(); 19 | return tableFromProto(protoTable); 20 | } 21 | 22 | private Object tableFromProto(Spec.ProtoTable protoTable) { 23 | if (protoTable.getHeaders() == null) { 24 | throw new RuntimeException("Invalid table passed"); 25 | } 26 | Spec.ProtoTableRow headerRow = protoTable.getHeaders(); 27 | List headers = getTableRowFor(headerRow); 28 | Table table = new Table(headers); 29 | 30 | for (int i = 0; i < protoTable.getRowsCount(); i++) { 31 | Spec.ProtoTableRow protoRow = protoTable.getRows(i); 32 | table.addRow(getTableRowFor(protoRow)); 33 | } 34 | return table; 35 | 36 | } 37 | 38 | private List getTableRowFor(Spec.ProtoTableRow tableRow) { 39 | List row = new ArrayList<>(); 40 | for (int i = 0; i < tableRow.getCellsCount(); i++) { 41 | row.add(tableRow.getCells(i)); 42 | } 43 | return row; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/types/EnumParameterParser.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import com.google.common.base.Throwables; 9 | import com.thoughtworks.gauge.execution.parameters.ParsingException; 10 | import com.thoughtworks.gauge.execution.parameters.parsers.base.ParameterParser; 11 | import gauge.messages.Spec; 12 | import gauge.messages.Spec.Parameter; 13 | 14 | public class EnumParameterParser implements ParameterParser { 15 | public static final String ENUM_VALUE_NOT_FOUND_MESSAGE = "%s is not an enum value of %s."; 16 | 17 | @Override 18 | public boolean canParse(Class parameterType, Parameter parameter) { 19 | return parameterType.isEnum(); 20 | } 21 | 22 | @Override 23 | public Object parse(Class parameterType, Parameter parameter) throws ParsingException { 24 | @SuppressWarnings("unchecked") 25 | Class> enumClass = (Class>) parameterType; 26 | String enumValue = parameter.getValue(); 27 | try { 28 | return getEnumInstance(enumClass, enumValue); 29 | } catch (IllegalArgumentException e) { 30 | throw new ParsingException(Spec.ProtoExecutionResult.newBuilder().setFailed(true).setExecutionTime(0) 31 | .setStackTrace(Throwables.getStackTraceAsString(e)) 32 | .setErrorMessage(String.format(ENUM_VALUE_NOT_FOUND_MESSAGE, enumValue, enumClass.getSimpleName())) 33 | .build()); 34 | } 35 | } 36 | 37 | @SuppressWarnings({ "unchecked", "rawtypes" }) 38 | public > Enum getEnumInstance(Class clazz, String name) { 39 | return Enum.valueOf(clazz, name); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/types/PrimitiveParameterParser.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import com.google.common.base.Throwables; 9 | import com.thoughtworks.gauge.execution.parameters.ParsingException; 10 | import com.thoughtworks.gauge.execution.parameters.parsers.base.ParameterParser; 11 | import gauge.messages.Spec; 12 | import gauge.messages.Spec.Parameter; 13 | 14 | public class PrimitiveParameterParser implements ParameterParser { 15 | private final PrimitivesConverter primitivesConverter; 16 | 17 | public PrimitiveParameterParser(PrimitivesConverter primitivesConverter) { 18 | this.primitivesConverter = primitivesConverter; 19 | } 20 | 21 | @Override 22 | public boolean canParse(Class parameterType, Parameter parameter) { 23 | return primitivesConverter.contains(parameterType); 24 | } 25 | 26 | @Override 27 | public Object parse(Class parameterType, Parameter parameter) throws ParsingException { 28 | try { 29 | return primitivesConverter.convert(parameterType, parameter); 30 | } catch (Exception e) { 31 | throw new ParsingException(Spec.ProtoExecutionResult.newBuilder().setFailed(true).setExecutionTime(0) 32 | .setStackTrace(Throwables.getStackTraceAsString(e)) 33 | .setErrorMessage(String.format("Failed to convert argument from type String to type %s. %s", 34 | parameterType.toString(), e.getMessage())) 35 | .build()); 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/types/PrimitivesConverter.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import com.thoughtworks.gauge.execution.parameters.parsers.converters.StringToPrimitiveConverter; 9 | import gauge.messages.Spec.Parameter; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | public class PrimitivesConverter { 15 | private final Map, StringToPrimitiveConverter> primitiveConverters = new HashMap<>(); 16 | 17 | public PrimitivesConverter() { 18 | primitiveConverters.put(int.class, source -> Integer.parseInt(source.getValue())); 19 | primitiveConverters.put(Integer.class, source -> Integer.parseInt(source.getValue())); 20 | primitiveConverters.put(boolean.class, source -> Boolean.parseBoolean(source.getValue())); 21 | primitiveConverters.put(Boolean.class, source -> Boolean.parseBoolean(source.getValue())); 22 | primitiveConverters.put(long.class, source -> Long.parseLong(source.getValue())); 23 | primitiveConverters.put(Long.class, source -> Long.parseLong(source.getValue())); 24 | primitiveConverters.put(float.class, source -> Float.parseFloat(source.getValue())); 25 | primitiveConverters.put(Float.class, source -> Float.parseFloat(source.getValue())); 26 | primitiveConverters.put(double.class, source -> Double.parseDouble(source.getValue())); 27 | primitiveConverters.put(Double.class, source -> Double.parseDouble(source.getValue())); 28 | } 29 | 30 | public boolean contains(Class parameterType) { 31 | return primitiveConverters.containsKey(parameterType); 32 | } 33 | 34 | public Object convert(Class parameterType, Parameter parameter) throws Exception { 35 | return primitiveConverters.get(parameterType).convert(parameter); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/execution/parameters/parsers/types/TableParameterParser.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import com.thoughtworks.gauge.execution.parameters.parsers.base.ParameterParser; 9 | import com.thoughtworks.gauge.execution.parameters.parsers.converters.TableConverter; 10 | import gauge.messages.Spec.Parameter; 11 | import gauge.messages.Spec.Parameter.ParameterType; 12 | 13 | public class TableParameterParser implements ParameterParser { 14 | private final TableConverter tableConverter; 15 | 16 | public TableParameterParser(TableConverter tableConverter) { 17 | this.tableConverter = tableConverter; 18 | } 19 | 20 | @Override 21 | public boolean canParse(Class parameterType, Parameter parameter) { 22 | return parameter.getParameterType().equals(ParameterType.Special_Table) 23 | || parameter.getParameterType().equals(ParameterType.Table); 24 | } 25 | 26 | @Override 27 | public Object parse(Class parameterType, Parameter parameter) { 28 | return tableConverter.convert(parameter); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/hook/Hook.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.hook; 7 | 8 | import com.thoughtworks.gauge.Operator; 9 | 10 | import java.lang.reflect.Method; 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | public class Hook implements Comparable { 16 | private final Method method; 17 | private List tags = new ArrayList<>(); 18 | private Operator operator = Operator.AND; 19 | 20 | public Hook(Method method, String[] tags, Operator operator) { 21 | this.method = method; 22 | this.tags = Arrays.asList(tags); 23 | this.operator = operator; 24 | } 25 | 26 | public Hook(Method method) { 27 | this.method = method; 28 | } 29 | 30 | public Method getMethod() { 31 | return method; 32 | } 33 | 34 | public List getTags() { 35 | return tags; 36 | } 37 | 38 | public Operator getTagsAggregation() { 39 | return operator; 40 | } 41 | 42 | public boolean isTagged() { 43 | return !tags.isEmpty(); 44 | } 45 | 46 | @Override 47 | public int compareTo(Hook h) { 48 | if (this.isTagged() && !h.isTagged()) { 49 | return 1; 50 | } 51 | if (!this.isTagged() && h.isTagged()) { 52 | return -1; 53 | } 54 | return this.getMethod().getName().compareTo(h.getMethod().getName()); 55 | } 56 | 57 | @Override 58 | public boolean equals(Object o) { 59 | if (this == o) { 60 | return true; 61 | } 62 | if (o == null || getClass() != o.getClass()) { 63 | return false; 64 | } 65 | Hook hook = (Hook) o; 66 | return getMethod() != null ? getMethod().equals(hook.getMethod()) : hook.getMethod() == null; 67 | } 68 | 69 | @Override 70 | public int hashCode() { 71 | return getMethod() != null ? getMethod().hashCode() : 0; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/CacheFileRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.scan.StaticScanner; 9 | import gauge.messages.Messages; 10 | 11 | import java.io.File; 12 | import java.nio.charset.StandardCharsets; 13 | 14 | public class CacheFileRequestProcessor implements IMessageProcessor { 15 | private final StaticScanner staticScanner; 16 | 17 | public CacheFileRequestProcessor(StaticScanner staticScanner) { 18 | this.staticScanner = staticScanner; 19 | } 20 | 21 | @Override 22 | public Messages.Message process(Messages.Message request) { 23 | String fileName = request.getCacheFileRequest().getFilePath(); 24 | String contents = request.getCacheFileRequest().getContent(); 25 | Messages.CacheFileRequest.FileStatus status = request.getCacheFileRequest().getStatus(); 26 | switch (status) { 27 | case OPENED: 28 | case CHANGED: 29 | staticScanner.reloadSteps(fileName, contents); 30 | break; 31 | case DELETED: 32 | staticScanner.removeSteps(fileName); 33 | break; 34 | case CREATED: 35 | if (!staticScanner.isFileCached(fileName)) { 36 | loadFromDisk(fileName); 37 | } 38 | break; 39 | case CLOSED: 40 | loadFromDisk(fileName); 41 | break; 42 | default: 43 | throw new IllegalArgumentException(); 44 | } 45 | return Messages.Message.newBuilder().build(); 46 | } 47 | 48 | private void loadFromDisk(String fileName) { 49 | if ((new File(fileName).exists())) { 50 | staticScanner.reloadSteps(fileName, staticScanner.readFile(fileName, StandardCharsets.UTF_8)); 51 | } 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/ClearObjectCache.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | 10 | public enum ClearObjectCache { 11 | SUITE_LEVEL("suite"), SPEC_LEVEL("spec"), SCENARIO_LEVEL("scenario"); 12 | 13 | private static final String CLEAR_STATE_FLAG = "gauge_clear_state_level"; 14 | private final String level; 15 | 16 | ClearObjectCache(String level) { 17 | this.level = level; 18 | } 19 | 20 | public static void clear(ClearObjectCache currentPosition, ClassInstanceManager manager) { 21 | String level = System.getenv(CLEAR_STATE_FLAG); 22 | if (level != null && level.equals(currentPosition.level)) { 23 | manager.clearCache(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/DefaultMessageProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import gauge.messages.Messages; 9 | import gauge.messages.Spec; 10 | 11 | public class DefaultMessageProcessor implements IMessageProcessor { 12 | @Override 13 | public Messages.Message process(Messages.Message message) { 14 | Messages.ExecutionStatusResponse.Builder response = Messages.ExecutionStatusResponse.newBuilder().setExecutionResult(Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(0).build()); 15 | 16 | return Messages.Message.newBuilder() 17 | .setMessageId(message.getMessageId()) 18 | .setMessageType(Messages.Message.MessageType.ExecutionStatusResponse) 19 | .setExecutionStatusResponse(response) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/ExecuteStepProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.Logger; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionPipeline; 13 | import com.thoughtworks.gauge.execution.HookExecutionStage; 14 | import com.thoughtworks.gauge.execution.StepExecutionStage; 15 | import com.thoughtworks.gauge.execution.parameters.parsers.base.ParameterParsingChain; 16 | import com.thoughtworks.gauge.registry.HooksRegistry; 17 | import com.thoughtworks.gauge.registry.StepRegistry; 18 | import gauge.messages.Messages; 19 | import gauge.messages.Spec; 20 | 21 | import java.lang.reflect.Method; 22 | 23 | public class ExecuteStepProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 24 | 25 | private final ParameterParsingChain chain; 26 | private final StepRegistry registry; 27 | 28 | public ExecuteStepProcessor(ClassInstanceManager instanceManager, ParameterParsingChain chain, StepRegistry stepRegistry) { 29 | super(instanceManager); 30 | this.chain = chain; 31 | this.registry = stepRegistry; 32 | } 33 | 34 | public Messages.Message process(Messages.Message message) { 35 | String stepText = message.getExecuteStepRequest().getParsedStepText(); 36 | Method method = registry.get(stepText).getMethodInfo(); 37 | if (method == null) { 38 | Logger.fatal("No step definition found. Try compiling the source before execution."); 39 | } 40 | Logger.debug("Executing '" + stepText + "' using '" + method.getDeclaringClass() + "." + method.getName()); 41 | ExecutionPipeline pipeline = new ExecutionPipeline(new HookExecutionStage(HooksRegistry.getBeforeClassStepsHooksOfClass(method.getDeclaringClass()), getInstanceManager())); 42 | pipeline.addStages(new StepExecutionStage(message.getExecuteStepRequest(), getInstanceManager(), chain, registry), 43 | new HookExecutionStage(HooksRegistry.getAfterClassStepsHooksOfClass(method.getDeclaringClass()), getInstanceManager())); 44 | Spec.ProtoExecutionResult executionResult = pipeline.start(); 45 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 46 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 47 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/IMessageProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | 9 | import gauge.messages.Messages; 10 | 11 | public interface IMessageProcessor { 12 | Messages.Message process(Messages.Message message); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/KillProcessProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import gauge.messages.Messages; 9 | 10 | public class KillProcessProcessor implements IMessageProcessor { 11 | 12 | public KillProcessProcessor() { 13 | } 14 | 15 | public Messages.Message process(Messages.Message message) { 16 | return message; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/MethodExecutionMessageProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.execution.HooksExecutor; 11 | import com.thoughtworks.gauge.execution.MethodExecutor; 12 | import com.thoughtworks.gauge.hook.Hook; 13 | import gauge.messages.Messages; 14 | import gauge.messages.Spec; 15 | 16 | import java.lang.reflect.Method; 17 | import java.util.HashSet; 18 | import java.util.List; 19 | import java.util.Set; 20 | 21 | public abstract class MethodExecutionMessageProcessor { 22 | 23 | private final ClassInstanceManager instanceManager; 24 | 25 | public MethodExecutionMessageProcessor(ClassInstanceManager instanceManager) { 26 | this.instanceManager = instanceManager; 27 | } 28 | 29 | public Messages.Message execute(Method method, Messages.Message message, Object... args) { 30 | HashSet methods = new HashSet<>(); 31 | methods.add(method); 32 | return execute(methods, message, args); 33 | } 34 | 35 | protected ClassInstanceManager getInstanceManager() { 36 | return instanceManager; 37 | } 38 | 39 | public Messages.Message execute(Set methods, Messages.Message message, Object... args) { 40 | MethodExecutor methodExecutor = new MethodExecutor(instanceManager); 41 | long totalExecutionTime = 0; 42 | for (Method method : methods) { 43 | Spec.ProtoExecutionResult result = methodExecutor.execute(method, args); 44 | totalExecutionTime += result.getExecutionTime(); 45 | if (result.getFailed()) { 46 | return createMessageWithExecutionStatusResponse(message, result); 47 | } 48 | } 49 | 50 | Spec.ProtoExecutionResult passingExecution = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(totalExecutionTime).build(); 51 | return createMessageWithExecutionStatusResponse(message, passingExecution); 52 | } 53 | 54 | public Messages.Message executeHooks(List hooks, Messages.Message message, ExecutionContext executionInfo) { 55 | Spec.ProtoExecutionResult executionStatusResponse = new HooksExecutor(hooks, executionInfo, instanceManager).execute(); 56 | return createMessageWithExecutionStatusResponse(message, executionStatusResponse); 57 | } 58 | 59 | public Messages.Message createMessageWithExecutionStatusResponse(Messages.Message receivedMessage, Spec.ProtoExecutionResult result) { 60 | return Messages.Message.newBuilder() 61 | .setMessageId(receivedMessage.getMessageId()) 62 | .setMessageType(Messages.Message.MessageType.ExecutionStatusResponse) 63 | .setExecutionStatusResponse(Messages.ExecutionStatusResponse.newBuilder().setExecutionResult(result).build()) 64 | .build(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/RefactorRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | 9 | import com.thoughtworks.gauge.StepValue; 10 | import com.thoughtworks.gauge.refactor.JavaRefactoring; 11 | import com.thoughtworks.gauge.refactor.RefactoringResult; 12 | import com.thoughtworks.gauge.registry.StepRegistry; 13 | import gauge.messages.Messages; 14 | 15 | import java.util.List; 16 | 17 | public class RefactorRequestProcessor implements IMessageProcessor { 18 | private final StepRegistry registry; 19 | 20 | public RefactorRequestProcessor(StepRegistry registry) { 21 | this.registry = registry; 22 | } 23 | 24 | public Messages.Message process(Messages.Message message) { 25 | Messages.RefactorRequest refactorRequest = message.getRefactorRequest(); 26 | boolean saveChanges = refactorRequest.getSaveChanges(); 27 | StepValue oldStepValue = StepValue.from(refactorRequest.getOldStepValue()); 28 | StepValue newStepValue = StepValue.from(refactorRequest.getNewStepValue()); 29 | String parameterizedStepValue = refactorRequest.getNewStepValue().getParameterizedStepValue(); 30 | List paramPositions = refactorRequest.getParamPositionsList(); 31 | RefactoringResult result = new JavaRefactoring(oldStepValue, newStepValue, paramPositions, registry, parameterizedStepValue, saveChanges).performRefactoring(); 32 | return createRefactorResponse(message, result); 33 | } 34 | 35 | private Messages.Message createRefactorResponse(Messages.Message message, RefactoringResult result) { 36 | Messages.RefactorResponse response = Messages.RefactorResponse.newBuilder() 37 | .setSuccess(result.passed()) 38 | .setError(result.errorMessage()) 39 | .addFilesChanged(result.fileChanged()) 40 | .addFileChanges(result.fileChanges()) 41 | .build(); 42 | 43 | return Messages.Message.newBuilder() 44 | .setMessageId(message.getMessageId()) 45 | .setMessageType(Messages.Message.MessageType.RefactorResponse) 46 | .setRefactorResponse(response) 47 | .build(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/ScenarioExecutionEndingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class ScenarioExecutionEndingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | public ScenarioExecutionEndingProcessor(ClassInstanceManager instanceManager) { 20 | super(instanceManager); 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getScenarioExecutionEndingRequest().getCurrentExecutionInfo()); 25 | Messages.Message result = executeHooks(HooksRegistry.getAfterScenarioHooks(), message, info); 26 | ClearObjectCache.clear(ClearObjectCache.SCENARIO_LEVEL, getInstanceManager()); 27 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 28 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 29 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 30 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/ScenarioExecutionStartingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class ScenarioExecutionStartingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | public ScenarioExecutionStartingProcessor(ClassInstanceManager instanceManager) { 19 | super(instanceManager); 20 | } 21 | 22 | public Messages.Message process(Messages.Message message) { 23 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getScenarioExecutionStartingRequest().getCurrentExecutionInfo()); 24 | Messages.Message result = executeHooks(HooksRegistry.getBeforeScenarioHooks(), message, info); 25 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 26 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 27 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 28 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/SpecExecutionEndingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class SpecExecutionEndingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | public SpecExecutionEndingProcessor(ClassInstanceManager instanceManager) { 20 | super(instanceManager); 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getSpecExecutionEndingRequest().getCurrentExecutionInfo()); 25 | Messages.Message result = executeHooks(HooksRegistry.getAfterSpecHooks(), message, info); 26 | ClearObjectCache.clear(ClearObjectCache.SPEC_LEVEL, getInstanceManager()); 27 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 28 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 29 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 30 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/SpecExecutionStartingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.MessageCollector; 10 | import com.thoughtworks.gauge.ScreenshotCollector; 11 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 12 | import com.thoughtworks.gauge.registry.HooksRegistry; 13 | import com.thoughtworks.gauge.ExecutionContext; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class SpecExecutionStartingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | public SpecExecutionStartingProcessor(ClassInstanceManager instanceManager) { 20 | super(instanceManager); 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getSpecExecutionStartingRequest().getCurrentExecutionInfo()); 25 | Messages.Message result = executeHooks(HooksRegistry.getBeforeSpecHooks(), message, info); 26 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 27 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 28 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 29 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/StepExecutionEndingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class StepExecutionEndingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | public StepExecutionEndingProcessor(ClassInstanceManager instanceManager) { 20 | super(instanceManager); 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getStepExecutionEndingRequest().getCurrentExecutionInfo()); 25 | Messages.Message result = executeHooks(HooksRegistry.getAfterStepHooks(), message, info); 26 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 27 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 28 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 29 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/StepExecutionStartingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class StepExecutionStartingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | public StepExecutionStartingProcessor(ClassInstanceManager instanceManager) { 20 | super(instanceManager); 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getStepExecutionStartingRequest().getCurrentExecutionInfo()); 25 | Messages.Message result = executeHooks(HooksRegistry.getBeforeStepHooks(), message, info); 26 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 27 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 28 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 29 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/StepNameRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.github.javaparser.Range; 9 | import com.thoughtworks.gauge.StepRegistryEntry; 10 | import com.thoughtworks.gauge.registry.StepRegistry; 11 | import gauge.messages.Messages; 12 | import gauge.messages.Spec; 13 | 14 | import java.util.List; 15 | 16 | public class StepNameRequestProcessor implements IMessageProcessor { 17 | private final StepRegistry registry; 18 | 19 | public StepNameRequestProcessor(StepRegistry registry) { 20 | this.registry = registry; 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | boolean isStepPresent = registry.contains(message.getStepNameRequest().getStepValue()); 25 | if (!isStepPresent) { 26 | return Messages.Message.newBuilder() 27 | .setMessageId(message.getMessageId()) 28 | .setMessageType(Messages.Message.MessageType.StepNameResponse) 29 | .setStepNameResponse(Messages.StepNameResponse.newBuilder().setIsStepPresent(false).build()) 30 | .build(); 31 | } 32 | StepRegistryEntry entry = registry.get(message.getStepNameRequest().getStepValue()); 33 | 34 | if (entry.getIsExternal()) { 35 | return Messages.Message.newBuilder() 36 | .setMessageId(message.getMessageId()) 37 | .setMessageType(Messages.Message.MessageType.StepNameResponse) 38 | .setStepNameResponse(Messages.StepNameResponse.newBuilder() 39 | .setIsStepPresent(true) 40 | .setIsExternal(true)) 41 | .build(); 42 | } 43 | List stepTexts = entry.getAliases(); 44 | Range range = entry.getSpan(); 45 | String stepText = entry.getStepText(); 46 | String fileName = entry.getFileName(); 47 | boolean hasAlias = entry.getHasAlias(); 48 | if (!hasAlias) { 49 | stepTexts.add(stepText); 50 | } 51 | Spec.Span.Builder spanBuilder = Spec.Span.newBuilder() 52 | .setStart(range.begin.line) 53 | .setStartChar(range.begin.column) 54 | .setEnd(range.end.line) 55 | .setEndChar(range.end.column); 56 | 57 | return Messages.Message.newBuilder() 58 | .setMessageId(message.getMessageId()) 59 | .setMessageType(Messages.Message.MessageType.StepNameResponse) 60 | .setStepNameResponse(Messages.StepNameResponse.newBuilder() 61 | .addAllStepName(stepTexts) 62 | .setIsStepPresent(true) 63 | .setHasAlias(hasAlias) 64 | .setFileName(fileName) 65 | .setSpan(spanBuilder).build()) 66 | .build(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/StepNamesRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | 9 | import com.thoughtworks.gauge.registry.StepRegistry; 10 | import gauge.messages.Messages; 11 | 12 | import java.util.List; 13 | 14 | public class StepNamesRequestProcessor implements IMessageProcessor { 15 | private final StepRegistry registry; 16 | 17 | public StepNamesRequestProcessor(StepRegistry registry) { 18 | this.registry = registry; 19 | } 20 | 21 | public Messages.Message process(Messages.Message receivedMessage) { 22 | List stepTexts = registry.getAllStepAnnotationTexts(); 23 | 24 | return Messages.Message.newBuilder() 25 | .setMessageId(receivedMessage.getMessageId()) 26 | .setMessageType(Messages.Message.MessageType.StepNamesResponse) 27 | .setStepNamesResponse(Messages.StepNamesResponse.newBuilder().addAllSteps(stepTexts).build()) 28 | .build(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/StepPositionsRequestProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.registry.StepRegistry; 9 | import gauge.messages.Messages; 10 | 11 | import java.util.List; 12 | 13 | public class StepPositionsRequestProcessor implements IMessageProcessor { 14 | private final StepRegistry stepRegistry; 15 | 16 | public StepPositionsRequestProcessor(StepRegistry stepRegistry) { 17 | this.stepRegistry = stepRegistry; 18 | } 19 | 20 | @Override 21 | public Messages.Message process(Messages.Message message) { 22 | List positions = stepRegistry.getStepPositions(message.getStepPositionsRequest().getFilePath()); 23 | 24 | return Messages.Message.newBuilder() 25 | .setMessageId(message.getMessageId()) 26 | .setStepPositionsResponse(Messages.StepPositionsResponse.newBuilder().addAllStepPositions(positions)) 27 | .setMessageType(Messages.Message.MessageType.StepPositionsResponse) 28 | .build(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/SuiteExecutionEndingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class SuiteExecutionEndingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | public SuiteExecutionEndingProcessor(ClassInstanceManager instanceManager) { 20 | super(instanceManager); 21 | } 22 | 23 | public Messages.Message process(Messages.Message message) { 24 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getExecutionEndingRequest().getCurrentExecutionInfo()); 25 | Messages.Message result = executeHooks(HooksRegistry.getAfterSuiteHooks(), message, info); 26 | ClearObjectCache.clear(ClearObjectCache.SPEC_LEVEL, getInstanceManager()); 27 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 28 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 29 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 30 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/processor/SuiteExecutionStartingProcessor.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.ClassInstanceManager; 9 | import com.thoughtworks.gauge.ExecutionContext; 10 | import com.thoughtworks.gauge.MessageCollector; 11 | import com.thoughtworks.gauge.ScreenshotCollector; 12 | import com.thoughtworks.gauge.execution.ExecutionInfoMapper; 13 | import com.thoughtworks.gauge.registry.HooksRegistry; 14 | import gauge.messages.Messages; 15 | import gauge.messages.Spec; 16 | 17 | public class SuiteExecutionStartingProcessor extends MethodExecutionMessageProcessor implements IMessageProcessor { 18 | 19 | 20 | public SuiteExecutionStartingProcessor(ClassInstanceManager instanceManager) { 21 | super(instanceManager); 22 | } 23 | 24 | public Messages.Message process(Messages.Message message) { 25 | ExecutionContext info = new ExecutionInfoMapper().executionInfoFrom(message.getExecutionStartingRequest().getCurrentExecutionInfo()); 26 | Messages.Message result = executeHooks(HooksRegistry.getBeforeSuiteHooks(), message, info); 27 | Spec.ProtoExecutionResult executionResult = result.getExecutionStatusResponse().getExecutionResult(); 28 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessagesTo(executionResult); 29 | protoExecutionResult = new ScreenshotCollector().addPendingScreenshotTo(protoExecutionResult); 30 | return createMessageWithExecutionStatusResponse(message, protoExecutionResult); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/refactor/Diff.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.refactor; 7 | 8 | import com.github.javaparser.Range; 9 | 10 | public class Diff { 11 | private final String text; 12 | private final Range range; 13 | 14 | public Diff(String text, Range range) { 15 | this.text = text; 16 | this.range = range; 17 | } 18 | 19 | public String getText() { 20 | return text; 21 | } 22 | 23 | public Range getRange() { 24 | return range; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/refactor/FileModifier.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.refactor; 7 | 8 | import java.io.IOException; 9 | import java.nio.file.Files; 10 | 11 | public class FileModifier { 12 | private final JavaRefactoringElement javaElement; 13 | 14 | public FileModifier(JavaRefactoringElement javaElement) { 15 | this.javaElement = javaElement; 16 | } 17 | 18 | public void refactor() throws IOException { 19 | write(); 20 | } 21 | 22 | private void write() throws IOException { 23 | Files.writeString(javaElement.getFile().toPath(), javaElement.getText(), JavaParseWorker.CHARSET); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/refactor/JavaParseWorker.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.refactor; 7 | 8 | 9 | import com.github.javaparser.JavaParser; 10 | import com.github.javaparser.ast.CompilationUnit; 11 | import com.thoughtworks.gauge.Logger; 12 | 13 | import java.io.File; 14 | import java.nio.charset.Charset; 15 | import java.nio.charset.StandardCharsets; 16 | import java.util.Optional; 17 | 18 | public class JavaParseWorker extends Thread { 19 | 20 | public static final Charset CHARSET = StandardCharsets.UTF_8; 21 | private final File javaFile; 22 | private CompilationUnit compilationUnit; 23 | 24 | JavaParseWorker(File javaFile) { 25 | this.javaFile = javaFile; 26 | } 27 | 28 | public void run() { 29 | try { 30 | Optional result = new JavaParser().parse(javaFile).getResult(); 31 | result.ifPresent(value -> compilationUnit = value); 32 | } catch (Exception e) { 33 | Logger.error("Unable to parse file " + javaFile.getName()); 34 | } 35 | } 36 | 37 | public File getJavaFile() { 38 | return javaFile; 39 | } 40 | 41 | CompilationUnit getCompilationUnit() { 42 | try { 43 | join(); 44 | } catch (InterruptedException e) { 45 | Thread.currentThread().interrupt(); 46 | } 47 | return compilationUnit; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/refactor/JavaRefactoringElement.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.refactor; 7 | 8 | import java.io.File; 9 | import java.util.ArrayList; 10 | 11 | public class JavaRefactoringElement { 12 | private final ArrayList diffs; 13 | private final String text; 14 | private File file; 15 | 16 | public JavaRefactoringElement(String text, File file) { 17 | this.text = text; 18 | this.file = file; 19 | this.diffs = new ArrayList<>(); 20 | } 21 | 22 | public File getFile() { 23 | return file; 24 | } 25 | 26 | public void setFile(File file) { 27 | this.file = file; 28 | } 29 | 30 | public String getText() { 31 | return text; 32 | } 33 | 34 | public ArrayList getDiffs() { 35 | return diffs; 36 | } 37 | 38 | public void addDiffs(Diff diff) { 39 | this.diffs.add(diff); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/refactor/RefactoringException.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.refactor; 7 | 8 | 9 | public class RefactoringException extends Exception { 10 | public RefactoringException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/refactor/RefactoringResult.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.refactor; 7 | 8 | import com.github.javaparser.Range; 9 | import gauge.messages.Messages; 10 | import gauge.messages.Spec; 11 | 12 | import java.util.ArrayList; 13 | 14 | public class RefactoringResult { 15 | private final boolean passed; 16 | private final String errorMessage; 17 | private final String fileChanged; 18 | private final Messages.FileChanges fileChanges; 19 | 20 | public RefactoringResult(boolean passed, String errorMessage) { 21 | this.passed = passed; 22 | this.errorMessage = errorMessage; 23 | this.fileChanged = ""; 24 | this.fileChanges = Messages.FileChanges.newBuilder().build(); 25 | } 26 | 27 | public RefactoringResult(boolean passed, JavaRefactoringElement element) { 28 | this.passed = passed; 29 | this.errorMessage = ""; 30 | this.fileChanged = element.getFile().getAbsolutePath(); 31 | this.fileChanges = getFileChanges(element); 32 | } 33 | 34 | private Messages.FileChanges getFileChanges(JavaRefactoringElement element) { 35 | ArrayList diffs = element.getDiffs(); 36 | Messages.FileChanges.Builder changes = Messages.FileChanges.newBuilder().setFileName(element.getFile().getAbsolutePath()); 37 | for (Diff diff : diffs) { 38 | Range range = diff.getRange(); 39 | String text = diff.getText(); 40 | Spec.Span span = Spec.Span.newBuilder() 41 | .setStart(range.begin.line) 42 | .setStartChar(range.begin.column) 43 | .setEnd(range.end.line) 44 | .setEndChar(range.end.column).build(); 45 | Messages.TextDiff textDiff = Messages.TextDiff.newBuilder().setContent(text).setSpan(span).build(); 46 | changes.addDiffs(textDiff); 47 | } 48 | return changes.build(); 49 | } 50 | 51 | public boolean passed() { 52 | return this.passed; 53 | } 54 | 55 | public String errorMessage() { 56 | return this.errorMessage; 57 | } 58 | 59 | public String fileChanged() { 60 | return this.fileChanged; 61 | } 62 | 63 | public Messages.FileChanges fileChanges() { 64 | return this.fileChanges; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/registry/ClassInitializerRegistry.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.registry; 7 | 8 | import com.thoughtworks.gauge.ClassInitializer; 9 | import com.thoughtworks.gauge.DefaultClassInitializer; 10 | 11 | public class ClassInitializerRegistry { 12 | private static ClassInitializer classInitializer = new DefaultClassInitializer(); 13 | 14 | public static void classInitializer(ClassInitializer initializer) { 15 | classInitializer = initializer; 16 | } 17 | 18 | public static ClassInitializer classInitializer() { 19 | return classInitializer; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/scan/ClasspathScanner.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.scan; 7 | 8 | import com.thoughtworks.gauge.ClasspathHelper; 9 | import org.reflections.Configuration; 10 | import org.reflections.Reflections; 11 | import org.reflections.scanners.Scanners; 12 | import org.reflections.util.ConfigurationBuilder; 13 | import org.reflections.util.FilterBuilder; 14 | import org.reflections.vfs.SystemDir; 15 | import org.reflections.vfs.Vfs; 16 | import org.reflections.vfs.ZipDir; 17 | 18 | import java.io.File; 19 | import java.net.URL; 20 | import java.util.jar.JarFile; 21 | 22 | import static com.thoughtworks.gauge.GaugeConstant.PACKAGE_TO_SCAN; 23 | 24 | /** 25 | * Scans the current Classpath and passes to all the scanners passed. 26 | */ 27 | public class ClasspathScanner { 28 | 29 | private Reflections reflections; 30 | 31 | public void scan(IScanner... scanners) { 32 | reflections = createReflections(); 33 | for (IScanner scanner : scanners) { 34 | scanner.scan(reflections); 35 | } 36 | } 37 | 38 | private Reflections createReflections() { 39 | Vfs.addDefaultURLTypes(new Vfs.UrlType() { 40 | @Override 41 | public boolean matches(URL url) { 42 | return "file".equals(url.getProtocol()); 43 | } 44 | 45 | @Override 46 | public Vfs.Dir createDir(URL url) throws Exception { 47 | File file = Vfs.getFile(url); 48 | return file.isDirectory() ? new SystemDir(file) : new ZipDir(new JarFile(Vfs.getFile(url))); 49 | } 50 | }); 51 | 52 | Configuration config = new ConfigurationBuilder() 53 | .setScanners(Scanners.MethodsAnnotated, Scanners.SubTypes) 54 | .addUrls(ClasspathHelper.getUrls()) 55 | .filterInputsBy(this::shouldScan); 56 | 57 | return new Reflections(config); 58 | } 59 | 60 | private boolean shouldScan(String s) { 61 | final String packagesToScan = System.getenv(PACKAGE_TO_SCAN); 62 | if (packagesToScan == null || packagesToScan.isEmpty()) { 63 | return new FilterBuilder().includePattern(".+\\.class").test(s); 64 | } 65 | final String[] packages = packagesToScan.split(","); 66 | for (String packageToScan : packages) { 67 | String regex = String.format(".?\\.??%s\\..+\\.class", packageToScan); 68 | if (new FilterBuilder().includePattern(regex).test(s)) { 69 | return true; 70 | } 71 | } 72 | return false; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/scan/CustomClassInitializerScanner.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.scan; 7 | 8 | import com.thoughtworks.gauge.ClassInitializer; 9 | import com.thoughtworks.gauge.DefaultClassInitializer; 10 | import com.thoughtworks.gauge.Logger; 11 | import com.thoughtworks.gauge.registry.ClassInitializerRegistry; 12 | import org.reflections.Reflections; 13 | 14 | import java.util.Set; 15 | 16 | public class CustomClassInitializerScanner implements IScanner { 17 | @Override 18 | public void scan(Reflections reflections) { 19 | scanForInitializer(reflections); 20 | } 21 | 22 | private void scanForInitializer(Reflections reflections) { 23 | Set> initializers = reflections.getSubTypesOf(ClassInitializer.class); 24 | initializers.remove(DefaultClassInitializer.class); 25 | if (initializers.size() == 1) { 26 | Class initializer = initializers.iterator().next(); 27 | try { 28 | ClassInitializerRegistry.classInitializer(initializer.newInstance()); 29 | Logger.debug(String.format("Using %s as class initializer", initializer.getName())); 30 | } catch (InstantiationException e) { 31 | Logger.error(String.format("Could not instantiate %s, continuing using default class initializer", initializer.getName())); 32 | } catch (IllegalAccessException e) { 33 | Logger.error(String.format("Could not access %s constructor, continuing using default class initializer", initializer.getName())); 34 | } 35 | } 36 | 37 | if (initializers.size() > 1) { 38 | Logger.warning("Multiple class initializers found, switching to default."); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/scan/HooksScanner.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.scan; 7 | 8 | import com.thoughtworks.gauge.AfterClassSteps; 9 | import com.thoughtworks.gauge.AfterScenario; 10 | import com.thoughtworks.gauge.AfterSpec; 11 | import com.thoughtworks.gauge.AfterStep; 12 | import com.thoughtworks.gauge.AfterSuite; 13 | import com.thoughtworks.gauge.BeforeClassSteps; 14 | import com.thoughtworks.gauge.BeforeScenario; 15 | import com.thoughtworks.gauge.BeforeSpec; 16 | import com.thoughtworks.gauge.BeforeStep; 17 | import com.thoughtworks.gauge.BeforeSuite; 18 | import com.thoughtworks.gauge.Logger; 19 | import com.thoughtworks.gauge.registry.HooksRegistry; 20 | import org.reflections.Reflections; 21 | 22 | /** 23 | * Scans for all Execution Hooks. 24 | */ 25 | public class HooksScanner implements IScanner { 26 | 27 | public void scan(Reflections reflections) { 28 | Logger.debug("Scanning packages for hooks"); 29 | buildHooksRegistry(reflections); 30 | } 31 | 32 | private void buildHooksRegistry(Reflections reflections) { 33 | HooksRegistry.addBeforeSuiteHooks(reflections.getMethodsAnnotatedWith(BeforeSuite.class)); 34 | HooksRegistry.addAfterSuiteHooks(reflections.getMethodsAnnotatedWith(AfterSuite.class)); 35 | HooksRegistry.addBeforeSpecHooks(reflections.getMethodsAnnotatedWith(BeforeSpec.class)); 36 | HooksRegistry.addAfterSpecHooks(reflections.getMethodsAnnotatedWith(AfterSpec.class)); 37 | HooksRegistry.addBeforeScenarioHooks(reflections.getMethodsAnnotatedWith(BeforeScenario.class)); 38 | HooksRegistry.addAfterScenarioHooks(reflections.getMethodsAnnotatedWith(AfterScenario.class)); 39 | HooksRegistry.addBeforeStepHooks(reflections.getMethodsAnnotatedWith(BeforeStep.class)); 40 | HooksRegistry.setAfterStepHooks(reflections.getMethodsAnnotatedWith(AfterStep.class)); 41 | HooksRegistry.addBeforeClassStepsHooks(reflections.getMethodsAnnotatedWith(BeforeClassSteps.class)); 42 | HooksRegistry.addAfterClassStepsHooks(reflections.getMethodsAnnotatedWith(AfterClassSteps.class)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/scan/IScanner.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.scan; 7 | 8 | import org.reflections.Reflections; 9 | 10 | public interface IScanner { 11 | 12 | void scan(Reflections reflections); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/scan/StepsScanner.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.scan; 7 | 8 | import com.thoughtworks.gauge.*; 9 | import com.thoughtworks.gauge.registry.StepRegistry; 10 | import org.reflections.Reflections; 11 | 12 | import java.lang.reflect.Method; 13 | import java.util.List; 14 | import java.util.Set; 15 | 16 | /** 17 | * Scans for step implementations. 18 | */ 19 | public class StepsScanner implements IScanner { 20 | private final StepRegistry registry; 21 | 22 | public StepsScanner(StepRegistry registry) { 23 | this.registry = registry; 24 | } 25 | 26 | public void scan(Reflections reflections) { 27 | Logger.debug("Scanning packages for steps"); 28 | Set stepImplementations = reflections.getMethodsAnnotatedWith(Step.class); 29 | buildStepRegistry(stepImplementations); 30 | } 31 | 32 | private void buildStepRegistry(Set stepImplementations) { 33 | StepsUtil stepsUtil = new StepsUtil(); 34 | for (Method method : stepImplementations) { 35 | Step annotation = method.getAnnotation(Step.class); 36 | if (annotation != null) { 37 | for (String stepName : annotation.value()) { 38 | String parameterizedStep = Util.trimQuotes(stepName); 39 | String stepText = stepsUtil.getStepText(parameterizedStep); 40 | if (registry.contains(stepText)) { 41 | StepRegistryEntry entry = registry.getForCurrentProject(stepText, method); 42 | if (entry != null) { 43 | Logger.debug("Found " + stepText + " in current project scope."); 44 | entry.setMethodInfo(method); 45 | } else { 46 | addExternalStepEntryToRegistry(stepsUtil, method, parameterizedStep, stepText); 47 | } 48 | } else { 49 | addExternalStepEntryToRegistry(stepsUtil, method, parameterizedStep, stepText); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | private void addExternalStepEntryToRegistry(StepsUtil stepsUtil, Method method, String parameterizedStep, String stepText) { 57 | Logger.debug("Loading " + stepText + "via reflected sources."); 58 | List parameters = stepsUtil.getParameters(parameterizedStep); 59 | StepValue stepValue = new StepValue(stepText, parameterizedStep, parameters); 60 | registry.addStepImplementation(stepValue, method, true); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/scan/StepsUtil.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.scan; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.regex.Pattern; 11 | import java.util.stream.Collectors; 12 | 13 | public class StepsUtil { 14 | public String getStepText(String parameterizedStepText) { 15 | return parameterizedStepText 16 | .replaceAll("(<.*?>)", "{}"); 17 | } 18 | 19 | public List getParameters(String parameterizedStepText) { 20 | Pattern pattern = Pattern.compile("(<.*?>)"); 21 | return Arrays.stream(parameterizedStepText.split(" ")) 22 | .filter(pattern.asPredicate()) 23 | .map(s -> s.substring(1, s.length() - 1)) 24 | .collect(Collectors.toList()); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshot.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.screenshot; 7 | 8 | interface CustomScreenshot { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotScanner.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.screenshot; 7 | 8 | import com.thoughtworks.gauge.Logger; 9 | import com.thoughtworks.gauge.scan.IScanner; 10 | import org.reflections.Reflections; 11 | 12 | import java.util.Set; 13 | 14 | /** 15 | * Scans for a custom screenshot grabber. 16 | */ 17 | public class CustomScreenshotScanner implements IScanner { 18 | public void scan(Reflections reflections) { 19 | Set> customScreenshotGrabbers = reflections.getSubTypesOf(ICustomScreenshotGrabber.class); 20 | 21 | if (customScreenshotGrabbers.size() > 0) { 22 | Class customScreenGrabber = customScreenshotGrabbers.iterator().next(); 23 | Logger.debug(String.format("Using %s as custom screenshot grabber", customScreenGrabber.getName())); 24 | ScreenshotFactory.setCustomScreenshotGrabber(customScreenGrabber); 25 | } 26 | 27 | Set> customScreenshotWriters = reflections.getSubTypesOf(CustomScreenshotWriter.class); 28 | 29 | if (customScreenshotWriters.size() > 0) { 30 | Class customScreenWriter = customScreenshotWriters.iterator().next(); 31 | Logger.debug(String.format("Using %s as custom screenshot grabber", customScreenWriter.getName())); 32 | ScreenshotFactory.setCustomScreenshotGrabber(customScreenWriter); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/screenshot/CustomScreenshotWriter.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.screenshot; 7 | 8 | /** 9 | * Implement this interface to take Custom Screenshots on Failure. It overrides the default screenshot taking mechanism. 10 | * The captured screenshots can be seen on the reports on failure. 11 | * If multiple implementations are found, one will be picked randomly to capture screenshots. 12 | * Implementation of this interface should capture screenshot and write them into a unique file 13 | * inside screenshots directory. Use "gauge_screenshots_dir" env to get screenshot directory path" 14 | */ 15 | public interface CustomScreenshotWriter extends CustomScreenshot { 16 | 17 | /** 18 | * @return Name of the screenshot file taken. 19 | */ 20 | String takeScreenshot(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/screenshot/ICustomScreenshotGrabber.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.screenshot; 7 | 8 | /** 9 | * Implement this interface to take Custom Screenshots on Failure. It overrides the default screenshot taking mechanism. 10 | * The captured screenshots can be seen on the reports on failure. 11 | * If multiple implementations are found, one will be picked randomly to capture screenshots. 12 | */ 13 | @Deprecated 14 | public interface ICustomScreenshotGrabber extends CustomScreenshot { 15 | 16 | 17 | /** 18 | * @return Byte array of the screenshot taken. 19 | * Return an empty Byte array if unable to capture screen. 20 | */ 21 | byte[] takeScreenshot(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/tag/AndMatcher.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.tag; 7 | 8 | import java.util.List; 9 | 10 | public class AndMatcher implements SimpleTagMatcher { 11 | public boolean isMatch(List tagsToMatch, List tagsToMatchWith) { 12 | if (tagsToMatch.size() == 0) { 13 | return true; 14 | } 15 | for (String tag : tagsToMatch) { 16 | if (!tagsToMatchWith.contains(tag)) { 17 | return false; 18 | } 19 | } 20 | return true; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/tag/OrMatcher.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.tag; 7 | 8 | import java.util.List; 9 | 10 | public class OrMatcher implements SimpleTagMatcher { 11 | public boolean isMatch(List tagsToMatch, List tagsToMatchWith) { 12 | if (tagsToMatch.size() == 0) { 13 | return true; 14 | } 15 | for (String tag : tagsToMatch) { 16 | if (tagsToMatchWith.contains(tag)) { 17 | return true; 18 | } 19 | } 20 | return false; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/tag/SimpleTagMatcher.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.tag; 7 | 8 | import java.util.List; 9 | 10 | public interface SimpleTagMatcher { 11 | boolean isMatch(List tagsToMatch, List tagsToMatchWith); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/thoughtworks/gauge/tag/TagMatcher.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.tag; 7 | 8 | import com.thoughtworks.gauge.Operator; 9 | 10 | import java.util.List; 11 | 12 | public class TagMatcher { 13 | public boolean isMatch(List tags, Operator operator, List allTags) { 14 | return new TagMatcherFactory().matcherFor(operator).isMatch(tags, allTags); 15 | } 16 | 17 | private static final class TagMatcherFactory { 18 | public SimpleTagMatcher matcherFor(Operator operator) { 19 | switch (operator) { 20 | case OR: 21 | return new OrMatcher(); 22 | default: 23 | return new AndMatcher(); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/ClassInstanceManagerTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.*; 12 | 13 | public class ClassInstanceManagerTest { 14 | 15 | @Test 16 | public void testObjectsAreCachedInClassInstanceManager() throws Exception { 17 | ClassInstanceManager manager = new ClassInstanceManager(); 18 | Object object = manager.get(TestStepImplClass.class); 19 | assertInstanceOf(TestStepImplClass.class, object); 20 | 21 | Object object2 = manager.get(TestStepImplClass.class); 22 | assertInstanceOf(TestStepImplClass.class, object2); 23 | assertEquals(object, object2); 24 | } 25 | 26 | @Test 27 | public void testSettingClassInitializer() throws Exception { 28 | final TestStepImplClass expectedObject = new TestStepImplClass(); 29 | ClassInstanceManager manager = new ClassInstanceManager(); 30 | ClassInstanceManager.setClassInitializer(classToInitialize -> expectedObject); 31 | Object object1 = manager.get(TestStepImplClass.class); 32 | Object object2 = manager.get(String.class); 33 | ClassInstanceManager.setClassInitializer(null); 34 | 35 | assertEquals(expectedObject, object1); 36 | assertEquals(expectedObject, object2); 37 | } 38 | 39 | @Test 40 | public void testClearingCache() throws Exception { 41 | ClassInstanceManager manager = new ClassInstanceManager(); 42 | Object object1 = manager.get(TestStepImplClass.class); 43 | manager.clearCache(); 44 | Object object2 = manager.get(TestStepImplClass.class); 45 | assertInstanceOf(TestStepImplClass.class, object1); 46 | assertInstanceOf(TestStepImplClass.class, object2); 47 | assertNotEquals(object1, object2); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/ExecutionContextTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import static org.junit.jupiter.api.Assertions.assertTrue; 16 | 17 | public class ExecutionContextTest { 18 | 19 | @Test 20 | public void testGettingAllScenarioAndSpecTags() throws Exception { 21 | String tag1 = "tag1"; 22 | String tag2 = "tag2"; 23 | String tag3 = "tag3"; 24 | String tag4 = "tag4"; 25 | String tag5 = "tag5"; 26 | 27 | ExecutionContext executionContext = new ExecutionContext(specWithTags(tag1, tag2), scenarioWithTags(tag3, tag4, tag5), new StepDetails()); 28 | List allTags = executionContext.getAllTags(); 29 | assertEquals(5, allTags.size()); 30 | assertTrue(allTags.contains(tag1)); 31 | assertTrue(allTags.contains(tag2)); 32 | assertTrue(allTags.contains(tag3)); 33 | assertTrue(allTags.contains(tag4)); 34 | assertTrue(allTags.contains(tag5)); 35 | } 36 | 37 | @Test 38 | public void testGettingAllScenarioAndSpecTagsWhenOnlySpecTagsPresent() throws Exception { 39 | String tag1 = "tag1"; 40 | String tag2 = "tag2"; 41 | String tag3 = "tag3"; 42 | 43 | ExecutionContext executionContext = new ExecutionContext(specWithTags(tag1, tag2, tag3, tag3), new Scenario(), new StepDetails()); 44 | List allTags = executionContext.getAllTags(); 45 | assertEquals(3, allTags.size()); 46 | assertTrue(allTags.contains(tag1)); 47 | assertTrue(allTags.contains(tag2)); 48 | assertTrue(allTags.contains(tag3)); 49 | } 50 | 51 | @Test 52 | public void testGettingAllScenarioAndSpecTagsWhenOnlyScenarioTagsPresent() throws Exception { 53 | String tag2 = "tag2"; 54 | String tag3 = "tag3"; 55 | 56 | ExecutionContext executionContext = new ExecutionContext(new Specification(), scenarioWithTags(tag3, tag2, tag3), new StepDetails()); 57 | List allTags = executionContext.getAllTags(); 58 | assertEquals(2, allTags.size()); 59 | assertTrue(allTags.contains(tag2)); 60 | assertTrue(allTags.contains(tag3)); 61 | } 62 | 63 | private Specification specWithTags(String... tags) { 64 | List tagsList = Arrays.asList(tags); 65 | return new Specification("foo", "foo.spec", false, tagsList); 66 | } 67 | 68 | private Scenario scenarioWithTags(String... tags) { 69 | List tagsList = Arrays.asList(tags); 70 | return new Scenario("foo", false, tagsList); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/MessageCollectorTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import com.google.protobuf.ProtocolStringList; 9 | import gauge.messages.Spec; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import java.util.Arrays; 13 | 14 | import static org.junit.jupiter.api.Assertions.*; 15 | 16 | public class MessageCollectorTest { 17 | 18 | @Test 19 | public void testAddingMessagesToProtoResult() { 20 | Spec.ProtoExecutionResult executionResult = emptyExecResult(); 21 | String[] messages = {"first message", "second message"}; 22 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessages(executionResult, Arrays.asList(messages)); 23 | ProtocolStringList actualMessageList = protoExecutionResult.getMessageList(); 24 | for (String message : messages) { 25 | assertTrue(actualMessageList.contains(message)); 26 | } 27 | } 28 | 29 | @Test 30 | public void testAddingNullMessagesToProtoResult() { 31 | Spec.ProtoExecutionResult executionResult = emptyExecResult(); 32 | String[] messages = {"first message", "second message", null}; 33 | Spec.ProtoExecutionResult protoExecutionResult = new MessageCollector().addPendingMessages(executionResult, Arrays.asList(messages)); 34 | ProtocolStringList actualMessageList = protoExecutionResult.getMessageList(); 35 | assertEquals(2, actualMessageList.size()); 36 | assertFalse(actualMessageList.contains(null)); 37 | } 38 | 39 | private Spec.ProtoExecutionResult emptyExecResult() { 40 | return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(0).build(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/ScreenshotCollectorTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | import gauge.messages.Spec; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | public class ScreenshotCollectorTest { 17 | @Test 18 | public void testAddingScreenshotsToProtoResult() { 19 | Spec.ProtoExecutionResult executionResult = emptyExecResult(); 20 | String a = "1"; 21 | String b = "2"; 22 | List screenshots = new ArrayList<>(); 23 | screenshots.add(a); 24 | screenshots.add(b); 25 | Spec.ProtoExecutionResult protoExecutionResult = new ScreenshotCollector().addPendingScreenshot(executionResult, screenshots); 26 | List actualScreenshotList = protoExecutionResult.getScreenshotFilesList(); 27 | for (String screenshot : screenshots) { 28 | assertTrue(actualScreenshotList.contains(screenshot)); 29 | } 30 | } 31 | 32 | private Spec.ProtoExecutionResult emptyExecResult() { 33 | return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(0).build(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/TableRowTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 13 | 14 | public class TableRowTest { 15 | 16 | @Test 17 | public void testToString() { 18 | TableRow row = new TableRow(); 19 | row.addCell("hello", "world"); 20 | row.addCell("foo", "bar"); 21 | 22 | assertEquals("TableRow{cells={hello=world, foo=bar}}", row.toString()); 23 | } 24 | 25 | @Test 26 | public void testEqualSameValuesAndOrder() { 27 | TableRow row = new TableRow(); 28 | row.addCell("hello", "world"); 29 | row.addCell("foo", "bar"); 30 | 31 | TableRow otherRow = new TableRow(); 32 | otherRow.addCell("hello", "world"); 33 | otherRow.addCell("foo", "bar"); 34 | assertEquals(row, otherRow); 35 | } 36 | 37 | @Test 38 | public void testEqualSameValuesDifferentOrder() { 39 | TableRow row = new TableRow(); 40 | row.addCell("hello", "world"); 41 | row.addCell("foo", "bar"); 42 | 43 | TableRow otherRow = new TableRow(); 44 | otherRow.addCell("foo", "bar"); 45 | otherRow.addCell("hello", "world"); 46 | assertEquals(row, otherRow); 47 | } 48 | 49 | @Test 50 | public void testEqualDifferentValues() { 51 | TableRow row = new TableRow(); 52 | row.addCell("hello", "world"); 53 | row.addCell("foo", "bar"); 54 | 55 | TableRow otherRow = new TableRow(); 56 | otherRow.addCell("foo1", "bar1"); 57 | otherRow.addCell("hello1", "world1"); 58 | assertNotEquals(row, otherRow); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/TestStepImplClass.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | public class TestStepImplClass { 9 | @Step("hello world") 10 | public void helloWorld() { 11 | 12 | } 13 | 14 | @Step("hello world ") 15 | public int helloWorldWithOneParam(int i) { 16 | return 0; 17 | } 18 | 19 | @Step("a step with and ") 20 | public Table helloWorldWithTwoParams(String a, Table table) { 21 | return null; 22 | } 23 | 24 | @Step({"first step name with name ", "second step name with "}) 25 | public Table aliasMethod(String a) { 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/UtilTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge; 7 | 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | 13 | public class UtilTest { 14 | 15 | @Test 16 | public void testGetCamelCase() throws Exception { 17 | assertEquals("helloWorld", Util.convertToCamelCase("Hello world")); 18 | assertEquals("gaugeJavaProject", Util.convertToCamelCase("gauge Java project ")); 19 | assertEquals("123Go", Util.convertToCamelCase("12 3 go")); 20 | assertEquals("allhailTheKing", Util.convertToCamelCase(" AllHaiL tHe king")); 21 | 22 | } 23 | 24 | @Test 25 | public void testGetValidJavaIdentifier() { 26 | assertEquals("", Util.getValidJavaIdentifier("%")); 27 | assertEquals("", Util.getValidJavaIdentifier("^%@!*^&|()")); 28 | assertEquals("", Util.getValidJavaIdentifier("|")); 29 | assertEquals("hello", Util.getValidJavaIdentifier("hello")); 30 | assertEquals("hello", Util.getValidJavaIdentifier("hello&")); 31 | assertEquals("_hello", Util.getValidJavaIdentifier("_hello&")); 32 | assertEquals("_hello", Util.getValidJavaIdentifier("_hello&(")); 33 | assertEquals("2hello", Util.getValidJavaIdentifier("2hello&(")); 34 | assertEquals("ƒ", Util.getValidJavaIdentifier("˚¬∆˙©ƒ∂")); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/execution/HooksExecutorTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import com.thoughtworks.gauge.BeforeScenario; 9 | import com.thoughtworks.gauge.ClassInstanceManager; 10 | import com.thoughtworks.gauge.ContinueOnFailure; 11 | import com.thoughtworks.gauge.Operator; 12 | import com.thoughtworks.gauge.hook.Hook; 13 | import gauge.messages.Spec; 14 | import org.junit.jupiter.api.Test; 15 | 16 | import java.util.ArrayList; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertFalse; 19 | 20 | public class HooksExecutorTest { 21 | 22 | @Test 23 | public void testHookExecutor() throws Exception { 24 | final Hook hook1 = new Hook(HooksExecutorTest.TestHook.class.getMethod("foo"), new String[0], Operator.AND); 25 | HookExecutionStage hookExecutionStage = new HookExecutionStage(new ArrayList<>() {{ 26 | add(hook1); 27 | }}, new ClassInstanceManager()); 28 | Spec.ProtoExecutionResult prevResult = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(0).build(); 29 | Spec.ProtoExecutionResult result = hookExecutionStage.execute(prevResult); 30 | assertFalse(result.getRecoverableError()); 31 | } 32 | 33 | private static class TestHook { 34 | @ContinueOnFailure 35 | @BeforeScenario 36 | public void foo() { 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/execution/ParameterTestHelpers.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution; 7 | 8 | import static com.thoughtworks.gauge.test.TestValues.A_VALUE; 9 | 10 | import com.thoughtworks.gauge.test.TestValues; 11 | 12 | import gauge.messages.Spec; 13 | import gauge.messages.Spec.Parameter; 14 | import gauge.messages.Spec.Parameter.ParameterType; 15 | 16 | public class ParameterTestHelpers { 17 | public static Parameter parameter(String value) { 18 | return Spec.Parameter.newBuilder().setValue(value).build(); 19 | } 20 | 21 | public static Parameter aParameterWith(ParameterType type) { 22 | return Spec.Parameter.newBuilder().setParameterType(type).setValue(TestValues.A_VALUE).build(); 23 | } 24 | 25 | public static Parameter aSpecialTableParameter() { 26 | return aParameterWith(ParameterType.Special_Table); 27 | } 28 | 29 | public static Parameter aTableParameter() { 30 | return aParameterWith(ParameterType.Table); 31 | } 32 | 33 | public static Parameter aParameter() { 34 | return parameter(A_VALUE); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/execution/parameters/parsers/types/EnumParameterParserTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import com.thoughtworks.gauge.test.AnEnum; 9 | import org.junit.jupiter.api.Test; 10 | import org.junit.jupiter.api.extension.ExtendWith; 11 | import org.mockito.InjectMocks; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | import static com.thoughtworks.gauge.execution.ParameterTestHelpers.parameter; 15 | import static org.assertj.core.api.Assertions.assertThat; 16 | 17 | @ExtendWith(MockitoExtension.class) 18 | public class EnumParameterParserTest { 19 | @InjectMocks 20 | private EnumParameterParser enumParameterParser; 21 | 22 | @Test 23 | public void givenAnEnumParameterTypeAndAValidParameterForThatEnumThenTheEnumInstanceIsReturned() throws Exception { 24 | assertThat(enumParameterParser.parse(AnEnum.class, parameter(AnEnum.VALUE.name()))).isEqualTo(AnEnum.VALUE); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/execution/parameters/parsers/types/PrimitiveParameterParserTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | import static com.thoughtworks.gauge.execution.ParameterTestHelpers.aParameter; 15 | import static com.thoughtworks.gauge.test.TestValues.A_PRIMITIVE; 16 | import static com.thoughtworks.gauge.test.TestValues.PRIMITIVE_TYPE; 17 | import static org.assertj.core.api.Assertions.assertThat; 18 | import static org.mockito.Mockito.verify; 19 | import static org.mockito.Mockito.when; 20 | 21 | @ExtendWith(MockitoExtension.class) 22 | public class PrimitiveParameterParserTest { 23 | @Mock 24 | private PrimitivesConverter primitivesConverterMock; 25 | @InjectMocks 26 | private PrimitiveParameterParser primitiveParameterParser; 27 | 28 | @Test 29 | public void givenPrimitiveTypeWhenParseAPrimitiveParameterThenThePrimitiveTypeIsConverted() throws Exception { 30 | primitiveParameterParser.parse(PRIMITIVE_TYPE, aParameter()); 31 | 32 | verify(primitivesConverterMock).convert(PRIMITIVE_TYPE, aParameter()); 33 | } 34 | 35 | @Test 36 | public void givenPrimitiveTypeWhenParseAPrimitiveParameterThenTheConvertedPrimitiveTypeIsReturned() 37 | throws Exception { 38 | when(primitivesConverterMock.convert(PRIMITIVE_TYPE, aParameter())).thenReturn(A_PRIMITIVE); 39 | 40 | assertThat(primitiveParameterParser.parse(PRIMITIVE_TYPE, aParameter())).isSameAs(A_PRIMITIVE); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/execution/parameters/parsers/types/TableParameterParserTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.execution.parameters.parsers.types; 7 | 8 | import com.thoughtworks.gauge.execution.parameters.parsers.converters.TableConverter; 9 | import org.junit.jupiter.api.Test; 10 | import org.junit.jupiter.api.extension.ExtendWith; 11 | import org.mockito.InjectMocks; 12 | import org.mockito.Mock; 13 | import org.mockito.junit.jupiter.MockitoExtension; 14 | 15 | import static com.thoughtworks.gauge.execution.ParameterTestHelpers.aSpecialTableParameter; 16 | import static com.thoughtworks.gauge.execution.ParameterTestHelpers.aTableParameter; 17 | import static com.thoughtworks.gauge.test.TestValues.ANY_TYPE; 18 | import static com.thoughtworks.gauge.test.TestValues.SPECIFIC_VALUE; 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | import static org.mockito.Mockito.verify; 21 | import static org.mockito.Mockito.when; 22 | 23 | @ExtendWith(MockitoExtension.class) 24 | public class TableParameterParserTest { 25 | @Mock 26 | private TableConverter tableConverterMock; 27 | @InjectMocks 28 | private TableParameterParser tableParameterParser; 29 | 30 | @Test 31 | public void whenATableParameterParsedThenTheTableConverterIsPassedThatParameter() throws Exception { 32 | tableParameterParser.parse(ANY_TYPE, aTableParameter()); 33 | 34 | verify(tableConverterMock).convert(aTableParameter()); 35 | } 36 | 37 | @Test 38 | public void whenASpecialTableParameterParsedThenTheTableConverterIsPassedThatParameter() throws Exception { 39 | tableParameterParser.parse(ANY_TYPE, aSpecialTableParameter()); 40 | 41 | verify(tableConverterMock).convert(aSpecialTableParameter()); 42 | } 43 | 44 | @Test 45 | public void whenATableParameterParsedThenTheTheConvertedTableIsReturned() throws Exception { 46 | when(tableConverterMock.convert(aTableParameter())).thenReturn(SPECIFIC_VALUE); 47 | 48 | assertThat(tableParameterParser.parse(ANY_TYPE, aTableParameter())).isSameAs(SPECIFIC_VALUE); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/hook/HookTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.hook; 7 | 8 | import com.thoughtworks.gauge.BeforeScenario; 9 | import com.thoughtworks.gauge.Operator; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collections; 14 | import java.util.HashSet; 15 | import java.util.Set; 16 | 17 | import static org.junit.jupiter.api.Assertions.assertEquals; 18 | 19 | public class HookTest { 20 | 21 | @Test 22 | public void testSortingOfHookCollection() throws NoSuchMethodException { 23 | final Hook hook1 = new Hook(TestHook.class.getMethod("foo"), new String[0], Operator.AND); 24 | final Hook hook2 = new Hook(TestHook.class.getMethod("barfoo"), new String[]{"hello"}, Operator.AND); 25 | final Hook hook3 = new Hook(TestHook.class.getMethod("bar"), new String[0], Operator.AND); 26 | final Hook hook4 = new Hook(TestHook.class.getMethod("foobar"), new String[]{"hello"}, Operator.AND); 27 | 28 | Set hooks = new HashSet<>() {{ 29 | add(hook1); 30 | add(hook2); 31 | add(hook3); 32 | add(hook4); 33 | }}; 34 | ArrayList hooksList = new ArrayList<>(hooks); 35 | Collections.sort(hooksList); 36 | assertEquals("bar", hooksList.get(0).getMethod().getName()); 37 | assertEquals("foo", hooksList.get(1).getMethod().getName()); 38 | assertEquals("barfoo", hooksList.get(2).getMethod().getName()); 39 | assertEquals("foobar", hooksList.get(3).getMethod().getName()); 40 | } 41 | 42 | private static class TestHook { 43 | @BeforeScenario 44 | public void foo() { 45 | } 46 | 47 | @BeforeScenario 48 | public void bar() { 49 | } 50 | 51 | @BeforeScenario(tags = "hello") 52 | public void foobar() { 53 | } 54 | 55 | @BeforeScenario(tags = "hello") 56 | public void barfoo() { 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/processor/DefaultMessageProcessorTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import gauge.messages.Messages; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | import static org.junit.jupiter.api.Assertions.assertFalse; 13 | 14 | public class DefaultMessageProcessorTest { 15 | 16 | @Test 17 | public void shouldProcessMessage() { 18 | Messages.Message request = Messages.Message.newBuilder().setMessageId(1L).setMessageType(Messages.Message.MessageType.ExecutionStatusResponse).build(); 19 | Messages.Message response = new DefaultMessageProcessor().process(request); 20 | 21 | assertEquals(response.getMessageId(), 1L); 22 | assertEquals(response.getMessageType(), Messages.Message.MessageType.ExecutionStatusResponse); 23 | assertFalse(response.getExecutionStatusResponse().getExecutionResult().getFailed()); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/processor/StubImplementationCodeProcessorTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.processor; 7 | 8 | import com.thoughtworks.gauge.connection.StubImplementationCodeProcessor; 9 | import gauge.messages.Messages; 10 | import gauge.messages.Spec; 11 | import org.junit.jupiter.api.Test; 12 | 13 | import java.util.ArrayList; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | public class StubImplementationCodeProcessorTest { 18 | @Test 19 | public void testProcessStubImplementationCode() { 20 | String file = getClass().getClassLoader().getResource("test/files/Empty.java").getFile(); 21 | Messages.StubImplementationCodeRequest codeRequest = Messages.StubImplementationCodeRequest 22 | .newBuilder() 23 | .setImplementationFilePath(file) 24 | .addAllCodes(new ArrayList<>() { 25 | { 26 | add("@Step\npublic void foo(){\n}"); 27 | } 28 | }).build(); 29 | StubImplementationCodeProcessor processor = new StubImplementationCodeProcessor(); 30 | Messages.Message message = processor.process(Messages.Message.newBuilder().setStubImplementationCodeRequest(codeRequest).build()); 31 | Messages.FileDiff fileDiff = message.getFileDiff(); 32 | Spec.Span span = fileDiff.getTextDiffsList().get(0).getSpan(); 33 | assertEquals(span.getStart(), 1); 34 | assertEquals(span.getStartChar(), 0); 35 | assertEquals(span.getEnd(), 1); 36 | assertEquals(span.getEndChar(), 0); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/tag/AndMatcherTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.tag; 7 | 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertFalse; 15 | import static org.junit.jupiter.api.Assertions.assertTrue; 16 | 17 | public class AndMatcherTest { 18 | 19 | @Test 20 | public void testIsMatch() throws Exception { 21 | SimpleTagMatcher matcher = new AndMatcher(); 22 | assertTrue(matcher.isMatch(Arrays.asList("tag1", "tag2"), Arrays.asList("tag1", "tag3", "tag4", "tag2"))); 23 | assertFalse(matcher.isMatch(Arrays.asList("tag1", "tag2"), Arrays.asList("tag5", "tag3", "tag4"))); 24 | assertFalse(matcher.isMatch(Arrays.asList("tag1"), Arrays.asList("tag5", "tag3", "tag4"))); 25 | assertFalse(matcher.isMatch(Arrays.asList("tag1", "tag4", "tag8", "tag9"), Arrays.asList("tag4", "tag8"))); 26 | assertTrue(matcher.isMatch(Arrays.asList(""), Arrays.asList(""))); 27 | assertTrue(matcher.isMatch(new ArrayList<>(), new ArrayList<>())); 28 | assertFalse(matcher.isMatch(Arrays.asList("tag1", "tag3"), new ArrayList<>())); 29 | assertTrue(matcher.isMatch(new ArrayList<>(), Arrays.asList("tag1", "tag2", "tag3"))); 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/tag/OrMatcherTest.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.tag; 7 | 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | 14 | import static org.junit.jupiter.api.Assertions.assertFalse; 15 | import static org.junit.jupiter.api.Assertions.assertTrue; 16 | 17 | public class OrMatcherTest { 18 | 19 | @Test 20 | public void testMatching() throws Exception { 21 | OrMatcher matcher = new OrMatcher(); 22 | assertTrue(matcher.isMatch(Arrays.asList("tag1", "tag2"), Arrays.asList("tag1", "tag3", "tag4"))); 23 | assertFalse(matcher.isMatch(Arrays.asList("tag1", "tag2"), Arrays.asList("tag5", "tag3", "tag4"))); 24 | assertFalse(matcher.isMatch(Arrays.asList("tag1"), Arrays.asList("tag5", "tag3", "tag4"))); 25 | assertTrue(matcher.isMatch(Arrays.asList("tag1", "tag4", "tag8", "tag9"), Arrays.asList("tag4"))); 26 | assertTrue(matcher.isMatch(Arrays.asList(""), Arrays.asList(""))); 27 | assertTrue(matcher.isMatch(new ArrayList<>(), new ArrayList<>())); 28 | assertFalse(matcher.isMatch(Arrays.asList("tag1"), Arrays.asList(""))); 29 | assertTrue(matcher.isMatch(new ArrayList<>(), Arrays.asList("tag1", "tag2", "tag3"))); 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/test/AnEnum.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.test; 7 | 8 | public enum AnEnum { 9 | FIRST, SECOND, THIRD, VALUE; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/com/thoughtworks/gauge/test/TestValues.java: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------- 2 | * Copyright (c) ThoughtWorks, Inc. 3 | * Licensed under the Apache License, Version 2.0 4 | * See LICENSE.txt in the project root for license information. 5 | *----------------------------------------------------------------*/ 6 | package com.thoughtworks.gauge.test; 7 | 8 | public class TestValues { 9 | public static final String A_VALUE = "a value"; 10 | public static final Class ANY_TYPE = Object.class; 11 | public static final Object SPECIFIC_VALUE = new Object(); 12 | public static final Class PRIMITIVE_TYPE = int.class; 13 | public static final int A_PRIMITIVE = 1; 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/test/files/Empty.java: -------------------------------------------------------------------------------- 1 | class Empty { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/resources/test/files/foo.java: -------------------------------------------------------------------------------- 1 | package test.files; 2 | 3 | import com.thoughtworks.gauge.Step; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class StepTest { 8 | 9 | @Step("new step") 10 | public void newstep() { 11 | assertThat(2).isEqualTo(2); 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/test/files/fooAliases.java: -------------------------------------------------------------------------------- 1 | package test.files; 2 | 3 | import com.thoughtworks.gauge.Step; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class StepTest { 8 | 9 | @Step({"new step", "another step"}) 10 | public void newstep() { 11 | assertThat(2).isEqualTo(2); 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/test/files/formatted/StepImpl.java: -------------------------------------------------------------------------------- 1 | package test.files.formatted; 2 | 3 | import com.thoughtworks.gauge.Step; 4 | import com.thoughtworks.gauge.Table; 5 | 6 | public class StepImpl { 7 | @Step("Say to ") 8 | public String helloWorld(String greeting, int name) { 9 | } 10 | 11 | @Step("step and a table
") 12 | public void stepWithTable(float a, Table table) { 13 | } 14 | 15 | @Step("A step with no params") 16 | public void someStepStep() { 17 | } 18 | 19 | @Step("Tell to ") 20 | public void helloWorld(String greeting, String name) { 21 | System.out.println(greeting + ", " + name); 22 | } 23 | 24 | @Step("Tell ") 25 | public void helloWorld(String greeting, String argName) { 26 | } 27 | 28 | @Step("† ‡ µ ¢ step with <Û> and <į>") 29 | public void stepWith(String a, String b) { 30 | } 31 | 32 | @Step("A step with comments") 33 | public void someStepWithComments() { 34 | // comment1 35 | // comment2 36 | /* 37 | comment3 38 | comment4 39 | */ 40 | /* 41 | comment6 42 | comment7 43 | comment8 44 | */ 45 | System.out.println(""); 46 | } 47 | 48 | @Step("A step with newLine") 49 | public void someStepStep() { 50 | System.out.println("\n"); 51 | } 52 | 53 | @Step("A step with \\") 54 | public void stepWithDualBackSlashes() { 55 | } 56 | 57 | @Step("A step with /") 58 | public void stepWithCommonSlash() { 59 | } 60 | 61 | @Step("A step with //") 62 | public void stepWithCommonDualSlashes() { 63 | } 64 | 65 | @Step("A step with |") 66 | public void stepWithPipeline() { 67 | } 68 | 69 | @Step("A step 123") 70 | public void stepWithTab() { 71 | } 72 | 73 | @Step("A step with ` ~ = + ? # $ % ^ ! & * ( ) : ; , . - _ [ ]") 74 | public void stepWithSpecialChars() { 75 | } 76 | 77 | @Step({"A step defined with alias syntax"}) 78 | public void stepDefinedWithAliasSyntax() { 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/resources/test/files/formatted/StepImplWithComments.java: -------------------------------------------------------------------------------- 1 | package test.files.formatted; 2 | 3 | import com.thoughtworks.gauge.Step; 4 | 5 | public class StepImpl { 6 | @Step("A step with comments") 7 | public void someStepWithComments() { 8 | // comment1 9 | // comment2 10 | /* 11 | comment3 12 | comment4 13 | */ 14 | /* 15 | comment6 16 | comment7 17 | comment8 18 | */ 19 | System.out.println(""); 20 | // comment9 21 | // comment10 22 | /* 23 | comment11 24 | comment12 25 | */ 26 | /* 27 | comment13 28 | comment14 29 | comment15 30 | */ 31 | } 32 | } -------------------------------------------------------------------------------- /src/test/resources/test/files/unformatted/UnFormattedStepImpl.java: -------------------------------------------------------------------------------- 1 | package test.files.unformatted; 2 | public class StepImpl {@Step("A step with no params") public void someStepStep() {}} --------------------------------------------------------------------------------