package gs.predicate.v0.json.query import cats.Eq import io.circe.Json class CompiledQueryEvalTests extends munit.FunSuite: import CompiledQueryEvalTests.Data test("should handle a single, top-level key (matching case)") { val query = compile("key") val expectedValue = Json.fromString("value") val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test("should handle a single, top-level key (non-matching case)") { val query = compile("missing") val expectedValue = Json.fromString("value") val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } test( "should handle an array-all nested beneath an array-any (matching case)" ) { val query = compile("foo.bar[any].baz[all].x") val expectedValue = Json.fromInt(10) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test( "should handle an array-all nested beneath an array-any (non-matching case)" ) { val query = compile("foo.bar[any].baz[all].z") val expectedValue = Json.fromInt(0) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } test( "should handle an array-any nested beneath an array-all (matching case)" ) { val query = compile("foo.bar[all].baz[any].y") val expectedValue = Json.fromString("a") val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test( "should handle an array-any nested beneath an array-all (non-matching case)" ) { val query = compile("foo.bar[all].baz[any].z") val expectedValue = Json.fromInt(0) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } test("should handle nested index (matching case)") { val query = compile("foo.bar[0].baz[2].z") val expectedValue = Json.fromInt(2) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test("should handle nested index (non-matching case)") { val query = compile("foo.bar[0].baz[1].z") val expectedValue = Json.fromInt(2) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } test("should handle index after all (matching case)") { val query = compile("foo.bar[all].baz[0].x") val expectedValue = Json.fromInt(10) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test("should handle index after all (non-matching case)") { val query = compile("foo.bar[all].baz[0].z") val expectedValue = Json.fromInt(0) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } test("should handle [any] raw array values (matching case)") { val query = compile("rawValuesAny[any]") val expectedValue = Json.fromInt(1) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test("should handle [any] raw array values (non-matching case)") { val query = compile("rawValuesAny[any]") val expectedValue = Json.fromInt(6) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } test("should handle [all] raw array values (matching case)") { val query = compile("rawValuesAll[all]") val expectedValue = Json.fromInt(1) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, true) } test("should handle [all] raw array values (non-matching case)") { val query = compile("rawValuesAll[all]") val expectedValue = Json.fromInt(6) val p = (json: Json) => Eq[Json].eqv(json, expectedValue) val result = query.eval(Data.parsedJson, p) assertEquals(result, false) } private def compile(query: String): JsonQuery = CompiledQuery.compile(query) object CompiledQueryEvalTests: object Data: /** Reference data that supports all tests. */ val rawJson: String = """ { "foo": { "bar": [ { "baz": [ { "x": 10, "y": "a", "z": 0 }, { "x": 10, "y": "a", "z": 1 }, { "x": 10, "y": "a", "z": 2 } ] }, { "baz": [ { "x": 10, "y": "a", "z": 3 }, { "x": 20, "y": "a", "z": 4 } ] } ] }, "key": "value", "rawValuesAny": [ 1, 2, 3, 4, 5 ], "rawValuesAll": [ 1, 1, 1, 1, 1 ] } """.stripMargin /** Typically passed for predicate/query evaluation. */ val parsedJson: Json = parse(rawJson) end Data private def parse(json: String): Json = io.circe.parser.parse(json) match case Left(failure) => throw failure case Right(value) => value end CompiledQueryEvalTests