Adding some tests for predicates.
This commit is contained in:
parent
fae37780e9
commit
16f8356e2c
5 changed files with 331 additions and 0 deletions
49
src/main/scala/gs/predicate/v0/json/JsonQueryIn.scala
Normal file
49
src/main/scala/gs/predicate/v0/json/JsonQueryIn.scala
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package gs.predicate.v0.json
|
||||
|
||||
import cats.Applicative
|
||||
import cats.syntax.all.*
|
||||
import gs.predicate.v0.api.Predicate
|
||||
import gs.predicate.v0.json.query.JsonQuery
|
||||
import io.circe.Json
|
||||
|
||||
/** Predicate that matches if the JSON provider contains a JSON blob with the
|
||||
* given key, and that blob contains the given query, and the result of the
|
||||
* query matches one of the given values.
|
||||
*
|
||||
* @param key
|
||||
* The name of the JSON value that must satisfy the given query.
|
||||
* @param query
|
||||
* The [[JsonQuery]] that must be satisfied.
|
||||
* @param values
|
||||
* The set of JSON values, such that one value should match the input.
|
||||
*/
|
||||
final class JsonQueryIn[F[_]: Applicative: JsonProvider](
|
||||
val key: String,
|
||||
val query: JsonQuery,
|
||||
val values: Set[Json]
|
||||
) extends Predicate[F]:
|
||||
|
||||
/** @inheritDocs
|
||||
*/
|
||||
final override val predicateType: String = JsonQueryIn.PredicateType
|
||||
|
||||
/** @inheritDocs
|
||||
*/
|
||||
override def eval(): F[Predicate.Result] =
|
||||
JsonProvider[F].get(key).map {
|
||||
case None => Predicate.Result.missed()
|
||||
case Some(json) => Predicate.Result(query.eval(json, values.contains))
|
||||
}
|
||||
|
||||
object JsonQueryIn:
|
||||
|
||||
final val PredicateType: String = "json-query-in"
|
||||
|
||||
def apply[F[_]: Applicative: JsonProvider](
|
||||
key: String,
|
||||
query: JsonQuery,
|
||||
values: Set[Json]
|
||||
): JsonQueryIn[F] =
|
||||
new JsonQueryIn[F](key, query, values)
|
||||
|
||||
end JsonQueryIn
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package gs.predicate.v0.json
|
||||
|
||||
import cats.effect.std.MapRef
|
||||
import io.circe.Json
|
||||
|
||||
/** Provides keys and JSON values, given some in-memory map.
|
||||
*
|
||||
* @param map
|
||||
* The underlying map.
|
||||
*/
|
||||
final class MemoryMapJsonProvider[F[_]](
|
||||
private val map: MapRef[F, String, Option[Json]]
|
||||
) extends JsonProvider[F]:
|
||||
|
||||
/** @inheritDocs
|
||||
*/
|
||||
override def get(key: String): F[Option[Json]] =
|
||||
map.apply(key).get
|
||||
|
||||
end MemoryMapJsonProvider
|
||||
128
src/test/scala/gs/predicate/v0/json/JsonQueryEqualsTests.scala
Normal file
128
src/test/scala/gs/predicate/v0/json/JsonQueryEqualsTests.scala
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
package gs.predicate.v0.json
|
||||
|
||||
import cats.effect.IO
|
||||
import cats.effect.std.MapRef
|
||||
import gs.datagen.v0.Gen
|
||||
import gs.datagen.v0.generators.Size
|
||||
import gs.predicate.v0.api.Predicate
|
||||
import gs.predicate.v0.json.query.JsonQuery
|
||||
import io.circe.Json
|
||||
import support.IOSuite
|
||||
|
||||
class JsonQueryEqualsTests extends IOSuite:
|
||||
|
||||
import JsonQueryEqualsTests.Data
|
||||
import JsonQueryEqualsTests.newProvider
|
||||
|
||||
iotest("should find an exact match against some string value") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.strValGen.gen()
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryEquals[IO](key, JsonQuery.compile(query), value)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.matched()))
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should fail to match against some non-equal string value") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.strValGen.gen()
|
||||
val searchValue = Data.strValGen.gen()
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryEquals[IO](key, JsonQuery.compile(query), searchValue)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.missed()))
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should find an exact match against some integer value") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.intValGen.gen()
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryEquals[IO](key, JsonQuery.compile(query), value)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.matched()))
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should fail to match against some non-equal integer value") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.intValGen.gen()
|
||||
val searchValue = Data.intValGen.gen()
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryEquals[IO](key, JsonQuery.compile(query), searchValue)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.missed()))
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should find an exact match against some boolean value") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.boolValGen.gen()
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryEquals[IO](key, JsonQuery.compile(query), value)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.matched()))
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should fail to match against some non-equal boolean value") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Json.fromBoolean(true)
|
||||
val searchValue = Json.fromBoolean(false)
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryEquals[IO](key, JsonQuery.compile(query), searchValue)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.missed()))
|
||||
}
|
||||
}
|
||||
|
||||
object JsonQueryEqualsTests:
|
||||
|
||||
object Data:
|
||||
|
||||
val keyGen: Gen[String] = Gen.string.alphaNumeric(Size.between(4, 16))
|
||||
|
||||
val strValGen: Gen[Json] =
|
||||
Gen.string.uppercaseAlpha(Size.fixed(8)).map(Json.fromString)
|
||||
|
||||
val intValGen: Gen[Json] = Gen.integer.inRange(0, 1000).map(Json.fromInt)
|
||||
val boolValGen: Gen[Json] = Gen.boolean().map(Json.fromBoolean)
|
||||
|
||||
end Data
|
||||
|
||||
def newProvider(data: Map[String, Json]): IO[JsonProvider[IO]] =
|
||||
for map <- MapRef.ofSingleImmutableMap[IO, String, Json](data)
|
||||
yield new MemoryMapJsonProvider(map)
|
||||
|
||||
end JsonQueryEqualsTests
|
||||
68
src/test/scala/gs/predicate/v0/json/JsonQueryInTests.scala
Normal file
68
src/test/scala/gs/predicate/v0/json/JsonQueryInTests.scala
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
package gs.predicate.v0.json
|
||||
|
||||
import cats.effect.IO
|
||||
import cats.effect.std.MapRef
|
||||
import gs.datagen.v0.Gen
|
||||
import gs.datagen.v0.generators.Size
|
||||
import gs.predicate.v0.api.Predicate
|
||||
import gs.predicate.v0.json.query.JsonQuery
|
||||
import io.circe.Json
|
||||
import support.IOSuite
|
||||
|
||||
class JsonQueryInTests extends IOSuite:
|
||||
|
||||
import JsonQueryInTests.Data
|
||||
import JsonQueryInTests.newProvider
|
||||
|
||||
iotest("should find an exact match against some set of values") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.strValGen.gen()
|
||||
val values = Set(value, Data.strValGen.gen(), Data.intValGen.gen())
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryIn[IO](key, JsonQuery.compile(query), values)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.matched()))
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should fail to match anything within some set of values") {
|
||||
val key = Data.keyGen.gen()
|
||||
val value = Data.strValGen.gen()
|
||||
val searchValues = Set(Data.strValGen.gen())
|
||||
val query = key
|
||||
val blob = Json.obj(
|
||||
key -> value
|
||||
)
|
||||
|
||||
newProvider(Map(key -> blob)).flatMap { provider =>
|
||||
given JsonProvider[IO] = provider
|
||||
val p = JsonQueryIn[IO](key, JsonQuery.compile(query), searchValues)
|
||||
p.eval().map(result => assertEquals(result, Predicate.Result.missed()))
|
||||
}
|
||||
}
|
||||
|
||||
end JsonQueryInTests
|
||||
|
||||
object JsonQueryInTests:
|
||||
|
||||
object Data:
|
||||
|
||||
val keyGen: Gen[String] = Gen.string.alphaNumeric(Size.between(4, 16))
|
||||
|
||||
val strValGen: Gen[Json] =
|
||||
Gen.string.uppercaseAlpha(Size.fixed(8)).map(Json.fromString)
|
||||
|
||||
val intValGen: Gen[Json] = Gen.integer.inRange(0, 1000).map(Json.fromInt)
|
||||
|
||||
end Data
|
||||
|
||||
def newProvider(data: Map[String, Json]): IO[JsonProvider[IO]] =
|
||||
for map <- MapRef.ofSingleImmutableMap[IO, String, Json](data)
|
||||
yield new MemoryMapJsonProvider(map)
|
||||
|
||||
end JsonQueryInTests
|
||||
66
src/test/scala/gs/predicate/v0/kv/ValueInTests.scala
Normal file
66
src/test/scala/gs/predicate/v0/kv/ValueInTests.scala
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package gs.predicate.v0.kv
|
||||
|
||||
import cats.effect.IO
|
||||
import cats.effect.std.MapRef
|
||||
import gs.datagen.v0.Gen
|
||||
import gs.datagen.v0.generators.Size
|
||||
import gs.predicate.v0.api.Predicate
|
||||
import support.IOSuite
|
||||
|
||||
class ValueInTests extends IOSuite:
|
||||
|
||||
import ValueInTests.Data
|
||||
|
||||
iotest("should find an exact match against some value") {
|
||||
ValueInTests.newProvider(Data.KeyValues).flatMap { provider =>
|
||||
given KeyValueProvider[IO] = provider
|
||||
val p =
|
||||
ValueIn[IO](
|
||||
Data.ExistingKey,
|
||||
Set(
|
||||
Data.ExistingValue,
|
||||
"",
|
||||
Gen.string.alphaNumeric(Size.Fixed(8)).gen()
|
||||
)
|
||||
)
|
||||
for result <- p.eval()
|
||||
yield assertEquals(result, Predicate.Result.matched())
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should not find a value if it is not associated to a key") {
|
||||
ValueInTests.newProvider(Data.KeyValues).flatMap { provider =>
|
||||
given KeyValueProvider[IO] = provider
|
||||
val p =
|
||||
ValueIn[IO](Data.ExistingKey, Set(Data.NotExistingValue))
|
||||
for result <- p.eval()
|
||||
yield assertEquals(result, Predicate.Result.missed())
|
||||
}
|
||||
}
|
||||
|
||||
iotest("should not find a key that does not exist within some provider") {
|
||||
ValueInTests.newProvider(Data.KeyValues).flatMap { provider =>
|
||||
given KeyValueProvider[IO] = provider
|
||||
val p = ValueIn[IO](Data.NotExistingKey, Set(""))
|
||||
for result <- p.eval()
|
||||
yield assertEquals(result, Predicate.Result.missed())
|
||||
}
|
||||
}
|
||||
|
||||
object ValueInTests:
|
||||
|
||||
object Data:
|
||||
|
||||
val ExistingKey: String = Gen.string.alphaNumeric(Size.Fixed(8)).gen()
|
||||
val NotExistingKey: String = Gen.string.alphaNumeric(Size.Fixed(6)).gen()
|
||||
val ExistingValue: String = Gen.string.alphaNumeric(Size.Fixed(10)).gen()
|
||||
val NotExistingValue: String = Gen.string.alphaNumeric(Size.Fixed(4)).gen()
|
||||
val KeyValues: Map[String, String] = Map(ExistingKey -> ExistingValue)
|
||||
|
||||
end Data
|
||||
|
||||
def newProvider(data: Map[String, String]): IO[KeyValueProvider[IO]] =
|
||||
for map <- MapRef.ofSingleImmutableMap[IO, String, String](data)
|
||||
yield new MemoryMapKeyValueProvider(map)
|
||||
|
||||
end ValueInTests
|
||||
Loading…
Add table
Reference in a new issue