Fixed the way package and class names are generated
with the new layout of contracts and stubs the package name was improperly generated (for chars like +, or digits) with this change we're converting those chars to _ fixes #276
This commit is contained in:
@@ -42,7 +42,6 @@ class FileSaver {
|
||||
}
|
||||
|
||||
void saveClassFile(String fileName, String basePackageClass, String includedDirectoryRelativePath, byte[] classBytes) {
|
||||
|
||||
Path testBaseDir = Paths.get(targetDirectory.absolutePath, packageToDirectory(basePackageClass),
|
||||
beforeLast(includedDirectoryRelativePath, File.separator))
|
||||
Files.createDirectories(testBaseDir)
|
||||
|
||||
@@ -87,9 +87,10 @@ class TestGenerator {
|
||||
final String includedDirectoryRelativePath, Collection<ContractMetadata> contracts, final String basePackageNameForClass) {
|
||||
if (contracts.size()) {
|
||||
def className = afterLast(includedDirectoryRelativePath.toString(), File.separator) + resolveNameSuffix()
|
||||
def convertedClassName = convertIllegalPackageChars(className)
|
||||
def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath)
|
||||
def classBytes = generator.buildClass(contracts, className, packageName, includedDirectoryRelativePath).getBytes(StandardCharsets.UTF_8)
|
||||
saver.saveClassFile(className, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath.toString()), classBytes)
|
||||
def classBytes = generator.buildClass(contracts, convertedClassName, packageName, includedDirectoryRelativePath).getBytes(StandardCharsets.UTF_8)
|
||||
saver.saveClassFile(convertedClassName, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath.toString()), classBytes)
|
||||
counter.incrementAndGet()
|
||||
}
|
||||
}
|
||||
@@ -98,9 +99,10 @@ class TestGenerator {
|
||||
return configProperties.nameSuffixForTests ?: configProperties.targetFramework.classNameSuffix
|
||||
}
|
||||
|
||||
private static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) {
|
||||
protected static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) {
|
||||
String directory = beforeLast(includedDirectoryRelativePath, File.separator)
|
||||
return !directory.empty ? "$packageNameForClass.${directoryToPackage(convertIllegalPackageChars(directory))}" : packageNameForClass
|
||||
String convertedPackage = "$packageNameForClass.${directoryToPackage(convertIllegalPackageChars(directory))}"
|
||||
return !directory.empty ? convertedPackage : packageNameForClass
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,13 +99,16 @@ class NamesUtil {
|
||||
* Converts the path format to a Java package notation
|
||||
*/
|
||||
static String directoryToPackage(String directory) {
|
||||
return directory.replace(File.separator, '.')
|
||||
return directory
|
||||
.replace('.', '_')
|
||||
.replace(File.separator, '.')
|
||||
.replaceAll('\\.([0-9])', '._$1')
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts illegal package characters to underscores
|
||||
*/
|
||||
static String convertIllegalPackageChars(String packageName) {
|
||||
return packageName.replaceAll('[_\\- .]', '_')
|
||||
return packageName.replaceAll('[_\\- .+]', '_')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,9 +63,9 @@ class ClassBuilderSpec extends Specification {
|
||||
def "should return a class from the generated path by when external contracts are picked"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties props = new ContractVerifierConfigProperties(packageWithBaseClasses: "foo.Bar")
|
||||
String contractRelativeFolder = ["org","springframework","cloud","contract","verifier","tests","META_INF","com.example","hello_world","1.0.0"].join(File.separator)
|
||||
String contractRelativeFolder = ["org","springframework","cloud","contract","verifier","tests","META_INF","com.example","hello_world","0.1.0_dev.1.uncommitted+d1174dd"].join(File.separator)
|
||||
expect:
|
||||
ClassBuilder.retrieveBaseClass(props, contractRelativeFolder) == 'foo.Bar.Hello_world1_0_0Base'
|
||||
ClassBuilder.retrieveBaseClass(props, contractRelativeFolder) == 'foo.Bar.Hello_world0_1_0_dev_1_uncommitted_d1174ddBase'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.contract.verifier.builder
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.rules.TemporaryFolder
|
||||
import org.springframework.cloud.contract.verifier.TestGenerator
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode
|
||||
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
||||
@@ -82,14 +83,26 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
|
||||
public static final Closure JAVA_ASSERTER = { String classToTest ->
|
||||
String name = Math.abs(new Random().nextInt())
|
||||
String changedTest = classToTest.replace("public class Test", "public class Test${name}")
|
||||
SyntaxChecker.tryToCompileJavaWithoutImports("test.Test${name}", changedTest)
|
||||
String changedTest = classToTest
|
||||
.replace("public class Test", "public class Test${name}")
|
||||
.replace("public class ContractsTest", "public class Test${name}")
|
||||
String fqn = FQN(classToTest)
|
||||
SyntaxChecker.tryToCompileJavaWithoutImports("${fqn}${name}", changedTest)
|
||||
}
|
||||
|
||||
static String FQN(String classToTest) {
|
||||
return classToTest.contains("0_1_0_dev_1_uncommitted_d1174dd") ?
|
||||
"org.springframework.cloud.contract.verifier.tests.com_uscm.dale_api44_spec._0_1_0_dev_1_uncommitted_d1174dd.Test" :
|
||||
"test.Test"
|
||||
}
|
||||
|
||||
public static final Closure JAVA_JAXRS_ASSERTER = { String classToTest ->
|
||||
String name = Math.abs(new Random().nextInt())
|
||||
String changedTest = classToTest.replace("public class Test {", "public class Test${name} {\njavax.ws.rs.client.WebTarget webTarget;\n")
|
||||
SyntaxChecker.tryToCompileJavaWithoutImports("test.Test${name}", changedTest)
|
||||
String changedTest = classToTest
|
||||
.replace("public class Test {", "public class Test${name} {\njavax.ws.rs.client.WebTarget webTarget;\n")
|
||||
.replace("public class ContractsTest {", "public class Test${name} {\njavax.ws.rs.client.WebTarget webTarget;\n")
|
||||
String fqn = FQN(classToTest)
|
||||
SyntaxChecker.tryToCompileJavaWithoutImports("${fqn}${name}", changedTest)
|
||||
}
|
||||
|
||||
public static final Closure GROOVY_ASSERTER = { String classToTest ->
|
||||
@@ -98,6 +111,10 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
|
||||
def setup() {
|
||||
file = tmpFolder.newFile()
|
||||
wiriteContract(file)
|
||||
}
|
||||
|
||||
private wiriteContract(File file) {
|
||||
file.write("""
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
@@ -136,6 +153,33 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
SPOCK | TestMode.EXPLICIT | explicitSpockClassStrings | GROOVY_ASSERTER
|
||||
}
|
||||
|
||||
def "should build test class for #testFramework when the path contains bizarre signs"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
|
||||
properties.targetFramework = testFramework
|
||||
properties.basePackageForTests = "org.springframework.cloud.contract.verifier.tests"
|
||||
and:
|
||||
File newFolder = tmpFolder.newFolder("META_INF")
|
||||
File subfolders = new File(newFolder, "/com.uscm/dale_api44_spec/0.1.0_dev.1.uncommitted+d1174dd/contracts/")
|
||||
subfolders.mkdirs()
|
||||
File newFile = new File(subfolders, "contract.groovy")
|
||||
newFile.createNewFile()
|
||||
wiriteContract(newFile)
|
||||
properties.contractsDslDir = newFolder
|
||||
properties.generatedTestSourcesDir = newFolder.parentFile
|
||||
when:
|
||||
int size = new TestGenerator(properties).generate()
|
||||
then:
|
||||
size > 0
|
||||
asserter(new File(newFolder.parent, "/org/springframework/cloud/contract/verifier/tests/com_uscm/dale_api44_spec/0_1_0_dev_1_uncommitted_d1174dd/${testName}").text)
|
||||
where:
|
||||
testFramework | mode | asserter | testName
|
||||
JUNIT | TestMode.MOCKMVC | JAVA_ASSERTER | "ContractsTest.java"
|
||||
JUNIT | TestMode.EXPLICIT | JAVA_ASSERTER | "ContractsTest.java"
|
||||
SPOCK | TestMode.MOCKMVC | GROOVY_ASSERTER | "ContractsSpec.groovy"
|
||||
SPOCK | TestMode.EXPLICIT | GROOVY_ASSERTER | "ContractsSpec.groovy"
|
||||
}
|
||||
|
||||
def "should build test class for #testFramework with Rest Assured 3.0"() {
|
||||
given:
|
||||
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
|
||||
@@ -406,4 +450,6 @@ class SingleTestGeneratorSpec extends Specification {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,90 +11,97 @@ class NamesUtilSpec extends Specification {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
"a.b.c.d" == NamesUtil.beforeLast(string, ".")
|
||||
NamesUtil.beforeLast(string, ".") == "a.b.c.d"
|
||||
}
|
||||
|
||||
def "should return empty string when no token was found for before last"() {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
"" == NamesUtil.beforeLast(string, "/")
|
||||
NamesUtil.beforeLast(string, "/") == ""
|
||||
}
|
||||
|
||||
def "should return first token after the last one"() {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
"e" == NamesUtil.afterLast(string, ".")
|
||||
NamesUtil.afterLast(string, ".") == "e"
|
||||
}
|
||||
|
||||
def "should return the input string when no token was found for after last"() {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
string == NamesUtil.afterLast(string, "/")
|
||||
NamesUtil.afterLast(string, "/") == string
|
||||
}
|
||||
|
||||
def "should return first token after the last dot"() {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
"e" == NamesUtil.afterLastDot(string)
|
||||
NamesUtil.afterLastDot(string) == "e"
|
||||
}
|
||||
|
||||
def "should return the input string when no token was found for after last dot"() {
|
||||
given:
|
||||
String string = "abcde"
|
||||
expect:
|
||||
string == NamesUtil.afterLastDot(string)
|
||||
NamesUtil.afterLastDot(string) == string
|
||||
}
|
||||
|
||||
def "should return camel case version of a string"() {
|
||||
given:
|
||||
String string = "BlaBlaBla"
|
||||
expect:
|
||||
"blaBlaBla" == NamesUtil.camelCase(string)
|
||||
NamesUtil.camelCase(string) == "blaBlaBla"
|
||||
}
|
||||
|
||||
def "should return capitalized version of a string"() {
|
||||
given:
|
||||
String string = "blaBlaBla"
|
||||
expect:
|
||||
"BlaBlaBla" == NamesUtil.capitalize(string)
|
||||
NamesUtil.capitalize(string) == "BlaBlaBla"
|
||||
}
|
||||
|
||||
def "should return all text to last dot"() {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
"a.b.c.d" == NamesUtil.toLastDot(string)
|
||||
NamesUtil.toLastDot(string) == "a.b.c.d"
|
||||
}
|
||||
|
||||
def "should return the input string when no token was found for to last dot"() {
|
||||
given:
|
||||
String string = "abcde"
|
||||
expect:
|
||||
string == NamesUtil.toLastDot(string)
|
||||
NamesUtil.toLastDot(string) == string
|
||||
}
|
||||
|
||||
def "should convert a package notation to directory"() {
|
||||
given:
|
||||
String string = "a.b.c.d.e"
|
||||
expect:
|
||||
"a/b/c/d/e".replace("/", File.separator) == NamesUtil.packageToDirectory(string)
|
||||
NamesUtil.packageToDirectory(string) == "a/b/c/d/e".replace("/", File.separator)
|
||||
}
|
||||
|
||||
def "should convert a directory notation to package"() {
|
||||
given:
|
||||
String string = "a/b/c/d/e".replace("/", File.separator)
|
||||
expect:
|
||||
"a.b.c.d.e" == NamesUtil.directoryToPackage(string)
|
||||
NamesUtil.directoryToPackage(string) == "a.b.c.d.e"
|
||||
}
|
||||
|
||||
def "should convert a directory notation to package when folder is a digit"() {
|
||||
given:
|
||||
String string = "a/b/c/1.0.0/e".replace("/", File.separator)
|
||||
expect:
|
||||
NamesUtil.directoryToPackage(string) == "a.b.c._1_0_0.e"
|
||||
}
|
||||
|
||||
def "should convert all illegal package chars to legal ones"() {
|
||||
given:
|
||||
String string = "a-b c.1.0.x"
|
||||
String string = "a-b c.1.0.x+d1174dd"
|
||||
expect:
|
||||
"a_b_c_1_0_x" == NamesUtil.convertIllegalPackageChars(string)
|
||||
NamesUtil.convertIllegalPackageChars(string) == "a_b_c_1_0_x_d1174dd"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user