Repository: trautonen/coveralls-maven-plugin Branch: master Commit: 773a396fa382 Files: 134 Total size: 410.1 KB Directory structure: gitextract_4r5n4qdh/ ├── .gitignore ├── .gitmodules ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.MIT ├── MIGRATION.md ├── README.md ├── README_2_x.md ├── pom.xml ├── sample/ │ ├── README.md │ ├── module1/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── eluder/ │ │ │ │ └── coverage/ │ │ │ │ └── sample/ │ │ │ │ ├── InnerClassCoverage.java │ │ │ │ └── SimpleCoverage.java │ │ │ └── resources/ │ │ │ ├── Components.js │ │ │ └── Localization.js │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── eluder/ │ │ │ └── coverage/ │ │ │ └── sample/ │ │ │ ├── InnerClassCoverageTest.java │ │ │ └── SimpleCoverageTest.java │ │ └── specs/ │ │ └── ComponentsSpec.coffee │ ├── module2/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── eluder/ │ │ │ └── coverage/ │ │ │ └── sample/ │ │ │ └── PartialCoverage.java │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── eluder/ │ │ └── coverage/ │ │ └── sample/ │ │ ├── PartialCoverageIT.java │ │ └── PartialCoverageTest.java │ └── pom.xml ├── scripts/ │ ├── bump-version.sh │ ├── functions.sh │ └── release.sh └── src/ ├── main/ │ └── java/ │ └── org/ │ └── eluder/ │ └── coveralls/ │ └── maven/ │ └── plugin/ │ ├── CoverageParser.java │ ├── CoverallsReportMojo.java │ ├── Environment.java │ ├── ProcessingException.java │ ├── domain/ │ │ ├── Branch.java │ │ ├── CoverallsResponse.java │ │ ├── Git.java │ │ ├── GitRepository.java │ │ ├── Job.java │ │ ├── JsonObject.java │ │ └── Source.java │ ├── httpclient/ │ │ ├── CoverallsClient.java │ │ ├── CoverallsProxyClient.java │ │ └── HttpClientFactory.java │ ├── json/ │ │ └── JsonWriter.java │ ├── logging/ │ │ ├── CoverageTracingLogger.java │ │ ├── DryRunLogger.java │ │ ├── JobLogger.java │ │ └── Logger.java │ ├── parser/ │ │ ├── AbstractXmlEventParser.java │ │ ├── CoberturaParser.java │ │ ├── JaCoCoParser.java │ │ └── SagaParser.java │ ├── service/ │ │ ├── AbstractServiceSetup.java │ │ ├── Appveyor.java │ │ ├── Bamboo.java │ │ ├── Circle.java │ │ ├── General.java │ │ ├── Jenkins.java │ │ ├── ServiceSetup.java │ │ ├── Shippable.java │ │ ├── Travis.java │ │ └── Wercker.java │ ├── source/ │ │ ├── AbstractSourceLoader.java │ │ ├── ChainingSourceCallback.java │ │ ├── DirectorySourceLoader.java │ │ ├── MultiSourceLoader.java │ │ ├── ScanSourceLoader.java │ │ ├── SourceCallback.java │ │ ├── SourceLoader.java │ │ ├── UniqueSourceCallback.java │ │ └── UrlSourceLoader.java │ ├── util/ │ │ ├── CoverageParsersFactory.java │ │ ├── ExistingFiles.java │ │ ├── MavenProjectCollector.java │ │ ├── Md5DigestInputStream.java │ │ ├── SourceLoaderFactory.java │ │ ├── TimestampParser.java │ │ ├── UrlUtils.java │ │ └── Wildcards.java │ └── validation/ │ ├── JobValidator.java │ ├── ValidationError.java │ ├── ValidationErrors.java │ └── ValidationException.java └── test/ ├── java/ │ └── org/ │ └── eluder/ │ └── coveralls/ │ └── maven/ │ └── plugin/ │ ├── CoverageFixture.java │ ├── CoverallsReportMojoTest.java │ ├── EnvironmentTest.java │ ├── ProcessingExceptionTest.java │ ├── domain/ │ │ ├── GitRepositoryTest.java │ │ ├── JobTest.java │ │ └── SourceTest.java │ ├── httpclient/ │ │ ├── CoverallsClientTest.java │ │ ├── CoverallsProxyClientTest.java │ │ └── HttpClientFactoryTest.java │ ├── json/ │ │ └── JsonWriterTest.java │ ├── logging/ │ │ ├── CoverageTracingLoggerTest.java │ │ ├── DryRunLoggerTest.java │ │ └── JobLoggerTest.java │ ├── parser/ │ │ ├── AbstractCoverageParserTest.java │ │ ├── CoberturaParserTest.java │ │ ├── JaCoCoParserTest.java │ │ └── SagaParserTest.java │ ├── service/ │ │ ├── AbstractServiceSetupTest.java │ │ ├── AppveyorTest.java │ │ ├── BambooTest.java │ │ ├── CircleTest.java │ │ ├── GeneralTest.java │ │ ├── JenkinsTest.java │ │ ├── ShippableTest.java │ │ ├── TravisTest.java │ │ └── WerckerTest.java │ ├── source/ │ │ ├── DirectorySourceLoaderTest.java │ │ ├── MultiSourceLoaderTest.java │ │ ├── ScanSourceLoaderTest.java │ │ ├── UniqueSourceCallbackTest.java │ │ └── UrlSourceLoaderTest.java │ ├── util/ │ │ ├── CoverageParsersFactoryTest.java │ │ ├── ExistingFilesTest.java │ │ ├── Md5DigestInputStreamTest.java │ │ ├── SourceLoaderFactoryTest.java │ │ ├── TestIoUtil.java │ │ ├── TimestampParserTest.java │ │ ├── UrlUtilsTest.java │ │ └── WildcardsTest.java │ └── validation/ │ ├── JobValidatorTest.java │ ├── ValidationErrorTest.java │ ├── ValidationErrorsTest.java │ └── ValidationExceptionTest.java └── resources/ ├── Components.js ├── InnerClassCoverage.java ├── Localization.js ├── PartialCoverage.java ├── SimpleCoverage.java ├── cobertura.xml ├── jacoco1.xml ├── jacoco2-it.xml ├── jacoco2.xml └── saga.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ target target/* # Eclipse .settings .project .classpath # Idea *.iml .idea # Atlassian atlassian-ide-plugin.xml ================================================ FILE: .gitmodules ================================================ [submodule "etc"] path = etc url = git://github.com/trautonen/etc.git ================================================ FILE: .travis.yml ================================================ dist: xenial language: java sudo: false jdk: - openjdk8 - openjdk10 - openjdk11 env: global: - secure: "pmNBqCAW1rc4WKHEmnroZNwAMus18K1VWhRYwt+CN0acH8griJp612tjwWcI\n9XkZcSPR0CJx1TZqGDZZTFH44Pkm6ELU1kc54xtJR6WMXnubEVoEom0tcv/1\nNyzxv9UFJfaNgaTESww+OXSlO9wQre5ZS0/wn2xrz0+twtOPYDU=" - secure: "CZ9mejMLJdrh+a5TFXsNSiYyK9K/zNYOtubv2sPq1OEGhuohdUfLtdsk7bK9\nQcIlhZjrE5Q/wVgjZcFsnVpKhnUSRLC7sTOh6tu08EwpNtnNLl5AeUztOMCs\nxhG5H7jDu9uEH81WDZnIuK4Zq4qxXx523rnqQfk4DsTCKLVh9jI=" addons: apt: packages: - python-yaml before_install: - git submodule update --init --recursive before_script: - python etc/travis-sonatype.py script: python etc/travis-build.py --settings ~/.m2/sonatype.xml after_success: - mvn clean cobertura:cobertura org.eluder.coveralls:coveralls-maven-plugin:report ================================================ FILE: CHANGELOG.md ================================================ # Changelog ## 4.2.0 - #95, #96: Improved error message for misbehaving Coveralls API - #92: Support for HTTP proxies in settings.xml - #91: Support for epoch formatted timestamps ## 4.1.0 - #88: Support for AppVeyor CI ## 4.0.0 - #85: Merge coverages from multiple reports to single source file - #84: Change source content to source digest per new Coveralls API - #83: Require Java 7 to support new features and syntax - #77: Support for custom build timestamp format ## 3.2.1 - #87: Downgraded jgit version to support Java 6 ## 3.2.0 - #82: Improved error message for duplicate classes in different modules - #76: Property to allow Coveralls service fail without build failure - #74: Handle transitive logging dependencies better ## 3.1.0 - #67: Configurable project basedir - #65, #66, #68: Support for Shippable CI - #63: Directory scanning source loader ## 3.0.1 - #53: Improved error message for missing source encoding - #52: Ignore duplicate source files on Cobertura aggregate mode ## 3.0.0 - #48: Removed support for URL based source loading due to Coveralls changes - #42, #45, #46: Support Coveralls new GitHub based source view - #40: Proper multi-module support and report aggregation - #37, #41: Disclaimer for Java 8 usage ## 2.2.0 - #31: Improved error messages for Coveralls API failures - #30: Improved error message for missing charset - #28: More lenient XML parsing - #26, #29: Support for Saga coverage tool and chain multiple coverage reports ## 2.1.0 - #24: Filter out remote names from git branches - #19, #20: Skip configuration property to allow skipping of plugin execution ## 2.0.1 - #18: Update to HttpComponents HttpClient 4.3 - #15, #16, #17: Disable PKCS cryptography provider at runtime to work around OpenJDK SSL issue ## 2.0.0 - #13: Dry run property for test builds - #12: Use ServiceSetup as secondary configuration source and Maven/VM properties as primary - #11: Support multiple source directories - #9: Support for other CI tools and platforms - #8: Aggregated reports for multi-module projects ## 1.2.0 - #10: Validation of the Coveralls job - #4: Report build timestamp to Coveralls - #3: Log code lines from generated report to Maven console ## 1.1.0 - #1: Easier configuration for Travis CI ## 1.0.0 - Initial release ================================================ FILE: LICENSE.MIT ================================================ The MIT License (MIT) Copyright (c) 2013 - 2016, Tapio Rautonen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MIGRATION.md ================================================ # Migration guide Changes marked with bold affect the plugin usage. Other changes are only related to development and codebase. ## 2.x to 3.x - ## 1.x to 2.x - **`sourceDirectory` parameter removed and replaced with a list parameter `sourceDirectories`** - **service environment parameters do not override configuration parameters** - `org.eluder.coveralls.maven.plugin.service.ServiceSetup` interface completely changed to reflect the service specific configuration properly - `org.eluder.coveralls.maven.plugin.service.Travis` changed to reflect the new service setup interface - `org.eluder.coveralls.maven.plugin.domain.JobValidator` and all validation related code is now located in `org.eluder.coveralls.maven.plugin.validation` package - `org.eluder.coveralls.maven.plugin.domain.GitRepository` does not take custom branch parameter as constructor argument anymore, the same behavior is handled with the new service environment setup - `org.eluder.coveralls.maven.plugin.domain.Job` has only default constructor and initialization is done with _with*_ methods, _validate()_ method returns list of validation errors instead of throwing exception - `org.eluder.coveralls.maven.plugin.domain.SourceLoader` constructor takes a list of source directories instead of a single source directory ================================================ FILE: README.md ================================================ coveralls-maven-plugin ====================== [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) [![Coverage Status](http://img.shields.io/coveralls/trautonen/coveralls-maven-plugin/master.svg?style=flat-square)](https://coveralls.io/r/trautonen/coveralls-maven-plugin?branch=master) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.eluder.coveralls/coveralls-maven-plugin/badge.svg?style=flat-square)](https://maven-badges.herokuapp.com/maven-central/org.eluder.coveralls/coveralls-maven-plugin/) Maven plugin for submitting Java code coverage reports to [Coveralls](https://coveralls.io/) web service. ## !!! Deprecated !!! This project is deprecated due to lack of time and interest. Please use https://github.com/hazendaz/coveralls-maven-plugin from now on. ### Requirements * Java 6 up to 3.x and Java 7 for 4.x onwards. * Maven 3.0.0 or newer. ### Features * Supports [Cobertura](http://mojo.codehaus.org/cobertura-maven-plugin/), [JaCoCo](http://www.eclemma.org/jacoco/trunk/doc/maven.html) and [Saga](http://timurstrekalov.github.io/saga/) coverage tools * Multi-module report aggregation * Built-in support for [Travis CI](https://travis-ci.org/), [Circle](https://circleci.com/), [Codeship](https://www.codeship.io/), [Jenkins](http://jenkins-ci.org/), [Bamboo](https://www.atlassian.com/software/bamboo/), [Shippable](https://www.shippable.com/) and [Appveyor](http://www.appveyor.com/) continuous integration services * Fully streaming implementation for fast report generation and small memory footprint * Provides clean interfaces to allow easy extending to different coverage tools * Convention over configuration for almost zero configuration usage * Applies [semantic versioning](http://semver.org/) ### Usage Set up the Coveralls maven plugin in the build section of the project pom.xml: ```xml org.eluder.coveralls coveralls-maven-plugin 4.3.0 yourcoverallsprojectrepositorytoken ``` #### Configuration If used as a standalone Maven build or with any continuous integration server other than Travis CI, the Coveralls repository token must be provided. This can be achieved by setting the configuration section in the plugin or setting the Maven property `repoToken` to your coveralls project repository token, using `-DrepoToken=yourcoverallsprojectrepositorytoken` when running the maven command. **Do not publish your repository token in public GitHub repositories.** If you do, anyone can submit coverage data without permission. If you are using Travis CI, CircleCI, Codeship, Jenkins or Bamboo continuous integration services, no other configuration is required. The plugin's built-in service environment support take care of the rest. The plugin tries to find report files for any of the supported coverage tools and finally aggregates the coverage report. Java 8 is currently supported only by JaCoCo. See [Complete plugin configuration](#complete-plugin-configuration) for all of the available configuration parameters. #### Cobertura Set up the Cobertura Maven plugin with XML report format in the build section of the project pom.xml: ```xml org.codehaus.mojo cobertura-maven-plugin 2.7 xml 256m true ``` Execute Maven to create Cobertura report and submit Coveralls data: ``` mvn cobertura:cobertura coveralls:report ``` For example if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean cobertura:cobertura coveralls:report ``` #### JaCoCo Set up the JaCoCo Maven plugin in the build section of the project pom.xml: ```xml org.jacoco jacoco-maven-plugin 0.7.6.201602180812 prepare-agent prepare-agent ``` Execute Maven to create JaCoCo report and submit Coveralls data: ``` mvn clean test jacoco:report coveralls:report ``` Again, if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean test jacoco:report coveralls:report ``` #### Saga Set up the Saga Maven plugin in the build section of the project pom.xml: ```xml com.github.timurstrekalov saga-maven-plugin 1.5.5 coverage http://localhost:${jasmine.serverPort} ${project.build.directory}/saga-coverage .*/spec/.* .*/classpath/.* .*/webjars/.* ``` Note that Saga does not have default report output directory, but the plugin assumes `${project.build.directory}/saga-coverage`. Execute Maven to create Saga report and submit Coveralls data: ``` mvn clean test saga:coverage coveralls:report ``` And if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean test saga:coverage coveralls:report ``` #### Aggregate multiple reports Report aggregation is applied by default and the only thing the user must take care of is to run all the desired coverage tools. You can use JaCoCo in a multi-module project so that all modules run JaCoCo separately and let the plugin aggregate the report, or you can run Saga and Cobertura in same project and get coverage report for JavaScript and Java files. Execute Maven to create Saga and Cobertura report and submit Coveralls data: ``` mvn clean test saga:coverage cobertura:cobertura coveralls:report ``` And if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean test saga:coverage cobertura:cobertura coveralls:report ``` ### Complete plugin configuration Configuration can be changed by the configuration section of plugin's definition in POM or with Java virtual machine system properties using the syntax `-Dparameter=value`. See [Maven plugin guide](http://maven.apache.org/guides/plugin/guide-java-plugin-development.html#Configuring_Parameters_in_a_Project) how different types are mapped in the configuration XML. Some of the optional parameters are set by the built-in service environment setups. Note that if a parameter is explicitly defined, the service environment will not override it. | Parameter | Type | Description | | --------- | ---- | ----------- | | `jacocoReports` | `List` | List of additional JaCoCo report files. ${project.reporting.outputDirectory}/jacoco/jacoco.xml is used as default for every module. | | `coberturaReports` | `List` | List of additional Cobertura report files. ${project.reporting.outputDirectory}/cobertura/coverage.xml is used as default for every module. | | `sagaReports` | `List` | List of additional Saga report files. ${project.build.directory}/saga-coverage/total-coverage.xml is used as default for every module. | | `relativeReportDirs` | `List` | List of additional relative report directories. Directories relative to ${project.reporting.outputDirectory} and ${project.build.directory} are scanned for reports. | | `coverallsFile` | `File` | **Default: ${project.build.directory}/coveralls.json**
File path to write and submit Coveralls data. | | `coverallsUrl` | `String` | **Default: https://coveralls.io/api/v1/jobs**
Url for the Coveralls API. | | `sourceDirectories` | `List` | List of additional source directories. The plugin will scan the project's compiled source roots for defaults. | | `sourceEncoding` | `String` | **Default: ${project.build.sourceEncoding}**
Source file encoding. | | `serviceName` | `String` | CI service name. If not provided the supported service environments are used. | | `serviceJobId` | `String` | CI service job id. Currently supported only with Travis CI. If this property is set, `repoToken` is not required. If not provided the supported service environments are used. | | `serviceBuildNumber` | `String` | CI service build number. If not provided the supported service environments are used. | | `serviceBuildUrl` | `String` | CI service build url. If not provided the supported service environments are used. | | `serviceEnvironment` | `Properties` | CI service specific environment properties. If not provided the supported service environments are used. | | `repoToken` | `String` | Coveralls repository token. **Do not publish this parameter unencrypted in public GitHub repositories.** | | `parallel` | `boolean` | **Default: false**
Coveralls API flag: If this is set, the build will not be considered done until a webhook has been sent to https://coveralls.io/webhook?repo_token=… | | `branch` | `String` | Git branch name. If not provided the supported service environments are used. | | `pullRequest` | `String` | GitHub pull request identifier. If not provided the supported service environments are used. | | `timestampFormat` | `String` | **Default: ${maven.build.timestamp}**
Build timestamp format. Must be in format supported by SimpleDateFormat. | | `timestamp` | `String` | **Default: ${timestamp}**
Build timestamp. Must be in format defined by 'timestampFormat' if it's available or in default timestamp format yyyy-MM-dd'T'HH:mm:ss'Z'. | | `dryRun` | `boolean` | **Default: false**
Dry run Coveralls report without actually sending it. | | `failOnServiceError` | `boolean` | **Default: true**
Fail build if Coveralls service is not available or submission fails for internal errors. | | `scanForSources` | `boolean` | **Default: false**
Scan subdirectories for source files. | | `coveralls.basedir` | `File` | **Default: ${project.basedir}**
Base directory of the project. | | `coveralls.skip` | `boolean` | **Default: false**
Skip the plugin execution. | ### FAQ > **Q:** How do I know that my coverage report was submitted successfully to Coveralls? > **A:** The plugin will end with BUILD SUCCESS and the log contains the reported job id and > direct URL to Coveralls. > **Q:** I get BUILD SUCCESS but why Coveralls shows only question marks in the reports? > **A:** The data is most likely reported correctly, but Coveralls might take hours, or even a > day, to update the actual coverage numbers. > **Q:** Can I use Java 8 with the plugin? > **A:** Yes. The Coveralls plugin works fine with Java 8, but the problem is the coverage tools. > Currently only tool supporting Java 8 is JaCoCo. You can use JaCoCo in a single module or > a multi-module project and let the Coveralls plugin handle the report aggregation. This is not > true aggregation though and does not address cross module coverage calculation (see > https://github.com/jacoco/jacoco/pull/97) > **Q:** Build fails with 'javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated' > exception, what to do? > **A:** If the build is run with OpenJDK, you probably hit an issue with the Cryptography Package > Providers not supporting all Elliptic Curves. The [issue](https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776) > is described in the Ubuntu issue tracker. A workaround is to disable the PKCS provider from the > `java.security` options file. > ``` > sudo sed -i 's/security.provider.9/#security.provider.9/g' $JAVA_HOME/jre/lib/security/java.security > ``` > In Travis CI the above command can be added to before_install phase. See complete example from > this project's `.travis.yml`. > **Q:** How can I use Scala or some other project which sources reside in other folder than > `src/main/java`? > **A:** The plugin uses all compiled source roots available for the project at runtime. If the > source directories are available, everything is fine. Otherwise additional source directories > can be applied with `sourceDirectories` configuration parameter that takes a Maven configuration > style list of source directories. > **Q:** How can I set the plugin to use multiple source directories? > **A:** For multi-module projects, the plugin automatically scans the project hierarchy and adds > all required source directories. You can also customize the used source directories with > `sourceDirectories` configuration parameter that takes a Maven configuration style list of > source directories. > **Q:** Why source files are not found for generated sources? > **A:** Generated source directories under target are not added to the sources list > automatically. It is often not good practice to test generated code, because the code is not > managed by the project under test, unless you are testing a source generator. Cobertura and > JaCoCo both have `` configuration directive that provides ignoring of class files. If > the generated sources still must be tested, all source directories can be explicitly defined > with `sourceDirectories` configuration parameter. > **Q:** JaCoCo or Cobertura, which one should i choose? > **A:** For multi-module projects, only Cobertura supports report aggregation out of the box. The > coverage metrics and performance of the two plugins are not much different for a small or medium > sized project, but there are 2 notable differences with the tools: > - JaCoCo does not track how many times a single line of code is hit by all the tests together, > so Coveralls is always reported with 1 as the number of hits if the line is covered. Cobertura > tracks the number of hits and the number is reported to Coveralls. > - Cobertura tracks all inner classes separately, so a single source file will contain multiple > records with same file name in Coveralls if there are any innner classes defined. The > coveralls-maven-plugin adds classifier from the inner class to distinguish the files, but if > there are lot of inner classes defined this creates some noise to the Coveralls reports. JaCoCo > tracks inner classes within same source file so each source file is only reported once to > Coveralls. ### Changelog See [changelog](CHANGELOG.md) for more details. ### Migration See [migration](MIGRATION.md) documentation for more information. ### Credits - Jakub Bednář (@bednar) for Saga integration and the idea of chaining multiple reports provided by different coverage tools. - Marvin Froeder (@velo) for Shippable and Appveyor support, configurable basedir and directory scanning source loader. - Pasi Niemi (@psiniemi) for coverage merging from different reports to single source file. ### Continuous integration Travis CI builds the plugin with Oracle JDK 7. All successfully built snapshots are deployed to Sonatype OSS repository. Cobertura is used to gather coverage metrics and the report is submitted to Coveralls with this plugin. ### Using test versions Add the following repository configurations to your `pom.xml` to enable snapshot versions of this plugin to be used. ```xml sonatype-nexus-snapshots https://oss.sonatype.org/content/repositories/snapshots false true sonatype-nexus-snapshot https://oss.sonatype.org/content/repositories/snapshots false true ``` ### License The project coveralls-maven-plugin is licensed under the MIT license. ================================================ FILE: README_2_x.md ================================================ coveralls-maven-plugin ====================== [![Build Status](http://img.shields.io/travis/trautonen/coveralls-maven-plugin/master.svg)](https://travis-ci.org/trautonen/coveralls-maven-plugin) [![Coverage Status](http://img.shields.io/coveralls/trautonen/coveralls-maven-plugin/master.svg)](https://coveralls.io/r/trautonen/coveralls-maven-plugin?branch=master) Maven plugin for submitting Java code coverage reports to [Coveralls](https://coveralls.io/) web service. ### Features * Supports [Cobertura](http://mojo.codehaus.org/cobertura-maven-plugin/), [JaCoCo](http://www.eclemma.org/jacoco/trunk/doc/maven.html) and [Saga](http://timurstrekalov.github.io/saga/) coverage tools * Multi-module report aggregation with Cobertura * Built-in support for [Travis CI](https://travis-ci.org/), [Circle](https://circleci.com/), [Codeship](https://www.codeship.io/), [Jenkins](http://jenkins-ci.org/) and [Bamboo](https://www.atlassian.com/software/bamboo/) continuous integration services * Fully streaming implementation for fast report generation and small memory footprint * Provides clean interfaces to allow easy extending to different coverage tools * Convention over configuration for almost zero configuration usage * Applies [semantic versioning](http://semver.org/) ### Usage Set up the Coveralls maven plugin in the build section of the project pom.xml: ```xml org.eluder.coveralls coveralls-maven-plugin 2.2.0 yourcoverallsprojectrepositorytoken ``` #### Configuration If used as a standalone Maven build or with any continuous integration server other than Travis CI, the Coveralls repository token must be provided. This can be achieved by setting the configuration section in the plugin or setting the Maven property `repoToken` to your coveralls project repository token, using `-DrepoToken=yourcoverallsprojectrepositorytoken` when running the maven command. **Do not publish your repository token in public GitHub repositories.** If you do, anyone can submit coverage data without permission. If you are using Travis CI, Circle, Codeship, Jenkins or Bamboo continuous integration services, no other configuration is required. The plugin's built-in service environment support take care of the rest. Multi-module projects that require aggregated reports have to set up Cobertura Maven plugin for the root project with `aggregate=true`. For other projects you are free to choose either [Cobertura](#cobertura) or [JaCoCo](#jacoco) plugin. Finally add the corresponding Maven command for the selected plugin to your continuous integration service build job. See [Complete plugin configuration](#complete-plugin-configuration) for all of the available configuration parameters. #### Cobertura Set up the Cobertura Maven plugin with XML report format in the build section of the project pom.xml: ```xml org.codehaus.mojo cobertura-maven-plugin 2.6 xml 256m true ``` Execute Maven to create Cobertura report and submit Coveralls data: ``` mvn cobertura:cobertura coveralls:cobertura ``` For example if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean cobertura:cobertura coveralls:cobertura ``` #### JaCoCo Set up the JaCoCo Maven plugin in the build section of the project pom.xml: ```xml org.jacoco jacoco-maven-plugin 0.7.2.201409121644 prepare-agent prepare-agent ``` Execute Maven to create JaCoCo report and submit Coveralls data: ``` mvn clean test jacoco:report coveralls:jacoco ``` Again, if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean test jacoco:report coveralls:jacoco ``` #### Saga Set up the Saga Maven plugin in the build section of the project pom.xml: ```xml com.github.timurstrekalov saga-maven-plugin 1.5.2 coverage http://localhost:${jasmine.serverPort} ${project.build.directory}/saga-coverage .*/spec/.* ``` You should also set the `sourceUrls` parameter for the plugin to load the sources from Jaasmine server. This allows creating coverage reports also for example CoffeeScript sources: ```xml http://localhost:${jasmine.serverPort} ``` Execute Maven to create Saga report and submit Coveralls data: ``` mvn clean test saga:coverage coveralls:saga ``` And if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean test saga:coverage coveralls:saga ``` #### Chain Create Coveralls data from multiple coverage tools. *Note: The chaining approach will be the default approach for future versions of coveralls maven plugin usage. Probably with the difference that the goal is changed from `chain` to `report`.* Configure the coverage plugins as described earlier and instead of single coverage tool goal use the `chain` goal to aggregate all coverage sources. Execute Maven to create Cobertura and Saga report and submit Coveralls data: ``` mvn clean test saga:coverage cobertura:cobertura coveralls:chain ``` And if you are using Travis CI this means you need to add to your `.travis.yml` the lines: ``` after_success: - mvn clean test saga:coverage cobertura:cobertura coveralls:chain ``` ### Complete plugin configuration Configuration can be changed by the configuration section of plugin's definition in POM or with Java virtual machine system properties using the syntax `-Dparameter=value`. See [Maven plugin guide](http://maven.apache.org/guides/plugin/guide-java-plugin-development.html#Configuring_Parameters_in_a_Project) how different types are mapped in the configuration XML. Some of the optional parameters are set by the built-in service environment setups. Note that if a parameter is explicitly defined, the service environment will not override it. | Parameter | Type | Description | | --------- | ---- | ----------- | | `coverallsFile` | `File` | **Default: ${project.build.directory}/coveralls.json**
File path to write and submit Coveralls data. | | `coverallsUrl` | `String` | **Default: https://coveralls.io/api/v1/jobs**
Url for the Coveralls API. | | `sourceDirectories` | `List` | List of source directories. If not provided, the plugin will scan the project's compiled source roots. | | `sourceUrls` | `List` | List of source urls. Can be used to load sources from external service, e.g. Jasmine server. | | `sourceEncoding` | `String` | **Default: ${project.build.sourceEncoding}**
Source file encoding. | | `serviceName` | `String` | CI service name. If not provided the supported service environments are used. | | `serviceJobId` | `String` | CI service job id. Currently supported only with Travis CI. If this property is set, `repoToken` is not required. If not provided the supported service environments are used. | | `serviceBuildNumber` | `String` | CI service build number. If not provided the supported service environments are used. | | `serviceBuildUrl` | `String` | CI service build url. If not provided the supported service environments are used. | | `serviceEnvironment` | `Properties` | CI service specific environment properties. If not provided the supported service environments are used. | | `repoToken` | `String` | Coveralls repository token. **Do not publish this parameter unencrypted in public GitHub repositories.** | | `branch` | `String` | Git branch name. If not provided the supported service environments are used. | | `pullRequest` | `String` | GitHub pull request identifier. If not provided the supported service environments are used. | | `timestamp` | `Date` | **Default: ${timestamp}**
Build timestamp. Must be in Maven supported 'yyyy-MM-dd HH:mm:ssa' format. | | `dryRun` | `boolean` | **Default: false**
Dry run Coveralls report without actually sending it. | | `coveralls.skip` | `boolean` | **Default: false**
Skip the plugin execution. | | `coberturaFile` | `File` | **Default: ${project.reporting.outputDirectory}/cobertura/coverage.xml**
Only for `chain` goal. Cobertura report file. | | `jacocoFile` | `File` | **Default: ${project.reporting.outputDirectory}/jacoco/jacoco.xml**
Only for `chain` goal. JaCoCo report file. | | `sagaFile` | `File` | **Default: ${project.build.directory}/saga-coverage/total-coverage.xml**
Only for `chain` goal. Saga report file. | ### FAQ > **Q:** How do I know that my coverage report was submitted successfully to Coveralls? > **A:** The plugin will end with BUILD SUCCESS and the log contains the reported job id and > direct URL to Coveralls. > **Q:** I get BUILD SUCCESS but why Coveralls shows only question marks in the reports? > **A:** The data is most likely reported correctly, but Coveralls might take hours, or even a > day, to update the actual coverage numbers. > **Q:** Build fails with 'javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated' > exception, what to do? > **A:** If the build is run with OpenJDK, you probably hit an issue with the Cryptography Package > Providers not supporting all Elliptic Curves. The [issue](https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776) > is described in the Ubuntu issue tracker. A workaround is to disable the PKCS provider from the > `java.security` options file. > ``` > sudo sed -i 's/security.provider.9/#security.provider.9/g' $JAVA_HOME/jre/lib/security/java.security > ``` > In Travis CI the above command can be added to before_install phase. See complete example from > this project's `.travis.yml`. > **Q:** How can I use Scala or some other project which sources reside in other folder than > `src/main/java`? > **A:** The plugin uses all compiled source roots available for the project at runtime. If the > source directories are available, everything is fine. Otherwise the used source directories can > be changed with `sourceDirectories` configuration parameter that takes a Maven configuration > style list of source directories. > **Q:** How can I set the plugin to use multiple source directories? > **A:** For multi-module projects, the plugin automatically scans the project hierarchy and adds > all required source directories. You can also customize the used source directories with > `sourceDirectories` configuration parameter that takes a Maven configuration style list of > source directories. > **Q:** Why source files are not found for generated sources? > **A:** Generated source directories under target are not added to the sources list > automatically. It is often not good practice to test generated code, because the code is not > managed by the project under test, unless you are testing a source generator. Cobertura and > JaCoCo both have `` configuration directive that provides ignoring of class files. If > the generated sources still must be tested, all source directories can be explicitly defined > with `sourceDirectories` configuration parameter. > **Q:** JaCoCo or Cobertura, which one should i choose? > **A:** For multi-module projects, only Cobertura supports report aggregation out of the box. The > coverage metrics and performance of the two plugins are not much different for a small or medium > sized project, but there are 2 notable differences with the tools: > - JaCoCo does not track how many times a single line of code is hit by all the tests together, > so Coveralls is always reported with 1 as the number of hits if the line is covered. Cobertura > tracks the number of hits and the number is reported to Coveralls. > - Cobertura tracks all inner classes separately, so a single source file will contain multiple > records with same file name in Coveralls if there are any innner classes defined. The > coveralls-maven-plugin adds classifier from the inner class to distinguish the files, but if > there are lot of inner classes defined this creates some noise to the Coveralls reports. JaCoCo > tracks inner classes within same source file so each source file is only reported once to > Coveralls. ### Changelog #### 2.2.0 - #31: Improved error messages for Coveralls API failures - #30: Improved error message for missing charset - #28: More lenient XML parsing - #26, #29: Support for Saga coverage tool and chain multiple coverage reports #### 2.1.0 - #24: Filter out remote names from git branches - #19, #20: Skip configuration property to allow skipping of plugin execution #### 2.0.1 - #18: Update to HttpComponents HttpClient 4.3 - #15, #16, #17: Disable PKCS cryptography provider at runtime to work around OpenJDK SSL issue #### 2.0.0 - #13: Dry run property for test builds - #12: Use ServiceSetup as secondary configuration source and Maven/VM properties as primary - #11: Support multiple source directories - #9: Support for other CI tools and platforms - #8: Aggregated reports for multi-module projects #### 1.2.0 - #10: Validation of the Coveralls job - #4: Report build timestamp to Coveralls - #3: Log code lines from generated report to Maven console #### 1.1.0 - #1: Easier configuration for Travis CI #### 1.0.0 - Initial release ### Migration guide Changes marked with bold affect the plugin usage. Other changes are only related to development and codebase. #### 1.x to 2.x - **`sourceDirectory` parameter removed and replaced with a list parameter `sourceDirectories`** - **service environment parameters do not override configuration parameters** - `org.eluder.coveralls.maven.plugin.service.ServiceSetup` interface completely changed to reflect the service specific configuration properly - `org.eluder.coveralls.maven.plugin.service.Travis` changed to reflect the new service setup interface - `org.eluder.coveralls.maven.plugin.domain.JobValidator` and all validation related code is now located in `org.eluder.coveralls.maven.plugin.validation` package - `org.eluder.coveralls.maven.plugin.domain.GitRepository` does not take custom branch parameter as constructor argument anymore, the same behavior is handled with the new service environment setup - `org.eluder.coveralls.maven.plugin.domain.Job` has only default constructor and initialization is done with _with*_ methods, _validate()_ method returns list of validation errors instead of throwing exception - `org.eluder.coveralls.maven.plugin.domain.SourceLoader` constructor takes a list of source directories instead of a single source directory ### Credits - Jakub Bednář (@bednar) for Saga integration and the idea of chaining multiple reports provided by different coverage tools. ### Continuous integration Travis CI builds the plugin with Oracle JDK 7. All successfully built snapshots are deployed to Sonatype OSS repository. Cobertura is used to gather coverage metrics and the report is submitted to Coveralls with this plugin. ### License The project coveralls-maven-plugin is licensed under the MIT license. ================================================ FILE: pom.xml ================================================ 4.0.0 org.eluder eluder-parent 9 org.eluder.coveralls coveralls-maven-plugin 4.4.0-SNAPSHOT maven-plugin coveralls-maven-plugin Maven plugin for submitting Java code coverage reports to Coveralls web service. https://github.com/trautonen/coveralls-maven-plugin 2013 Tapio Rautonen The MIT License (MIT) http://opensource.org/licenses/MIT repo scm:git:git://github.com/trautonen/coveralls-maven-plugin.git scm:git:git://github.com/trautonen/coveralls-maven-plugin.git https://github.com/trautonen/coveralls-maven-plugin 1.8 4.5.10 2.10.0 4.5.0.201609210915-r 3.5.4 yyyy-MM-dd'T'HH:mm:ss'Z' ${maven.build.timestamp} org.apache.httpcomponents httpclient commons-logging commons-logging org.apache.httpcomponents httpmime commons-codec commons-codec 1.13 com.fasterxml.jackson.core jackson-core com.fasterxml.jackson.core jackson-annotations com.fasterxml.jackson.core jackson-databind org.eclipse.jgit org.eclipse.jgit org.codehaus.plexus plexus-utils org.apache.maven maven-plugin-api org.apache.maven maven-core org.apache.maven.plugin-tools maven-plugin-annotations 3.5.2 provided org.slf4j slf4j-api org.slf4j jcl-over-slf4j junit junit test org.mockito mockito-core test org.hamcrest hamcrest-all 1.3 test org.apache.commons commons-lang3 3.9 test com.github.tomakehurst wiremock 2.25.1 test org.apache.httpcomponents httpclient ${httpclient.version} org.apache.httpcomponents httpmime ${httpclient.version} com.fasterxml.jackson.core jackson-core ${jackson.version} com.fasterxml.jackson.core jackson-annotations ${jackson.version} com.fasterxml.jackson.core jackson-databind ${jackson.version} org.eclipse.jgit org.eclipse.jgit ${jgit.version} org.apache.maven maven-plugin-api ${maven.version} org.apache.maven maven-model ${maven.version} org.apache.maven maven-artifact ${maven.version} org.apache.maven maven-core ${maven.version} org.apache.maven maven-settings ${maven.version} org.apache.maven maven-settings-builder ${maven.version} org.apache.maven maven-repository-metadata ${maven.version} org.apache.maven maven-model-builder ${maven.version} org.sonatype.sisu sisu-inject-plexus 1.4.3.2 org.codehaus.plexus plexus-utils 2.0.7 org.apache.maven.plugins maven-plugin-plugin 3.5.2 true mojo-descriptor descriptor help-goal helpmojo org.codehaus.mojo cobertura-maven-plugin org.eluder.coveralls coveralls-maven-plugin ${project.version} org.apache.maven.plugins maven-checkstyle-plugin org.apache.maven.plugins maven-jar-plugin 2.6 org.codehaus.mojo cobertura-maven-plugin ${maven.cobertura.version} **/HelpMojo.class org.apache.maven.plugins maven-checkstyle-plugin 2.17 **/HelpMojo.java org.apache.maven.plugins maven-javadoc-plugin ${maven.javadoc.version} ${project.basedir}/src/main/java org.codehaus.mojo license-maven-plugin ${maven.license.version} **/cobertura.xml **/jacoco1.xml **/jacoco2.xml **/SimpleCoverage.java **/InnerClassCoverage.java **/PartialCoverage.java **/saga.xml **/Components.js **/Localization.js ================================================ FILE: sample/README.md ================================================ Coverage samples ================ ### Cobertura ``` mvn -Pcobertura clean cobertura:cobertura ``` ### JaCoCo ``` mvn -Pjacoco clean verify jacoco:report ``` ### Saga ``` mvn -Psaga clean test saga:coverage ``` ================================================ FILE: sample/module1/pom.xml ================================================ 4.0.0 sample org.eluder.coverage 1.0-SNAPSHOT module1 1.0-SNAPSHOT jar ================================================ FILE: sample/module1/src/main/java/org/eluder/coverage/sample/InnerClassCoverage.java ================================================ package org.eluder.coverage.sample; public class InnerClassCoverage { public void anonymous() { InnerClass i = new InnerClass() { @Override public void run() { System.out.println("overridden"); } }; i.run(); } public boolean delegate() { return new InnerClass().isInner(); } public static class InnerClass { public boolean isInner() { return true; } public void run() { System.out.println("run"); } } } ================================================ FILE: sample/module1/src/main/java/org/eluder/coverage/sample/SimpleCoverage.java ================================================ package org.eluder.coverage.sample; public class SimpleCoverage { public boolean isTested() { return false; } public void neverRun() { System.out.println("oops"); } } ================================================ FILE: sample/module1/src/main/resources/Components.js ================================================ (function() { this.Components = {}; }).call(this); ================================================ FILE: sample/module1/src/main/resources/Localization.js ================================================ (function() { var Localization; Localization = (function() { function Localization(values) { this.values = values; } Localization.prototype.byKey = function(key) { return this.values[key]; }; return Localization; })(); }).call(this); ================================================ FILE: sample/module1/src/test/java/org/eluder/coverage/sample/InnerClassCoverageTest.java ================================================ package org.eluder.coverage.sample; import org.junit.Test; public class InnerClassCoverageTest { @Test public void testAnonymous() { new InnerClassCoverage().anonymous(); } @Test public void testDelegate() { new InnerClassCoverage().delegate(); } } ================================================ FILE: sample/module1/src/test/java/org/eluder/coverage/sample/SimpleCoverageTest.java ================================================ package org.eluder.coverage.sample; import org.junit.Test; public class SimpleCoverageTest { @Test public void test() { new SimpleCoverage().isTested(); } } ================================================ FILE: sample/module1/src/test/specs/ComponentsSpec.coffee ================================================ describe 'Components testing', -> it 'Components object on window not null', -> expect(window.Components).not.toBe(null) ================================================ FILE: sample/module2/pom.xml ================================================ 4.0.0 sample org.eluder.coverage 1.0-SNAPSHOT module2 1.0-SNAPSHOT jar ================================================ FILE: sample/module2/src/main/java/org/eluder/coverage/sample/PartialCoverage.java ================================================ package org.eluder.coverage.sample; public class PartialCoverage { public void partial(boolean test) { if (test) { System.out.println("test"); } else { System.out.println("not test"); } } } ================================================ FILE: sample/module2/src/test/java/org/eluder/coverage/sample/PartialCoverageIT.java ================================================ package org.eluder.coverage.sample; import org.junit.Test; public class PartialCoverageIT { @Test public void testSum() { new PartialCoverage().partial(false); } } ================================================ FILE: sample/module2/src/test/java/org/eluder/coverage/sample/PartialCoverageTest.java ================================================ package org.eluder.coverage.sample; import org.junit.Test; public class PartialCoverageTest { @Test public void testPartial() { new PartialCoverage().partial(true); } } ================================================ FILE: sample/pom.xml ================================================ 4.0.0 org.eluder eluder-parent 9 org.eluder.coverage sample 1.0-SNAPSHOT pom 3.1.0 0.8.1 2.7 2.2 1.5.5 module1 module2 junit junit test org.eluder.coveralls coveralls-maven-plugin 4.3.0 module1/src/main/resources maven-surefire-plugin maven-failsafe-plugin org.apache.maven.plugins maven-jar-plugin 2.6 cobertura org.codehaus.mojo cobertura-maven-plugin ${maven.cobertura.version} cobertura true jacoco org.jacoco jacoco-maven-plugin ${maven.jacoco.version} default-prepare-agent prepare-agent default-prepare-agent-integration prepare-agent-integration default-report report default-report-integration report-integration saga com.github.searls jasmine-maven-plugin ${maven.jasmine.version} test ${project.basedir}/src/main/resources/ ${project.basedir}/src/test/specs true org.openqa.selenium.htmlunit.HtmlUnitDriver com.github.timurstrekalov saga-maven-plugin ${maven.saga.version} coverage http://localhost:${jasmine.serverPort} ${project.build.directory}/saga-coverage .*/spec/.* .*/classpath/.* .*/webjars/.* ================================================ FILE: scripts/bump-version.sh ================================================ #!/bin/bash if [ $# -ne 1 ] then echo "Invalid number of arguments" echo "USAGE: $0 " exit 1 fi version=$1 script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" working_dir="$( pwd )" files=( "pom.xml" "README.md" ) source $script_dir/functions.sh if ! ( contains_files ${files[@]} ) then working_dir=$working_dir/.. cd $working_dir fi if ! ( contains_files ${files[@]} ) then echo "Some of the required files (${files[@]}) not found, aborting version bump" exit 1 fi echo "Updating version to $version in all poms" mvn versions:set -DnewVersion=$version > /dev/null mvn versions:commit > /dev/null if [[ "$version" != *-SNAPSHOT ]]; then echo "Replacing version numbers in readme" sed -n -i '1h;1!H;${;g;s,coveralls-maven-plugin\n [^<]*,coveralls-maven-plugin\n '"$version"',g;p;}' README.md fi echo "Committing version changes" git add ${files[@]} git commit -m "Updated to version $version." ================================================ FILE: scripts/functions.sh ================================================ #!/bin/bash contains_files() { for file in "$@" do if ! [ -f $file ] then return 1 fi done return 0 } ================================================ FILE: scripts/release.sh ================================================ #!/bin/bash script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" working_dir="$( pwd )" files=( "pom.xml" "README.md" ) source $script_dir/functions.sh if ! ( contains_files ${files[@]} ) then working_dir=$working_dir/.. cd $working_dir fi if ! ( contains_files ${files[@]} ) then echo "Some of the required files (${files[@]}) not found, aborting release" exit 1 fi echo -n "Enter release version: " read release_version echo -n "Enter new development version: " read develop_version echo -n "Enter GPG passphrase: " stty_orig=$(stty -g) stty -echo read passphrase stty $stty_orig echo "$passphrase" | gpg --passphrase-fd 0 --armor --output pom.xml.asc --detach-sig pom.xml > /dev/null gpg --verify pom.xml.asc > /dev/null if [ $? -ne 0 ]; then echo "Seems that the GPG passphrase was invalid" exit $? fi rm pom.xml.asc echo "" echo "Starting release process for $release_version" echo "Working in $( pwd )" echo "Press return to continue or CTRL-C to abort" read echo "Cleaning project" mvn clean > /dev/null echo "Updating license information" mvn license:update-project-license license:update-file-header > /dev/null git add -A git commit -m "Updated license information." $script_dir/bump-version.sh $release_version echo "Creating tag for v$release_version" git tag -a v$release_version -m "coveralls-maven-plugin version $release_version" git checkout v$release_version echo "" echo "If everything went fine artifacts can be deployed to staging repository" echo "After artifacts are deployed, login to https://oss.sonatype.org/ and complete the release" echo "Press return to continue deploying or CTRL-C to abort" read mvn -Pprepare-deploy,prepare-release -Dgpg.passphrase=$passphrase clean deploy echo "" echo "Preparing for next development version $develop_version" git checkout master $script_dir/bump-version.sh $develop_version echo "" echo "Pushing everything to origin" git push origin git push origin --tags echo "" echo "Release completed for $release_version, current development version is $develop_version!" ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/CoverageParser.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.io.IOException; import org.eluder.coveralls.maven.plugin.source.SourceCallback; /** * Handles parsing of a coverage report. The implemenation can be statefull, and the same instance * should be used only one time to parse a coverage report. Completed source files are passed to * the {@link org.eluder.coveralls.maven.plugin.source.SourceCallback} handler. To maximize performance, the parser should use streaming. */ public interface CoverageParser { /** * Parses a coverage report. Parsed source files are passed to the callback handler. This * method should be called only once per instance. * * @param callback the source callback handler * @throws ProcessingException if processing of the coverage report fails * @throws IOException if an I/O error occurs */ void parse(SourceCallback callback) throws ProcessingException, IOException; /** * @return the coverage report file under processing */ File getCoverageFile(); } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/CoverallsReportMojo.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.settings.Settings; import org.eluder.coveralls.maven.plugin.domain.CoverallsResponse; import org.eluder.coveralls.maven.plugin.domain.Git; import org.eluder.coveralls.maven.plugin.domain.GitRepository; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.httpclient.CoverallsClient; import org.eluder.coveralls.maven.plugin.httpclient.CoverallsProxyClient; import org.eluder.coveralls.maven.plugin.json.JsonWriter; import org.eluder.coveralls.maven.plugin.logging.CoverageTracingLogger; import org.eluder.coveralls.maven.plugin.logging.DryRunLogger; import org.eluder.coveralls.maven.plugin.logging.JobLogger; import org.eluder.coveralls.maven.plugin.logging.Logger; import org.eluder.coveralls.maven.plugin.logging.Logger.Position; import org.eluder.coveralls.maven.plugin.service.Appveyor; import org.eluder.coveralls.maven.plugin.service.Bamboo; import org.eluder.coveralls.maven.plugin.service.Circle; import org.eluder.coveralls.maven.plugin.service.General; import org.eluder.coveralls.maven.plugin.service.Jenkins; import org.eluder.coveralls.maven.plugin.service.ServiceSetup; import org.eluder.coveralls.maven.plugin.service.Shippable; import org.eluder.coveralls.maven.plugin.service.Travis; import org.eluder.coveralls.maven.plugin.service.Wercker; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import org.eluder.coveralls.maven.plugin.source.UniqueSourceCallback; import org.eluder.coveralls.maven.plugin.util.CoverageParsersFactory; import org.eluder.coveralls.maven.plugin.util.SourceLoaderFactory; import org.eluder.coveralls.maven.plugin.util.TimestampParser; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; @Mojo(name = "report", threadSafe = false, aggregator = true) public class CoverallsReportMojo extends AbstractMojo { /** * File paths to additional JaCoCo coverage report files. */ @Parameter(property = "jacocoReports") protected List jacocoReports; /** * File paths to additional Cobertura coverage report files. */ @Parameter(property = "coberturaReports") protected List coberturaReports; /** * File paths to additional Saga coverage report files. */ @Parameter(property = "sagaReports") protected List sagaReports; /** * Directories for relative per module specific report files. */ @Parameter(property = "relativeReportDirs") protected List relativeReportDirs; /** * File path to write and submit Coveralls data. */ @Parameter(property = "coverallsFile", defaultValue = "${project.build.directory}/coveralls.json") protected File coverallsFile; /** * Url for the Coveralls API. */ @Parameter(property = "coverallsUrl", defaultValue = "https://coveralls.io/api/v1/jobs") protected String coverallsUrl; /** * Source directories. */ @Parameter(property = "sourceDirectories") protected List sourceDirectories; /** * Source file encoding. */ @Parameter(property = "sourceEncoding", defaultValue = "${project.build.sourceEncoding}") protected String sourceEncoding; /** * CI service name. */ @Parameter(property = "serviceName") protected String serviceName; /** * CI service job id. */ @Parameter(property = "serviceJobId") protected String serviceJobId; /** * CI service build number. */ @Parameter(property = "serviceBuildNumber") protected String serviceBuildNumber; /** * CI service build url. */ @Parameter(property = "serviceBuildUrl") protected String serviceBuildUrl; /** * CI service specific environment properties. */ @Parameter(property = "serviceEnvironment") protected Properties serviceEnvironment; /** * Coveralls repository token. */ @Parameter(property = "repoToken") protected String repoToken; /** * Git branch name. */ @Parameter(property = "branch") protected String branch; /** * GitHub pull request identifier. */ @Parameter(property = "pullRequest") protected String pullRequest; /** * Coveralls parallel flag. */ @Parameter(property = "parallel") protected boolean parallel; /** * Build timestamp format. Must be in format supported by SimpleDateFormat. */ @Parameter(property = "timestampFormat", defaultValue = "${maven.build.timestamp.format}") protected String timestampFormat; /** * Build timestamp. Must be in format defined by 'timestampFormat' if it's available or in * default timestamp format yyyy-MM-dd'T'HH:mm:ss'Z'. */ @Parameter(property = "timestamp", defaultValue = "${maven.build.timestamp}") protected String timestamp; /** * Dry run Coveralls report without actually sending it. */ @Parameter(property = "dryRun", defaultValue = "false") protected boolean dryRun; /** * Fail build if Coveralls service is not available or submission fails for internal errors. */ @Parameter(property = "failOnServiceError", defaultValue = "true") protected boolean failOnServiceError; /** * Scan subdirectories for source files. */ @Parameter(property = "scanForSources", defaultValue = "false") protected boolean scanForSources; /** * Base directory of the project. */ @Parameter(property = "coveralls.basedir", defaultValue = "${project.basedir}") protected File basedir; /** * Skip the plugin execution. */ @Parameter(property = "coveralls.skip", defaultValue = "false") protected boolean skip; /** * Maven settings. */ @Parameter(defaultValue = "${settings}", readonly = true, required = true) protected Settings settings; /** * Maven project for runtime value resolution. */ @Component protected MavenProject project; @Override public final void execute() throws MojoExecutionException, MojoFailureException { if (skip) { getLog().info("Skip property set, skipping plugin execution"); return; } try { createEnvironment().setup(); Job job = createJob(); job.validate().throwOrInform(getLog()); SourceLoader sourceLoader = createSourceLoader(job); List parsers = createCoverageParsers(sourceLoader); JsonWriter writer = createJsonWriter(job); CoverallsClient client = createCoverallsClient(); List reporters = new ArrayList<>(); reporters.add(new JobLogger(job)); SourceCallback sourceCallback = createSourceCallbackChain(writer, reporters); reporters.add(new DryRunLogger(job.isDryRun(), writer.getCoverallsFile())); report(reporters, Position.BEFORE); writeCoveralls(writer, sourceCallback, parsers); report(reporters, Position.AFTER); if (!job.isDryRun()) { submitData(client, writer.getCoverallsFile()); } } catch (ProcessingException ex) { throw new MojoFailureException("Processing of input or output data failed", ex); } catch (IOException ex) { throw new MojoFailureException("I/O operation failed", ex); } catch (Exception ex) { throw new MojoExecutionException("Build error", ex); } } /** * * @param sourceLoader source loader that extracts source files * @return coverage parsers for all maven modules and additional reports * @throws IOException if parsers cannot be created */ protected List createCoverageParsers(final SourceLoader sourceLoader) throws IOException { return new CoverageParsersFactory(project, sourceLoader) .withJaCoCoReports(jacocoReports) .withCoberturaReports(coberturaReports) .withSagaReports(sagaReports) .withRelativeReportDirs(relativeReportDirs) .createParsers(); } /** * @return source loader that extracts source files * * @param job the job describing the coveralls report */ protected SourceLoader createSourceLoader(final Job job) { return new SourceLoaderFactory(job.getGit().getBaseDir(), project, sourceEncoding) .withSourceDirectories(sourceDirectories) .withScanForSources(scanForSources) .createSourceLoader(); } /** * @return environment to setup mojo and service specific properties */ protected Environment createEnvironment() { return new Environment(this, getServices()); } /** * @return list of available continuous integration services */ protected List getServices() { Map env = System.getenv(); List services = new ArrayList<>(); services.add(new Shippable(env)); services.add(new Travis(env)); services.add(new Circle(env)); services.add(new Jenkins(env)); services.add(new Bamboo(env)); services.add(new Appveyor(env)); services.add(new Wercker(env)); services.add(new General(env)); return services; } /** * @return job that describes the coveralls report * @throws ProcessingException if processing of timestamp fails * @throws IOException if an I/O error occurs */ protected Job createJob() throws ProcessingException, IOException { Git git = new GitRepository(basedir).load(); Date time = new TimestampParser(timestampFormat).parse(timestamp); return new Job() .withRepoToken(repoToken) .withServiceName(serviceName) .withServiceJobId(serviceJobId) .withServiceBuildNumber(serviceBuildNumber) .withServiceBuildUrl(serviceBuildUrl) .withParallel(parallel) .withServiceEnvironment(serviceEnvironment) .withDryRun(dryRun) .withBranch(branch) .withPullRequest(pullRequest) .withTimestamp(time) .withGit(git); } /** * @param job the job describing the coveralls report * @return JSON writer that writes the coveralls data * @throws IOException if an I/O error occurs */ protected JsonWriter createJsonWriter(final Job job) throws IOException { return new JsonWriter(job, coverallsFile); } /** * @return http client that submits the coveralls data */ protected CoverallsClient createCoverallsClient() { return new CoverallsProxyClient(coverallsUrl, settings.getActiveProxy()); } /** * @param writer the JSON writer * @param reporters the logging reporters * @return source callback chain for different source handlers */ protected SourceCallback createSourceCallbackChain(final JsonWriter writer, final List reporters) { SourceCallback chain = writer; if (getLog().isInfoEnabled()) { CoverageTracingLogger coverageTracingReporter = new CoverageTracingLogger(chain); chain = coverageTracingReporter; reporters.add(coverageTracingReporter); } chain = new UniqueSourceCallback(chain); return chain; } /** * Writes coverage data to JSON file. * * @param writer JSON writer that writes the coveralls data * @param sourceCallback the source callback handler * @param parsers list of coverage parsers * @throws ProcessingException if process to to create JSON file fails * @throws IOException if an I/O error occurs */ protected void writeCoveralls(final JsonWriter writer, final SourceCallback sourceCallback, final List parsers) throws ProcessingException, IOException { try { getLog().info("Writing Coveralls data to " + writer.getCoverallsFile().getAbsolutePath() + "..."); long now = System.currentTimeMillis(); sourceCallback.onBegin(); for (CoverageParser parser : parsers) { getLog().info("Processing coverage report from " + parser.getCoverageFile().getAbsolutePath()); parser.parse(sourceCallback); } sourceCallback.onComplete(); long duration = System.currentTimeMillis() - now; getLog().info("Successfully wrote Coveralls data in " + duration + "ms"); } finally { writer.close(); } } private void submitData(final CoverallsClient client, final File coverallsFile) throws ProcessingException, IOException { getLog().info("Submitting Coveralls data to API"); long now = System.currentTimeMillis(); try { CoverallsResponse response = client.submit(coverallsFile); long duration = System.currentTimeMillis() - now; getLog().info("Successfully submitted Coveralls data in " + duration + "ms for " + response.getMessage()); getLog().info(response.getUrl()); getLog().info("*** It might take hours for Coveralls to update the actual coverage numbers for a job"); getLog().info(" If you see question marks in the report, please be patient"); } catch (ProcessingException ex) { long duration = System.currentTimeMillis() - now; String message = "Submission failed in " + duration + "ms while processing data"; handleSubmissionError(ex, message, true); } catch (IOException ex) { long duration = System.currentTimeMillis() - now; String message = "Submission failed in " + duration + "ms while handling I/O operations"; handleSubmissionError(ex, message, failOnServiceError); } } private void handleSubmissionError(final T ex, final String message, final boolean failOnException) throws T { if (failOnException) { getLog().error(message); throw ex; } else { getLog().warn(message); } } private void report(final List reporters, final Position position) { for (Logger reporter : reporters) { if (position.equals(reporter.getPosition())) { reporter.log(getLog()); } } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/Environment.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Properties; import org.codehaus.plexus.util.StringUtils; import org.eluder.coveralls.maven.plugin.service.ServiceSetup; /** * Constructs and setups the project environment and continuous integration service. */ public final class Environment { private final CoverallsReportMojo mojo; private final Iterable services; public Environment(final CoverallsReportMojo mojo, final Iterable services) { if (mojo == null) { throw new IllegalArgumentException("mojo must be defined"); } if (services == null) { throw new IllegalArgumentException("services must be defined"); } this.mojo = mojo; this.services = services; } public void setup() { setupService(); verify(); } private void verify() { if (mojo.sourceEncoding == null) { throw new IllegalArgumentException("Source encoding not set, use configuration option or set project wide property "); } } private void setupService() { for (ServiceSetup service : services) { if (service.isSelected()) { setupEnvironment(service); break; } } } private void setupEnvironment(final ServiceSetup service) { String name = service.getName(); if (StringUtils.isBlank(mojo.serviceName) && StringUtils.isNotBlank(name)) { mojo.serviceName = name; } String jobId = service.getJobId(); if (StringUtils.isBlank(mojo.serviceJobId) && StringUtils.isNotBlank(jobId)) { mojo.serviceJobId = jobId; } String buildNumber = service.getBuildNumber(); if (StringUtils.isBlank(mojo.serviceBuildNumber) && StringUtils.isNotBlank(buildNumber)) { mojo.serviceBuildNumber = buildNumber; } String buildUrl = service.getBuildUrl(); if (StringUtils.isBlank(mojo.serviceBuildUrl) && StringUtils.isNotBlank(buildUrl)) { mojo.serviceBuildUrl = buildUrl; } String branch = service.getBranch(); if (StringUtils.isBlank(mojo.branch) && StringUtils.isNotBlank(branch)) { mojo.branch = branch; } String pullRequest = service.getPullRequest(); if (StringUtils.isBlank(mojo.pullRequest) && StringUtils.isNotBlank(pullRequest)) { mojo.pullRequest = pullRequest; } Properties environment = service.getEnvironment(); if ((mojo.serviceEnvironment == null || mojo.serviceEnvironment.isEmpty()) && (environment != null && !environment.isEmpty())) { mojo.serviceEnvironment = environment; } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/ProcessingException.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ /** * Exception to indicate if processing of input or output data fails. */ public class ProcessingException extends Exception { public ProcessingException() { super(); } public ProcessingException(final String message) { super(message); } public ProcessingException(final Throwable cause) { super(cause); } public ProcessingException(final String message, final Throwable cause) { super(message, cause); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/Branch.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ public class Branch { private final int lineNumber; private final int blockNumber; private final int branchNumber; private final int hits; public Branch(final int lineNumber, final int blockNumber, final int branchNumber, final int hits) { this.lineNumber = lineNumber; this.blockNumber = blockNumber; this.branchNumber = branchNumber; this.hits = hits; } public int getLineNumber() { return lineNumber; } public int getBlockNumber() { return blockNumber; } public int getBranchNumber() { return branchNumber; } public int getHits() { return hits; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/CoverallsResponse.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; public final class CoverallsResponse implements JsonObject { private final String message; private final boolean error; private final String url; @JsonCreator public CoverallsResponse( @JsonProperty("message") final String message, @JsonProperty("error") final boolean error, @JsonProperty("url") final String url) { this.message = message; this.error = error; this.url = url; } public String getMessage() { return message; } public boolean isError() { return error; } public String getUrl() { return url; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/Git.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.io.Serializable; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; public class Git implements JsonObject { @JsonIgnore private final File baseDir; @JsonProperty("head") private final Head head; @JsonProperty("branch") private final String branch; @JsonProperty("remotes") private final List remotes; public Git(final File baseDir, final Head head, final String branch, final List remotes) { this.baseDir = baseDir; this.head = head; this.branch = branch; this.remotes = remotes; } public File getBaseDir() { return baseDir; } public Head getHead() { return head; } public String getBranch() { return branch; } public List getRemotes() { return remotes; } public static class Head implements Serializable { @JsonProperty("id") private final String id; @JsonProperty("author_name") private final String authorName; @JsonProperty("author_email") private final String authorEmail; @JsonProperty("committer_name") private final String committerName; @JsonProperty("committer_email") private final String committerEmail; @JsonProperty("message") private final String message; public Head(final String id, final String authorName, final String authorEmail, final String committerName, final String committerEmail, final String message) { this.id = id; this.authorName = authorName; this.authorEmail = authorEmail; this.committerName = committerName; this.committerEmail = committerEmail; this.message = message; } public String getId() { return id; } public String getAuthorName() { return authorName; } public String getAuthorEmail() { return authorEmail; } public String getCommitterName() { return committerName; } public String getCommitterEmail() { return committerEmail; } public String getMessage() { return message; } } public static class Remote implements Serializable { @JsonProperty("name") private final String name; @JsonProperty("url") private final String url; public Remote(final String name, final String url) { this.name = name; this.url = url; } public String getName() { return name; } public String getUrl() { return url; } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/GitRepository.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryBuilder; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class GitRepository { private final File sourceDirectory; public GitRepository(final File sourceDirectory) { this.sourceDirectory = sourceDirectory; } public Git load() throws IOException { try (Repository repository = new RepositoryBuilder().findGitDir(this.sourceDirectory).build()) { Git.Head head = getHead(repository); String branch = getBranch(repository); List remotes = getRemotes(repository); return new Git(repository.getWorkTree(), head, branch, remotes); } } private Git.Head getHead(final Repository repository) throws IOException { ObjectId revision = repository.resolve(Constants.HEAD); RevCommit commit = new RevWalk(repository).parseCommit(revision); Git.Head head = new Git.Head( revision.getName(), commit.getAuthorIdent().getName(), commit.getAuthorIdent().getEmailAddress(), commit.getCommitterIdent().getName(), commit.getCommitterIdent().getEmailAddress(), commit.getFullMessage() ); return head; } private String getBranch(final Repository repository) throws IOException { return repository.getBranch(); } private List getRemotes(final Repository repository) { Config config = repository.getConfig(); List remotes = new ArrayList<>(); for (String remote : config.getSubsections("remote")) { String url = config.getString("remote", remote, "url"); remotes.add(new Git.Remote(remote, url)); } return remotes; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/Job.java ================================================ package org.eluder.coveralls.maven.plugin.domain; import java.util.Date; import java.util.Properties; import org.eluder.coveralls.maven.plugin.domain.Git.Remote; import org.eluder.coveralls.maven.plugin.validation.JobValidator; import org.eluder.coveralls.maven.plugin.validation.ValidationErrors; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ public class Job { private String repoToken; private String serviceName; private String serviceJobId; private String serviceBuildNumber; private String serviceBuildUrl; private boolean parallel; private Properties serviceEnvironment; private Date timestamp; private boolean dryRun; private String branch; private String pullRequest; private Git git; public Job() { // noop } public Job withRepoToken(final String repoToken) { this.repoToken = repoToken; return this; } public Job withServiceName(final String serviceName) { this.serviceName = serviceName; return this; } public Job withServiceJobId(final String serviceJobId) { this.serviceJobId = serviceJobId; return this; } public Job withServiceBuildNumber(final String serviceBuildNumber) { this.serviceBuildNumber = serviceBuildNumber; return this; } public Job withServiceBuildUrl(final String serviceBuildUrl) { this.serviceBuildUrl = serviceBuildUrl; return this; } public Job withParallel(final boolean parallel) { this.parallel = parallel; return this; } public Job withServiceEnvironment(final Properties serviceEnvironment) { this.serviceEnvironment = serviceEnvironment; return this; } public Job withTimestamp(final Date timestamp) { this.timestamp = timestamp; return this; } public Job withDryRun(final boolean dryRun) { this.dryRun = dryRun; return this; } public Job withBranch(final String branch) { this.branch = branch; return this; } public Job withPullRequest(final String pullRequest) { this.pullRequest = pullRequest; return this; } public Job withGit(final Git git) { this.git = git; return this; } public String getRepoToken() { return repoToken; } public String getServiceName() { return serviceName; } public String getServiceJobId() { return serviceJobId; } public String getServiceBuildNumber() { return serviceBuildNumber; } public String getServiceBuildUrl() { return serviceBuildUrl; } public Properties getServiceEnvironment() { return serviceEnvironment; } public Date getTimestamp() { return timestamp; } public boolean isParallel() { return parallel; } public boolean isDryRun() { return dryRun; } public String getBranch() { if (branch != null && getGit() != null && getGit().getRemotes() != null) { for (Remote remote : getGit().getRemotes()) { if (branch.startsWith(remote.getName() + "/")) { return branch.substring(remote.getName().length() + 1); } } } return branch; } public String getPullRequest() { return pullRequest; } public Git getGit() { return git; } public ValidationErrors validate() { JobValidator validator = new JobValidator(this); return validator.validate(); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/JsonObject.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.Serializable; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) public interface JsonObject extends Serializable { } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/domain/Source.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.ListIterator; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class Source implements JsonObject { private static final Pattern NEWLINE = Pattern.compile("\r\n|\r|\n"); //private static final String CLASSIFIER_SEPARATOR = "#"; private final String name; private final String digest; private final Integer[] coverage; private final List branches; private String classifier; public Source(final String name, final String source, final String digest) { this(name, getLines(source), digest, null); } protected Source(final String name, final int lines, final String digest, final String classifier) { this.name = name; this.digest = digest; this.coverage = new Integer[lines]; this.classifier = classifier; this.branches = new ArrayList<>(); } @JsonIgnore public String getName() { return name; } @JsonProperty("name") public String getFullName() { return name; // #45: cannot use identifier due to unfetchable source files //return (classifier == null ? name : name + CLASSIFIER_SEPARATOR + classifier); } @JsonProperty("source_digest") public String getDigest() { return digest; } @JsonProperty("coverage") public Integer[] getCoverage() { return coverage; } @JsonProperty("branches") public Integer[] getBranches() { final List branchesRaw = new ArrayList<>(branches.size() * 4); for (final Branch b : branches) { branchesRaw.add(b.getLineNumber()); branchesRaw.add(b.getBlockNumber()); branchesRaw.add(b.getBranchNumber()); branchesRaw.add(b.getHits()); } return branchesRaw.toArray(new Integer[branchesRaw.size()]); } public List getBranchesList() { return Collections.unmodifiableList(branches); } @JsonIgnore public String getClassifier() { return classifier; } public void setClassifier(final String classifier) { this.classifier = classifier; } private void checkLineRange(final int lineNumber) { int index = lineNumber - 1; if (index >= this.coverage.length) { throw new IllegalArgumentException("Line number " + lineNumber + " is greater than the source file " + name + " size"); } } public void addCoverage(final int lineNumber, final Integer coverage) { checkLineRange(lineNumber); this.coverage[lineNumber - 1] = coverage; } public void addBranchCoverage(final int lineNumber, final int blockNumber, final int branchNumber, final int hits) { addBranchCoverage(false, lineNumber, blockNumber, branchNumber, hits); } private void addBranchCoverage(final boolean merge, final int lineNumber, final int blockNumber, final int branchNumber, final int hits) { checkLineRange(lineNumber); int hitSum = hits; final ListIterator it = this.branches.listIterator(); while (it.hasNext()) { final Branch b = it.next(); if (b.getLineNumber() == lineNumber && b.getBlockNumber() == blockNumber && b.getBranchNumber() == branchNumber) { it.remove(); if (merge) { hitSum += b.getHits(); } } } this.branches.add(new Branch(lineNumber, blockNumber, branchNumber, hitSum)); } public Source merge(final Source source) { Source copy = new Source(this.name, this.coverage.length, this.digest, this.classifier); System.arraycopy(this.coverage, 0, copy.coverage, 0, this.coverage.length); copy.branches.addAll(this.branches); if (copy.equals(source)) { for (int i = 0; i < copy.coverage.length; i++) { if (source.coverage[i] != null) { int base = copy.coverage[i] != null ? copy.coverage[i] : 0; copy.coverage[i] = base + source.coverage[i]; } } for (final Branch b : source.branches) { copy.addBranchCoverage(true, b.getLineNumber(), b.getBlockNumber(), b.getBranchNumber(), b.getHits()); } } return copy; } @Override public boolean equals(final Object obj) { if (!(obj instanceof Source)) { return false; } Source other = (Source) obj; return (Objects.equals(this.name, other.name) && Objects.equals(this.digest, other.digest) && Objects.equals(this.coverage.length, other.coverage.length)); } @Override public int hashCode() { return Objects.hash(this.name, this.digest, this.coverage.length); } private static int getLines(final String source) { int lines = 1; Matcher matcher = NEWLINE.matcher(source); while (matcher.find()) { lines++; } return lines; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsClient.java ================================================ package org.eluder.coveralls.maven.plugin.httpclient; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.CoverallsResponse; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.security.Provider; import java.security.Security; public class CoverallsClient { static { for (Provider provider : Security.getProviders()) { if (provider.getName().startsWith("SunPKCS11")) { Security.removeProvider(provider.getName()); } } } private static final String FILE_NAME = "coveralls.json"; private static final ContentType MIME_TYPE = ContentType.create("application/octet-stream", "utf-8"); private final String coverallsUrl; private final HttpClient httpClient; private final ObjectMapper objectMapper; public CoverallsClient(final String coverallsUrl) { this(coverallsUrl, new HttpClientFactory(coverallsUrl).create(), new ObjectMapper()); } public CoverallsClient(final String coverallsUrl, final HttpClient httpClient, final ObjectMapper objectMapper) { this.coverallsUrl = coverallsUrl; this.httpClient = httpClient; this.objectMapper = objectMapper; } public CoverallsResponse submit(final File file) throws ProcessingException, IOException { HttpEntity entity = MultipartEntityBuilder.create() .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) .addBinaryBody("json_file", file, MIME_TYPE, FILE_NAME) .build(); HttpPost post = new HttpPost(coverallsUrl); post.setEntity(entity); HttpResponse response = httpClient.execute(post); return parseResponse(response); } private CoverallsResponse parseResponse(final HttpResponse response) throws ProcessingException, IOException { HttpEntity entity = response.getEntity(); ContentType contentType = ContentType.getOrDefault(entity); if (contentType.getCharset() == null) { throw new ProcessingException(getResponseErrorMessage(response, "Response doesn't contain Content-Type header")); } InputStreamReader reader = null; try { if (response.getStatusLine().getStatusCode() >= HttpStatus.SC_INTERNAL_SERVER_ERROR) { throw new IOException("Coveralls API internal error"); } reader = new InputStreamReader(entity.getContent(), contentType.getCharset()); CoverallsResponse cr = objectMapper.readValue(reader, CoverallsResponse.class); if (cr.isError()) { throw new ProcessingException(getResponseErrorMessage(response, cr.getMessage())); } return cr; } catch (JsonProcessingException ex) { throw new ProcessingException(getResponseErrorMessage(response, ex.getMessage()), ex); } catch (IOException ex) { throw new IOException(getResponseErrorMessage(response, ex.getMessage()), ex); } finally { IOUtil.close(reader); } } private String getResponseErrorMessage(final HttpResponse response, final String message) { int status = response.getStatusLine().getStatusCode(); String reason = response.getStatusLine().getReasonPhrase(); String errorMessage = "Report submission to Coveralls API failed with HTTP status " + status + ":"; if (StringUtils.isNotBlank(reason)) { errorMessage += " " + reason; } if (StringUtils.isNotBlank(message)) { errorMessage += " (" + message + ")"; } return errorMessage; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsProxyClient.java ================================================ package org.eluder.coveralls.maven.plugin.httpclient; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.maven.settings.Proxy; public class CoverallsProxyClient extends CoverallsClient { public CoverallsProxyClient(final String coverallsUrl, final Proxy proxy) { super(coverallsUrl, new HttpClientFactory(coverallsUrl).proxy(proxy).create(), new ObjectMapper()); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/httpclient/HttpClientFactory.java ================================================ package org.eluder.coveralls.maven.plugin.httpclient; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.maven.settings.Proxy; import org.codehaus.plexus.util.StringUtils; import org.eluder.coveralls.maven.plugin.util.UrlUtils; import org.eluder.coveralls.maven.plugin.util.Wildcards; class HttpClientFactory { private static final int DEFAULT_CONNECTION_TIMEOUT = 10000; private static final int DEFAULT_SOCKET_TIMEOUT = 60000; private final String targetUrl; private final HttpClientBuilder hcb = HttpClientBuilder.create(); private final RequestConfig.Builder rcb = RequestConfig.custom() .setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT) .setSocketTimeout(DEFAULT_SOCKET_TIMEOUT); HttpClientFactory(final String targetUrl) { this.targetUrl = targetUrl; } public HttpClientFactory proxy(final Proxy proxy) { if (proxy != null && isProxied(targetUrl, proxy)) { rcb.setProxy(new HttpHost(proxy.getHost(), proxy.getPort(), proxy.getProtocol())); if (StringUtils.isNotBlank(proxy.getUsername())) { CredentialsProvider cp = new BasicCredentialsProvider(); cp.setCredentials( new AuthScope(proxy.getHost(), proxy.getPort()), new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()) ); hcb.setDefaultCredentialsProvider(cp); } } return this; } public HttpClient create() { return hcb.setDefaultRequestConfig(rcb.build()).build(); } private boolean isProxied(final String url, final Proxy proxy) { if (StringUtils.isNotBlank(proxy.getNonProxyHosts())) { String host = UrlUtils.create(url).getHost(); String[] excludes = proxy.getNonProxyHosts().split("\\|"); for (String exclude : excludes) { if (StringUtils.isNotBlank(exclude) && Wildcards.matches(host, exclude.trim())) { return false; } } } return true; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/json/JsonWriter.java ================================================ package org.eluder.coveralls.maven.plugin.json; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.MappingJsonFactory; import org.codehaus.plexus.util.StringUtils; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map.Entry; import java.util.Properties; public class JsonWriter implements SourceCallback, Closeable { protected static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss Z"; private final Job job; private final File coverallsFile; private final JsonGenerator generator; public JsonWriter(final Job job, final File coverallsFile) throws IOException { File directory = coverallsFile.getParentFile(); if (!directory.exists()) { directory.mkdirs(); } this.job = job; this.coverallsFile = coverallsFile; this.generator = new MappingJsonFactory().createGenerator(coverallsFile, JsonEncoding.UTF8); } public final Job getJob() { return job; } public final File getCoverallsFile() { return coverallsFile; } @Override public void onBegin() throws ProcessingException, IOException { try { generator.writeStartObject(); writeOptionalString("repo_token", job.getRepoToken()); writeOptionalString("service_name", job.getServiceName()); writeOptionalString("service_job_id", job.getServiceJobId()); writeOptionalString("service_number", job.getServiceBuildNumber()); writeOptionalString("service_build_url", job.getServiceBuildUrl()); writeOptionalString("service_branch", job.getBranch()); writeOptionalString("service_pull_request", job.getPullRequest()); writeOptionalBoolean("parallel", job.isParallel()); writeOptionalTimestamp("run_at", job.getTimestamp()); writeOptionalEnvironment("environment", job.getServiceEnvironment()); writeOptionalObject("git", job.getGit()); generator.writeArrayFieldStart("source_files"); } catch (JsonProcessingException ex) { throw new ProcessingException(ex); } } @Override public void onSource(final Source source) throws ProcessingException, IOException { try { generator.writeObject(source); } catch (JsonProcessingException ex) { throw new ProcessingException(ex); } } @Override public void onComplete() throws ProcessingException, IOException { try { generator.writeEndArray(); generator.writeEndObject(); } catch (JsonProcessingException ex) { throw new ProcessingException(ex); } } @Override public void close() throws IOException { generator.close(); } private void writeOptionalString(final String field, final String value) throws ProcessingException, IOException { if (StringUtils.isNotBlank(value)) { generator.writeStringField(field, value); } } private void writeOptionalBoolean(final String field, final boolean value) throws ProcessingException, IOException { if (value) { generator.writeBooleanField(field, value); } } private void writeOptionalObject(final String field, final Object value) throws ProcessingException, IOException { if (value != null) { generator.writeObjectField(field, value); } } private void writeOptionalTimestamp(final String field, final Date value) throws ProcessingException, IOException { if (value != null) { SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_FORMAT); writeOptionalString(field, format.format(value)); } } private void writeOptionalEnvironment(final String field, final Properties properties) throws ProcessingException, IOException { if (properties != null) { generator.writeObjectFieldStart(field); for (Entry property : properties.entrySet()) { writeOptionalString(property.getKey().toString(), property.getValue().toString()); } generator.writeEndObject(); } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/logging/CoverageTracingLogger.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Branch; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.source.ChainingSourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import java.io.IOException; public class CoverageTracingLogger extends ChainingSourceCallback implements Logger { private long files = 0; private long lines = 0; private long relevant = 0; private long covered = 0; private long branches = 0; private long coveredBranches = 0; public CoverageTracingLogger(final SourceCallback chained) { super(chained); } public long getFiles() { return files; } public final long getLines() { return lines; } public final long getRelevant() { return relevant; } public final long getCovered() { return covered; } public final long getMissed() { return relevant - covered; } public final long getBranches() { return branches; } public final long getCoveredBranches() { return coveredBranches; } public final long getMissedBranches() { return branches - coveredBranches; } @Override public Position getPosition() { return Position.AFTER; } @Override public void log(final Log log) { log.info("Gathered code coverage metrics for " + getFiles() + " source files with " + getLines() + " lines of code:"); log.info("- " + getRelevant() + " relevant lines"); log.info("- " + getCovered() + " covered lines"); log.info("- " + getMissed() + " missed lines"); log.info("- " + getBranches() + " branches"); log.info("- " + getCoveredBranches() + " covered branches"); log.info("- " + getMissedBranches() + " missed branches"); } @Override protected void onSourceInternal(final Source source) throws ProcessingException, IOException { files++; lines += source.getCoverage().length; for (Integer coverage : source.getCoverage()) { if (coverage != null) { relevant++; if (coverage > 0) { covered++; } } } this.branches += source.getBranchesList().size(); for (final Branch b : source.getBranchesList()) { if (b.getHits() > 0) { coveredBranches++; } } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/logging/DryRunLogger.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import org.apache.maven.plugin.logging.Log; public class DryRunLogger implements Logger { private final boolean dryRun; private final File coverallsFile; public DryRunLogger(final boolean dryRun, final File coverallsFile) { if (coverallsFile == null) { throw new IllegalArgumentException("coverallsFile must be defined"); } this.dryRun = dryRun; this.coverallsFile = coverallsFile; } @Override public Position getPosition() { return Position.AFTER; } @Override public void log(final Log log) { if (dryRun) { log.info("Dry run enabled, Coveralls report will NOT be submitted to API"); log.info(coverallsFile.length() + " bytes of data was recorded in " + coverallsFile.getAbsolutePath()); } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/logging/JobLogger.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.domain.Job; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; public class JobLogger implements Logger { private static final int ABBREV = 7; private final Job job; private final ObjectMapper jsonMapper; public JobLogger(final Job job) { this(job, null); } public JobLogger(final Job job, final ObjectMapper jsonMapper) { if (job == null) { throw new IllegalArgumentException("job must be defined"); } this.job = job; this.jsonMapper = (jsonMapper != null ? jsonMapper : createDefaultJsonMapper()); } @Override public Position getPosition() { return Position.BEFORE; } @Override public void log(final Log log) { StringBuilder starting = new StringBuilder("Starting Coveralls job"); if (job.getServiceName() != null) { starting.append(" for " + job.getServiceName()); if (job.getServiceJobId() != null) { starting.append(" (" + job.getServiceJobId() + ")"); } else if (job.getServiceBuildNumber() != null) { starting.append(" (" + job.getServiceBuildNumber()); if (job.getServiceBuildUrl() != null) { starting.append(" / " + job.getServiceBuildUrl()); } starting.append(")"); } } if (job.isDryRun()) { starting.append(" in dry run mode"); } if (job.isParallel()) { starting.append(" with parallel option enabled"); } log.info(starting.toString()); if (job.getRepoToken() != null) { log.info("Using repository token "); } if (job.getGit() != null) { String commit = job.getGit().getHead().getId(); String branch = (job.getBranch() != null ? job.getBranch() : job.getGit().getBranch()); log.info("Git commit " + commit.substring(0, ABBREV) + " in " + branch); } if (log.isDebugEnabled()) { try { log.debug("Complete Job description:\n" + jsonMapper.writeValueAsString(job)); } catch (JsonProcessingException ex) { throw new RuntimeException(ex); } } } private ObjectMapper createDefaultJsonMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true); mapper.configure(SerializationFeature.INDENT_OUTPUT, true); mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true); return mapper; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/logging/Logger.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.plugin.logging.Log; public interface Logger { /** * Position of the log output. */ enum Position { BEFORE, AFTER } /** * @return the position for log output, before or after the Coveralls data writing */ Position getPosition(); /** * Create the log output. * * @param log the logger to output */ void log(Log log); } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/parser/AbstractXmlEventParser.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.xml.XmlStreamReader; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import javax.xml.stream.FactoryConfigurationError; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import java.io.File; import java.io.IOException; import java.io.Reader; public abstract class AbstractXmlEventParser implements CoverageParser { private final File coverageFile; private final SourceLoader sourceLoader; public AbstractXmlEventParser(final File coverageFile, final SourceLoader sourceLoader) { this.coverageFile = coverageFile; this.sourceLoader = sourceLoader; } @Override public final void parse(final SourceCallback callback) throws ProcessingException, IOException { XmlStreamReader reader = ReaderFactory.newXmlReader(coverageFile); XMLStreamReader xml = createEventReader(reader); try { while (xml.hasNext()) { xml.next(); onEvent(xml, callback); } } catch (XMLStreamException ex) { throw new ProcessingException(ex); } finally { close(xml); IOUtil.close(reader); } } @Override public final File getCoverageFile() { return coverageFile; } protected XMLStreamReader createEventReader(final Reader reader) throws ProcessingException { try { XMLInputFactory xmlif = XMLInputFactory.newInstance(); xmlif.setProperty(XMLInputFactory.SUPPORT_DTD, false); xmlif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); xmlif.setProperty(XMLInputFactory.IS_VALIDATING, false); return xmlif.createXMLStreamReader(reader); } catch (FactoryConfigurationError ex) { throw new IllegalArgumentException(ex); } catch (XMLStreamException ex) { throw new ProcessingException(ex); } } private void close(final XMLStreamReader xml) throws ProcessingException { if (xml != null) { try { xml.close(); } catch (XMLStreamException ex) { throw new ProcessingException(ex); } } } protected abstract void onEvent(final XMLStreamReader xml, SourceCallback callback) throws XMLStreamException, ProcessingException, IOException; protected final Source loadSource(final String sourceFile) throws IOException { return sourceLoader.load(sourceFile); } protected final boolean isStartElement(final XMLStreamReader xml, final String name) { return (XMLStreamConstants.START_ELEMENT == xml.getEventType() && xml.getLocalName().equals(name)); } protected final boolean isEndElement(final XMLStreamReader xml, final String name) { return (XMLStreamConstants.END_ELEMENT == xml.getEventType() && xml.getLocalName().equals(name)); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/parser/CoberturaParser.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.io.IOException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceLoader; public class CoberturaParser extends AbstractXmlEventParser { protected Source source; protected boolean inMethods; private int branchId; public CoberturaParser(final File coverageFile, final SourceLoader sourceLoader) { super(coverageFile, sourceLoader); } @Override protected void onEvent(final XMLStreamReader xml, final SourceCallback callback) throws XMLStreamException, ProcessingException, IOException { if (isStartElement(xml, "class")) { source = loadSource(xml.getAttributeValue(null, "filename")); String className = xml.getAttributeValue(null, "name"); int classifierPosition = className.indexOf('$'); if (classifierPosition > 0) { source.setClassifier(className.substring(classifierPosition + 1)); } this.branchId = 0; } else if (isStartElement(xml, "methods") && source != null) { inMethods = true; } else if (isEndElement(xml, "methods") && source != null) { inMethods = false; } else if (isStartElement(xml, "line") && !inMethods && source != null) { final int nr = Integer.parseInt(xml.getAttributeValue(null, "number")); source.addCoverage(nr, Integer.valueOf(xml.getAttributeValue(null, "hits"))); if (Boolean.parseBoolean(xml.getAttributeValue(null, "branch"))) { final String value = xml.getAttributeValue(null, "condition-coverage"); // Is "condition-coverage" attribute always here? if (value == null) { return; } // C'mon Cobertura, human readable format for XML ? final String[] values = value // 50% (2/4) .replace(" ", "") // 50%(2/4) .replace("%", "/") // 50/(2/4) .replace("(", "") // 50/2/4) .replace(")", "") // 50/2/4 .split("/"); final int cb = Integer.parseInt(values[1]); final int tb = Integer.parseInt(values[2]); final int mb = tb - cb; // add branches. unfortunately, there is NO block number and // branch number will NOT be unique between coverage changes. for (int b = 0; b < cb; b++) { this.source.addBranchCoverage(nr, 0, this.branchId++, 1); } for (int b = 0; b < mb; b++) { this.source.addBranchCoverage(nr, 0, this.branchId++, 0); } } } else if (isEndElement(xml, "class") && source != null) { callback.onSource(source); source = null; } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/parser/JaCoCoParser.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.io.IOException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceLoader; public class JaCoCoParser extends AbstractXmlEventParser { private String packageName; private Source source; private int branchId; public JaCoCoParser(final File coverageFile, final SourceLoader sourceLoader) { super(coverageFile, sourceLoader); } @Override protected void onEvent(final XMLStreamReader xml, final SourceCallback callback) throws XMLStreamException, ProcessingException, IOException { if (isStartElement(xml, "package")) { this.packageName = xml.getAttributeValue(null, "name"); } else if (isStartElement(xml, "sourcefile") && packageName != null) { String sourceFile = this.packageName + "/" + xml.getAttributeValue(null, "name"); this.source = loadSource(sourceFile); this.branchId = 0; } else if (isStartElement(xml, "line") && this.source != null) { int ci = Integer.parseInt(xml.getAttributeValue(null, "ci")); int cb = Integer.parseInt(xml.getAttributeValue(null, "cb")); int mb = Integer.parseInt(xml.getAttributeValue(null, "mb")); int nr = Integer.parseInt(xml.getAttributeValue(null, "nr")); // jacoco does not count hits. this is why hits is always 0 or 1 this.source.addCoverage(nr, (ci == 0 ? 0 : 1)); // add branches. unfortunately, there is NO block number and // branch number will NOT be unique between coverage changes. for (int b = 0; b < cb; b++) { this.source.addBranchCoverage(nr, 0, this.branchId++, 1); } for (int b = 0; b < mb; b++) { this.source.addBranchCoverage(nr, 0, this.branchId++, 0); } } else if (isEndElement(xml, "sourcefile") && this.source != null) { callback.onSource(this.source); this.source = null; } else if (isEndElement(xml, "package")) { this.packageName = null; } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/parser/SagaParser.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.io.IOException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceLoader; /** * @author Jakub Bednář (25/12/2013 10:07) */ public class SagaParser extends CoberturaParser { public SagaParser(final File coverageFile, final SourceLoader sourceLoader) { super(coverageFile, sourceLoader); } @Override protected void onEvent(final XMLStreamReader xml, final SourceCallback callback) throws XMLStreamException, ProcessingException, IOException { if (isStartElement(xml, "class")) { String name = xml.getAttributeValue(null, "name"); source = loadSource(name); } else { super.onEvent(xml, callback); } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/AbstractServiceSetup.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; import java.util.Properties; import org.codehaus.plexus.util.StringUtils; /** * Convenient base class for service setups. */ public abstract class AbstractServiceSetup implements ServiceSetup { private final Map env; public AbstractServiceSetup(final Map env) { this.env = env; } @Override public String getJobId() { return null; } @Override public String getBuildNumber() { return null; } @Override public String getBuildUrl() { return null; } @Override public String getBranch() { return null; } @Override public String getPullRequest() { return null; } @Override public Properties getEnvironment() { return null; } protected final String getProperty(final String name) { return env.get(name); } protected final void addProperty(final Properties properties, final String name, final String value) { if (StringUtils.isBlank(name)) { throw new IllegalArgumentException("name must be defined"); } if (StringUtils.isNotBlank(value)) { properties.setProperty(name, value); } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Appveyor.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; /** * Service implementation for Appveyor. *

