Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Test Field of Specmatic Config Private #1581

Merged
merged 8 commits into from
Feb 6, 2025
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 {
joelrosario marked this conversation as resolved.
Show resolved Hide resolved
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