Added option of multiple test base classes
without this change the user was forced to use a single base class for all of the generated tests. It could become problematic after some time. With this change we provide a range of options of providing different base classes for different contracts. fixes #16
This commit is contained in:
@@ -818,4 +818,9 @@ and contracts present under the `com/example/server` will be picked as the ones
|
||||
tests and the stubs. Due to this convention the producer team will know which consumer teams will be broken
|
||||
when some incompatible changes are done.
|
||||
|
||||
The rest of the flow looks the same.
|
||||
The rest of the flow looks the same.
|
||||
|
||||
===== Can I have multiple base classes for tests?
|
||||
|
||||
Yes! Check out the https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#different_base_classes_for_contracts[Different base classes for contracts] sections
|
||||
of either Gradle or Maven plugins.
|
||||
@@ -182,7 +182,9 @@ contracts {
|
||||
- **imports** - array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default empty array []
|
||||
- **staticImports** - array with static imports that should be included in generated tests(for example ['org.myorg.Matchers.*']). By default empty array []
|
||||
- **basePackageForTests** - specifies base package for all generated tests. By default set to org.springframework.cloud.verifier.tests
|
||||
- **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests.
|
||||
- **baseClassForTests** - base class for all generated tests. By default `spock.lang.Specification` if using Spock tests.
|
||||
- **packageWithBaseClasses** - instead of providing a fixed value for base class you can provide a package where all the base classes lay. Takes precedence over **baseClassForTests**.
|
||||
- **baseClassMappings** - explicitly map contract package to a FQN of a base class. Takes precedence over **packageWithBaseClasses** and **baseClassForTests**.
|
||||
- **ruleClassForTests** - specifies Rule which should be added to generated test classes.
|
||||
- **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array []
|
||||
- **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/resources/contracts`
|
||||
@@ -196,7 +198,7 @@ The following properties are used when you want to provide where the JAR with co
|
||||
- **contractsPath** - if contract deps are downloaded will default to `groupid/artifactid` where `groupid` will be slash separated. Otherwise will scan contracts under provided directory
|
||||
- **contractsWorkOffline** - in order not to download the dependencies each time you can download them once and work offline afterwards (reuse local Maven repo)
|
||||
|
||||
====== Base class for tests
|
||||
====== Single base class for all tests
|
||||
|
||||
When using Spring Cloud Contract Verifier in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified.
|
||||
|
||||
@@ -208,6 +210,43 @@ include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/resources/f
|
||||
In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class
|
||||
should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server.
|
||||
|
||||
====== Different base classes for contracts
|
||||
|
||||
If your base classes differ between contracts you can tell the Spring Cloud Contract plugin which class should get
|
||||
extended by the autogenerated tests. You have two options:
|
||||
|
||||
- follow a convention by providing the `packageWithBaseClasses`
|
||||
- provide explicit mapping via `baseClassMappings`
|
||||
|
||||
*Convention*
|
||||
|
||||
The convention is such that if you have a contract under e.g. `src/test/resources/contract/foo/bar/baz/` and provide the value of the `packageWithBaseClasses` property
|
||||
to `com.example.base` then we will assume that there is a `BarBazBase` class under `com.example.base` package. In other words we take last two parts of package
|
||||
if they exist and form a class with a `Base` suffix. Takes precedence over **baseClassForTests**. Example of usage in the `contracts` closure:
|
||||
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy[tags=package_with_base_classes,indent=0]
|
||||
----
|
||||
|
||||
*Mapping*
|
||||
|
||||
You can manually map a regular expression of the contract's package to fully qualified name of the base class for the matched contract.
|
||||
Let's take a look at the following example:
|
||||
|
||||
[source,groovy,indent=0]
|
||||
----
|
||||
include::{plugins_path}/spring-cloud-contract-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierSpec.groovy[tags=base_class_mappings,indent=0]
|
||||
----
|
||||
|
||||
Let's assume that you have contracts under
|
||||
- `src/test/resources/contract/com/`
|
||||
- `src/test/resources/contract/foo/`
|
||||
|
||||
By providing the `baseClassForTests` we have a fallback in case mapping didn't succeed (you could also provide
|
||||
the `packageWithBaseClasses` as fallback). That way the tests generated from `src/test/resources/contract/com/` contracts
|
||||
will be extending the `com.example.ComBase` whereas the rest of tests will extend `com.example.FooBase`.
|
||||
|
||||
===== Invoking generated tests
|
||||
|
||||
To ensure that provider side is complaint with defined contracts, you need to invoke:
|
||||
@@ -341,6 +380,15 @@ To change default configuration just add `configuration` section to plugin defin
|
||||
- **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests.
|
||||
- **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/resources/contracts`.
|
||||
- **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework
|
||||
- **packageWithBaseClasses** - instead of providing a fixed value for base class you can provide a package where all the base classes lay.
|
||||
The convention is such that if you have a contract under `src/test/resources/contract/foo/bar/baz/` and provide the value of this property
|
||||
to `com.example.base` then we will assume that there is a `BarBazBase` class under `com.example.base` package. Takes precedence
|
||||
over **baseClassForTests**
|
||||
- **baseClassMappings** - list of base class mappings that where you have to provide `contractPackageRegex` which is checked
|
||||
against the package in which the contract lays and `baseClassFQN` that maps to fully qualified name of the base class for the matched
|
||||
contract. If you have a contract under `src/test/resources/contract/foo/bar/baz/` and map the property `.*` -> `com.example.base.BaseClass` then
|
||||
the test class generated from these contracts will extend `com.example.base.BaseClass`. Takes precedence over **packageWithBaseClasses**
|
||||
and **baseClassForTests**.
|
||||
|
||||
If you want to download your contract definitions from a Maven repository you can use
|
||||
|
||||
@@ -351,7 +399,7 @@ If you want to download your contract definitions from a Maven repository you ca
|
||||
|
||||
For complete information take a look at https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/plugin-info.html[Plugin Documentation]
|
||||
|
||||
====== Base class for tests
|
||||
====== Single base class for all tests
|
||||
|
||||
When using Spring Cloud Contract Verifier in default MockMvc you need to create a base specification for all generated acceptance tests.
|
||||
In this class you need to point to endpoint which should be verified.
|
||||
@@ -373,6 +421,44 @@ class MvcSpec extends Specification {
|
||||
|
||||
In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server.
|
||||
|
||||
====== Different base classes for contracts
|
||||
|
||||
If your base classes differ between contracts you can tell the Spring Cloud Contract plugin which class should get
|
||||
extended by the autogenerated tests. You have two options:
|
||||
|
||||
- follow a convention by providing the `packageWithBaseClasses`
|
||||
- provide explicit mapping via `baseClassMappings`
|
||||
|
||||
*Convention*
|
||||
|
||||
The convention is such that if you have a contract under e.g. `src/test/resources/contract/hello/v1/` and provide the value of the `packageWithBaseClasses` property
|
||||
to `hello` then we will assume that there is a `HelloV1Base` class under `hello` package. In other words we take last two parts of package
|
||||
if they exist and form a class with a `Base` suffix. Takes precedence over **baseClassForTests**. Example of usage in the `contracts` closure:
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include::{plugins_path}/spring-cloud-contract-maven-plugin/src/test/projects/basic-generated-baseclass/pom.xml[tags=convention,indent=0]
|
||||
----
|
||||
|
||||
*Mapping*
|
||||
|
||||
You can manually map a regular expression of the contract's package to fully qualified name of the base class for the matched contract.
|
||||
You have to provide a list `baseClassMappings` of `baseClassMapping` that takes a `contractPackageRegex` to `baseClassFQN` mapping.
|
||||
Let's take a look at the following example:
|
||||
|
||||
[source,xml,indent=0]
|
||||
----
|
||||
include::{plugins_path}/spring-cloud-contract-maven-plugin/src/test/projects/basic-baseclass-from-mappings/pom.xml[tags=mapping,indent=0]
|
||||
----
|
||||
|
||||
Let's assume that you have contracts under
|
||||
- `src/test/resources/contract/com/`
|
||||
- `src/test/resources/contract/foo/`
|
||||
|
||||
By providing the `baseClassForTests` we have a fallback in case mapping didn't succeed (you could also provide
|
||||
the `packageWithBaseClasses` as fallback). That way the tests generated from `src/test/resources/contract/com/` contracts
|
||||
will be extending the `com.example.ComBase` whereas the rest of tests will extend `com.example.FooBase`.
|
||||
|
||||
===== Invoking generated tests
|
||||
|
||||
Spring Cloud Contract Verifier Maven Plugin generates verification code into directory `/generated-test-sources/contractVerifier` and attach this directory to `testCompile` goal.
|
||||
|
||||
@@ -39,7 +39,7 @@ dependencyManagement {
|
||||
}
|
||||
|
||||
contracts {
|
||||
baseClassForTests = 'com.example.fraud.MvcTest'
|
||||
packageWithBaseClasses = 'com.example.fraud'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<baseClassForTests>com.example.fraud.MvcTest</baseClassForTests>
|
||||
<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- end::contract_maven_plugin[] -->
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
public class MvcTest {
|
||||
public class FraudBase {
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -39,7 +39,9 @@ ext {
|
||||
}
|
||||
|
||||
contracts {
|
||||
baseClassForTests = 'com.example.source.SensorSourceTestBase'
|
||||
baseClassMappings {
|
||||
baseClassMapping('.*', 'com.example.source.SensorSourceTestBase')
|
||||
}
|
||||
stubsOutputDir = stubsOutputDirRoot
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,12 @@
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<baseClassForTests>com.example.source.SensorSourceTestBase</baseClassForTests>
|
||||
<baseClassMappings>
|
||||
<baseClassMapping>
|
||||
<contractPackageRegex>.*</contractPackageRegex>
|
||||
<baseClassFQN>com.example.source.SensorSourceTestBase</baseClassFQN>
|
||||
</baseClassMapping>
|
||||
</baseClassMappings>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
@@ -112,11 +112,38 @@ class ContractVerifierExtension {
|
||||
*/
|
||||
boolean contractsWorkOffline
|
||||
|
||||
/**
|
||||
* A package that contains all the base clases for generated tests. If your contract resides in a location
|
||||
* {@code src/test/resources/contracts/com/example/v1/} and you provide the {@code packageWithBaseClasses}
|
||||
* value to {@code com.example.contracts.base} then we will search for a test source file that will
|
||||
* have the package {@code com.example.contracts.base} and name {@code ExampleV1Base}. As you can see
|
||||
* it will take the two last folders to and attach {@code Base} to its name.
|
||||
*/
|
||||
String packageWithBaseClasses
|
||||
|
||||
/**
|
||||
* A way to override any base class mappings. The keys are regular expressions on the package name
|
||||
* and the values FQN to a base class for that given expression.
|
||||
* </p>
|
||||
* Example of a mapping
|
||||
* </p>
|
||||
* {@code .*.com.example.v1..*} -> {@code com.example.SomeBaseClass}
|
||||
* </p>
|
||||
* When a contract's package matches the provided regular expression then extending class will be the one
|
||||
* provided in the map - in this case {@code com.example.SomeBaseClass}
|
||||
*/
|
||||
Map<String, String> baseClassMappings = [:]
|
||||
|
||||
void contractDependency(@DelegatesTo(Dependency) Closure closure) {
|
||||
closure.delegate = contractDependency
|
||||
closure.call()
|
||||
}
|
||||
|
||||
void baseClassMappings(@DelegatesTo(BaseClassMapping) Closure closure) {
|
||||
closure.delegate = new BaseClassMapping(baseClassMappings)
|
||||
closure.call()
|
||||
}
|
||||
|
||||
static class Dependency {
|
||||
String groupId
|
||||
String artifactId
|
||||
@@ -124,4 +151,20 @@ class ContractVerifierExtension {
|
||||
String version
|
||||
String stringNotation
|
||||
}
|
||||
|
||||
static class BaseClassMapping {
|
||||
private final Map<String, String> delegate
|
||||
|
||||
BaseClassMapping(Map<String, String> delegate) {
|
||||
this.delegate = delegate
|
||||
}
|
||||
|
||||
void baseClassMapping(String packageRegex, String fqnBaseClass) {
|
||||
this.delegate[packageRegex] = fqnBaseClass
|
||||
}
|
||||
|
||||
void baseClassMapping(Map mapping) {
|
||||
this.delegate.putAll(mapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@ class ExtensionToProperties {
|
||||
generatedTestSourcesDir: extension.generatedTestSourcesDir,
|
||||
stubsOutputDir: extension.stubsOutputDir,
|
||||
stubsSuffix: extension.stubsSuffix,
|
||||
assertJsonSize: extension.assertJsonSize
|
||||
assertJsonSize: extension.assertJsonSize,
|
||||
packageWithBaseClasses: extension.packageWithBaseClasses,
|
||||
baseClassMappings: extension.baseClassMappings
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ abstract class ContractVerifierIntegrationSpec extends Specification {
|
||||
|
||||
public static final String SPOCK = "targetFramework = 'Spock'"
|
||||
public static final String JUNIT = "targetFramework = 'JUnit'"
|
||||
public static final String MVC_SPEC = "baseClassForTests = 'org.springframework.cloud.MvcSpec'"
|
||||
public static final String MVC_TEST = "baseClassForTests = 'org.springframework.cloud.MvcTest'"
|
||||
public static final String MVC_SPEC = "'org.springframework.cloud.MvcSpec'"
|
||||
public static final String MVC_TEST = "'org.springframework.cloud.MvcTest'"
|
||||
protected static final boolean WORK_OFFLINE = Boolean.parseBoolean(System.getProperty('WORK_OFFLINE', 'false'))
|
||||
|
||||
File testProjectDir
|
||||
|
||||
@@ -138,4 +138,25 @@ class ContractVerifierSpec extends Specification {
|
||||
it.group == "org.assertj" && it.name == "assertj-core"
|
||||
} != null
|
||||
}
|
||||
|
||||
def "should compile"() {
|
||||
given:
|
||||
ContractVerifierExtension extension = new ContractVerifierExtension()
|
||||
extension.with {
|
||||
|
||||
// tag::package_with_base_classes[]
|
||||
packageWithBaseClasses = 'com.example.base'
|
||||
// end::package_with_base_classes[]
|
||||
|
||||
// tag::base_class_mappings[]
|
||||
baseClassForTests = "com.example.FooBase"
|
||||
baseClassMappings {
|
||||
baseClassMapping('.*/com/.*', 'com.example.ComBase')
|
||||
baseClassMapping('.*/bar/.*':'com.example.BarBase')
|
||||
}
|
||||
// end::base_class_mappings[]
|
||||
}
|
||||
expect:
|
||||
extension
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,12 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService')
|
||||
targetFramework = 'Spock'
|
||||
// end::target_framework[]
|
||||
testMode = 'MockMvc'
|
||||
baseClassForTests = 'org.springframework.cloud.MvcSpec'
|
||||
//baseClassForTests = 'org.springframework.cloud.MvcSpec'
|
||||
// tag::base_class_mapping[]
|
||||
baseClassMappings {
|
||||
baseClassMapping('.*', 'org.springframework.cloud.MvcSpec')
|
||||
}
|
||||
// end::base_class_mapping[]
|
||||
contractsDslDir = file("${project.projectDir.absolutePath}/mappings/")
|
||||
generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/")
|
||||
stubsOutputDir = stubsOutputDirRoot
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.springframework.cloud.contract.maven.verifier;
|
||||
|
||||
/**
|
||||
* Represents a single mapping of regex on package where contracts reside
|
||||
* to the FQN of the base test class
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class BaseClassMapping {
|
||||
|
||||
private String contractPackageRegex;
|
||||
|
||||
private String baseClassFQN;
|
||||
|
||||
public String getContractPackageRegex() {
|
||||
return this.contractPackageRegex;
|
||||
}
|
||||
|
||||
public void setContractPackageRegex(String contractPackageRegex) {
|
||||
this.contractPackageRegex = contractPackageRegex;
|
||||
}
|
||||
|
||||
public String getBaseClassFQN() {
|
||||
return this.baseClassFQN;
|
||||
}
|
||||
|
||||
public void setBaseClassFQN(String baseClassFQN) {
|
||||
this.baseClassFQN = baseClassFQN;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
BaseClassMapping that = (BaseClassMapping) o;
|
||||
if (this.contractPackageRegex != null ?
|
||||
!this.contractPackageRegex.equals(that.contractPackageRegex) :
|
||||
that.contractPackageRegex != null)
|
||||
return false;
|
||||
return this.baseClassFQN != null ?
|
||||
this.baseClassFQN.equals(that.baseClassFQN) :
|
||||
that.baseClassFQN == null;
|
||||
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int result = this.contractPackageRegex != null ? this.contractPackageRegex.hashCode() : 0;
|
||||
result = 31 * result + (this.baseClassFQN != null ? this.baseClassFQN.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,6 @@ public class ConvertMojo extends AbstractMojo {
|
||||
new CopyContracts(this.project, this.mavenSession, this.mavenResourcesFiltering)
|
||||
.copy(contractsDirectory, this.outputDirectory);
|
||||
|
||||
|
||||
config.setContractsDslDir(isInsideProject() ? contractsDirectory : this.source);
|
||||
config.setStubsOutputDir(
|
||||
isInsideProject() ? new File(this.outputDirectory, "mappings") : this.destination);
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
package org.springframework.cloud.contract.maven.verifier;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.maven.model.Dependency;
|
||||
@@ -140,6 +141,30 @@ public class GenerateTestsMojo extends AbstractMojo {
|
||||
@Parameter(property = "contractsWorkOffline", defaultValue = "false")
|
||||
private boolean contractsWorkOffline;
|
||||
|
||||
/**
|
||||
* A package that contains all the base clases for generated tests. If your contract resides in a location
|
||||
* {@code src/test/resources/contracts/com/example/v1/} and you provide the {@code packageWithBaseClasses}
|
||||
* value to {@code com.example.contracts.base} then we will search for a test source file that will
|
||||
* have the package {@code com.example.contracts.base} and name {@code ExampleV1Base}. As you can see
|
||||
* it will take the two last folders to and attach {@code Base} to its name.
|
||||
*/
|
||||
@Parameter(property = "packageWithBaseClasses")
|
||||
private String packageWithBaseClasses;
|
||||
|
||||
/**
|
||||
* A way to override any base class mappings. The keys are regular expressions on the package name of the contract
|
||||
* and the values FQN to a base class for that given expression.
|
||||
* </p>
|
||||
* Example of a mapping
|
||||
* </p>
|
||||
* {@code .*.com.example.v1..*} -> {@code com.example.SomeBaseClass}
|
||||
* </p>
|
||||
* When a contract's package matches the provided regular expression then extending class will be the one
|
||||
* provided in the map - in this case {@code com.example.SomeBaseClass}
|
||||
*/
|
||||
@Parameter(property = "baseClassMappings")
|
||||
private List<BaseClassMapping> baseClassMappings;
|
||||
|
||||
private final AetherStubDownloaderFactory aetherStubDownloaderFactory;
|
||||
|
||||
@Inject
|
||||
@@ -175,6 +200,10 @@ public class GenerateTestsMojo extends AbstractMojo {
|
||||
config.setIgnoredFiles(this.ignoredFiles);
|
||||
config.setExcludedFiles(this.excludedFiles);
|
||||
config.setAssertJsonSize(this.assertJsonSize);
|
||||
config.setPackageWithBaseClasses(this.packageWithBaseClasses);
|
||||
if (this.baseClassMappings != null) {
|
||||
config.setBaseClassMappings(mappingsToMap());
|
||||
}
|
||||
this.project.addTestCompileSourceRoot(this.generatedTestSourcesDir.getAbsolutePath());
|
||||
if (getLog().isInfoEnabled()) {
|
||||
getLog().info(
|
||||
@@ -195,6 +224,17 @@ public class GenerateTestsMojo extends AbstractMojo {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> mappingsToMap() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (this.baseClassMappings == null) {
|
||||
return map;
|
||||
}
|
||||
for (BaseClassMapping mapping : this.baseClassMappings) {
|
||||
map.put(mapping.getContractPackageRegex(), mapping.getBaseClassFQN());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public List<String> getExcludedFiles() {
|
||||
return this.excludedFiles;
|
||||
}
|
||||
|
||||
@@ -162,4 +162,51 @@ public class PluginUnitTest {
|
||||
assertFilesPresent(basedir, "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/com/example/server/client1/ContractsTest.java");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateContractTestsWithBaseClassResolvedFromConvention() throws Exception {
|
||||
File basedir = this.resources.getBasedir("basic-generated-baseclass");
|
||||
|
||||
this.maven.executeMojo(basedir, "generateTests", newParameter("testFramework", "JUNIT"));
|
||||
|
||||
String path = "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/hello/V1Test.java";
|
||||
assertFilesPresent(basedir, path);
|
||||
File test = new File(basedir, path);
|
||||
then(FileUtils.readFileToString(test)).contains("extends HelloV1Base").contains("import hello.HelloV1Base");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateContractTestsWithBaseClassResolvedFromConventionForSpock() throws Exception {
|
||||
File basedir = this.resources.getBasedir("basic-generated-baseclass");
|
||||
|
||||
this.maven.executeMojo(basedir, "generateTests", newParameter("testFramework", "SPOCK"));
|
||||
|
||||
String path = "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/hello/V1Spec.groovy";
|
||||
assertFilesPresent(basedir, path);
|
||||
File test = new File(basedir, path);
|
||||
then(FileUtils.readFileToString(test)).contains("extends HelloV1Base").contains("import hello.HelloV1Base");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateContractTestsWithBaseClassResolvedFromMapping() throws Exception {
|
||||
File basedir = this.resources.getBasedir("basic-baseclass-from-mappings");
|
||||
|
||||
this.maven.executeMojo(basedir, "generateTests", newParameter("testFramework", "JUNIT"));
|
||||
|
||||
String path = "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/com/hello/V1Test.java";
|
||||
assertFilesPresent(basedir, path);
|
||||
File test = new File(basedir, path);
|
||||
then(FileUtils.readFileToString(test)).contains("extends TestBase").contains("import com.example.TestBase");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateContractTestsWithBaseClassResolvedFromMappingNameForSpock() throws Exception {
|
||||
File basedir = this.resources.getBasedir("basic-baseclass-from-mappings");
|
||||
|
||||
this.maven.executeMojo(basedir, "generateTests", newParameter("testFramework", "SPOCK"));
|
||||
|
||||
String path = "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/com/hello/V1Spec.groovy";
|
||||
assertFilesPresent(basedir, path);
|
||||
File test = new File(basedir, path);
|
||||
then(FileUtils.readFileToString(test)).contains("extends TestBase").contains("import com.example.TestBase");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright 2013-2016 the original author or authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud.verifier.sample</groupId>
|
||||
<artifactId>sample-project</artifactId>
|
||||
<version>0.1</version>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- tag::mapping[] -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<baseClassForTests>com.example.FooBase</baseClassForTests>
|
||||
<baseClassMappings>
|
||||
<baseClassMapping>
|
||||
<contractPackageRegex>.*com.*</contractPackageRegex>
|
||||
<baseClassFQN>com.example.TestBase</baseClassFQN>
|
||||
</baseClassMapping >
|
||||
</baseClassMappings>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- end::mapping[] -->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url('/users') {
|
||||
|
||||
}
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
body '''{ "login" : "john", "name": "John The Contract" }'''
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Location': '/users/john'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url('/users') {
|
||||
|
||||
}
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Location': '/users/john'
|
||||
}
|
||||
body '''{ "list" : [ "login", "john", "name", "John The Contract" ] }'''
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright 2013-2016 the original author or authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud.verifier.sample</groupId>
|
||||
<artifactId>sample-project</artifactId>
|
||||
<version>0.1</version>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- tag::convention[] -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<packageWithBaseClasses>hello</packageWithBaseClasses>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- tag::convention[] -->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url('/users') {
|
||||
|
||||
}
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
body '''{ "login" : "john", "name": "John The Contract" }'''
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Location': '/users/john'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
method 'POST'
|
||||
url('/users') {
|
||||
|
||||
}
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Location': '/users/john'
|
||||
}
|
||||
body '''{ "list" : [ "login", "john", "name", "John The Contract" ] }'''
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class TestGenerator {
|
||||
if (contracts.size()) {
|
||||
def className = afterLast(includedDirectoryRelativePath.toString(), File.separator) + resolveNameSuffix()
|
||||
def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath)
|
||||
def classBytes = generator.buildClass(contracts, className, packageName).getBytes(StandardCharsets.UTF_8)
|
||||
def classBytes = generator.buildClass(contracts, className, packageName, includedDirectoryRelativePath).getBytes(StandardCharsets.UTF_8)
|
||||
saver.saveClassFile(className, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath.toString()), classBytes)
|
||||
counter.incrementAndGet()
|
||||
}
|
||||
|
||||
@@ -57,16 +57,46 @@ class ClassBuilder {
|
||||
/**
|
||||
* Returns a {@link ClassBuilder} for the given parameters
|
||||
*/
|
||||
static ClassBuilder createClass(String className, String classPackage, ContractVerifierConfigProperties properties) {
|
||||
static ClassBuilder createClass(String className, String classPackage, ContractVerifierConfigProperties properties,
|
||||
String includedDirectoryRelativePath) {
|
||||
String baseClassForTests
|
||||
if (properties.targetFramework == TestFramework.SPOCK && !properties.baseClassForTests) {
|
||||
if (properties.targetFramework == TestFramework.SPOCK && !properties.baseClassForTests
|
||||
&& !properties.packageWithBaseClasses && !properties.baseClassMappings) {
|
||||
baseClassForTests = 'spock.lang.Specification'
|
||||
} else {
|
||||
baseClassForTests = properties.baseClassForTests
|
||||
baseClassForTests = retrieveBaseClass(properties, includedDirectoryRelativePath)
|
||||
}
|
||||
return new ClassBuilder(className, classPackage, baseClassForTests, properties.targetFramework)
|
||||
}
|
||||
|
||||
protected static String retrieveBaseClass(ContractVerifierConfigProperties properties, String includedDirectoryRelativePath) {
|
||||
String contractPackage = includedDirectoryRelativePath.replace(File.separator, '.')
|
||||
// package mapping takes super precedence
|
||||
if (properties.baseClassMappings) {
|
||||
Map.Entry<String, String> mapping = properties.baseClassMappings.find { String pattern, String fqn ->
|
||||
return contractPackage.matches(pattern)
|
||||
}
|
||||
if (mapping) {
|
||||
return mapping.value
|
||||
}
|
||||
}
|
||||
if (!properties.packageWithBaseClasses) {
|
||||
return properties.baseClassForTests
|
||||
}
|
||||
String generatedClassName = generateDefaultBaseClassName(contractPackage, properties)
|
||||
return "${generatedClassName}Base"
|
||||
}
|
||||
|
||||
private static String generateDefaultBaseClassName(String classPackage, ContractVerifierConfigProperties properties) {
|
||||
String[] splitPackage = classPackage.split("\\.")
|
||||
if (splitPackage.size() > 1) {
|
||||
String last = NamesUtil.capitalize(splitPackage[-1])
|
||||
String butLast = NamesUtil.capitalize(splitPackage[-2])
|
||||
return "${properties.packageWithBaseClasses}.${butLast}${last}"
|
||||
}
|
||||
return "${properties.packageWithBaseClasses}.${NamesUtil.capitalize(splitPackage[0])}"
|
||||
}
|
||||
|
||||
ClassBuilder addImport(String importToAdd) {
|
||||
imports << importToAdd
|
||||
return this
|
||||
|
||||
@@ -23,14 +23,12 @@ import groovy.util.logging.Slf4j
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.config.TestFramework
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode
|
||||
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode
|
||||
|
||||
import static ClassBuilder.createClass
|
||||
import static MethodBuilder.createTestMethod
|
||||
import static org.springframework.cloud.contract.verifier.util.NamesUtil.capitalize
|
||||
|
||||
/**
|
||||
* Builds a single test for the given {@link ContractVerifierConfigProperties properties}
|
||||
*
|
||||
@@ -53,8 +51,8 @@ class SingleTestGenerator {
|
||||
* each {@link ContractMetadata}
|
||||
*/
|
||||
@PackageScope
|
||||
String buildClass(Collection<ContractMetadata> listOfFiles, String className, String classPackage) {
|
||||
ClassBuilder clazz = createClass(capitalize(className), classPackage, configProperties)
|
||||
String buildClass(Collection<ContractMetadata> listOfFiles, String className, String classPackage, String includedDirectoryRelativePath) {
|
||||
ClassBuilder clazz = createClass(capitalize(className), classPackage, configProperties, includedDirectoryRelativePath)
|
||||
|
||||
if (configProperties.imports) {
|
||||
configProperties.imports.each {
|
||||
@@ -112,7 +110,7 @@ class SingleTestGenerator {
|
||||
}
|
||||
conditionalImportsAdded = true
|
||||
}
|
||||
clazz.addMethod(createTestMethod(key.contract, key.stubsFile, key.groovyDsl, configProperties))
|
||||
clazz.addMethod(MethodBuilder.createTestMethod(key.contract, key.stubsFile, key.groovyDsl, configProperties))
|
||||
}
|
||||
return clazz.build()
|
||||
}
|
||||
@@ -123,7 +121,7 @@ class SingleTestGenerator {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Stub content from file [${stubsFile.text}]")
|
||||
}
|
||||
org.springframework.cloud.contract.spec.Contract stubContent = ContractVerifierDslConverter.convert(stubsFile)
|
||||
Contract stubContent = ContractVerifierDslConverter.convert(stubsFile)
|
||||
TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP
|
||||
return [(new ParsedDsl(it, stubContent, stubsFile)): testType]
|
||||
}
|
||||
|
||||
@@ -109,4 +109,26 @@ class ContractVerifierConfigProperties {
|
||||
*/
|
||||
String includedContracts = ".*"
|
||||
|
||||
/**
|
||||
* A package that contains all the base clases for generated tests. If your contract resides in a location
|
||||
* {@code src/test/resources/contracts/com/example/v1/} and you provide the {@code packageWithBaseClasses}
|
||||
* value to {@code com.example.contracts.base} then we will search for a test source file that will
|
||||
* have the package {@code com.example.contracts.base} and name {@code ExampleV1Base}. As you can see
|
||||
* it will take the two last folders to and attach {@code Base} to its name.
|
||||
*/
|
||||
String packageWithBaseClasses
|
||||
|
||||
/**
|
||||
* A way to override any base class mappings. The keys are regular expressions on the package name of the contract
|
||||
* and the values FQN to a base class for that given expression.
|
||||
* </p>
|
||||
* Example of a mapping
|
||||
* </p>
|
||||
* {@code .*.com.example.v1..*} -> {@code com.example.SomeBaseClass}
|
||||
* </p>
|
||||
* When a contract's package matches the provided regular expression then extending class will be the one
|
||||
* provided in the map - in this case {@code com.example.SomeBaseClass}
|
||||
*/
|
||||
Map<String, String> baseClassMappings
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class GeneratorScannerSpec extends Specification {
|
||||
when:
|
||||
testGenerator.generateTestClasses("org.springframework.cloud.contract.verifier")
|
||||
then:
|
||||
6 * classGenerator.buildClass(_, _, _) >> "qwerty"
|
||||
6 * classGenerator.buildClass(_, _, _, _) >> "qwerty"
|
||||
}
|
||||
|
||||
def "should create class with full package"() {
|
||||
@@ -45,9 +45,9 @@ class GeneratorScannerSpec extends Specification {
|
||||
when:
|
||||
testGenerator.generateTestClasses("org.springframework.cloud.contract.verifier")
|
||||
then:
|
||||
1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier') >> "spec"
|
||||
1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier.v1') >> "spec1"
|
||||
1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier.v2') >> "spec2"
|
||||
1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier', _) >> "spec"
|
||||
1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier.v1', _) >> "spec1"
|
||||
1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier.v2', _) >> "spec2"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.springframework.cloud.contract.verifier.builder
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import spock.lang.Specification
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class ClassBuilderSpec extends Specification {
|
||||
|
||||
def "should return explicit base class if provided and no default package for base classes is provided"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties props = new ContractVerifierConfigProperties(baseClassForTests: 'a.b.Class')
|
||||
expect:
|
||||
'a.b.Class' == ClassBuilder.retrieveBaseClass(props, 'com/example/foo')
|
||||
}
|
||||
|
||||
def "should return a class from the generated path by taking two last folders when package with base classes is provided"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties props = new ContractVerifierConfigProperties(packageWithBaseClasses: 'com.example.base')
|
||||
String contractRelativeFolder = 'com/example/some/superpackage'
|
||||
expect:
|
||||
ClassBuilder.retrieveBaseClass(props, contractRelativeFolder) == 'com.example.base.SomeSuperpackageBase'
|
||||
}
|
||||
|
||||
def "should return a class from the generated path by taking a single folder when package with base classes is provided and there are not enough package elements"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties props = new ContractVerifierConfigProperties(packageWithBaseClasses: 'com.example.base')
|
||||
String contractRelativeFolder = 'superpackage'
|
||||
expect:
|
||||
ClassBuilder.retrieveBaseClass(props, contractRelativeFolder) == 'com.example.base.SuperpackageBase'
|
||||
}
|
||||
|
||||
def "should return a class from mappings regardless of other entries if mapping exists"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties props = new ContractVerifierConfigProperties(
|
||||
packageWithBaseClasses: 'com.example.base',
|
||||
baseClassMappings: ['.*' : 'com.example.base.SuperClass'])
|
||||
String contractRelativeFolder = 'superpackage'
|
||||
expect:
|
||||
ClassBuilder.retrieveBaseClass(props, contractRelativeFolder) == 'com.example.base.SuperClass'
|
||||
}
|
||||
|
||||
def "should return the first matching base class when provided mapping doesn't match"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties props = new ContractVerifierConfigProperties(
|
||||
baseClassForTests: 'a.b.Class',
|
||||
packageWithBaseClasses: 'com.example.base',
|
||||
baseClassMappings: ['patternNotMatchingAnything' : 'com.example.base.SuperClass'])
|
||||
String contractRelativeFolder = 'superpackage'
|
||||
expect:
|
||||
ClassBuilder.retrieveBaseClass(props, contractRelativeFolder) == 'com.example.base.SuperpackageBase'
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
SingleTestGenerator testGenerator = new SingleTestGenerator(properties)
|
||||
|
||||
when:
|
||||
String clazz = testGenerator.buildClass([contract], "test", "test")
|
||||
String clazz = testGenerator.buildClass([contract], "test", "test", 'com/foo')
|
||||
|
||||
then:
|
||||
classStrings.each { clazz.contains(it) }
|
||||
@@ -90,7 +90,7 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
SingleTestGenerator testGenerator = new SingleTestGenerator(properties)
|
||||
|
||||
when:
|
||||
String clazz = testGenerator.buildClass([contract], "test", "test")
|
||||
String clazz = testGenerator.buildClass([contract], "test", "test", 'com/foo')
|
||||
|
||||
then:
|
||||
classStrings.each { clazz.contains(it) }
|
||||
@@ -133,7 +133,7 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
SingleTestGenerator testGenerator = new SingleTestGenerator(properties)
|
||||
|
||||
when:
|
||||
String clazz = testGenerator.buildClass([contract, contract2], "test", "test")
|
||||
String clazz = testGenerator.buildClass([contract, contract2], "test", "test", 'com/foo')
|
||||
|
||||
then:
|
||||
classStrings.each { clazz.contains(it) }
|
||||
|
||||
Reference in New Issue
Block a user