* http://appveyor.com/ */ public class Appveyor extends AbstractServiceSetup { public static final String APPVEYOR_NAME = "Appveyor"; public static final String APPVEYOR = "APPVEYOR"; public static final String APPVEYOR_BUILD_NUMBER = "APPVEYOR_BUILD_NUMBER"; public static final String APPVEYOR_BUILD_ID = "APPVEYOR_BUILD_ID"; public static final String APPVEYOR_BRANCH = "APPVEYOR_REPO_BRANCH"; public static final String APPVEYOR_COMMIT = "APPVEYOR_REPO_COMMIT"; public static final String APPVEYOR_PULL_REQUEST = "APPVEYOR_PULL_REQUEST_NUMBER"; public static final String APPVEYOR_REPO_NAME = "APPVEYOR_REPO_NAME"; public Appveyor(final Map env) { super(env); } @Override public boolean isSelected() { return ("true".equalsIgnoreCase(getProperty(APPVEYOR))); } @Override public String getName() { return APPVEYOR_NAME; } @Override public String getBuildNumber() { return getProperty(APPVEYOR_BUILD_NUMBER); } @Override public String getBuildUrl() { return "https://ci.appveyor.com/project/" + getProperty(APPVEYOR_REPO_NAME) + "/build/" + getProperty(APPVEYOR_BUILD_NUMBER); } @Override public String getBranch() { return getProperty(APPVEYOR_BRANCH); } @Override public String getPullRequest() { return getProperty(APPVEYOR_PULL_REQUEST); } @Override public String getJobId() { return getProperty(APPVEYOR_BUILD_ID); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Bamboo.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; /** * Service implementation for Atlassian Bamboo. *

