All Downloads are FREE. Search and download functionalities are using the official Maven repository.

in.specmatic.core.GenerativeTestsEnabled.kt Maven / Gradle / Ivy

Go to download

Turn your contracts into executable specifications. Contract Driven Development - Collaboratively Design & Independently Deploy MicroServices & MicroFrontends. Deprecation Notice for group ID "in.specmatic" ****************************************************************************************************** Updates for "specmatic-core" will no longer be available under the deprecated group ID "in.specmatic". Please update your dependencies to use the new group ID "io.specmatic". ******************************************************************************************************

There is a newer version: 1.3.39
Show newest version
package `in`.specmatic.core

import `in`.specmatic.core.pattern.*
import `in`.specmatic.core.pattern.isOptional
import `in`.specmatic.core.pattern.withoutOptionality
import `in`.specmatic.core.value.Value

data class GenerativeTestsEnabled(private val positiveOnly: Boolean = Flags.onlyPositive()) : GenerationStrategies {

    override fun generatedPatternsForGenerativeTests(
        resolver: Resolver,
        pattern: Pattern,
        key: String
    ): Sequence> {
        // TODO generate value outside
        return resolver.withCyclePrevention(pattern, isOptional(key)) { cyclePreventedResolver ->
            pattern.newBasedOnR(Row(), cyclePreventedResolver)
        } ?: emptySequence()
    }

    override fun generateHttpRequestBodies(
        resolver: Resolver,
        body: Pattern,
        row: Row,
        requestBodyAsIs: Pattern,
        value: Value
    ): Sequence> {
        // TODO generate value outside
        val requestsFromFlattenedRow: Sequence> =
            resolver.withCyclePrevention(body) { cyclePreventedResolver ->
                body.newBasedOnR(row.noteRequestBody(), cyclePreventedResolver)
            }

        var matchFound = false

        val iterator = requestsFromFlattenedRow.iterator()

        return sequence {

            while(iterator.hasNext()) {
                val next = iterator.next()

                next.withDefault(false) {
                    if(it.encompasses(requestBodyAsIs, resolver, resolver, emptySet()) is Result.Success)
                        matchFound = true
                }

                yield(next)
            }

            if(!matchFound)
                yield(HasValue(requestBodyAsIs))
        }
    }

    override fun generateHttpRequestBodies(
        resolver: Resolver,
        body: Pattern,
        row: Row
    ): Sequence> {
        // TODO generate value outside
        val vanilla: Sequence> = resolver.withCyclePrevention(body) { cyclePreventedResolver ->
            body.newBasedOnR(Row(), cyclePreventedResolver)
        }

        val fromExamples: Sequence> = resolver.withCyclePrevention(body) { cyclePreventedResolver ->
            body.newBasedOnR(row, cyclePreventedResolver)
        }

        val remainingVanilla: Sequence> = vanilla.filterNot { vanillaTypeR ->
            fromExamples.any { typeFromExamplesR ->
                vanillaTypeR.withDefault(false, typeFromExamplesR) { vanillaType, typeFromExamples ->
                    vanillaType.encompasses(
                        typeFromExamples,
                        resolver,
                        resolver
                    ).isSuccess()
                }
            }
        }

        return fromExamples.plus(remainingVanilla)
    }

    override fun resolveRow(row: Row): Row {
        return Row()
    }

    override fun generateKeySubLists(key: String, subList: List): Sequence> {
        return if(isOptional(key)) {
            sequenceOf(subList, subList + key)
        } else
            sequenceOf(subList + key)
    }

    override fun positiveTestScenarios(feature: Feature, suggestions: List): Sequence>> {
        return feature.positiveTestScenarios(suggestions)
    }

    override fun negativeTestScenarios(feature: Feature): Sequence>> {
        return if(positiveOnly)
            emptySequence()
        else
            feature.negativeTestScenarios()
    }

    override fun fillInTheMissingMapPatterns(
        newQueryParamsList: Sequence>,
        queryPatterns: Map,
        additionalProperties: Pattern?,
        row: Row,
        resolver: Resolver
    ): Sequence> {
        val additionalPatterns = attempt(breadCrumb = QUERY_PARAMS_BREADCRUMB) {
            val queryParams = queryPatterns.let {
                if (additionalProperties != null)
                    it.plus(randomString(5) to additionalProperties)
                else
                    it
            }

            forEachKeyCombinationIn(queryParams, Row()) { entry ->
                newBasedOn(entry, row, resolver)
            }.map {
                it.mapKeys { withoutOptionality(it.key) }
            }
        }

        return additionalPatterns.map {
            noOverlapBetween(it, newQueryParamsList, resolver)
        }.filterNotNull()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy