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:
@@ -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" ] }'''
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user