* https://www.atlassian.com/software/bamboo/ */ public class Bamboo extends AbstractServiceSetup { public static final String BAMBOO_NAME = "bamboo"; public static final String BAMBOO_BUILD_NUMBER = "bamboo.buildNumber"; public static final String BAMBOO_BUILD_URL = "bamboo.buildResultsUrl"; public static final String BAMBOO_BRANCH = "bamboo.repository.git.branch"; public Bamboo(final Map env) { super(env); } @Override public boolean isSelected() { return (getProperty(BAMBOO_BUILD_NUMBER) != null); } @Override public String getName() { return BAMBOO_NAME; } @Override public String getBuildNumber() { return getProperty(BAMBOO_BUILD_NUMBER); } @Override public String getBuildUrl() { return getProperty(BAMBOO_BUILD_URL); } @Override public String getBranch() { return getProperty(BAMBOO_BRANCH); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Circle.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; import java.util.Properties; /** * Service implementation for CircleCI. *

* https://circleci.com/ */ public class Circle extends AbstractServiceSetup { public static final String CIRCLE_NAME = "circleci"; public static final String CIRCLE = "CIRCLECI"; public static final String CIRCLE_BUILD_NUMBER = "CIRCLE_BUILD_NUM"; public static final String CIRCLE_BRANCH = "CIRCLE_BRANCH"; public static final String CIRCLE_COMMIT = "CIRCLE_SHA1"; public Circle(final Map env) { super(env); } @Override public boolean isSelected() { return (getProperty(CIRCLE) != null); } @Override public String getName() { return CIRCLE_NAME; } @Override public String getBuildNumber() { return getProperty(CIRCLE_BUILD_NUMBER); } @Override public String getBranch() { return getProperty(CIRCLE_BRANCH); } @Override public Properties getEnvironment() { Properties environment = new Properties(); addProperty(environment, "circleci_build_num", getProperty(CIRCLE_BUILD_NUMBER)); addProperty(environment, "branch", getProperty(CIRCLE_BRANCH)); addProperty(environment, "commit_sha", getProperty(CIRCLE_COMMIT)); return environment; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/General.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; /** * General implementation for any continuous integration service that provides the required * environment properties. */ public class General extends AbstractServiceSetup { public static final String CI_NAME = "CI_NAME"; public static final String CI_BUILD_NUMBER = "CI_BUILD_NUMBER"; public static final String CI_BUILD_URL = "CI_BUILD_URL"; public static final String CI_BRANCH = "CI_BRANCH"; public static final String CI_PULL_REQUEST = "CI_PULL_REQUEST"; public General(final Map env) { super(env); } @Override public boolean isSelected() { return (getProperty(CI_NAME) != null); } @Override public String getName() { return getProperty(CI_NAME); } @Override public String getBuildNumber() { return getProperty(CI_BUILD_NUMBER); } @Override public String getBuildUrl() { return getProperty(CI_BUILD_URL); } @Override public String getBranch() { return getProperty(CI_BRANCH); } @Override public String getPullRequest() { return getProperty(CI_PULL_REQUEST); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Jenkins.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; import java.util.Properties; /** * Service implementation for Jenkins. *

