Skip to content

Commit

Permalink
Merge pull request #1581 from znsio/specmatic-config-revamp_test
Browse files Browse the repository at this point in the history
Make Test Field of Specmatic Config Private
  • Loading branch information
joelrosario authored Feb 6, 2025
2 parents 9fd9c1c + 820c6be commit 583a946
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 37 deletions.
10 changes: 1 addition & 9 deletions core/src/main/kotlin/io/specmatic/core/Feature.kt
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,11 @@ data class Feature(
val strictMode: Boolean = false
): IFeature {
fun enableGenerativeTesting(onlyPositive: Boolean = false): Feature {
val updatedSpecmaticConfig = specmaticConfig.copy(
test = specmaticConfig.test?.copy(
resiliencyTests = specmaticConfig.test.resiliencyTests?.copy(
enable = if(onlyPositive) ResiliencyTestSuite.positiveOnly else ResiliencyTestSuite.all
)
)
)

return this.copy(flagsBased = this.flagsBased.copy(
generation = GenerativeTestsEnabled(onlyPositive),
positivePrefix = POSITIVE_TEST_DESCRIPTION_PREFIX,
negativePrefix = NEGATIVE_TEST_DESCRIPTION_PREFIX),
specmaticConfig = updatedSpecmaticConfig
specmaticConfig = specmaticConfig.copyResiliencyTestsConfig(onlyPositive)
)
}

Expand Down
73 changes: 57 additions & 16 deletions core/src/main/kotlin/io/specmatic/core/SpecmaticConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ data class SpecmaticConfig(
private val repository: RepositoryInfo? = null,
val report: ReportConfiguration? = null,
private val security: SecurityConfiguration? = null,
val test: TestConfiguration? = TestConfiguration(),
private val test: TestConfiguration? = TestConfiguration(),
val stub: StubConfiguration = StubConfiguration(),
private val virtualService: VirtualServiceConfiguration = VirtualServiceConfiguration(),
private val examples: List<String>? = null,
Expand Down Expand Up @@ -170,6 +170,11 @@ data class SpecmaticConfig(
return specmaticConfig?.security
}

@JsonIgnore
fun getTestConfiguration(specmaticConfig: SpecmaticConfig): TestConfiguration? {
return specmaticConfig.test
}

@JsonIgnore
fun getVirtualServiceConfiguration(specmaticConfig: SpecmaticConfig): VirtualServiceConfiguration {
return specmaticConfig.virtualService
Expand Down Expand Up @@ -220,22 +225,22 @@ data class SpecmaticConfig(

@JsonIgnore
fun isExtensibleSchemaEnabled(): Boolean {
return test?.allowExtensibleSchema ?: getBooleanValue(EXTENSIBLE_SCHEMA)
return test?.getAllowExtensibleSchema() ?: getBooleanValue(EXTENSIBLE_SCHEMA)
}

@JsonIgnore
fun isResiliencyTestingEnabled(): Boolean {
return (getResiliencyTestsEnable() != ResiliencyTestSuite.none)
return (getResiliencyTestsEnabled() != ResiliencyTestSuite.none)
}

@JsonIgnore
fun isOnlyPositiveTestingEnabled(): Boolean {
return (getResiliencyTestsEnable() == ResiliencyTestSuite.positiveOnly)
return (getResiliencyTestsEnabled() == ResiliencyTestSuite.positiveOnly)
}

@JsonIgnore
fun isResponseValueValidationEnabled(): Boolean {
return test?.validateResponseValues ?: getBooleanValue(VALIDATE_RESPONSE_VALUE)
return test?.getValidateResponseValues() ?: getBooleanValue(VALIDATE_RESPONSE_VALUE)
}

@JsonIgnore
Expand All @@ -249,8 +254,24 @@ data class SpecmaticConfig(
}

@JsonIgnore
fun getResiliencyTestsEnable(): ResiliencyTestSuite {
return test?.resiliencyTests?.enable ?: ResiliencyTestSuite.none
fun getResiliencyTestsEnabled(): ResiliencyTestSuite {
return test?.getResiliencyTests()?.getEnableTestSuite() ?: ResiliencyTestSuite.none
}

@JsonIgnore
fun getTestTimeoutInMilliseconds(): Long? {
return test?.getTimeoutInMilliseconds()
}

@JsonIgnore
fun copyResiliencyTestsConfig(onlyPositive: Boolean): SpecmaticConfig {
return this.copy(
test = test?.copy(
resiliencyTests = test.getResiliencyTests().copy(
enable = if (onlyPositive) ResiliencyTestSuite.positiveOnly else ResiliencyTestSuite.all
)
)
)
}

@JsonIgnore
Expand Down Expand Up @@ -369,26 +390,46 @@ data class SpecmaticConfig(
}

data class TestConfiguration(
val resiliencyTests: ResiliencyTestsConfig? = ResiliencyTestsConfig(
isResiliencyTestFlagEnabled = getBooleanValue(SPECMATIC_GENERATIVE_TESTS),
isOnlyPositiveFlagEnabled = getBooleanValue(ONLY_POSITIVE)
),
val validateResponseValues: Boolean? = null,
val allowExtensibleSchema: Boolean? = null,
val timeoutInMilliseconds: Long? = getLongValue(SPECMATIC_TEST_TIMEOUT)
)
private val resiliencyTests: ResiliencyTestsConfig? = null,
private val validateResponseValues: Boolean? = null,
private val allowExtensibleSchema: Boolean? = null,
private val timeoutInMilliseconds: Long? = null
) {
fun getResiliencyTests(): ResiliencyTestsConfig {
return resiliencyTests ?: ResiliencyTestsConfig(
isResiliencyTestFlagEnabled = getBooleanValue(SPECMATIC_GENERATIVE_TESTS),
isOnlyPositiveFlagEnabled = getBooleanValue(ONLY_POSITIVE)
)
}

fun getValidateResponseValues(): Boolean? {
return validateResponseValues
}

fun getAllowExtensibleSchema(): Boolean? {
return allowExtensibleSchema
}

fun getTimeoutInMilliseconds(): Long? {
return timeoutInMilliseconds ?: getLongValue(SPECMATIC_TEST_TIMEOUT)
}
}

enum class ResiliencyTestSuite {
all, positiveOnly, none
}

data class ResiliencyTestsConfig(
val enable: ResiliencyTestSuite? = null
private val enable: ResiliencyTestSuite? = null
) {
constructor(isResiliencyTestFlagEnabled: Boolean, isOnlyPositiveFlagEnabled: Boolean) : this(
enable = getEnableFrom(isResiliencyTestFlagEnabled, isOnlyPositiveFlagEnabled)
)

fun getEnableTestSuite(): ResiliencyTestSuite? {
return enable
}

companion object {
private fun getEnableFrom(
isResiliencyTestFlagEnabled: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.specmatic.core.SpecmaticConfig.Companion.getPipeline
import io.specmatic.core.SpecmaticConfig.Companion.getRepository
import io.specmatic.core.SpecmaticConfig.Companion.getSecurityConfiguration
import io.specmatic.core.SpecmaticConfig.Companion.getVirtualServiceConfiguration
import io.specmatic.core.SpecmaticConfig.Companion.getTestConfiguration
import io.specmatic.core.config.SpecmaticConfigVersion
import io.specmatic.core.config.SpecmaticVersionedConfig
import io.specmatic.core.config.SpecmaticVersionedConfigLoader
Expand Down Expand Up @@ -75,7 +76,7 @@ data class SpecmaticConfigV2(
repository = getRepository(config),
report = config.report,
security = getSecurityConfiguration(config),
test = config.test,
test = getTestConfiguration(config),
stub = config.stub,
virtualService = getVirtualServiceConfiguration(config),
examples = config.getExamples(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ data class SpecmaticConfigV3(
repository = getRepository(config),
report = config.report,
security = getSecurityConfiguration(config),
test = config.test,
test = SpecmaticConfig.getTestConfiguration(config),
stub = config.stub,
virtualService = SpecmaticConfig.getVirtualServiceConfiguration(config),
examples = config.getExamples(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ internal class SpecmaticConfigKtTest {
assertThat(htmlConfig?.heading).isEqualTo("Test Results")
assertThat(htmlConfig?.outputDirectory).isEqualTo("output")

assertThat(config.test?.timeoutInMilliseconds).isEqualTo(3000)
assertThat(config.getTestTimeoutInMilliseconds()).isEqualTo(3000)
}

@Test
Expand Down Expand Up @@ -194,7 +194,7 @@ internal class SpecmaticConfigKtTest {
assertThat(config.isExtensibleSchemaEnabled()).isFalse()
assertThat(config.getExamples()).isEqualTo(listOf("folder1/examples", "folder2/examples"))
assertThat(config.stub.delayInMilliseconds).isEqualTo(1000L)
assertThat(config.test?.timeoutInMilliseconds).isEqualTo(5000)
assertThat(config.getTestTimeoutInMilliseconds()).isEqualTo(5000)
} finally {
properties.forEach { System.clearProperty(it.key) }
}
Expand Down Expand Up @@ -243,7 +243,7 @@ internal class SpecmaticConfigKtTest {
assertThat(config.isExtensibleSchemaEnabled()).isTrue()
assertThat(config.getExamples()).isEqualTo(listOf("folder1/examples", "folder2/examples"))
assertThat(config.stub.delayInMilliseconds).isEqualTo(1000L)
assertThat(config.test?.timeoutInMilliseconds).isEqualTo(3000)
assertThat(config.getTestTimeoutInMilliseconds()).isEqualTo(3000)
} finally {
props.forEach { System.clearProperty(it.key) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import com.fasterxml.jackson.databind.JsonMappingException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import io.specmatic.core.Source
import io.specmatic.core.SourceProvider
import io.specmatic.core.SpecmaticConfig
import io.specmatic.core.*
import io.specmatic.core.config.v1.SpecmaticConfigV1
import io.specmatic.core.config.v2.ContractConfig
import io.specmatic.core.config.v2.ContractConfig.FileSystemContractSource
Expand All @@ -15,7 +13,6 @@ import io.specmatic.core.config.v2.SpecmaticConfigV2
import io.specmatic.core.config.v3.Consumes
import io.specmatic.core.config.v3.ContractConfigV2
import io.specmatic.core.config.v3.SpecmaticConfigV3
import io.specmatic.core.loadSpecmaticConfig
import io.specmatic.core.pattern.ContractException
import io.specmatic.core.pattern.parsedJSON
import org.assertj.core.api.Assertions.assertThat
Expand Down Expand Up @@ -450,7 +447,7 @@ internal class SpecmaticConfigAllTest {
}

@Test
fun `should serialize SpecmaticConfig successfully when AllPatternsMandatory key is present`() {
fun `should convert config from v1 to v2 when AllPatternsMandatory key is present`() {
val configYaml = """
allPatternsMandatory: true
""".trimIndent()
Expand All @@ -475,7 +472,7 @@ internal class SpecmaticConfigAllTest {
}

@Test
fun `should serialize SpecmaticConfig successfully when IgnoreInlineExamples key is present`() {
fun `should convert config from v1 to v2 when IgnoreInlineExamples key is present`() {
val configYaml = """
ignoreInlineExamples: true
""".trimIndent()
Expand All @@ -485,4 +482,49 @@ internal class SpecmaticConfigAllTest {

assertThat(configV2.ignoreInlineExamples).isTrue()
}

@Test
fun `should deserialize test configuration in SpecmaticConfig successfully key`(@TempDir tempDir: File) {
val configFile = tempDir.resolve("specmatic.yaml")
val configYaml = """
test:
resiliencyTests:
enable: all
validateResponseValues: true
allowExtensibleSchema: true
timeoutInMilliseconds: 10
""".trimIndent()
configFile.writeText(configYaml)

val specmaticConfig = configFile.toSpecmaticConfig()

specmaticConfig.apply {
assertThat(isResiliencyTestingEnabled()).isTrue()
assertThat(isResponseValueValidationEnabled()).isTrue()
assertThat(isExtensibleSchemaEnabled()).isTrue()
assertThat(getTestTimeoutInMilliseconds()).isEqualTo(10)
}
}

@Test
fun `should convert config from v1 to v2 when test configuration is present`() {
val configYaml = """
test:
resiliencyTests:
enable: all
validateResponseValues: true
allowExtensibleSchema: true
timeoutInMilliseconds: 10
""".trimIndent()

val configFromV1 = objectMapper.readValue(configYaml, SpecmaticConfigV1::class.java).transform()
val configV2 = SpecmaticConfigV2.loadFrom(configFromV1) as SpecmaticConfigV2

configV2.test!!.apply {
assertThat(getResiliencyTests().getEnableTestSuite()).isEqualTo(ResiliencyTestSuite.all)
assertThat(getValidateResponseValues()).isTrue()
assertThat(getAllowExtensibleSchema()).isTrue()
assertThat(getTimeoutInMilliseconds()).isEqualTo(10)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ open class SpecmaticJUnitSupport {

specmaticConfig = getSpecmaticConfig()

val timeoutInMilliseconds = specmaticConfig?.test?.timeoutInMilliseconds ?: try {
val timeoutInMilliseconds = specmaticConfig?.getTestTimeoutInMilliseconds() ?: try {
getLongValue(SPECMATIC_TEST_TIMEOUT)
} catch (e: NumberFormatException) {
throw ContractException("$SPECMATIC_TEST_TIMEOUT should be a value of type long")
Expand Down

0 comments on commit 583a946

Please sign in to comment.