Skip to content

Artyomcool/gjmatch

Repository files navigation

GJMatch

Build Status codecov

GJMatch is a library that can help with complex JSON verification or pattern-matching.

The main feature is using Groovy GString syntax to create lightweight and readable JSON-patterns, that can be used as verifiers as well as documentation:

def marker = "Some String ID"

def json =
        """
        {
            "version":"5.7.10",
            "marker":"$marker",
            "numberValue":7,
            "someExtraValue": "Extra Value"
        }
        """

def pattern =
        """
        {
            "version":"5.7.10",
            "marker": "$marker",
            "numberValue": $anyNumber
        }
        """

match(json, pattern)

In example above it is validated, that all fields in the pattern exist and numberValue has a numeric value. If numberValue is not a number, e.g. "str", exception will be thrown:

NotMatchedException: Can't cast class java.lang.String to class java.lang.Number: expected any number, found "str", path: $.numberValue

Any level of json nesting is available, so you can validate even very deep parts of JSON (and detailed exception, pointing to a wrong part of JSON).

There are plenty build-in validators available in GMatchers class, but all of them can be created manually. It is also possible to validate exact matching part of json, or mark extra fields as unexpected, or mark concrete field as unexpected.

Most of typical usages can be found at com.github.artyomcool.gjmatch.Showcase, e.g.:

@Test
void complex() {

    def marker = "Hello"

    def json =
            """
            {
                "version":"5.7.10",
                "marker":"$marker",
                "nullValue": null,
                "hasNumberValue":"str",
                "array": [1, "4", 11, 10]
            }
            """

    def pattern =
            """
            {
                "version":"5.7.10",
                "marker": "$marker",
                "nullValue": null,
                "noValue": $expectNoValue,
                "hasNumberValue": $anyNumber,
                "array": [1,"4", $anyNumber, 10],
                $unmatchUnexpected
            }
            """

    match(json, pattern)
}

For complex manual verification you can collect interested fields with $capture verifier:

@Test
void capture() {
    def values = []
    def cap = capture(values)

    def json =
            """
            {
                "f1": "v1",
                "f2": "v2",
                "f3": {
                    "f4": "v4"
                },
                "f5": "v5",
                "f6": "skip",
                "a": [1, "skip", 3],
                "slice": ["a", "b", "c", "d", "e"]
            }
            """

    def pattern =
            """
            {
                "f1": $cap,
                "f2": $cap,
                "f3": {
                    "f4": $cap
                },
                "f5": $cap,
                "f6": "skip",
                "a": [$cap, "skip", $cap],
                "slice": ["a", ${arraySlice(cap)}, "e"]
            }
            """

    match(json, pattern)

    assert values == ["v1", "v2", "v4", "v5", 1, 3, "b", "c", "d"]
}

Note: it is non-goal to provide runtime-verifiers for production code. The main goal is to help with api testings.

Gradle dependency:

dependencies {
    testImplementation 'org.codehaus.groovy:groovy-all:3.0.3'
    testImplementation 'com.github.artyomcool:gjmatch:0.1'
}

About

JSON pattern-matching

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published