* http://jenkins-ci.org/ */ public class Jenkins extends AbstractServiceSetup { public static final String JENKINS_NAME = "jenkins"; public static final String JENKINS_URL = "JENKINS_URL"; public static final String JENKINS_BUILD_NUMBER = "BUILD_NUMBER"; public static final String JENKINS_BUILD_URL = "BUILD_URL"; public static final String JENKINS_BRANCH = "GIT_BRANCH"; public static final String JENKINS_COMMIT = "GIT_COMMIT"; public Jenkins(final Map env) { super(env); } @Override public boolean isSelected() { return (getProperty(JENKINS_URL) != null); } @Override public String getName() { return JENKINS_NAME; } @Override public String getBuildNumber() { return getProperty(JENKINS_BUILD_NUMBER); } @Override public String getBuildUrl() { return getProperty(JENKINS_BUILD_URL); } @Override public String getBranch() { return getProperty(JENKINS_BRANCH); } @Override public Properties getEnvironment() { Properties environment = new Properties(); addProperty(environment, "jenkins_build_num", getProperty(JENKINS_BUILD_NUMBER)); addProperty(environment, "jenkins_build_url", getProperty(JENKINS_BUILD_URL)); addProperty(environment, "branch", getProperty(JENKINS_BRANCH)); addProperty(environment, "commit_sha", getProperty(JENKINS_COMMIT)); return environment; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/ServiceSetup.java ================================================ package org.eluder.coveralls.maven.plugin.service; import java.util.Properties; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ /** * Service specific mojo properties. */ public interface ServiceSetup { /** * @return true if this service is selected, otherwise false */ boolean isSelected(); /** * @return service name */ String getName(); /** * @return service job id, or null if not defined */ String getJobId(); /** * @return service build number, or null if not defined */ String getBuildNumber(); /** * @return service build url, or null if not defined */ String getBuildUrl(); /** * @return git branch name, or null if not defined */ String getBranch(); /** * @return pull request identifier, or null if not defined */ String getPullRequest(); /** * @return environment related to service, or null if not defined */ Properties getEnvironment(); } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Shippable.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.util.Map; import java.util.Properties; /** * Service implementation for Shippable. *

* http://shippable.com/ */ public class Shippable extends AbstractServiceSetup { public static final String SHIPPABLE_NAME = "shippable"; public static final String SHIPPABLE = "SHIPPABLE"; public static final String SHIPPABLE_BUILD_NUMBER = "SHIPPABLE_BUILD_NUMBER"; public static final String SHIPPABLE_BUILD_ID = "SHIPPABLE_BUILD_ID"; public static final String SHIPPABLE_BRANCH = "BRANCH"; public static final String SHIPPABLE_COMMIT = "COMMIT"; public static final String SHIPPABLE_PULL_REQUEST = "PULL_REQUEST"; public Shippable(final Map env) { super(env); } @Override public boolean isSelected() { return ("true".equalsIgnoreCase(getProperty(SHIPPABLE))); } @Override public String getName() { return SHIPPABLE_NAME; } @Override public String getBuildNumber() { return getProperty(SHIPPABLE_BUILD_NUMBER); } @Override public String getBuildUrl() { return "https://app.shippable.com/builds/" + getProperty(SHIPPABLE_BUILD_ID); } @Override public String getBranch() { return getProperty(SHIPPABLE_BRANCH); } @Override public String getPullRequest() { String pullRequest = getProperty(SHIPPABLE_PULL_REQUEST); if ("false".equals(pullRequest)) { return null; } return pullRequest; } @Override public Properties getEnvironment() { Properties environment = new Properties(); addProperty(environment, "shippable_build_number", getProperty(SHIPPABLE_BUILD_NUMBER)); addProperty(environment, "shippable_build_id", getProperty(SHIPPABLE_BUILD_ID)); addProperty(environment, "shippable_build_url", getBuildUrl()); addProperty(environment, "branch", getProperty(SHIPPABLE_BRANCH)); addProperty(environment, "commit_sha", getProperty(SHIPPABLE_COMMIT)); return environment; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Travis.java ================================================ package org.eluder.coveralls.maven.plugin.service; import java.util.Map; import java.util.Properties; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ /** * Service implementation for Travis CI. *

* https://travis-ci.org/ */ public class Travis extends AbstractServiceSetup { public static final String TRAVIS_NAME = "travis-ci"; public static final String TRAVIS = "TRAVIS"; public static final String TRAVIS_JOB_ID = "TRAVIS_JOB_ID"; public static final String TRAVIS_BRANCH = "TRAVIS_BRANCH"; public static final String TRAVIS_PULL_REQUEST = "TRAVIS_PULL_REQUEST"; public Travis(final Map env) { super(env); } @Override public boolean isSelected() { return ("true".equalsIgnoreCase(getProperty(TRAVIS))); } @Override public String getName() { return TRAVIS_NAME; } @Override public String getJobId() { return getProperty(TRAVIS_JOB_ID); } @Override public String getBranch() { return getProperty(TRAVIS_BRANCH); } @Override public String getPullRequest() { return getProperty(TRAVIS_PULL_REQUEST); } @Override public Properties getEnvironment() { Properties environment = new Properties(); addProperty(environment, "travis_job_id", getProperty(TRAVIS_JOB_ID)); addProperty(environment, "travis_pull_request", getProperty(TRAVIS_PULL_REQUEST)); return environment; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/service/Wercker.java ================================================ package org.eluder.coveralls.maven.plugin.service; import java.util.Map; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ /** * Service implementation for Wercker CI. *

