Allows to use multiple stub converters

with this change all available stub converters on the classpath will be executed to convert the contract. That way you can make such a flow pass:

- from DSL input
- generate Java tests
- produce WireMock stubs
- produce Pact files

fixes #194
This commit is contained in:
Marcin Grzejszczak
2017-01-16 16:23:27 +01:00
parent bb42e10842
commit bda72f136c
5 changed files with 78 additions and 21 deletions

View File

@@ -855,6 +855,9 @@ include::{converters_path}/src/main/resources/META-INF/spring.factories[indent=0
The default implementation is the WireMock stub generation.
TIP: You can provide multiple stub generator implementations. That way for example from a single
DSL as input you can e.g. produce WireMock stubs and Pact files too!
==== Custom Stub Runner
If you decide to have a custom stub generation you also need a custom way of running

View File

@@ -69,7 +69,7 @@ class RecursiveFilesConverter {
log.debug("Will create a stub for contract [${contract}]")
}
File sourceFile = contract.path.toFile()
StubGenerator stubGenerator = contract.convertedContract ? holder.firstOrDefault(new DslToWireMockClientConverter()) :
Collection<StubGenerator> stubGenerators = contract.convertedContract ? holder.allOrDefault(new DslToWireMockClientConverter()) :
holder.converterForName(sourceFile.name)
try {
String path = sourceFile.path
@@ -79,25 +79,27 @@ class RecursiveFilesConverter {
}
return
}
if (!contract.convertedContract && !stubGenerator) {
if (!contract.convertedContract && !stubGenerators) {
return
}
int contractsSize = contract.convertedContract.size()
def entryKey = entry.key
if (log.isDebugEnabled()) {
log.debug("Stub Generator [${stubGenerator}] will convert contents of [${entryKey}]")
log.debug("Stub Generators [${stubGenerators}] will convert contents of [${entryKey}]")
}
Map<Contract, String> convertedContent = stubGenerator.convertContents(entryKey.last().toString(), contract)
if (!convertedContent) {
return
}
convertedContent.entrySet().eachWithIndex { Map.Entry<Contract, String> content, int index ->
Contract dsl = content.key
String converted = content.value
Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile)
File newJsonFile = createTargetFileWithProperName(stubGenerator, absoluteTargetPath,
sourceFile, contractsSize, index, dsl)
newJsonFile.setText(converted, StandardCharsets.UTF_8.toString())
stubGenerators.each { StubGenerator stubGenerator ->
Map<Contract, String> convertedContent = stubGenerator.convertContents(entryKey.last().toString(), contract)
if (!convertedContent) {
return
}
convertedContent.entrySet().eachWithIndex { Map.Entry<Contract, String> content, int index ->
Contract dsl = content.key
String converted = content.value
Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile)
File newJsonFile = createTargetFileWithProperName(stubGenerator, absoluteTargetPath,
sourceFile, contractsSize, index, dsl)
newJsonFile.setText(converted, StandardCharsets.UTF_8.toString())
}
}
} catch (Exception e) {
throw new ConversionContractVerifierException("Unable to make conversion of ${sourceFile.name}", e)

View File

@@ -22,11 +22,11 @@ class StubGeneratorProvider {
this.converters.addAll(converters)
}
StubGenerator converterForName(String fileName) {
return this.converters.find { it.canHandleFileName(fileName) }
Collection<StubGenerator> converterForName(String fileName) {
return this.converters.findAll { it.canHandleFileName(fileName) }
}
StubGenerator firstOrDefault(StubGenerator defaultStubGenerator) {
return this.converters.empty ? defaultStubGenerator : this.converters.first()
Collection<StubGenerator> allOrDefault(StubGenerator defaultStubGenerator) {
return this.converters.empty ? [defaultStubGenerator] : this.converters
}
}

View File

@@ -86,7 +86,7 @@ class RecursiveFilesConverter {
contracts.asMap().entrySet().each { entry ->
entry.value.each { ContractMetadata contract ->
File sourceFile = contract.path.toFile()
StubGenerator stubGenerator = holder.converterForName(sourceFile.name);
StubGenerator stubGenerator = holder.converterForName(sourceFile.name).first()
try {
String path = sourceFile.path
if (properties.isExcludeBuildFolders() && (matchesPath(path, "target") || matchesPath(path, "build"))) {

View File

@@ -19,7 +19,9 @@ package org.springframework.cloud.contract.verifier.converter
import groovy.io.FileType
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.util.FileSystemUtils
import spock.lang.Specification
@@ -98,12 +100,62 @@ class RecursiveFilesConverterSpec extends Specification {
e.cause?.message == "Test conversion error"
}
private
static Set<Path> getRelativePathsForFilesInDirectory(Collection<File> createdFiles, File targetRootDirectory) {
def "should convert contract into stub using all possible converters"() {
given:
def sourceFile = tmpFolder.newFile("test.groovy")
sourceFile.text = """
org.springframework.cloud.contract.spec.Contract.make {
request {
url "/baz"
method "GET"
}
response {
status 200
}
}
"""
and:
StubGenerator stubGenerator1 = stubGenerator("foo")
and:
StubGenerator stubGenerator2 = stubGenerator("bar")
and:
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
properties.contractsDslDir = tmpFolder.root
properties.stubsOutputDir = tmpFolder.root
and:
RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(properties, new StubGeneratorProvider([stubGenerator1, stubGenerator2]))
when:
recursiveFilesConverter.processFiles()
then:
tmpFolder.root.list().toList().containsAll("foo", "bar")
}
private static Set<Path> getRelativePathsForFilesInDirectory(Collection<File> createdFiles, File targetRootDirectory) {
Path rootSourcePath = Paths.get(targetRootDirectory.toURI())
Set<Path> relativizedCreatedFiles = createdFiles.collect { File file ->
rootSourcePath.relativize(Paths.get(file.toURI()))
}
return relativizedCreatedFiles
}
private StubGenerator stubGenerator(String stub) {
return new StubGenerator() {
@Override
boolean canHandleFileName(String fileName) {
return true
}
@Override
Map<Contract, String> convertContents(String rootName, ContractMetadata content) {
return [
(content.convertedContract.first()) : stub
]
}
@Override
String generateOutputFileNameForInput(String inputFileName) {
return stub
}
}
}
}