* http://wercker.com/ */ public class Wercker extends AbstractServiceSetup { public static final String WERCKER_NAME = "wercker"; public static final String WERCKER = "WERCKER"; public static final String WERCKER_BUILD_ID = "WERCKER_BUILD_ID"; public static final String WERCKER_BUILD_URL = "WERCKER_BUILD_URL"; public static final String WERCKER_BRANCH = "WERCKER_GIT_BRANCH"; public Wercker(final Map env) { super(env); } @Override public boolean isSelected() { return "true".equalsIgnoreCase(getProperty(WERCKER)); } @Override public String getName() { return WERCKER_NAME; } @Override public String getJobId() { return getProperty(WERCKER_BUILD_ID); } @Override public String getBuildUrl() { return getProperty(WERCKER_BUILD_URL); } @Override public String getBranch() { return getProperty(WERCKER_BRANCH); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/AbstractSourceLoader.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.codehaus.plexus.util.IOUtil; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.util.Md5DigestInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.nio.charset.Charset; import java.security.NoSuchAlgorithmException; public abstract class AbstractSourceLoader implements SourceLoader { private final Charset sourceEncoding; private final String directoryPrefix; public AbstractSourceLoader(final URI base, final URI sourceBase, final String sourceEncoding) { this.sourceEncoding = Charset.forName(sourceEncoding); this.directoryPrefix = base.relativize(sourceBase).toString(); } @Override public Source load(final String sourceFile) throws IOException { InputStream stream = locate(sourceFile); if (stream != null) { try (Md5DigestInputStream ds = new Md5DigestInputStream(stream); InputStreamReader reader = new InputStreamReader(ds, getSourceEncoding())) { String source = IOUtil.toString(reader); return new Source(getFileName(sourceFile), source, ds.getDigestHex()); } catch (NoSuchAlgorithmException ex) { throw new IOException("MD5 algorithm not available", ex); } } else { return null; } } protected Charset getSourceEncoding() { return sourceEncoding; } protected String getFileName(final String sourceFile) { return directoryPrefix + sourceFile; } protected abstract InputStream locate(String sourceFile) throws IOException; } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/ChainingSourceCallback.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Source; import java.io.IOException; /** * Source callback handler that allows chaining multiple callback handlers. Chained callback * handler is executed after this callback. */ public abstract class ChainingSourceCallback implements SourceCallback { private final SourceCallback chained; public ChainingSourceCallback(final SourceCallback chained) { if (chained == null) { throw new IllegalArgumentException("chained must be defined"); } this.chained = chained; } @Override public final void onBegin() throws ProcessingException, IOException { onBeginInternal(); chained.onBegin(); } @Override public final void onSource(final Source source) throws ProcessingException, IOException { onSourceInternal(source); chained.onSource(source); } @Override public final void onComplete() throws ProcessingException, IOException { onCompleteInternal(); chained.onComplete(); } /** * Defaults to no-op implementation. * * @see #onBegin() * * @throws ProcessingException if processing fails * @throws IOException if an I/O error occurs */ protected void onBeginInternal() throws ProcessingException, IOException { } /** * @see #onSource(Source) * * @param source the source file * @throws ProcessingException if further processing of the source fails * @throws IOException if an I/O error occurs */ protected abstract void onSourceInternal(final Source source) throws ProcessingException, IOException; /** * Defaults to no-op implementation. * * @see #onComplete() * * @throws ProcessingException if processing fails * @throws IOException if an I/O error occurs */ protected void onCompleteInternal() throws ProcessingException, IOException { } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/DirectorySourceLoader.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class DirectorySourceLoader extends AbstractSourceLoader { private final File sourceDirectory; public DirectorySourceLoader(final File base, final File sourceDirectory, final String sourceEncoding) { super(base.toURI(), sourceDirectory.toURI(), sourceEncoding); this.sourceDirectory = sourceDirectory; } @Override protected InputStream locate(final String sourceFile) throws IOException { File file = new File(sourceDirectory, sourceFile); if (file.exists()) { if (!file.isFile()) { throw new IllegalArgumentException(file.getAbsolutePath() + " is not file"); } return new BufferedInputStream(new FileInputStream(file)); } return null; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/MultiSourceLoader.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.domain.Source; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class MultiSourceLoader implements SourceLoader { private final List sourceLoaders = new ArrayList<>(); public MultiSourceLoader add(final SourceLoader sourceLoader) { this.sourceLoaders.add(sourceLoader); return this; } @Override public Source load(final String sourceFile) throws IOException { for (SourceLoader sourceLoader : sourceLoaders) { Source source = sourceLoader.load(sourceFile); if (source != null) { return source; } } throw new IOException("No source found for " + sourceFile); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/ScanSourceLoader.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.codehaus.plexus.util.DirectoryScanner; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.SelectorUtils; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; public class ScanSourceLoader extends AbstractSourceLoader { private final Map cache = new HashMap<>(); private final File sourceDirectory; public ScanSourceLoader(final File base, final File sourceDirectory, final String sourceEncoding) { super(base.toURI(), sourceDirectory.toURI(), sourceEncoding); this.sourceDirectory = sourceDirectory; } @Override protected InputStream locate(final String sourceFile) throws IOException { File file = new File(sourceDirectory, getFileName(sourceFile)); if (file.exists()) { if (!file.isFile()) { throw new IllegalArgumentException(file.getAbsolutePath() + " is not file"); } return new BufferedInputStream(new FileInputStream(file)); } return null; } private String[] scanFor(final String extension) { if (!cache.containsKey(extension)) { DirectoryScanner scanner = new DirectoryScanner(); scanner.setBasedir(sourceDirectory); scanner.addDefaultExcludes(); scanner.setIncludes(new String[] {"**/*." + extension}); scanner.scan(); cache.put(extension, scanner.getIncludedFiles()); } return cache.get(extension); } protected String getFileName(final String sourceFile) { String extension = FileUtils.extension(sourceFile); String[] matchingExtensionFiles = scanFor(extension); for (String matchingExtensionFile : matchingExtensionFiles) { if (SelectorUtils.matchPath("**/" + sourceFile, matchingExtensionFile, true)) { return matchingExtensionFile; } } return sourceFile; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/SourceCallback.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Source; import java.io.IOException; /** * Source callback handles parsed source files from coverage reports. */ public interface SourceCallback { /** * Called before source parsing has started. * * @throws ProcessingException if processing fails * @throws IOException if an I/O error occurs */ void onBegin() throws ProcessingException, IOException; /** * Handles a parsed source file. * * @param source the source file * @throws ProcessingException if further processing of the source fails * @throws IOException if an I/O error occurs */ void onSource(Source source) throws ProcessingException, IOException; /** * Called after all sources are handled. * * @throws ProcessingException if processing fails * @throws IOException if an I/O error occurs */ void onComplete() throws ProcessingException, IOException; } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/SourceLoader.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.IOException; import org.eluder.coveralls.maven.plugin.domain.Source; public interface SourceLoader { Source load(String sourceFile) throws IOException; } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/UniqueSourceCallback.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Source; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; /** * Source callback that tracks passed by source files and provides only unique * source files to the delegate. Note that the implementation is not thread * safe so the {@link #onSource(org.eluder.coveralls.maven.plugin.domain.Source)} * can be called only from single thread concurrently. */ public class UniqueSourceCallback implements SourceCallback { private final Map cache; private final SourceCallback delegate; public UniqueSourceCallback(final SourceCallback delegate) { this.cache = new LinkedHashMap<>(); this.delegate = delegate; } @Override public void onBegin() throws ProcessingException, IOException { delegate.onBegin(); } @Override public void onSource(final Source source) throws ProcessingException, IOException { Source merged = source.merge(cache.get(source)); cache.put(merged, merged); } @Override public void onComplete() throws ProcessingException, IOException { for (Source source : cache.values()) { delegate.onSource(source); } delegate.onComplete(); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/source/UrlSourceLoader.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.eluder.coveralls.maven.plugin.util.UrlUtils; public class UrlSourceLoader extends AbstractSourceLoader { private final URL sourceUrl; public UrlSourceLoader(final URL base, final URL sourceUrl, final String sourceEncoding) { super(UrlUtils.toUri(base), UrlUtils.toUri(sourceUrl), sourceEncoding); this.sourceUrl = sourceUrl; } @Override protected InputStream locate(final String sourceFile) throws IOException { URL url = new URL(sourceUrl, sourceFile); // Checkstyle OFF: EmptyBlock try { return url.openStream(); } catch (IOException ex) { // not found from url } // Checkstyle ON: EmptyBlock return null; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/CoverageParsersFactory.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.project.MavenProject; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.parser.CoberturaParser; import org.eluder.coveralls.maven.plugin.parser.JaCoCoParser; import org.eluder.coveralls.maven.plugin.parser.SagaParser; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CoverageParsersFactory { private static final String JACOCO_FILE = "/jacoco.xml"; private static final String JACOCO_PREFIX = "/jacoco"; private static final String JACOCO_IT_PREFIX = "/jacoco-it"; private static final String COBERTURA_FILE = "/coverage.xml"; private static final String COBERTURA_PREFIX = "/cobertura"; private static final String SAGA_FILE = "/total-coverage.xml"; private static final String SAGA_PREFIX = "/saga-coverage"; private final MavenProject project; private final SourceLoader sourceLoader; private List jacocoReports; private List coberturaReports; private List sagaReports; private List relativeReportDirs; public CoverageParsersFactory(final MavenProject project, final SourceLoader sourceLoader) { this.project = project; this.sourceLoader = sourceLoader; } public CoverageParsersFactory withJaCoCoReports(final List jacocoReports) { this.jacocoReports = jacocoReports; return this; } public CoverageParsersFactory withCoberturaReports(final List coberturaReports) { this.coberturaReports = coberturaReports; return this; } public CoverageParsersFactory withSagaReports(final List sagaReports) { this.sagaReports = sagaReports; return this; } public CoverageParsersFactory withRelativeReportDirs(final List relativeReportDirs) { this.relativeReportDirs = relativeReportDirs; return this; } public List createParsers() throws IOException { List parsers = new ArrayList<>(); List projects = new MavenProjectCollector(project).collect(); ExistingFiles jacocoFiles = ExistingFiles.create(jacocoReports); ExistingFiles coberturaFiles = ExistingFiles.create(coberturaReports); ExistingFiles sagaFiles = ExistingFiles.create(sagaReports); for (MavenProject p : projects) { File reportingDirectory = new File(p.getModel().getReporting().getOutputDirectory()); File buildDirectory = new File(p.getBuild().getDirectory()); jacocoFiles.add(new File(reportingDirectory, JACOCO_PREFIX + JACOCO_FILE)); jacocoFiles.add(new File(reportingDirectory, JACOCO_IT_PREFIX + JACOCO_FILE)); coberturaFiles.add(new File(reportingDirectory, COBERTURA_PREFIX + COBERTURA_FILE)); sagaFiles.add(new File(buildDirectory, SAGA_PREFIX + SAGA_FILE)); if (relativeReportDirs != null) { for (String relativeReportPath : relativeReportDirs) { File relativeReportingDirectory = reportingDirectory; File relativeBuildDirectory = buildDirectory; if (!relativeReportPath.isEmpty() && !File.separator.equals(relativeReportPath)) { relativeReportingDirectory = new File(reportingDirectory, relativeReportPath); relativeBuildDirectory = new File(buildDirectory, relativeReportPath); } jacocoFiles.add(new File(relativeReportingDirectory, JACOCO_FILE)); jacocoFiles.add(new File(relativeBuildDirectory, JACOCO_FILE)); coberturaFiles.add(new File(relativeReportingDirectory, COBERTURA_FILE)); coberturaFiles.add(new File(relativeBuildDirectory, COBERTURA_FILE)); sagaFiles.add(new File(relativeReportingDirectory, SAGA_FILE)); sagaFiles.add(new File(relativeBuildDirectory, SAGA_FILE)); } } } for (File jacocoFile : jacocoFiles) { parsers.add(new JaCoCoParser(jacocoFile, sourceLoader)); } for (File coberturaFile : coberturaFiles) { parsers.add(new CoberturaParser(coberturaFile, sourceLoader)); } for (File sagaFile : sagaFiles) { parsers.add(new SagaParser(sagaFile, sourceLoader)); } if (parsers.isEmpty()) { throw new IOException("No coverage report files found"); } return Collections.unmodifiableList(parsers); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/ExistingFiles.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.util.ArrayList; import java.util.Iterator; public class ExistingFiles implements Iterable { private final ArrayList delegate = new ArrayList<>(); public ExistingFiles addAll(final Iterable files) { if (files == null) { throw new NullPointerException("Files must be defined"); } for (File file : files) { add(file); } return this; } public ExistingFiles add(final File file) { if (file == null) { throw new NullPointerException("File must be defined"); } if (file.exists() && file.isFile() && !delegate.contains(file)) { delegate.add(file); } return this; } @Override public Iterator iterator() { return delegate.iterator(); } public static ExistingFiles create(final Iterable files) { ExistingFiles existingFiles = new ExistingFiles(); if (files != null) { existingFiles.addAll(files); } return existingFiles; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/MavenProjectCollector.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.project.MavenProject; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MavenProjectCollector { private final MavenProject root; public MavenProjectCollector(final MavenProject root) { this.root = root; } public List collect() { List projects = new ArrayList<>(); collect(root, projects); return Collections.unmodifiableList(projects); } private void collect(final MavenProject project, final List projects) { projects.add(project); for (MavenProject child : project.getCollectedProjects()) { collect(child, projects); } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/Md5DigestInputStream.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.InputStream; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.binary.Hex; public class Md5DigestInputStream extends DigestInputStream { public Md5DigestInputStream(final InputStream stream) throws NoSuchAlgorithmException { super(stream, MessageDigest.getInstance("MD5")); } public String getDigestHex() { return Hex.encodeHexString(getMessageDigest().digest(), false); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/SourceLoaderFactory.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.project.MavenProject; import org.eluder.coveralls.maven.plugin.source.DirectorySourceLoader; import org.eluder.coveralls.maven.plugin.source.MultiSourceLoader; import org.eluder.coveralls.maven.plugin.source.ScanSourceLoader; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import java.io.File; import java.util.ArrayList; import java.util.List; public class SourceLoaderFactory { private final File baseDir; private final MavenProject project; private final String sourceEncoding; private List sourceDirectories; private boolean scanForSources; public SourceLoaderFactory(final File baseDir, final MavenProject project, final String sourceEncoding) { this.baseDir = baseDir; this.project = project; this.sourceEncoding = sourceEncoding; } public SourceLoaderFactory withSourceDirectories(final List sourceDirectories) { this.sourceDirectories = sourceDirectories; return this; } public SourceLoaderFactory withScanForSources(final boolean scanForSources) { this.scanForSources = scanForSources; return this; } public SourceLoader createSourceLoader() { MultiSourceLoader multiSourceLoader = new MultiSourceLoader(); List directories = new ArrayList<>(); List modules = new MavenProjectCollector(project).collect(); for (MavenProject module : modules) { for (String sourceRoot : module.getCompileSourceRoots()) { File sourceDirectory = new File(sourceRoot); directories.add(sourceDirectory); } } if (sourceDirectories != null) { directories.addAll(sourceDirectories); } for (File directory: directories) { if (directory.exists() && directory.isDirectory()) { DirectorySourceLoader moduleSourceLoader = new DirectorySourceLoader(baseDir, directory, sourceEncoding); multiSourceLoader.add(moduleSourceLoader); } } if (scanForSources) { for (File directory: directories) { if (directory.exists() && directory.isDirectory()) { ScanSourceLoader scanSourceLoader = new ScanSourceLoader(baseDir, directory, sourceEncoding); multiSourceLoader.add(scanSourceLoader); } } } return multiSourceLoader; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/TimestampParser.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.codehaus.plexus.util.StringUtils; import org.eluder.coveralls.maven.plugin.ProcessingException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class TimestampParser { public static final String EPOCH_MILLIS = "EpochMillis"; public static final String DEFAULT_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; private final Parser parser; public TimestampParser(final String format) { try { if (EPOCH_MILLIS.equalsIgnoreCase(format)) { this.parser = new EpochMillisParser(); } else if (StringUtils.isNotBlank(format)) { this.parser = new DateFormatParser(format); } else { this.parser = new DateFormatParser(DEFAULT_FORMAT); } } catch (IllegalArgumentException ex) { throw new IllegalArgumentException("Invalid timestamp format \"" + format + "\"", ex); } } public Date parse(final String timestamp) throws ProcessingException { if (StringUtils.isBlank(timestamp)) { return null; } try { return parser.parse(timestamp); } catch (Exception ex) { throw new ProcessingException("Unable to parse timestamp \"" + timestamp + "\"", ex); } } private interface Parser { Date parse(String timestamp) throws Exception; } private static class DateFormatParser implements Parser { final DateFormat format; DateFormatParser(final String format) { this.format = new SimpleDateFormat(format); } @Override public synchronized Date parse(final String timestamp) throws ParseException { return format.parse(timestamp); } } private static class EpochMillisParser implements Parser { @Override public Date parse(final String timestamp) { return new Date(Long.valueOf(timestamp)); } } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/UrlUtils.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; public final class UrlUtils { public static URL create(final String url) { try { return new URL(url); } catch (MalformedURLException ex) { throw new IllegalArgumentException(ex); } } public static URI toUri(final URL url) { try { return url.toURI(); } catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); } } private UrlUtils() { // hide constructor } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/util/Wildcards.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ /** * Wildcard text utilities. */ public final class Wildcards { /** * Matches text against a wildcard pattern where ? is single letter and * is zero or more * letters. * * @param text the text to test against * @param wildcard the wildcard pattern * @return true if the given text matches the wildcard, otherwise false */ public static boolean matches(final String text, final String wildcard) { String pattern = wildcard.replace("?", "\\w").replace("*", "\\w*"); return (text != null && text.matches(pattern)); } private Wildcards() { // hide constructor } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/validation/JobValidator.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.codehaus.plexus.util.StringUtils; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.validation.ValidationError.Level; import java.util.Collections; import java.util.List; public class JobValidator { private final Job job; public JobValidator(final Job job) { if (job == null) { throw new IllegalArgumentException("job must be defined"); } this.job = job; } public ValidationErrors validate() { ValidationErrors errors = new ValidationErrors(); errors.addAll(repoTokenOrTravis()); errors.addAll(git()); return errors; } private List repoTokenOrTravis() { if (hasValue(job.getRepoToken())) { return Collections.emptyList(); } if (hasValue(job.getServiceName()) && hasValue(job.getServiceJobId())) { return Collections.emptyList(); } Level level = (job.isDryRun() ? Level.WARN : Level.ERROR); String message = "Either repository token or service with job id must be defined"; return Collections.singletonList(new ValidationError(level, message)); } private List git() { if (job.getGit() == null) { return Collections.emptyList(); } if (hasValue(job.getGit().getHead().getId())) { return Collections.emptyList(); } return Collections.singletonList(new ValidationError(Level.ERROR, "Commit id for HEAD must be defined")); } private boolean hasValue(final String value) { return StringUtils.isNotBlank(value); } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/validation/ValidationError.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ public final class ValidationError { public enum Level { WARN, ERROR } private final Level level; private final String message; public ValidationError(final Level level, final String message) { if (level == null) { throw new IllegalArgumentException("level must be defined"); } if (message == null) { throw new IllegalArgumentException("message must be defined"); } this.level = level; this.message = message; } public Level getLevel() { return level; } public String getMessage() { return message; } @Override public String toString() { return level + ": " + message; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/validation/ValidationErrors.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.validation.ValidationError.Level; import java.util.ArrayList; import java.util.List; public class ValidationErrors extends ArrayList { public void throwOrInform(final Log log) { List errors = filter(Level.ERROR); if (!errors.isEmpty()) { throw new ValidationException(errors.get(0).getMessage()); } for (ValidationError error : filter(Level.WARN)) { log.warn(error.getMessage()); } } private List filter(final Level level) { List filtered = new ArrayList<>(); for (ValidationError error : this) { if (level.equals(error.getLevel())) { filtered.add(error); } } return filtered; } } ================================================ FILE: src/main/java/org/eluder/coveralls/maven/plugin/validation/ValidationException.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ public class ValidationException extends IllegalArgumentException { public ValidationException() { super(); } public ValidationException(final String s) { super(s); } public ValidationException(final Throwable cause) { super(cause); } public ValidationException(final String message, final Throwable cause) { super(message, cause); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/CoverageFixture.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ public final class CoverageFixture { public static String[][] JAVA_FILES = new String[][] { // file lines covered lines missed lines covered branches missed brnches { "org/eluder/coverage/sample/SimpleCoverage.java", "14", "3,6", "10,11", "", "" }, { "org/eluder/coverage/sample/InnerClassCoverage.java", "31", "3,6,9,10,12,13,16,19,22", "26,27", "", "" }, { "org/eluder/coverage/sample/PartialCoverage.java", "14", "3,6,7,11", "9", "6", "6" } }; public static String[][] JAVA_FILES_IT = new String[][] { // file lines covered lines missed lines covered branches missed branches { "org/eluder/coverage/sample/SimpleCoverage.java", "14", "3,6", "10,11", "", "" }, { "org/eluder/coverage/sample/InnerClassCoverage.java", "31", "3,6,9,10,12,13,16,19,22", "26,27", "", "" }, { "org/eluder/coverage/sample/PartialCoverage.java", "14", "3,6,7,9,11", "", "6", "6" } }; public static String[][] JAVASCRIPT_FILES = new String[][] { // file lines covered lines missed lines covered branches missed branches { "Localization.js", "18", "1,2,4,5,9,13", "6,10", "", "" }, { "Components.js", "5", "1,2", "", "", "" } }; public static int getTotalLines(String[][] fixture) { int lines = 0; for (String[] file : fixture) { lines += Integer.parseInt(file[1]); } return lines; } public static int getTotalFiles(String[][] fixture) { return fixture.length; } private CoverageFixture() { // hide constructor } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/CoverallsReportMojoTest.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Reporting; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.apache.maven.settings.Settings; import org.eluder.coveralls.maven.plugin.domain.CoverallsResponse; import org.eluder.coveralls.maven.plugin.domain.Git; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.httpclient.CoverallsClient; import org.eluder.coveralls.maven.plugin.json.JsonWriter; import org.eluder.coveralls.maven.plugin.parser.CoberturaParser; import org.eluder.coveralls.maven.plugin.service.ServiceSetup; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.eluder.coveralls.maven.plugin.validation.ValidationErrors; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class CoverallsReportMojoTest { @Rule public TemporaryFolder folder = new TemporaryFolder(); public File coverallsFile; private CoverallsReportMojo mojo; @Mock private CoverallsClient coverallsClientMock; @Mock private SourceLoader sourceLoaderMock; @Mock private Job jobMock; @Mock private Log logMock; @Mock private MavenProject projectMock; @Mock private MavenProject collectedProjectMock; @Mock private Model modelMock; @Mock private Reporting reportingMock; @Mock private Build buildMock; @Mock private Settings settingsMock; @Before public void init() throws Exception { coverallsFile = folder.newFile(); when(sourceLoaderMock.load(anyString())).then(new Answer() { @Override public Source answer(final InvocationOnMock invocation) throws Throwable { String sourceFile = invocation.getArguments()[0].toString(); String content = readFileContent(sourceFile); return new Source(sourceFile, content, TestIoUtil.getMd5DigestHex(content)); } }); when(logMock.isInfoEnabled()).thenReturn(true); when(jobMock.validate()).thenReturn(new ValidationErrors()); mojo = new CoverallsReportMojo() { @Override protected SourceLoader createSourceLoader(final Job job) { return sourceLoaderMock; } @Override protected List createCoverageParsers(SourceLoader sourceLoader) throws IOException { List parsers = new ArrayList(); parsers.add(new CoberturaParser(TestIoUtil.getFile("cobertura.xml"), sourceLoader)); return parsers; } @Override protected Environment createEnvironment() { return new Environment(this, Collections.emptyList()); } @Override protected Job createJob() throws IOException { return jobMock; } @Override protected JsonWriter createJsonWriter(final Job job) throws IOException { return new JsonWriter(jobMock, CoverallsReportMojoTest.this.coverallsFile); } @Override protected CoverallsClient createCoverallsClient() { return coverallsClientMock; } @Override public Log getLog() { return logMock; } }; mojo.settings = settingsMock; mojo.project = projectMock; mojo.sourceEncoding = "UTF-8"; mojo.failOnServiceError = true; when(modelMock.getReporting()).thenReturn(reportingMock); when(reportingMock.getOutputDirectory()).thenReturn(folder.getRoot().getAbsolutePath()); when(buildMock.getDirectory()).thenReturn(folder.getRoot().getAbsolutePath()); List projects = new ArrayList(); projects.add(collectedProjectMock); when(projectMock.getCollectedProjects()).thenReturn(projects); when(projectMock.getBuild()).thenReturn(buildMock); when(projectMock.getModel()).thenReturn(modelMock); List sourceRoots = new ArrayList(); sourceRoots.add(folder.getRoot().getAbsolutePath()); when(collectedProjectMock.getCompileSourceRoots()).thenReturn(sourceRoots); when(collectedProjectMock.getBuild()).thenReturn(buildMock); when(collectedProjectMock.getModel()).thenReturn(modelMock); } @Test(expected = IOException.class) public void testCreateCoverageParsersWithoutCoverageReports() throws Exception { mojo = new CoverallsReportMojo(); mojo.settings = settingsMock; mojo.project = projectMock; mojo.createCoverageParsers(sourceLoaderMock); } @Test public void testCreateSourceLoader() throws Exception { Git gitMock = Mockito.mock(Git.class); when(gitMock.getBaseDir()).thenReturn(folder.newFolder("git")); when(jobMock.getGit()).thenReturn(gitMock); TestIoUtil.writeFileContent("public interface Test { }", folder.newFile("source.java")); mojo = new CoverallsReportMojo(); mojo.settings = settingsMock; mojo.project = projectMock; mojo.sourceEncoding = "UTF-8"; SourceLoader sourceLoader = mojo.createSourceLoader(jobMock); Source source = sourceLoader.load("source.java"); assertNotNull(source); } @Test public void testDefaultBehavior() throws Exception { mojo = new CoverallsReportMojo() { @Override protected SourceLoader createSourceLoader(final Job job) { return sourceLoaderMock; } @Override protected List createCoverageParsers(SourceLoader sourceLoader) throws IOException { return Collections.emptyList(); } }; mojo.sourceDirectories = Arrays.asList(TestIoUtil.getFile("/")); mojo.sourceEncoding = "UTF-8"; mojo.settings = settingsMock; mojo.project = projectMock; mojo.repoToken = "asdfg"; mojo.coverallsFile = folder.newFile(); mojo.dryRun = true; mojo.skip = false; mojo.basedir = TestIoUtil.getFile("/"); mojo.execute(); } @Test public void testSuccesfullSubmission() throws Exception { when(coverallsClientMock.submit(any(File.class))).thenReturn(new CoverallsResponse("success", false, null)); mojo.execute(); String json = TestIoUtil.readFileContent(coverallsFile); assertNotNull(json); String[][] fixture = CoverageFixture.JAVA_FILES; for (String[] coverageFile : fixture) { assertThat(json, containsString(coverageFile[0])); } verifySuccessfullSubmit(logMock, fixture); } @Test public void testFailWithProcessingException() throws Exception { when(coverallsClientMock.submit(any(File.class))).thenThrow(new ProcessingException()); try { mojo.execute(); fail("Should have failed with MojoFailureException"); } catch (MojoFailureException ex) { assertEquals(ex.getCause().getClass(), ProcessingException.class); } } @Test public void testProcessingExceptionWithAllowedServiceFailure() throws Exception { mojo.failOnServiceError = false; when(coverallsClientMock.submit(any(File.class))).thenThrow(new ProcessingException()); try { mojo.execute(); fail("Should have failed with MojoFailureException"); } catch (MojoFailureException ex) { assertEquals(ex.getCause().getClass(), ProcessingException.class); } } @Test public void testFailWithIOException() throws Exception { when(coverallsClientMock.submit(any(File.class))).thenThrow(new IOException()); try { mojo.execute(); fail("Should have failed with MojoFailureException"); } catch (MojoFailureException ex) { assertEquals(ex.getCause().getClass(), IOException.class); } } @Test public void testIOExceptionWithAllowedServiceFailure() throws Exception { mojo.failOnServiceError = false; when(coverallsClientMock.submit(any(File.class))).thenThrow(new IOException()); mojo.execute(); verify(logMock).warn(anyString()); } @Test public void testFailWithNullPointerException() throws Exception { when(coverallsClientMock.submit(any(File.class))).thenThrow(new NullPointerException()); try { mojo.execute(); fail("Should have failed with MojoFailureException"); } catch (MojoExecutionException ex) { assertEquals(ex.getCause().getClass(), NullPointerException.class); } } @Test public void testSkipExecution() throws Exception { mojo.skip = true; mojo.execute(); verifyZeroInteractions(jobMock); } public static void verifySuccessfullSubmit(Log logMock, String[][] fixture) { verify(logMock).info("Gathered code coverage metrics for " + CoverageFixture.getTotalFiles(fixture) + " source files with " + CoverageFixture.getTotalLines(fixture) + " lines of code:"); verify(logMock).info("*** It might take hours for Coveralls to update the actual coverage numbers for a job"); } protected String readFileContent(final String sourceFile) throws IOException { return TestIoUtil.readFileContent(TestIoUtil.getFile(sourceFile)); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/EnvironmentTest.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Properties; import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.service.ServiceSetup; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class EnvironmentTest { private CoverallsReportMojo mojo; @Mock private CoverageParser coverageParserMock; @Mock private Log logMock; @Mock private ServiceSetup serviceMock; @Before public void init() throws Exception { mojo = new CoverallsReportMojo() { @Override protected List createCoverageParsers(SourceLoader sourceLoader) { return Arrays.asList(coverageParserMock); } @Override public Log getLog() { return logMock; } }; mojo.serviceName = "service"; mojo.sourceEncoding = "UTF-8"; when(serviceMock.isSelected()).thenReturn(true); } @Test(expected = IllegalArgumentException.class) public void testMissingMojo() { new Environment(null, Arrays.asList(serviceMock)); } @Test(expected = IllegalArgumentException.class) public void testMissingServices() { new Environment(mojo, null); } @Test public void testSetupWithoutServices() { create(Collections.emptyList()).setup(); assertEquals("service", mojo.serviceName); } @Test(expected = IllegalArgumentException.class) public void testSetupWithoutSourceEncoding() { mojo.sourceEncoding = null; create(Arrays.asList(serviceMock)).setup(); } @Test public void testSetupWithIncompleteJob() { when(serviceMock.getJobId()).thenReturn(""); when(serviceMock.getBuildUrl()).thenReturn(" "); create(Arrays.asList(serviceMock)).setup(); assertEquals("service", mojo.serviceName); assertNull(mojo.serviceJobId); assertNull(mojo.serviceBuildNumber); assertNull(mojo.serviceBuildUrl); assertNull(mojo.branch); assertNull(mojo.pullRequest); assertNull(mojo.serviceEnvironment); } @Test public void testSetupWithCompleteJob() { mojo.serviceName = null; Properties environment = new Properties(); environment.setProperty("env", "true"); when(serviceMock.getName()).thenReturn("defined service"); when(serviceMock.getJobId()).thenReturn("123"); when(serviceMock.getBuildNumber()).thenReturn("456"); when(serviceMock.getBuildUrl()).thenReturn("http://ci.com/project"); when(serviceMock.getBranch()).thenReturn("master"); when(serviceMock.getPullRequest()).thenReturn("111"); when(serviceMock.getEnvironment()).thenReturn(environment); create(Arrays.asList(mock(ServiceSetup.class), serviceMock)).setup(); assertEquals("defined service", mojo.serviceName); assertEquals("123", mojo.serviceJobId); assertEquals("456", mojo.serviceBuildNumber); assertEquals("http://ci.com/project", mojo.serviceBuildUrl); assertEquals("master", mojo.branch); assertEquals("111", mojo.pullRequest); assertEquals("true", mojo.serviceEnvironment.get("env")); } @Test public void testSetupWithoutJobOverride() { Properties environment = new Properties(); environment.setProperty("env", "true"); Properties serviceEnvironment = new Properties(); serviceEnvironment.setProperty("env", "setProperty"); when(serviceMock.getName()).thenReturn("defined service"); when(serviceMock.getJobId()).thenReturn("123"); when(serviceMock.getBuildNumber()).thenReturn("456"); when(serviceMock.getBuildUrl()).thenReturn("http://ci.com/project"); when(serviceMock.getBranch()).thenReturn("master"); when(serviceMock.getPullRequest()).thenReturn("111"); when(serviceMock.getEnvironment()).thenReturn(environment); mojo.serviceJobId = "setJobId"; mojo.serviceBuildNumber = "setBuildNumber"; mojo.serviceBuildUrl = "setBuildUrl"; mojo.serviceEnvironment = serviceEnvironment; mojo.branch = "setBranch"; mojo.pullRequest = "setPullRequest"; create(Arrays.asList(serviceMock)).setup(); assertEquals("service", mojo.serviceName); assertEquals("setJobId", mojo.serviceJobId); assertEquals("setBuildNumber", mojo.serviceBuildNumber); assertEquals("setBuildUrl", mojo.serviceBuildUrl); assertEquals("setBranch", mojo.branch); assertEquals("setPullRequest", mojo.pullRequest); assertEquals("setProperty", mojo.serviceEnvironment.get("env")); } private Environment create(final Iterable services) { return new Environment(mojo, services); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/ProcessingExceptionTest.java ================================================ package org.eluder.coveralls.maven.plugin; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import org.junit.Test; public class ProcessingExceptionTest { private static final String MESSAGE = "message"; private static final RuntimeException CAUSE = new RuntimeException(); @Test public void testException() { ProcessingException exception = new ProcessingException(); assertNull(exception.getMessage()); assertNull(exception.getCause()); } @Test public void testExceptionWithMessage() { ProcessingException exception = new ProcessingException(MESSAGE); assertEquals(MESSAGE, exception.getMessage()); assertNull(exception.getCause()); } @Test public void testExceptionWithCause() { ProcessingException exception = new ProcessingException(CAUSE); assertEquals(CAUSE.toString(), exception.getMessage()); assertSame(CAUSE, exception.getCause()); } @Test public void testExceptionWithMessageAndCause() { ProcessingException exception = new ProcessingException(MESSAGE, CAUSE); assertEquals(MESSAGE, exception.getMessage()); assertSame(CAUSE, exception.getCause()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/domain/GitRepositoryTest.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertNotNull; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Test; public class GitRepositoryTest { /** * This tests assumes that the project resides in git repository. */ @Test public void testLoad() throws Exception { Git git = new GitRepository(TestIoUtil.getFile("/")).load(); assertNotNull(git.getHead().getId()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/domain/JobTest.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import java.io.File; import java.util.Arrays; import java.util.List; import org.eluder.coveralls.maven.plugin.domain.Git.Head; import org.eluder.coveralls.maven.plugin.domain.Git.Remote; import org.junit.Test; public class JobTest { @Test public void testGetBranchWithRemote() { List remotes = Arrays.asList(new Remote("origin", "git@github.com")); Git git = new Git(new File("."), new Head(null, null, null, null, null, null), "master", remotes); Job job = new Job().withBranch("origin/master").withGit(git); assertEquals(".", git.getBaseDir().getPath()); assertEquals("master", job.getBranch()); } @Test public void testGetBranch() { Job job = new Job().withBranch("master"); assertEquals("master", job.getBranch()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/domain/SourceTest.java ================================================ package org.eluder.coveralls.maven.plugin.domain; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; public class SourceTest { @Test public void testAddCoverage() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); source.addCoverage(1, 3); source.addCoverage(3, 3); assertArrayEquals(new Integer[] { 3, null, 3, null }, source.getCoverage()); } @Test public void testAddBranchCoverage() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n if(true) {\n }\n}\n", "609BD24390ADB11D11536CA2ADD18BD0"); source.addBranchCoverage(2, 0, 0, 2); source.addBranchCoverage(2, 0, 1, 3); assertArrayEquals(new Integer[] { 2, 0, 0, 2, 2, 0, 1, 3 }, source.getBranches()); } @Test public void testAddSameBranchReplaceExistingOne() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n if(true) {\n }\n}\n", "609BD24390ADB11D11536CA2ADD18BD0"); source.addBranchCoverage(2, 0, 0, 2); source.addBranchCoverage(2, 0, 0, 3); assertArrayEquals(new Integer[] { 2, 0, 0, 3 }, source.getBranches()); } @Test public void testAddSameBranchDoNotKeepOrdering() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n if(true) {\n }\n}\n", "609BD24390ADB11D11536CA2ADD18BD0"); source.addBranchCoverage(2, 0, 0, 0); source.addBranchCoverage(2, 0, 1, 0); source.addBranchCoverage(2, 0, 0, 1); assertArrayEquals(new Integer[] { 2, 0, 1, 0, 2, 0, 0, 1 }, source.getBranches()); } @Test(expected = IllegalArgumentException.class) public void testAddCoverageForSourceOutOfBounds() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); source.addCoverage(5, 1); } @Test(expected = IllegalArgumentException.class) public void testAddBranchCoverageForSourceOutOfBounds() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n if(true) {\n }\n}\n", "609BD24390ADB11D11536CA2ADD18BD0"); source.addBranchCoverage(6, 0, 0, 2); } @Test @Ignore("#45: https://github.com/trautonen/coveralls-maven-plugin/issues/45") public void testGetNameWithClassifier() throws Exception { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); source.setClassifier("Inner"); assertEquals("src/main/java/Hello.java", source.getName()); assertEquals("src/main/java/Hello.java#Inner", source.getFullName()); } @Test public void testMerge() { Source source1 = new Source("src/main/java/Hello.java", "public class Hello {\n if(true) {\n }\n}\n", "609BD24390ADB11D11536CA2ADD18BD0"); source1.addCoverage(1, 2); source1.addCoverage(3, 4); source1.addBranchCoverage(2, 0, 0, 1); Source source2 = new Source("src/main/java/Hello.java", "public class Hello {\n if(true) {\n }\n}\n", "609BD24390ADB11D11536CA2ADD18BD0"); source2.addCoverage(2, 1); source2.addCoverage(3, 3); source2.addBranchCoverage(2, 0, 0, 1); source2.addBranchCoverage(2, 0, 1, 3); Source merged = source1.merge(source2); assertFalse(source1 == merged); assertFalse(source2 == merged); assertEquals(source1.getName(), merged.getName()); assertEquals(source1.getDigest(), merged.getDigest()); assertEquals(source1.getClassifier(), merged.getClassifier()); assertEquals(new Integer(2), merged.getCoverage()[0]); assertEquals(new Integer(1), merged.getCoverage()[1]); assertEquals(new Integer(7), merged.getCoverage()[2]); assertNull(merged.getCoverage()[3]); assertEquals(new Integer(2), merged.getBranches()[0]); assertEquals(new Integer(0), merged.getBranches()[1]); assertEquals(new Integer(0), merged.getBranches()[2]); assertEquals(new Integer(2), merged.getBranches()[3]); assertEquals(new Integer(2), merged.getBranches()[4]); assertEquals(new Integer(0), merged.getBranches()[5]); assertEquals(new Integer(1), merged.getBranches()[6]); assertEquals(new Integer(3), merged.getBranches()[7]); } @Test public void testMergeDifferent() { Source source1 = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); source1.addCoverage(1, 3); Source source2 = new Source("src/main/java/Hello.java", "public class Hello {\n void();\n}\n", "CBA7831606B51D1499349451B70758E3"); source2.addCoverage(2, 4); Source merged = source1.merge(source2); assertFalse(source1 == merged); assertFalse(source2 == merged); assertArrayEquals(source1.getCoverage(), merged.getCoverage()); } @Test public void testEqualsForNull() { Source source = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); assertFalse(source.equals(null)); } @Test public void testEqualsForDifferentSources() throws Exception { Source source1 = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); Source source2 = new Source("src/main/java/Hello.java", "public class Hello {\n void();\n}\n", "CBA7831606B51D1499349451B70758E3"); assertFalse(source1.equals(source2)); } @Test public void testHashCode() { Source source1 = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); Source source2 = new Source("src/main/java/Hello.java", "public class Hello {\n \n}\n", "E8BD88CF0BDB77A6408234FD91FD22C3"); Source source3 = new Source("src/main/java/Hello.java", "public class Hello {\n void();\n}\n", "CBA7831606B51D1499349451B70758E3"); assertTrue(source1.hashCode() == source2.hashCode()); assertFalse(source1.hashCode() == source3.hashCode()); assertFalse(source2.hashCode() == source3.hashCode()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsClientTest.java ================================================ package org.eluder.coveralls.maven.plugin.httpclient; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.Header; import org.apache.http.HeaderElement; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.message.BasicStatusLine; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.CoverallsResponse; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class CoverallsClientTest { @Mock private HttpClient httpClientMock; @Mock private HttpResponse httpResponseMock; @Mock private HttpEntity httpEntityMock; @Rule public TemporaryFolder folder = new TemporaryFolder(); private File file; @Before public void init() throws IOException { file = folder.newFile(); } @Test public void testConstructors() { assertNotNull(new CoverallsClient("http://test.com/coveralls")); assertNotNull(new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper())); } @Test public void testSubmit() throws Exception { StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"); when(httpResponseMock.getStatusLine()).thenReturn(statusLine); when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock); when(httpResponseMock.getEntity()).thenReturn(httpEntityMock); when(httpEntityMock.getContent()).thenReturn(coverallsResponse(new CoverallsResponse("success", false, ""))); CoverallsClient client = new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper()); client.submit(file); } @Test(expected = IOException.class) public void testFailOnServiceError() throws Exception { StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 500, "Internal Error"); when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock); when(httpResponseMock.getStatusLine()).thenReturn(statusLine); CoverallsClient client = new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper()); client.submit(file); } @Test(expected = ProcessingException.class) public void testParseInvalidResponse() throws Exception { StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"); when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock); when(httpResponseMock.getStatusLine()).thenReturn(statusLine); when(httpResponseMock.getEntity()).thenReturn(httpEntityMock); when(httpEntityMock.getContent()).thenReturn(new ByteArrayInputStream("{bogus}".getBytes())); CoverallsClient client = new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper()); client.submit(file); } @Test(expected = ProcessingException.class) public void testParseErrorousResponse() throws Exception { StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 400, "Bad Request"); when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock); when(httpResponseMock.getStatusLine()).thenReturn(statusLine); when(httpResponseMock.getEntity()).thenReturn(httpEntityMock); when(httpEntityMock.getContent()).thenReturn(coverallsResponse(new CoverallsResponse("failure", true, "submission failed"))); CoverallsClient client = new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper()); client.submit(file); } @Test(expected = IOException.class) public void testParseFailingEntity() throws Exception { StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"); when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock); when(httpResponseMock.getStatusLine()).thenReturn(statusLine); when(httpResponseMock.getEntity()).thenReturn(httpEntityMock); when(httpEntityMock.getContent()).thenThrow(IOException.class); CoverallsClient client = new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper()); client.submit(file); } @Test(expected = ProcessingException.class) public void testParseEntityWithoutContentType() throws Exception { StatusLine statusLine = new BasicStatusLine(HttpVersion.HTTP_1_1, 400, "Bad Request"); when(httpResponseMock.getStatusLine()).thenReturn(statusLine); when(httpClientMock.execute(any(HttpUriRequest.class))).thenReturn(httpResponseMock); when(httpResponseMock.getEntity()).thenReturn(httpEntityMock); Header header = mock(Header.class); HeaderElement element = mock(HeaderElement.class); when(element.getName()).thenReturn("HeaderName"); NameValuePair pair = mock(NameValuePair.class); when(pair.getName()).thenReturn("name"); when(element.getParameters()).thenReturn(new NameValuePair[] { pair } ); when(header.getElements()).thenReturn(new HeaderElement[] { element } ); when(httpEntityMock.getContentType()).thenReturn(header); CoverallsClient client = new CoverallsClient("http://test.com/coveralls", httpClientMock, new ObjectMapper()); client.submit(file); } private InputStream coverallsResponse(final CoverallsResponse coverallsResponse) throws Exception { String content = new ObjectMapper().writeValueAsString(coverallsResponse); return new ByteArrayInputStream(content.getBytes()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/httpclient/CoverallsProxyClientTest.java ================================================ package org.eluder.coveralls.maven.plugin.httpclient; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.settings.Proxy; import org.junit.Test; import static org.junit.Assert.assertNotNull; public class CoverallsProxyClientTest { @Test public void testConstructorWithoutProxy() { assertNotNull(new CoverallsProxyClient("http://test.com/coveralls", null)); } @Test public void testConstructorWithProxy() { Proxy proxy = new Proxy(); proxy.setHost("localhost"); proxy.setPort(8080); proxy.setProtocol("http"); assertNotNull(new CoverallsProxyClient("http://test.com/coveralls", proxy)); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/httpclient/HttpClientFactoryTest.java ================================================ package org.eluder.coveralls.maven.plugin.httpclient; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.github.tomakehurst.wiremock.junit.WireMockRule; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.util.EntityUtils; import org.apache.maven.settings.Proxy; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import static com.github.tomakehurst.wiremock.client.WireMock.*; public class HttpClientFactoryTest { private final int PROXY_PORT = 9797; private final int TARGET_PORT = 9696; private final String TARGET_URL = "http://localhost:" + TARGET_PORT; @Rule public WireMockRule targetServer = new WireMockRule(TARGET_PORT); @Rule public WireMockRule proxyServer = new WireMockRule(PROXY_PORT); @Test public void testSimpleRequest() throws Exception { targetServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("Hello World!"))); HttpClient client = new HttpClientFactory(TARGET_URL).create(); String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity()); Assert.assertEquals("Hello World!", body); } @Test public void testUnAuthorizedProxyRequest() throws Exception { targetServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("Hello World!"))); proxyServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("Hello Proxy!"))); Proxy proxy = new Proxy(); proxy.setHost("localhost"); proxy.setPort(PROXY_PORT); proxy.setProtocol("http"); HttpClient client = new HttpClientFactory(TARGET_URL).proxy(proxy).create(); String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity()); Assert.assertEquals("Hello Proxy!", body); } @Test public void testAuthorixedProxyRequest() throws Exception { targetServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("Hello World!"))); proxyServer.stubFor(get(urlMatching(".*")).withHeader("Proxy-Authorization", matching("Basic Zm9vOmJhcg==")) .willReturn(aResponse().withBody("Hello Proxy!")) .atPriority(1)); proxyServer.stubFor(any(urlMatching(".*")) .willReturn(aResponse().withStatus(407).withHeader("Proxy-Authenticate", "Basic")) .atPriority(2)); Proxy proxy = new Proxy(); proxy.setHost("localhost"); proxy.setPort(PROXY_PORT); proxy.setProtocol("http"); proxy.setUsername("foo"); proxy.setPassword("bar"); HttpClient client = new HttpClientFactory(TARGET_URL).proxy(proxy).create(); String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity()); Assert.assertEquals("Hello Proxy!", body); } @Test public void testNonProxiedHostRequest() throws Exception { targetServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("Hello World!"))); proxyServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("Hello Proxy!"))); Proxy proxy = new Proxy(); proxy.setHost("localhost"); proxy.setPort(PROXY_PORT); proxy.setProtocol("http"); proxy.setNonProxyHosts("localhost|example.com"); HttpClient client = new HttpClientFactory(TARGET_URL).proxy(proxy).create(); String body = EntityUtils.toString(client.execute(new HttpGet(TARGET_URL)).getEntity()); Assert.assertEquals("Hello World!", body); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/json/JsonWriterTest.java ================================================ package org.eluder.coveralls.maven.plugin.json; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.MapType; import org.eluder.coveralls.maven.plugin.domain.Git; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import java.sql.Date; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; public class JsonWriterTest { private static final long TEST_TIME = 1357009200000l; @Rule public TemporaryFolder folder = new TemporaryFolder(); private File file; @Before public void init() throws IOException { file = folder.newFile(); } @Test public void testSubDirectoryCreation() throws Exception { File f = new File(new File(folder.getRoot(), "sub1"), "sub2"); Job job = job(); assertTrue(new JsonWriter(job, f).getCoverallsFile().getParentFile().isDirectory()); } @Test @SuppressWarnings("resource") public void testGetJob() throws Exception { Job job = job(); assertSame(job, new JsonWriter(job, file).getJob()); } @Test @SuppressWarnings("resource") public void testGetCoverallsFile() throws Exception { Job job = job(); assertSame(file, new JsonWriter(job, file).getCoverallsFile()); } @SuppressWarnings("rawtypes") @Test public void testWriteStartAndEnd() throws Exception { JsonWriter writer = new JsonWriter(job(), file); try { writer.onBegin(); writer.onComplete(); } finally { writer.close(); } String content = TestIoUtil.readFileContent(file); Map jsonMap = stringToJsonMap(content); assertEquals("service", jsonMap.get("service_name")); assertEquals("job123", jsonMap.get("service_job_id")); assertEquals("build5", jsonMap.get("service_number")); assertEquals("http://ci.com/build5", jsonMap.get("service_build_url")); assertEquals("foobar", ((Map) jsonMap.get("environment")).get("custom_property")); assertEquals("master", jsonMap.get("service_branch")); assertEquals("pull10", jsonMap.get("service_pull_request")); assertEquals(new SimpleDateFormat(JsonWriter.TIMESTAMP_FORMAT).format(new Date(TEST_TIME)), jsonMap.get("run_at")); assertEquals("af456fge34acd", ((Map) jsonMap.get("git")).get("branch")); assertEquals("aefg837fge", ((Map) ((Map) jsonMap.get("git")).get("head")).get("id")); assertEquals(0, ((Collection) jsonMap.get("source_files")).size()); } @Test public void testOnSource() throws Exception { JsonWriter writer = new JsonWriter(job(), file); try { writer.onBegin(); writer.onSource(source()); writer.onComplete(); } finally { writer.close(); } String content = TestIoUtil.readFileContent(file); Map jsonMap = stringToJsonMap(content); jsonMap = ((List>)jsonMap.get("source_files")).get(0); assertEquals("Foo.java", jsonMap.get("name")); assertEquals("6E0F89B516198DC6AB743EA5FBFB3108", jsonMap.get("source_digest")); assertEquals(1, ((Collection) jsonMap.get("coverage")).size()); } private Job job() { Git.Head head = new Git.Head("aefg837fge", "john", "john@mail.com", "john", "john@mail.com", "test commit"); Git.Remote remote = new Git.Remote("origin", "git@git.com:foo.git"); Properties environment = new Properties(); environment.setProperty("custom_property", "foobar"); return new Job() .withServiceName("service") .withServiceJobId("job123") .withServiceBuildNumber("build5") .withServiceBuildUrl("http://ci.com/build5") .withServiceEnvironment(environment) .withBranch("master") .withPullRequest("pull10") .withTimestamp(new Date(TEST_TIME)) .withGit(new Git(null, head, "af456fge34acd", Arrays.asList(remote))); } private Source source() { return new Source("Foo.java", "public class Foo { }", "6E0F89B516198DC6AB743EA5FBFB3108"); } private Map stringToJsonMap(final String content) throws Exception { ObjectMapper mapper = new ObjectMapper(); MapType type = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Object.class); return mapper.readValue(content, type); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/logging/CoverageTracingLoggerTest.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.logging.Logger.Position; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.UniqueSourceCallback; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class CoverageTracingLoggerTest { @Mock private Log logMock; @Mock private SourceCallback sourceCallbackMock; @Test(expected = IllegalArgumentException.class) public void testConstructorWithNull() { new CoverageTracingLogger(null); } @Test public void testGetPosition() { assertEquals(Position.AFTER, new CoverageTracingLogger(sourceCallbackMock).getPosition()); } @Test public void testLogForSources() throws Exception { Source source1 = new Source("Source1.java", "public class Source1 {\n if(true) { }\n}\n", "FE0538639E8CE73733E77659C1043B5C"); source1.addCoverage(1, 0); source1.addCoverage(2, 0); source1.addCoverage(3, 0); source1.addBranchCoverage(2, 0, 0, 3); source1.addBranchCoverage(2, 0, 1, 0); Source source2 = new Source("Source2.java", "public class Source2 {\n new Interface() { public void run() { } };\n}\n", "34BD6501A6D1CE5181AECEA688C7D382"); source2.addCoverage(1, 1); source2.addCoverage(3, 1); Source source2inner = new Source("Source2.java", "public class Source2 {\n new Interface() { public void run() { } };\n}\n", "34BD6501A6D1CE5181AECEA688C7D382"); source2inner.setClassifier("$1"); source2inner.addCoverage(2, 1); CoverageTracingLogger coverageTracingLogger = new CoverageTracingLogger(sourceCallbackMock); UniqueSourceCallback uniqueSourceCallback = new UniqueSourceCallback(coverageTracingLogger); uniqueSourceCallback.onSource(source1); uniqueSourceCallback.onSource(source2); uniqueSourceCallback.onSource(source2inner); uniqueSourceCallback.onComplete(); coverageTracingLogger.log(logMock); assertEquals(8, coverageTracingLogger.getLines()); assertEquals(6, coverageTracingLogger.getRelevant()); assertEquals(3, coverageTracingLogger.getCovered()); assertEquals(3, coverageTracingLogger.getMissed()); assertEquals(2, coverageTracingLogger.getBranches()); assertEquals(1, coverageTracingLogger.getCoveredBranches()); assertEquals(1, coverageTracingLogger.getMissedBranches()); verify(sourceCallbackMock, times(2)).onSource(any(Source.class)); verify(logMock).info("Gathered code coverage metrics for 2 source files with 8 lines of code:"); verify(logMock).info("- 6 relevant lines"); verify(logMock).info("- 3 covered lines"); verify(logMock).info("- 3 missed lines"); verify(logMock).info("- 2 branches"); verify(logMock).info("- 2 branches"); verify(logMock).info("- 1 covered branches"); verify(logMock).info("- 1 missed branches"); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/logging/DryRunLoggerTest.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import java.io.File; import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.logging.Logger.Position; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class DryRunLoggerTest { @Mock private Log logMock; @Mock private File coverallsFileMock; @Test(expected = IllegalArgumentException.class) public void testMissingCoverallsFile() { new DryRunLogger(true, null); } @Test public void testGetPosition() { assertEquals(Position.AFTER, new DryRunLogger(true, coverallsFileMock).getPosition()); } @Test public void testLogDryRunDisabled() { new DryRunLogger(false, coverallsFileMock).log(logMock); verifyZeroInteractions(logMock); } @Test public void testLogDryRunEnabled() { when(coverallsFileMock.length()).thenReturn(1024l); when(coverallsFileMock.getAbsolutePath()).thenReturn("/target/coveralls.json"); new DryRunLogger(true, coverallsFileMock).log(logMock); verify(logMock).info("Dry run enabled, Coveralls report will NOT be submitted to API"); verify(logMock).info("1024 bytes of data was recorded in /target/coveralls.json"); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/logging/JobLoggerTest.java ================================================ package org.eluder.coveralls.maven.plugin.logging; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.same; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.domain.Git; import org.eluder.coveralls.maven.plugin.domain.Git.Head; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.logging.Logger.Position; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(MockitoJUnitRunner.class) public class JobLoggerTest { @Mock private Job jobMock; @Mock private Log logMock; @Mock private ObjectMapper jsonMapperMock; @Test(expected = IllegalArgumentException.class) public void testMissingJob() { new JobLogger(null); } @Test public void testGetPosition() { assertEquals(Position.BEFORE, new JobLogger(jobMock).getPosition()); } @Test public void testLogJobWithId() { Git git = new Git(null, new Head("ab679cf2d81ac", null, null, null, null, null), "master", null); when(jobMock.getServiceName()).thenReturn("service"); when(jobMock.getServiceJobId()).thenReturn("666"); when(jobMock.getRepoToken()).thenReturn("123456789"); when(jobMock.isDryRun()).thenReturn(true); when(jobMock.getGit()).thenReturn(git); new JobLogger(jobMock).log(logMock); verify(logMock).info("Starting Coveralls job for service (666) in dry run mode"); verify(logMock).info("Using repository token "); verify(logMock).info("Git commit ab679cf in master"); verify(logMock).isDebugEnabled(); verifyNoMoreInteractions(logMock); } @Test public void testLogWithBuildNumberAndUrl() { when(jobMock.getServiceName()).thenReturn("service"); when(jobMock.getServiceBuildNumber()).thenReturn("10"); when(jobMock.getServiceBuildUrl()).thenReturn("http://ci.com/build/10"); new JobLogger(jobMock).log(logMock); verify(logMock).info("Starting Coveralls job for service (10 / http://ci.com/build/10)"); verify(logMock).isDebugEnabled(); verifyNoMoreInteractions(logMock); } @Test public void testLogDryRun() { when(jobMock.isDryRun()).thenReturn(true); new JobLogger(jobMock).log(logMock); verify(logMock).info("Starting Coveralls job in dry run mode"); verify(logMock).isDebugEnabled(); verifyNoMoreInteractions(logMock); } @Test public void testLogParallel() { when(jobMock.isParallel()).thenReturn(true); new JobLogger(jobMock).log(logMock); verify(logMock).info("Starting Coveralls job with parallel option enabled"); verify(logMock).isDebugEnabled(); verifyNoMoreInteractions(logMock); } @Test public void testLogJobWithDebug() throws Exception { when(logMock.isDebugEnabled()).thenReturn(true); when(jobMock.getServiceName()).thenReturn("service"); when(jsonMapperMock.writeValueAsString(same(jobMock))).thenReturn("{\"serviceName\":\"service\"}"); new JobLogger(jobMock, jsonMapperMock).log(logMock); verify(logMock).info("Starting Coveralls job for service"); verify(logMock).isDebugEnabled(); verify(logMock).debug("Complete Job description:\n{\"serviceName\":\"service\"}"); verifyNoMoreInteractions(logMock); } @Test(expected = RuntimeException.class) @SuppressWarnings("unchecked") public void testLogJobWithErrorInDebug() throws Exception { when(logMock.isDebugEnabled()).thenReturn(true); when(jobMock.getServiceName()).thenReturn("service"); when(jsonMapperMock.writeValueAsString(same(jobMock))).thenThrow(JsonProcessingException.class); new JobLogger(jobMock, jsonMapperMock).log(logMock); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/parser/AbstractCoverageParserTest.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.CoverageFixture; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.ProcessingException; import org.eluder.coveralls.maven.plugin.domain.Branch; import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.source.ChainingSourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceCallback; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import org.eluder.coveralls.maven.plugin.source.UniqueSourceCallback; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public abstract class AbstractCoverageParserTest { @Mock protected SourceLoader sourceLoaderMock; @Mock protected SourceCallback sourceCallbackMock; @Before public void init() throws IOException { for (String[] coverageFile : getCoverageFixture()) { final String name = sourceName(coverageFile[0]); final String content = TestIoUtil.readFileContent(TestIoUtil.getFile(name)); when(sourceLoaderMock.load(name)).then(sourceAnswer(name, content)); } } protected String sourceName(final String coverageFile) { return coverageFile; } protected Answer sourceAnswer(final String name, final String content) { return new Answer() { @Override public Source answer(final InvocationOnMock invocation) throws Throwable { return new Source(name, content, TestIoUtil.getMd5DigestHex(content)); } }; } @Test public void testParseCoverage() throws Exception { for (String coverageResource : getCoverageResources()) { CoverageParser parser = createCoverageParser(TestIoUtil.getFile(coverageResource), sourceLoaderMock); parser.parse(sourceCallbackMock); } String[][] fixture = getCoverageFixture(); ArgumentCaptor captor = ArgumentCaptor.forClass(Source.class); verify(sourceCallbackMock, atLeast(CoverageFixture.getTotalFiles(fixture))).onSource(captor.capture()); SourceCollector sourceCollector = new SourceCollector(); UniqueSourceCallback uniqueSourceCallback = new UniqueSourceCallback(sourceCollector); ClassifierRemover classifierRemover = new ClassifierRemover(uniqueSourceCallback); classifierRemover.onBegin(); for (Source source: captor.getAllValues()) { classifierRemover.onSource(source); } classifierRemover.onComplete(); for (String[] coverageFile : fixture) { assertCoverage(sourceCollector.sources, coverageFile[0], Integer.parseInt(coverageFile[1]), toIntegerSet(coverageFile[2]), toIntegerSet(coverageFile[3]), toIntegerSet(coverageFile[4]), toIntegerSet(coverageFile[5])); } } protected abstract CoverageParser createCoverageParser(File coverageFile, SourceLoader sourceLoader); protected abstract List getCoverageResources(); protected abstract String[][] getCoverageFixture(); private Set toIntegerSet(final String commaSeparated) { if (commaSeparated.isEmpty()) { return Collections.emptySet(); } String[] split = commaSeparated.split(","); Set values = new HashSet<>(); for (String value : split) { values.add(Integer.valueOf(value)); } return values; } private static class SourceCollector implements SourceCallback { private List sources = new ArrayList<>(); @Override public void onBegin() throws ProcessingException, IOException { } @Override public void onSource(Source source) throws ProcessingException, IOException { sources.add(source); } @Override public void onComplete() throws ProcessingException, IOException { } } private static class ClassifierRemover extends ChainingSourceCallback { public ClassifierRemover(SourceCallback chained) { super(chained); } @Override protected void onSourceInternal(Source source) throws ProcessingException, IOException { source.setClassifier(null); } } private static void assertCoverage(final Collection sources, final String name, final int lines, final Set coveredLines, final Set missedLines, final Set coveredBranches, final Set missedBranches) { Source tested = null; for (Source source : sources) { if (source.getName().endsWith(name)) { tested = source; break; } } if (tested == null) { fail("Expected source " + name + " not found from coverage report"); } if (tested.getCoverage().length != lines) { fail("Expected " + lines + " lines for " + name + " was " + tested.getCoverage().length); } for (int i = 0; i < tested.getCoverage().length; i++) { Integer lineNumber = i + 1; String message = name + " line " + lineNumber + " coverage"; if (coveredLines.contains(lineNumber)) { assertTrue(message, tested.getCoverage()[i] > 0); } else if (missedLines.contains(lineNumber)) { assertTrue(message, tested.getCoverage()[i] == 0); } else { assertNull(message, tested.getCoverage()[i]); } } for (final Branch b : tested.getBranchesList()) { final String message = name + " branch " + b.getBranchNumber() + " coverage in line " + b.getLineNumber(); if (b.getHits() > 0) { assertTrue(message, coveredBranches.contains(b.getLineNumber())); } else { assertTrue(message, missedBranches.contains(b.getLineNumber())); } } } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/parser/CoberturaParserTest.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.util.Arrays; import java.util.List; import org.eluder.coveralls.maven.plugin.CoverageFixture; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.source.SourceLoader; public class CoberturaParserTest extends AbstractCoverageParserTest { @Override protected CoverageParser createCoverageParser(final File coverageFile, final SourceLoader sourceLoader) { return new CoberturaParser(coverageFile, sourceLoader); } @Override protected List getCoverageResources() { return Arrays.asList("cobertura.xml"); } @Override protected String[][] getCoverageFixture() { return CoverageFixture.JAVA_FILES; } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/parser/JaCoCoParserTest.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.CoverageFixture; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import java.io.File; import java.util.Arrays; import java.util.List; public class JaCoCoParserTest extends AbstractCoverageParserTest { @Override protected CoverageParser createCoverageParser(final File coverageFile, final SourceLoader sourceLoader) { return new JaCoCoParser(coverageFile, sourceLoader); } @Override protected List getCoverageResources() { return Arrays.asList("jacoco1.xml", "jacoco2.xml", "jacoco2-it.xml"); } @Override protected String[][] getCoverageFixture() { return CoverageFixture.JAVA_FILES_IT; } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/parser/SagaParserTest.java ================================================ package org.eluder.coveralls.maven.plugin.parser; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.util.Arrays; import java.util.List; import org.eluder.coveralls.maven.plugin.CoverageFixture; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.source.SourceLoader; /** * @author Jakub Bednář (25/12/2013 10:17) */ public class SagaParserTest extends AbstractCoverageParserTest { @Override protected CoverageParser createCoverageParser(final File coverageFile, final SourceLoader sourceLoader) { return new SagaParser(coverageFile, sourceLoader); } @Override protected List getCoverageResources() { return Arrays.asList("saga.xml"); } @Override protected String[][] getCoverageFixture() { return CoverageFixture.JAVASCRIPT_FILES; } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/AbstractServiceSetupTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.junit.Test; public class AbstractServiceSetupTest { @Test public void testGetMissingProperty() { AbstractServiceSetup serviceSetup = create(new HashMap()); assertNull(serviceSetup.getProperty("property")); } @Test public void testGetProperty() { Map env = new HashMap(); env.put("CI_NAME", "bamboo"); assertEquals("bamboo", create(env).getProperty("CI_NAME")); } @Test(expected = IllegalArgumentException.class) public void testAddPropertyWithoutName() { create(new HashMap()).addProperty(new Properties(), null, "value"); } @Test public void testAddPropertyWithoutValue() { Properties properties = new Properties(); create(new HashMap()).addProperty(properties, "prop", " "); assertNull(properties.getProperty("prop")); } @Test public void testAddPropertyWithValue() { Properties properties = new Properties(); create(new HashMap()).addProperty(properties, "prop", "value"); assertEquals("value", properties.getProperty("prop")); } @Test public void testGetDefaultValues() { AbstractServiceSetup serviceSetup = create(new HashMap()); assertNull(serviceSetup.getName()); assertNull(serviceSetup.getJobId()); assertNull(serviceSetup.getBuildNumber()); assertNull(serviceSetup.getBuildUrl()); assertNull(serviceSetup.getBranch()); assertNull(serviceSetup.getPullRequest()); assertNull(serviceSetup.getEnvironment()); } private AbstractServiceSetup create(final Map env) { return new AbstractServiceSetup(env) { @Override public boolean isSelected() { return true; } @Override public String getName() { return getProperty("CI_NAME"); } }; } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/AppveyorTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Test; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.*; public class AppveyorTest { private Map env() { Map env = new HashMap(); env.put(Appveyor.APPVEYOR, "true"); env.put(Appveyor.APPVEYOR_BUILD_ID, "54de3316c44f"); env.put(Appveyor.APPVEYOR_BUILD_NUMBER, "77"); env.put(Appveyor.APPVEYOR_BRANCH, "master"); env.put(Appveyor.APPVEYOR_COMMIT, "a3562fgcd2"); env.put(Appveyor.APPVEYOR_PULL_REQUEST, "10"); env.put(Appveyor.APPVEYOR_REPO_NAME, "owner/project"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Appveyor(new HashMap()).isSelected()); } @Test public void testIsSelectedForAppveyor() { assertTrue(new Appveyor(env()).isSelected()); } @Test public void testGetName() { assertEquals("Appveyor", new Appveyor(env()).getName()); } @Test public void testGetBuildNumber() { assertEquals("77", new Appveyor(env()).getBuildNumber()); } @Test public void testGetBuildUrl() { assertEquals("https://ci.appveyor.com/project/owner/project/build/77", new Appveyor(env()).getBuildUrl()); } @Test public void testGetBranch() { assertEquals("master", new Appveyor(env()).getBranch()); } @Test public void testPullRequest() { assertEquals("10", new Appveyor(env()).getPullRequest()); } @Test public void testGetJobId() { assertEquals("54de3316c44f", new Appveyor(env()).getJobId()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/BambooTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import org.junit.Test; public class BambooTest { private Map env() { Map env = new HashMap(); env.put("bamboo.buildNumber", "build123"); env.put("bamboo.buildResultsUrl", "http://company.com/bamboo/build123"); env.put("bamboo.repository.git.branch", "master"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Bamboo(new HashMap()).isSelected()); } @Test public void testIsSelectedForBamboo() { assertTrue(new Bamboo(env()).isSelected()); } @Test public void testGetName() { assertEquals("bamboo", new Bamboo(env()).getName()); } @Test public void testGetBuildNumber() { assertEquals("build123", new Bamboo(env()).getBuildNumber()); } @Test public void testGetBuildUrl() { assertEquals("http://company.com/bamboo/build123", new Bamboo(env()).getBuildUrl()); } @Test public void testGetBranch() { assertEquals("master", new Bamboo(env()).getBranch()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/CircleTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.junit.Test; public class CircleTest { private Map env() { Map env = new HashMap(); env.put("CIRCLECI", "true"); env.put("CIRCLE_BUILD_NUM", "build123"); env.put("CIRCLE_BRANCH", "master"); env.put("CIRCLE_SHA1", "a3562fgcd2"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Circle(new HashMap()).isSelected()); } @Test public void testIsSelectedForCircle() { assertTrue(new Circle(env()).isSelected()); } @Test public void testGetName() { assertEquals("circleci", new Circle(env()).getName()); } @Test public void testGetBuildNumber() { assertEquals("build123", new Circle(env()).getBuildNumber()); } @Test public void testGetBranch() { assertEquals("master", new Circle(env()).getBranch()); } @Test public void testGetEnvironment() { Properties properties = new Circle(env()).getEnvironment(); assertEquals(3, properties.size()); assertEquals("build123", properties.getProperty("circleci_build_num")); assertEquals("master", properties.getProperty("branch")); assertEquals("a3562fgcd2", properties.getProperty("commit_sha")); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/GeneralTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import org.junit.Test; public class GeneralTest { private Map env() { Map env = new HashMap(); env.put("CI_NAME", "ci_service"); env.put("CI_BUILD_NUMBER", "build123"); env.put("CI_BUILD_URL", "http://ci.com/build123"); env.put("CI_BRANCH", "master"); env.put("CI_PULL_REQUEST", "pull10"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new General(new HashMap()).isSelected()); } @Test public void testIsSelectedForCi() { assertTrue(new General(env()).isSelected()); } @Test public void testGetName() { assertEquals("ci_service", new General(env()).getName()); } @Test public void testGetBuildNumber() { assertEquals("build123", new General(env()).getBuildNumber()); } @Test public void testGetBuildUrl() { assertEquals("http://ci.com/build123", new General(env()).getBuildUrl()); } @Test public void testGetBranch() { assertEquals("master", new General(env()).getBranch()); } @Test public void testGetPullRequest() { assertEquals("pull10", new General(env()).getPullRequest()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/JenkinsTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.junit.Test; public class JenkinsTest { private Map env() { Map env = new HashMap(); env.put("JENKINS_URL", "http://company.com/jenkins"); env.put("BUILD_NUMBER", "build123"); env.put("BUILD_URL", "http://company.com/jenkins/build123"); env.put("GIT_BRANCH", "master"); env.put("GIT_COMMIT", "a3562fgcd2"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Jenkins(new HashMap()).isSelected()); } @Test public void testIsSelectedForJenkins() { assertTrue(new Jenkins(env()).isSelected()); } @Test public void testGetName() { assertEquals("jenkins", new Jenkins(env()).getName()); } @Test public void testGetBuildNumber() { assertEquals("build123", new Jenkins(env()).getBuildNumber()); } @Test public void testGetBuildUrl() { assertEquals("http://company.com/jenkins/build123", new Jenkins(env()).getBuildUrl()); } @Test public void testGetBranch() { assertEquals("master", new Jenkins(env()).getBranch()); } @Test public void testGetEnvironment() { Properties properties = new Jenkins(env()).getEnvironment(); assertEquals(4, properties.size()); assertEquals("build123", properties.getProperty("jenkins_build_num")); assertEquals("http://company.com/jenkins/build123", properties.getProperty("jenkins_build_url")); assertEquals("master", properties.getProperty("branch")); assertEquals("a3562fgcd2", properties.getProperty("commit_sha")); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/ShippableTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Test; import java.util.HashMap; import java.util.Map; import java.util.Properties; import static org.junit.Assert.*; public class ShippableTest { private Map env() { Map env = new HashMap(); env.put(Shippable.SHIPPABLE, "true"); env.put(Shippable.SHIPPABLE_BUILD_ID, "54de3316c44f"); env.put(Shippable.SHIPPABLE_BUILD_NUMBER, "431.1"); env.put(Shippable.SHIPPABLE_BRANCH, "master"); env.put(Shippable.SHIPPABLE_COMMIT, "a3562fgcd2"); env.put(Shippable.SHIPPABLE_PULL_REQUEST, "10"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Shippable(new HashMap()).isSelected()); } @Test public void testIsSelectedForShippable() { assertTrue(new Shippable(env()).isSelected()); } @Test public void testGetName() { assertEquals("shippable", new Shippable(env()).getName()); } @Test public void testGetBuildNumber() { assertEquals("431.1", new Shippable(env()).getBuildNumber()); } @Test public void testGetBuildUrl() { assertEquals("https://app.shippable.com/builds/54de3316c44f", new Shippable(env()).getBuildUrl()); } @Test public void testGetBranch() { assertEquals("master", new Shippable(env()).getBranch()); } @Test public void testPullRequest() { assertEquals("10", new Shippable(env()).getPullRequest()); } @Test public void testPullRequestFalse() { Map env = env(); env.put(Shippable.SHIPPABLE_PULL_REQUEST, "false"); assertNull(new Shippable(env).getPullRequest()); } @Test public void testGetEnvironment() { Properties properties = new Shippable(env()).getEnvironment(); assertEquals(5, properties.size()); assertEquals("431.1", properties.getProperty("shippable_build_number")); assertEquals("54de3316c44f", properties.getProperty("shippable_build_id")); assertEquals("https://app.shippable.com/builds/54de3316c44f", properties.getProperty("shippable_build_url")); assertEquals("master", properties.getProperty("branch")); assertEquals("a3562fgcd2", properties.getProperty("commit_sha")); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/TravisTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.junit.Test; public class TravisTest { private Map env() { Map env = new HashMap(); env.put("TRAVIS", "true"); env.put("TRAVIS_JOB_ID", "job123"); env.put("TRAVIS_BRANCH", "master"); env.put("TRAVIS_PULL_REQUEST", "pull10"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Travis(new HashMap()).isSelected()); } @Test public void testIsSelectedForTravis() { assertTrue(new Travis(env()).isSelected()); } @Test public void testGetName() { assertEquals("travis-ci", new Travis(env()).getName()); } @Test public void testGetJobId() { assertEquals("job123", new Travis(env()).getJobId()); } @Test public void testGetBranch() { assertEquals("master", new Travis(env()).getBranch()); } @Test public void testGetPullRequest() { assertEquals("pull10", new Travis(env()).getPullRequest()); } @Test public void testGetEnvironment() { Properties properties = new Travis(env()).getEnvironment(); assertEquals(2, properties.size()); assertEquals("job123", properties.getProperty("travis_job_id")); assertEquals("pull10", properties.getProperty("travis_pull_request")); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/service/WerckerTest.java ================================================ package org.eluder.coveralls.maven.plugin.service; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Test; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class WerckerTest { private Map env() { Map env = new HashMap(); env.put("WERCKER", "true"); env.put("WERCKER_BUILD_URL", "https://app.wercker.com/build/123456789"); env.put("WERCKER_BUILD_ID", "123456789"); env.put("WERCKER_GIT_BRANCH", "master"); return env; } @Test public void testIsSelectedForNothing() { assertFalse(new Wercker(new HashMap()).isSelected()); } @Test public void testIsSelectedForWercker() { assertTrue(new Wercker(env()).isSelected()); } @Test public void testGetName() { assertEquals("wercker", new Wercker(env()).getName()); } @Test public void testGetJobId() { assertEquals("123456789", new Wercker(env()).getJobId()); } @Test public void testGetBuildUrl() { assertEquals("https://app.wercker.com/build/123456789", new Wercker(env()).getBuildUrl()); } @Test public void testGetBranch() { assertEquals("master", new Wercker(env()).getBranch()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/source/DirectorySourceLoaderTest.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.File; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @RunWith(MockitoJUnitRunner.class) public class DirectorySourceLoaderTest { @Mock private File dirMock; @Mock private File fileMock; @Rule public TemporaryFolder folder = new TemporaryFolder(); @Test public void testMissingSourceFileFromDirectory() throws Exception { DirectorySourceLoader sourceLoader = new DirectorySourceLoader(folder.getRoot(), folder.getRoot(), "UTF-8"); assertNull(sourceLoader.load("Foo.java")); } @Test(expected = IllegalArgumentException.class) public void testInvalidSourceFile() throws Exception { File subFolder = folder.newFolder(); DirectorySourceLoader sourceLoader = new DirectorySourceLoader(folder.getRoot(), folder.getRoot(), "UTF-8"); sourceLoader.load(subFolder.getName()); } @Test public void testLoadSource() throws Exception { File file = folder.newFile(); TestIoUtil.writeFileContent("public class Foo {\r\n \n}\r", file); DirectorySourceLoader sourceLoader = new DirectorySourceLoader(folder.getRoot(), folder.getRoot(), "UTF-8"); Source source = sourceLoader.load(file.getName()); assertEquals(file.getName(), source.getName()); assertEquals("2AC359C9A152FD7CD79C4EB147069224", source.getDigest()); assertEquals(4, source.getCoverage().length); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/source/MultiSourceLoaderTest.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.domain.Source; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.IOException; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class MultiSourceLoaderTest { @Mock private SourceLoader sl1; @Mock private SourceLoader sl2; private Source s1 = new Source("source", "{ 1 }", "9A0174D3A5B8D202C6E404601FC260D1"); private Source s2 = new Source("source", "{ 2 }", "849409F24F4BCAAC904F3B142447D65D"); @Test(expected = IOException.class) public void testMissingSource() throws Exception { creaMultiSourceLoader().load("source"); } @Test public void testPrimarySource() throws Exception { when(sl1.load("source")).thenReturn(s1); Source source = creaMultiSourceLoader().load("source"); assertSame(s1, source); } @Test public void testSecondarySource() throws Exception { when(sl2.load("source")).thenReturn(s2); Source source = creaMultiSourceLoader().load("source"); assertSame(s2, source); } private MultiSourceLoader creaMultiSourceLoader() { return new MultiSourceLoader().add(sl1).add(sl2); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/source/ScanSourceLoaderTest.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.File; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @RunWith(MockitoJUnitRunner.class) public class ScanSourceLoaderTest { @Mock private File dirMock; @Mock private File fileMock; @Rule public TemporaryFolder folder = new TemporaryFolder(); @Test public void testMissingSourceFileFromDirectory() throws Exception { ScanSourceLoader sourceLoader = new ScanSourceLoader(folder.getRoot(), folder.getRoot(), "UTF-8"); assertNull(sourceLoader.load("Foo.java")); } @Test(expected = IllegalArgumentException.class) public void testInvalidSourceFile() throws Exception { File subFolder = folder.newFolder(); ScanSourceLoader sourceLoader = new ScanSourceLoader(folder.getRoot(), folder.getRoot(), "UTF-8"); sourceLoader.load(subFolder.getName()); } @Test public void testLoadSource() throws Exception { File dir = folder.newFolder("level1", "level2", "level3"); File fileA = new File(dir, "AFile.java"); File fileB = new File(dir, "BFile.java"); TestIoUtil.writeFileContent("public class Foo {\r\n \n}\r", fileA); TestIoUtil.writeFileContent("public class Foo {\r\n \n}\r", fileB); ScanSourceLoader sourceLoader = new ScanSourceLoader(folder.getRoot(), folder.getRoot(), "UTF-8"); Source sourceA = sourceLoader.load(fileA.getName()); assertEquals("level1/level2/level3/AFile.java", sourceA.getName()); assertEquals("2AC359C9A152FD7CD79C4EB147069224", sourceA.getDigest()); assertEquals(4, sourceA.getCoverage().length); Source sourceB = sourceLoader.load(fileB.getName()); assertEquals("level1/level2/level3/BFile.java", sourceB.getName()); assertEquals("2AC359C9A152FD7CD79C4EB147069224", sourceB.getDigest()); assertEquals(4, sourceB.getCoverage().length); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/source/UniqueSourceCallbackTest.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class UniqueSourceCallbackTest { @Mock private SourceCallback sourceCallbackMock; @Test public void testOnSourceWithUniqueFiles() throws Exception { Source s1 = createSource("Foo.java", "{\n void();\n}\n", 2); Source s2 = createSource("Bar.java", "{\n bar();\n}\n", 2); UniqueSourceCallback cb = createUniqueSourceCallback(); cb.onBegin(); cb.onSource(s1); cb.onSource(s2); cb.onComplete(); verify(sourceCallbackMock).onBegin(); verify(sourceCallbackMock, times(2)).onSource(Mockito.any(Source.class)); verify(sourceCallbackMock).onComplete(); } @Test public void testOnSourceWithDuplicateSources() throws Exception { Source s1 = createSource("Foo.java", "{\n void();\n}\n", 2); Source s2 = createSource("Foo.java", "{\n void();\n}\n", 2); UniqueSourceCallback cb = createUniqueSourceCallback(); cb.onBegin(); cb.onSource(s1); cb.onSource(s2); cb.onComplete(); verify(sourceCallbackMock).onBegin(); verify(sourceCallbackMock, times(1)).onSource(Mockito.any(Source.class)); verify(sourceCallbackMock).onComplete(); } @Test public void testOnSourceWithUniqueSources() throws Exception { Source s1 = createSource("Foo.java", "{\n void();\n}\n", 2); Source s2 = createSource("Foo.java", "{\n void();\n func();\n}\n", 2, 3); UniqueSourceCallback cb = createUniqueSourceCallback(); cb.onBegin(); cb.onSource(s1); cb.onSource(s2); cb.onComplete(); verify(sourceCallbackMock).onBegin(); verify(sourceCallbackMock, times(2)).onSource(Mockito.any(Source.class)); verify(sourceCallbackMock).onComplete(); } private UniqueSourceCallback createUniqueSourceCallback() { return new UniqueSourceCallback(sourceCallbackMock); } private Source createSource(final String name, final String source, final int... relevant) throws Exception { Source s = new Source(name, source, TestIoUtil.getMd5DigestHex(source)); for (int i : relevant) { s.addCoverage(i, 1); } return s; } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/source/UrlSourceLoaderTest.java ================================================ package org.eluder.coveralls.maven.plugin.source; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.domain.Source; import org.eluder.coveralls.maven.plugin.util.TestIoUtil; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.File; import java.net.URL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @RunWith(MockitoJUnitRunner.class) public class UrlSourceLoaderTest { @Mock private File dirMock; @Mock private File fileMock; @Rule public TemporaryFolder folder = new TemporaryFolder(); @Test public void testMissingSourceFileFromUrl() throws Exception { UrlSourceLoader sourceLoader = new UrlSourceLoader(folder.getRoot().toURI().toURL(), new URL("http://domainthatreallydoesnotexistsdfsmshjsfsj.com"), "UTF-8"); assertNull(sourceLoader.load("Foo.java")); } @Test public void testLoadSourceFromUrl() throws Exception { String fileName = "scripts/file.coffee"; URL sourceUrl = folder.getRoot().toURI().toURL(); folder.newFolder("scripts"); File file = folder.newFile(fileName); TestIoUtil.writeFileContent("math =\n root: Math.sqrt\n square: square", file); UrlSourceLoader sourceLoader = new UrlSourceLoader(folder.getRoot().toURI().toURL(), sourceUrl, "UTF-8"); Source source = sourceLoader.load(fileName); assertEquals(fileName, source.getName()); assertEquals("9897A4BB0467180D3C6ACD95475DD77D", source.getDigest()); assertEquals(3, source.getCoverage().length); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/CoverageParsersFactoryTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Reporting; import org.apache.maven.project.MavenProject; import org.eluder.coveralls.maven.plugin.CoverageParser; import org.eluder.coveralls.maven.plugin.parser.CoberturaParser; import org.eluder.coveralls.maven.plugin.parser.JaCoCoParser; import org.eluder.coveralls.maven.plugin.parser.SagaParser; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class CoverageParsersFactoryTest { @Rule public TemporaryFolder folder = new TemporaryFolder(); @Mock private MavenProject projectMock; @Mock private SourceLoader sourceLoaderMock; @Mock private Model modelMock; @Mock private Reporting reportingMock; @Mock private Build buildMock; private File reportingDir; private File targetDir; @Before public void init() throws Exception{ reportingDir = folder.newFolder(); targetDir = folder.newFolder(); when(projectMock.getCollectedProjects()).thenReturn(Collections.emptyList()); when(projectMock.getModel()).thenReturn(modelMock); when(projectMock.getBuild()).thenReturn(buildMock); when(modelMock.getReporting()).thenReturn(reportingMock); when(reportingMock.getOutputDirectory()).thenReturn(reportingDir.getAbsolutePath()); when(buildMock.getDirectory()).thenReturn(targetDir.getAbsolutePath()); } @Test(expected = IOException.class) public void testCreateEmptyParsers() throws Exception { createCoverageParsersFactory().createParsers(); } @Test public void testCreateJaCoCoParser() throws Exception { File jacocoDir = new File(reportingDir, "jacoco"); jacocoDir.mkdir(); new File(jacocoDir, "jacoco.xml").createNewFile(); List parsers = createCoverageParsersFactory().createParsers(); assertEquals(1, parsers.size()); assertTrue(JaCoCoParser.class.equals(parsers.get(0).getClass())); } @Test public void testCreateCoberturaParser() throws Exception { File coberturaDir = new File(reportingDir, "cobertura"); coberturaDir.mkdir(); new File(coberturaDir, "coverage.xml").createNewFile(); List parsers = createCoverageParsersFactory().createParsers(); assertEquals(1, parsers.size()); assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass())); } @Test public void testCreateSagaParser() throws Exception { File sagaDir = new File(targetDir, "saga-coverage"); sagaDir.mkdir(); new File(sagaDir, "total-coverage.xml").createNewFile(); List parsers = createCoverageParsersFactory().createParsers(); assertEquals(1, parsers.size()); assertTrue(SagaParser.class.equals(parsers.get(0).getClass())); } @Test public void testWithJaCoCoReport() throws Exception { File jacocoFile = new File(reportingDir, "jacoco-report.xml"); jacocoFile.createNewFile(); CoverageParsersFactory factory = createCoverageParsersFactory().withJaCoCoReports(Arrays.asList(jacocoFile)); List parsers = factory.createParsers(); assertEquals(1, parsers.size()); assertTrue(JaCoCoParser.class.equals(parsers.get(0).getClass())); } @Test public void testWithCoberturaReport() throws Exception { File coberturaFile = new File(reportingDir, "cobertura-report.xml"); coberturaFile.createNewFile(); CoverageParsersFactory factory = createCoverageParsersFactory().withCoberturaReports(Arrays.asList(coberturaFile)); List parsers = factory.createParsers(); assertEquals(1, parsers.size()); assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass())); } @Test public void testWithSagaReport() throws Exception { File sagaFile = new File(reportingDir, "saga-report.xml"); sagaFile.createNewFile(); CoverageParsersFactory factory = createCoverageParsersFactory().withSagaReports(Arrays.asList(sagaFile)); List parsers = factory.createParsers(); assertEquals(1, parsers.size()); assertTrue(SagaParser.class.equals(parsers.get(0).getClass())); } @Test public void testWithRelativeReportDirectory() throws Exception { File coberturaDir = new File(reportingDir, "customdir"); coberturaDir.mkdir(); new File(coberturaDir, "coverage.xml").createNewFile(); CoverageParsersFactory factory = createCoverageParsersFactory().withRelativeReportDirs(Arrays.asList("customdir")); List parsers = factory.createParsers(); assertEquals(1, parsers.size()); assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass())); } @Test public void testWithRootRelativeReportDirectory() throws Exception { new File(reportingDir, "coverage.xml").createNewFile(); CoverageParsersFactory factory = createCoverageParsersFactory().withRelativeReportDirs(Arrays.asList(File.separator)); List parsers = factory.createParsers(); assertEquals(1, parsers.size()); assertTrue(CoberturaParser.class.equals(parsers.get(0).getClass())); } private CoverageParsersFactory createCoverageParsersFactory() { return new CoverageParsersFactory(projectMock, sourceLoaderMock); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/ExistingFilesTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.*; import java.io.File; import java.util.Arrays; import java.util.Iterator; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public class ExistingFilesTest { @Rule public TemporaryFolder folder = new TemporaryFolder(); @Test(expected = NullPointerException.class) public void testAddAllForNull() throws Exception { new ExistingFiles().addAll(null); } @Test(expected = NullPointerException.class) public void testAddForNull() throws Exception { new ExistingFiles().add(null); } @Test public void testAddForExisting() throws Exception { File f = folder.newFile(); Iterator iter = new ExistingFiles().add(f).add(f).iterator(); assertSize(iter, 1); } @Test public void testAddForDirectory() throws Exception { File d = folder.newFolder(); Iterator iter = new ExistingFiles().add(d).iterator(); assertSize(iter, 0); } @Test public void testCreateForNull() throws Exception { Iterator iter = ExistingFiles.create(null).iterator(); assertSize(iter, 0); } @Test public void testCreateForMultipleFiles() throws Exception { File f1 = folder.newFile(); File f2 = folder.newFile(); Iterator iter = ExistingFiles.create(Arrays.asList(f1, f2)).iterator(); assertSize(iter, 2); } private static void assertSize(Iterator iter, int size) { for (int i = 0; i < size; i++) { iter.next(); } assertFalse(iter.hasNext()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/Md5DigestInputStreamTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Test; import java.io.ByteArrayInputStream; import static org.junit.Assert.assertEquals; public class Md5DigestInputStreamTest { @Test public void testRead() throws Exception { byte[] data = new byte[] { (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD }; try (Md5DigestInputStream is = new Md5DigestInputStream(new ByteArrayInputStream(data))) { assertEquals(0xAA, is.read()); assertEquals(0xBB, is.read()); assertEquals(0xCC, is.read()); assertEquals(0xDD, is.read()); assertEquals(-1, is.read()); assertEquals("CA6FFBF95B47864FD4E73F2601326304", is.getDigestHex()); } } @Test public void testReadArray() throws Exception { byte[] data = new byte[] { (byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD }; try (Md5DigestInputStream is = new Md5DigestInputStream(new ByteArrayInputStream(data))) { byte[] buff = new byte[5]; assertEquals(4, is.read(buff)); assertEquals(-1, is.read()); for (int i = 0; i < data.length; i++) { assertEquals(data[i], buff[i]); } assertEquals("CA6FFBF95B47864FD4E73F2601326304", is.getDigestHex()); } } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/SourceLoaderFactoryTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.*; import static org.mockito.Mockito.when; import java.io.File; import java.util.Arrays; import java.util.Collections; import org.apache.maven.project.MavenProject; import org.eluder.coveralls.maven.plugin.source.SourceLoader; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class SourceLoaderFactoryTest { @Rule public TemporaryFolder folder = new TemporaryFolder(); @Mock private MavenProject root; @Mock private MavenProject m1; @Mock private MavenProject m2; private File rootSources; private File m1Sources; private File m2Sources; @Before public void init() throws Exception { rootSources = new File(folder.getRoot(), "src"); m1Sources = folder.newFolder("m1", "src"); m2Sources = folder.newFolder("m2", "src"); when(root.getCollectedProjects()).thenReturn(Arrays.asList(m1, m2)); when(m1.getCollectedProjects()).thenReturn(Collections.emptyList()); when(m2.getCollectedProjects()).thenReturn(Collections.emptyList()); when(root.getCompileSourceRoots()).thenReturn(Arrays.asList(rootSources.getAbsolutePath())); when(m1.getCompileSourceRoots()).thenReturn(Arrays.asList(m1Sources.getAbsolutePath())); when(m2.getCompileSourceRoots()).thenReturn(Arrays.asList(m2Sources.getAbsolutePath())); } @Test public void testCreateSourceLoader() throws Exception { SourceLoader sourceLoader = createSourceLoaderFactory("UTF-8").createSourceLoader(); assertNotNull(sourceLoader); } @Test public void testCreateSourceLoaderWithAdditionalSourceDirectories() throws Exception { File s1 = new File(folder.getRoot(), "s1"); File s2 = folder.newFolder("s2"); SourceLoader sourceLoader = createSourceLoaderFactory("UTF-8") .withSourceDirectories(Arrays.asList(s1, s2)) .createSourceLoader(); assertNotNull(sourceLoader); } @Test public void testCreateSourceLoaderWithScanForSources() throws Exception { SourceLoader sourceLoader = createSourceLoaderFactory("UTF-8") .withScanForSources( true ) .createSourceLoader(); assertNotNull(sourceLoader); } @Test public void testCreateSourceLoaderInvalidDirectory() throws Exception { File file = new File(folder.getRoot(), "aFile"); file.createNewFile(); SourceLoader sourceLoader = createSourceLoaderFactory("UTF-8") .withSourceDirectories(Arrays.asList(file)) .withScanForSources(true) .createSourceLoader(); assertNotNull(sourceLoader); } private SourceLoaderFactory createSourceLoaderFactory(String sourceEncoding) { return new SourceLoaderFactory(folder.getRoot(), root, sourceEncoding); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/TestIoUtil.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.security.NoSuchAlgorithmException; import org.apache.commons.codec.digest.DigestUtils; import org.codehaus.plexus.util.IOUtil; public class TestIoUtil { public static void writeFileContent(final String content, final File file) throws FileNotFoundException { PrintWriter writer = new PrintWriter(file); try { writer.write(content); } finally { IOUtil.close(writer); } } public static String readFileContent(final File file) throws IOException { InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")); try { return IOUtil.toString(reader); } finally { IOUtil.close(reader); } } public static File getFile(final String resource) { try { String local = resource; if (local.lastIndexOf("/") > 0) { local = local.substring(local.lastIndexOf('/')); } if (!local.startsWith("/")) { local = "/" + local; } return new File(getResourceUrl(local).toURI()); } catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); } } public static String getMd5DigestHex(final String content) throws NoSuchAlgorithmException { return DigestUtils.md5Hex(content).toUpperCase(); } private static URL getResourceUrl(final String resource) { return TestIoUtil.class.getResource(resource); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/TimestampParserTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.eluder.coveralls.maven.plugin.ProcessingException; import org.junit.Test; import java.text.SimpleDateFormat; import java.util.Date; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; public class TimestampParserTest { @Test(expected = IllegalArgumentException.class) public void testInvalidFormat() { new TimestampParser("scsscdfsd"); } @Test public void testParseEpochMillis() throws Exception { String format = TimestampParser.EPOCH_MILLIS; long time = System.currentTimeMillis(); Date parsed = new TimestampParser(format).parse(String.valueOf(time)); assertEquals(time, parsed.getTime()); } @Test public void testParseSimpleFormat() throws Exception { String format = "yyyy-MM-dd"; Date parsed = new TimestampParser(format).parse("2015-08-20"); String formatted = new SimpleDateFormat(format).format(parsed); assertEquals("2015-08-20", formatted); } @Test public void testParseDefaultFormat() throws Exception { String format = TimestampParser.DEFAULT_FORMAT; Date parsed = new TimestampParser(null).parse("2015-08-20T20:10:00Z"); String formatted = new SimpleDateFormat(format).format(parsed); assertEquals("2015-08-20T20:10:00Z", formatted); } @Test public void testParseNull() throws Exception { Date parsed = new TimestampParser(null).parse(null); assertNull(parsed); } @Test(expected = ProcessingException.class) public void testParseInvalidTimestamp() throws Exception { new TimestampParser(null).parse("2015-08-20"); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/UrlUtilsTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Test; import java.net.URI; import java.net.URL; import static org.junit.Assert.assertEquals; public class UrlUtilsTest { @Test(expected = IllegalArgumentException.class) public void testCreateInvalidUrl() throws Exception { UrlUtils.create("sdfds"); } @Test public void testCreateValidUrl() throws Exception { assertEquals("http://example.org", UrlUtils.create("http://example.org").toURI().toASCIIString()); } @Test(expected = IllegalArgumentException.class) public void testInvalidUrlToUri() throws Exception { UrlUtils.toUri(new URL("http://google.com?q=s|r")); } @Test public void testValidUrlToUri() throws Exception { URI uri = UrlUtils.toUri(new URL("http://google.com")); assertEquals(new URI("http://google.com"), uri); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/util/WildcardsTest.java ================================================ package org.eluder.coveralls.maven.plugin.util; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class WildcardsTest { @Test public void testMatchesAgainstNull() throws Exception { assertFalse(Wildcards.matches(null, "*")); } @Test public void testMatchesAgainstJoker() throws Exception { assertTrue(Wildcards.matches("a", "?")); } @Test public void testMatchesAgainstStar() throws Exception { assertTrue(Wildcards.matches("abc", "*")); } @Test public void testMatchesAgainstWildcards() throws Exception { assertTrue(Wildcards.matches("abcdefg", "a*d??g")); assertFalse(Wildcards.matches("abcdefg", "a*d?g?")); } @Test public void testMatchesAgainstText() throws Exception { assertTrue(Wildcards.matches("abc", "abc")); assertFalse(Wildcards.matches("abc", "cba")); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/validation/JobValidatorTest.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import org.eluder.coveralls.maven.plugin.domain.Git; import org.eluder.coveralls.maven.plugin.domain.Git.Head; import org.eluder.coveralls.maven.plugin.domain.Job; import org.eluder.coveralls.maven.plugin.validation.ValidationError.Level; import org.junit.Test; public class JobValidatorTest { @Test(expected = IllegalArgumentException.class) public void testMissingJob() { new JobValidator(null); } @Test public void testValidateWithoutRepoTokenOrTravis() { ValidationErrors errors = new JobValidator(new Job()).validate(); assertThat(errors, hasSize(1)); assertThat(errors.get(0).getLevel(), is(Level.ERROR)); } @Test public void testValidateWithoutRepoTokenOrTravisForDryRun() { ValidationErrors errors = new JobValidator(new Job().withDryRun(true)).validate(); assertThat(errors, hasSize(1)); assertThat(errors.get(0).getLevel(), is(Level.WARN)); } @Test public void testValidateWithInvalidTravis() { ValidationErrors errors = new JobValidator(new Job().withServiceName("travis-ci")).validate(); assertThat(errors, hasSize(1)); assertThat(errors.get(0).getLevel(), is(Level.ERROR)); } @Test public void testValidateWithRepoToken() { ValidationErrors errors = new JobValidator(new Job().withRepoToken("ad3fg5")).validate(); assertThat(errors, is(empty())); } @Test public void testValidateWithTravis() { ValidationErrors errors = new JobValidator(new Job().withServiceName("travis-ci").withServiceJobId("123")).validate(); assertThat(errors, is(empty())); } @Test public void testValidateWithoutGitCommitId() { Git git = new Git(null, new Head(null, null, null, null, null, null), null, null); ValidationErrors errors = new JobValidator(new Job().withRepoToken("ad3fg5").withGit(git)).validate(); assertThat(errors, hasSize(1)); assertThat(errors.get(0).getLevel(), is(Level.ERROR)); } @Test public void testValidateWithGit() { Git git = new Git(null, new Head("bc23af5", null, null, null, null, null), null, null); ValidationErrors errors = new JobValidator(new Job().withRepoToken("ad3fg5").withGit(git)).validate(); assertThat(errors, is(empty())); } @Test public void testValidateWithParallel() { ValidationErrors errors = new JobValidator(new Job().withRepoToken("ad3fg5").withParallel(true)).validate(); assertThat(errors, is(empty())); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/validation/ValidationErrorTest.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import org.eluder.coveralls.maven.plugin.validation.ValidationError.Level; import org.junit.Test; public class ValidationErrorTest { @Test(expected = IllegalArgumentException.class) public void testMissingLevel() { new ValidationError(null, "message"); } @Test(expected = IllegalArgumentException.class) public void testMissingMessage() { new ValidationError(Level.ERROR, null); } @Test public void testToString() { ValidationError error = new ValidationError(Level.WARN, "message"); assertEquals("WARN: message", error.toString()); } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/validation/ValidationErrorsTest.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.mockito.Matchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import org.apache.maven.plugin.logging.Log; import org.eluder.coveralls.maven.plugin.validation.ValidationError.Level; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ValidationErrorsTest { @Mock private Log logMock; @Test(expected = ValidationException.class) public void testThrowOrInformWithError() { createValidationErrors(new ValidationError(Level.ERROR, "message")).throwOrInform(logMock); } @Test public void testThrowOrInformWithWarnings() { createValidationErrors(new ValidationError(Level.WARN, "error1"), new ValidationError(Level.WARN, "error2")).throwOrInform(logMock); verify(logMock, times(2)).warn(any(CharSequence.class)); } private ValidationErrors createValidationErrors(final ValidationError... errors) { ValidationErrors validationErrors = new ValidationErrors(); for (ValidationError error : errors) { validationErrors.add(error); } return validationErrors; } } ================================================ FILE: src/test/java/org/eluder/coveralls/maven/plugin/validation/ValidationExceptionTest.java ================================================ package org.eluder.coveralls.maven.plugin.validation; /* * #[license] * coveralls-maven-plugin * %% * Copyright (C) 2013 - 2016 Tapio Rautonen * %% * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * %[license] */ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import org.junit.Test; public class ValidationExceptionTest { private static final String MESSAGE = "message"; private static final RuntimeException CAUSE = new RuntimeException(); @Test public void testException() { ValidationException exception = new ValidationException(); assertNull(exception.getMessage()); assertNull(exception.getCause()); } @Test public void testExceptionWithMessage() { ValidationException exception = new ValidationException(MESSAGE); assertEquals(MESSAGE, exception.getMessage()); assertNull(exception.getCause()); } @Test public void testExceptionWithCause() { ValidationException exception = new ValidationException(CAUSE); assertEquals(CAUSE.toString(), exception.getMessage()); assertSame(CAUSE, exception.getCause()); } @Test public void testExceptionWithMessageAndCause() { ValidationException exception = new ValidationException(MESSAGE, CAUSE); assertEquals(MESSAGE, exception.getMessage()); assertSame(CAUSE, exception.getCause()); } } ================================================ FILE: src/test/resources/Components.js ================================================ (function() { this.Components = {}; }).call(this); ================================================ FILE: src/test/resources/InnerClassCoverage.java ================================================ package org.eluder.coverage.sample; public class InnerClassCoverage { public void anonymous() { InnerClass i = new InnerClass() { @Override public void run() { System.out.println("overridden"); } }; i.run(); } public boolean delegate() { return new InnerClass().isInner(); } public static class InnerClass { public boolean isInner() { return true; } public void run() { System.out.println("run"); } } } ================================================ FILE: src/test/resources/Localization.js ================================================ (function() { var Localization; Localization = (function() { function Localization(values) { this.values = values; } Localization.prototype.byKey = function(key) { return this.values[key]; }; return Localization; })(); }).call(this); ================================================ FILE: src/test/resources/PartialCoverage.java ================================================ package org.eluder.coverage.sample; public class PartialCoverage { public void partial(boolean test) { if (test) { System.out.println("test"); } else { System.out.println("not test"); } } } ================================================ FILE: src/test/resources/SimpleCoverage.java ================================================ package org.eluder.coverage.sample; public class SimpleCoverage { public boolean isTested() { return false; } public void neverRun() { System.out.println("oops"); } } ================================================ FILE: src/test/resources/cobertura.xml ================================================ sample/module1/src/main/java sample/module2/src/main/java ================================================ FILE: src/test/resources/jacoco1.xml ================================================ ================================================ FILE: src/test/resources/jacoco2-it.xml ================================================ ================================================ FILE: src/test/resources/jacoco2.xml ================================================ ================================================ FILE: src/test/resources/saga.xml ================================================ coveralls-maven-plugin/sample/module1