diff options
author | vlad <vlad@driver.xyz> | 2018-01-25 14:12:31 -0800 |
---|---|---|
committer | vlad <vlad@driver.xyz> | 2018-01-25 14:12:31 -0800 |
commit | a0877d81ca2844d75dc361b5ce7c99afacd6e25f (patch) | |
tree | 8fe49f45cbcddbbb9a3d167099abe7aa2625e56b /src/test/scala/xyz/driver/pdsuicommon | |
parent | 46a22e9ab324a0068a85952cdc809800f360f445 (diff) | |
download | rest-query-a0877d81ca2844d75dc361b5ce7c99afacd6e25f.tar.gz rest-query-a0877d81ca2844d75dc361b5ce7c99afacd6e25f.tar.bz2 rest-query-a0877d81ca2844d75dc361b5ce7c99afacd6e25f.zip |
Extracting query library
Diffstat (limited to 'src/test/scala/xyz/driver/pdsuicommon')
8 files changed, 0 insertions, 613 deletions
diff --git a/src/test/scala/xyz/driver/pdsuicommon/db/SearchFilterExprSuite.scala b/src/test/scala/xyz/driver/pdsuicommon/db/SearchFilterExprSuite.scala deleted file mode 100644 index 35c8d30..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/db/SearchFilterExprSuite.scala +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.driver.pdsuicommon.db - -import org.scalatest.{FreeSpecLike, MustMatchers} - -class SearchFilterExprSuite extends FreeSpecLike with MustMatchers { - - "replace" - { - "all entities are changed" in { - val ast = SearchFilterExpr.Union( - Seq( - SearchFilterExpr.Intersection( - Seq( - SearchFilterExpr.Atom.Binary("foo", SearchFilterBinaryOperation.Gt, "10"), - SearchFilterExpr.Atom.Binary("foo", SearchFilterBinaryOperation.Lt, "20") - )), - SearchFilterExpr.Atom.NAry("bar", SearchFilterNAryOperation.In, Seq("x", "y", "z")), - SearchFilterExpr.Atom.Binary("foo", SearchFilterBinaryOperation.Eq, "40") - )) - - val newAst = ast.replace { - case x: SearchFilterExpr.Atom.Binary if x.dimension.name == "foo" => - x.copy(dimension = x.dimension.copy(name = "bar")) - } - - val result = newAst.find { - case x: SearchFilterExpr.Atom.Binary => x.dimension.name == "foo" - case _ => false - } - - result mustBe empty - } - } - -} diff --git a/src/test/scala/xyz/driver/pdsuicommon/error/UnexpectedFilterException.scala b/src/test/scala/xyz/driver/pdsuicommon/error/UnexpectedFilterException.scala deleted file mode 100644 index 567661a..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/error/UnexpectedFilterException.scala +++ /dev/null @@ -1,3 +0,0 @@ -package xyz.driver.pdsuicommon.error - -class UnexpectedFilterException(message: String) extends RuntimeException(message) diff --git a/src/test/scala/xyz/driver/pdsuicommon/logging/PhiStringContextSuite.scala b/src/test/scala/xyz/driver/pdsuicommon/logging/PhiStringContextSuite.scala deleted file mode 100644 index 8fd783f..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/logging/PhiStringContextSuite.scala +++ /dev/null @@ -1,31 +0,0 @@ -package xyz.driver.pdsuicommon.logging - -import org.scalatest.FreeSpecLike - -class PhiStringContextSuite extends FreeSpecLike { - - case class Foo(x: Int, y: String) { - val z: Boolean = true - } - - case class Bar(y: Boolean) - - implicit def fooToPhiString(foo: Foo): PhiString = new PhiString(s"Foo(z=${foo.z})") - - "should not compile if there is no PhiString implicit" in assertDoesNotCompile( - """val bar = Bar(true) - |phi"bar is $bar"""".stripMargin - ) - - "should compile if there is a PhiString implicit" in assertCompiles( - """val foo = new Foo(1, "test") - |println(phi"foo is $foo}")""".stripMargin - ) - - "should not contain private info" in { - val foo = new Foo(42, "test") - val result = phi"foo is $foo".text - assert(!result.contains("test")) - assert(!result.contains("42")) - } -} diff --git a/src/test/scala/xyz/driver/pdsuicommon/parsers/PaginationParserSuite.scala b/src/test/scala/xyz/driver/pdsuicommon/parsers/PaginationParserSuite.scala deleted file mode 100644 index 609c8c8..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/parsers/PaginationParserSuite.scala +++ /dev/null @@ -1,103 +0,0 @@ -package xyz.driver.pdsuicommon.parsers - -import xyz.driver.pdsuicommon.db.Pagination -import xyz.driver.pdsuicommon.parsers.TestUtils._ -import org.scalatest.{FreeSpecLike, MustMatchers} - -import scala.util.{Failure, Try} - -class PaginationParserSuite extends FreeSpecLike with MustMatchers { - - "parse" - { - "pageSize" - { - "should parse positive value" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "10", - "pageNumber" -> "1" - )) - pagination must success - pagination.get.pageSize mustBe 10 - } - - "should return a default value if there is no one" in { - val pagination = PaginationParser.parse( - Seq( - "pageNumber" -> "1" - )) - pagination must success - pagination.get.pageSize mustBe 100 - } - - "should return a error for zero value" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "0", - "pageNumber" -> "1" - )) - - checkFailedValidationOnlyOn(pagination, "pageSize") - } - - "should return a error for negative value" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "-10", - "pageNumber" -> "1" - )) - - checkFailedValidationOnlyOn(pagination, "pageSize") - } - } - - "pageNumber" - { - "should parse positive value" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "1", - "pageNumber" -> "1" - )) - pagination must success - pagination.get.pageSize mustBe 1 - } - - "should return a default value if there is no one" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "1" - )) - pagination must success - pagination.get.pageNumber mustBe 1 - } - - "should return a error for zero value" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "1", - "pageNumber" -> "0" - )) - - checkFailedValidationOnlyOn(pagination, "pageNumber") - } - - "should return a error for negative value" in { - val pagination = PaginationParser.parse( - Seq( - "pageSize" -> "1", - "pageNumber" -> "-1" - )) - - checkFailedValidationOnlyOn(pagination, "pageNumber") - } - } - } - - private def checkFailedValidationOnlyOn(pagination: Try[Pagination], key: String): Unit = { - pagination must failWith[ParseQueryArgException] - - val Failure(e: ParseQueryArgException) = pagination - e.errors.size mustBe 1 - e.errors.head._1 mustBe key - } - -} diff --git a/src/test/scala/xyz/driver/pdsuicommon/parsers/SearchFilterParserSuite.scala b/src/test/scala/xyz/driver/pdsuicommon/parsers/SearchFilterParserSuite.scala deleted file mode 100644 index 0209222..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/parsers/SearchFilterParserSuite.scala +++ /dev/null @@ -1,260 +0,0 @@ -package xyz.driver.pdsuicommon.parsers - -import java.util.UUID - -import xyz.driver.pdsuicommon.db.SearchFilterExpr.Dimension -import xyz.driver.pdsuicommon.db.{SearchFilterBinaryOperation, SearchFilterExpr, SearchFilterNAryOperation} -import xyz.driver.pdsuicommon.utils.Implicits.toStringOps -import xyz.driver.pdsuicommon.parsers.TestUtils._ -import fastparse.core.Parsed -import org.scalacheck.Arbitrary.arbitrary -import org.scalacheck.{Gen, Prop} -import org.scalatest.FreeSpecLike -import org.scalatest.prop.Checkers -import xyz.driver.pdsuicommon.db.SearchFilterBinaryOperation.Eq -import xyz.driver.pdsuicommon.db.SearchFilterNAryOperation.In -import xyz.driver.pdsuicommon.utils.Utils -import xyz.driver.pdsuicommon.utils.Utils._ - -import scala.util._ - -object SearchFilterParserSuite { - - class UnexpectedSearchFilterExprException(x: SearchFilterExpr) extends Exception(s"unexpected $x") - -} - -class SearchFilterParserSuite extends FreeSpecLike with Checkers { - - import SearchFilterParserSuite._ - - "parse" - { - "should convert column names to snake case" in { - import SearchFilterBinaryOperation._ - - val filter = SearchFilterParser.parse( - Seq( - "filters" -> "status IN Summarized,ReviewCriteria,Flagged,Done", - "filters" -> "previousStatus NOTEQ New", - "filters" -> "previousStatus NOTEQ ReviewSummary" - )) - - assert( - filter === Success(SearchFilterExpr.Intersection(List( - SearchFilterExpr.Atom - .NAry(Dimension(None, "status"), In, Seq("Summarized", "ReviewCriteria", "Flagged", "Done")), - SearchFilterExpr.Atom.Binary(Dimension(None, "previous_status"), NotEq, "New"), - SearchFilterExpr.Atom.Binary(Dimension(None, "previous_status"), NotEq, "ReviewSummary") - )))) - } - "dimensions" - { - "with table name" in check { - val dimensionGen = { - for (left <- Gen.identifier; right <- Gen.identifier) - yield left -> right - } - Prop.forAllNoShrink(dimensionGen) { - case (left, right) => - val raw = s"$left.$right" - val l = toSnakeCase(left) - val r = toSnakeCase(right) - SearchFilterParser.dimensionParser.parse(raw) match { - case Parsed.Success(Dimension(Some(`l`), `r`), _) => true - case _ => false - } - } - } - "just with field name" in check { - Prop.forAllNoShrink(Gen.identifier) { s => - val databaseS = Utils.toSnakeCase(s) - SearchFilterParser.dimensionParser.parse(s) match { - case Parsed.Success(Dimension(None, `databaseS`), _) => true - case _ => false - } - } - } - } - "atoms" - { - "binary" - { - "common operators" - { - "should be parsed with text values" in check { - import SearchFilterBinaryOperation._ - - val testQueryGen = queryGen( - dimensionGen = Gen.identifier, - opGen = commonBinaryOpsGen, - valueGen = nonEmptyString - ) - - Prop.forAllNoShrink(testQueryGen) { query => - SearchFilterParser - .parse(Seq("filters" -> query)) - .map { - case SearchFilterExpr.Atom.Binary(_, Eq | NotEq | Like, _) => true - case x => throw new UnexpectedSearchFilterExprException(x) - } - .successProp - } - } - } - - "numeric operators" - { - "should not be parsed with text values" in check { - val testQueryGen = queryGen( - dimensionGen = Gen.identifier, - opGen = numericBinaryOpsGen, - valueGen = nonEmptyString.filter { s => - !s.matches("^\\d+$") - } - ) - - Prop.forAllNoShrink(testQueryGen) { query => - SearchFilterParser.parse(Seq("filters" -> query)).failureProp - } - } - } - - "actual recordId" - { - "should not be parsed with numeric values" in { - val filter = SearchFilterParser.parse(Seq("filters" -> "recordId EQ 1")) - assert(filter === Success(SearchFilterExpr.Atom.Binary(Dimension(None, "record_id"), Eq, Long.box(1)))) - } - } - - "actual isVisible boolean" - { - "should not be parsed with boolean values" in { - val filter = SearchFilterParser.parse(Seq("filters" -> "isVisible EQ true")) - assert(filter === Success(SearchFilterExpr.Atom.Binary(Dimension(None, "is_visible"), Eq, Boolean.box(true)))) - } - } - - "actual patientId uuid" - { - "should parse the full UUID as java.util.UUID type" in { - val filter = SearchFilterParser.parse(Seq("filters" -> "patientId EQ 4b4879f7-42b3-4b7c-a685-5c97d9e69e7c")) - assert(filter === Success(SearchFilterExpr.Atom.Binary( - Dimension(None, "patient_id"), Eq, UUID.fromString("4b4879f7-42b3-4b7c-a685-5c97d9e69e7c")))) - } - } - - "all operators" - { - "should be parsed with numeric values" in check { - val testQueryGen = queryGen( - dimensionGen = Gen.identifier, - opGen = allBinaryOpsGen, - valueGen = numericBinaryAtomValuesGen - ) - - Prop.forAllNoShrink(testQueryGen) { query => - SearchFilterParser - .parse(Seq("filters" -> query)) - .map { - case _: SearchFilterExpr.Atom.Binary => true - case x => throw new UnexpectedSearchFilterExprException(x) - } - .successProp - } - } - } - } - - "n-ary" - { - "actual record Ids" - { - "should not be parsed with text values" in { - val filter = SearchFilterParser.parse(Seq("filters" -> "id IN 1,5")) - filter match { - case Success(_) => () - case Failure(t) => t.printStackTrace() - } - assert( - filter === Success(SearchFilterExpr.Atom.NAry(Dimension(None, "id"), In, Seq(Long.box(1), Long.box(5))))) - } - } - - "in" in check { - val testQueryGen = queryGen( - dimensionGen = Gen.identifier, - opGen = Gen.const("in"), - valueGen = inValuesGen - ) - - Prop.forAllNoShrink(testQueryGen) { query => - SearchFilterParser - .parse(Seq("filters" -> query)) - .map { - case SearchFilterExpr.Atom.NAry(_, SearchFilterNAryOperation.In, _) => true - case x => throw new UnexpectedSearchFilterExprException(x) - } - .successProp - } - } - } - } - - "intersections" - { - "should be parsed" in check { - val commonAtomsGen = queryGen( - dimensionGen = Gen.identifier, - opGen = commonBinaryOpsGen, - valueGen = nonEmptyString - ) - - val numericAtomsGen = queryGen( - dimensionGen = Gen.identifier, - opGen = numericBinaryOpsGen, - valueGen = numericBinaryAtomValuesGen - ) - - val allAtomsGen = Gen.oneOf(commonAtomsGen, numericAtomsGen) - val intersectionsGen = Gen.choose(1, 3).flatMap { size => - Gen.containerOfN[Seq, String](size, allAtomsGen) - } - - Prop.forAllNoShrink(intersectionsGen) { queries => - SearchFilterParser.parse(queries.map(query => "filters" -> query)).successProp - } - } - } - } - - private val CommonBinaryOps = Seq("eq", "noteq", "like") - private val NumericBinaryOps = Seq("gt", "gteq", "lt", "lteq") - - private val allBinaryOpsGen: Gen[String] = - Gen.oneOf(CommonBinaryOps ++ NumericBinaryOps).flatMap(randomCapitalization) - private val commonBinaryOpsGen: Gen[String] = Gen.oneOf(CommonBinaryOps).flatMap(randomCapitalization) - private val numericBinaryOpsGen: Gen[String] = Gen.oneOf(NumericBinaryOps).flatMap(randomCapitalization) - - private val inValueCharsGen: Gen[Char] = arbitrary[Char].filter(_ != ',') - - private val nonEmptyString = arbitrary[String].filter { s => - !s.safeTrim.isEmpty - } - - private val numericBinaryAtomValuesGen: Gen[String] = arbitrary[Long].map(_.toString) - private val inValueGen: Gen[String] = { - Gen.nonEmptyContainerOf[Seq, Char](inValueCharsGen).map(_.mkString).filter(_.safeTrim.nonEmpty) - } - private val inValuesGen: Gen[String] = Gen.choose(1, 5).flatMap { size => - Gen.containerOfN[Seq, String](size, inValueGen).map(_.mkString(",")) - } - - private def queryGen(dimensionGen: Gen[String], opGen: Gen[String], valueGen: Gen[String]): Gen[String] = - for { - dimension <- dimensionGen - op <- opGen - value <- valueGen - } yield s"$dimension $op $value" - - private def randomCapitalization(input: String): Gen[String] = { - Gen.containerOfN[Seq, Boolean](input.length, arbitrary[Boolean]).map { capitalize => - input.view - .zip(capitalize) - .map { - case (currChar, true) => currChar.toUpper - case (currChar, false) => currChar - } - .mkString - } - } - -} diff --git a/src/test/scala/xyz/driver/pdsuicommon/parsers/SortingParserSuite.scala b/src/test/scala/xyz/driver/pdsuicommon/parsers/SortingParserSuite.scala deleted file mode 100644 index f34f8e1..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/parsers/SortingParserSuite.scala +++ /dev/null @@ -1,96 +0,0 @@ -package xyz.driver.pdsuicommon.parsers - -import xyz.driver.pdsuicommon.parsers.TestUtils._ -import org.scalacheck.Arbitrary.arbitrary -import org.scalacheck.{Gen, Prop} -import org.scalatest.prop.Checkers -import org.scalatest.{FreeSpecLike, MustMatchers} - -class SortingParserSuite extends FreeSpecLike with MustMatchers with Checkers { - - "parse" - { - "single dimension" - commonTests(singleSortingQueryGen) - "multiple dimensions in one query" - commonTests(multipleSortingQueryGen) - "multiple queries" in { - val r = SortingParser.parse(Set("foo", "bar"), Seq("sort" -> "foo", "sort" -> "bar")) - r must failWith[ParseQueryArgException] - } - } - - private def commonTests(queryGen: Set[String] => Gen[String]): Unit = { - "valid" in check { - val inputGen: Gen[(Set[String], String)] = for { - validDimensions <- dimensionsGen - sorting <- queryGen(validDimensions) - } yield (validDimensions, sorting) - - Prop.forAllNoShrink(inputGen) { - case (validDimensions, query) => - SortingParser.parse(validDimensions, Seq("sort" -> query)).successProp - } - } - - "invalid" in check { - val inputGen: Gen[(Set[String], String)] = for { - validDimensions <- dimensionsGen - invalidDimensions <- dimensionsGen.filter { xs => - xs.intersect(validDimensions).isEmpty - } - sorting <- queryGen(invalidDimensions) - } yield (validDimensions, sorting) - - Prop.forAllNoShrink(inputGen) { - case (validDimensions, query) => - SortingParser.parse(validDimensions, Seq("sort" -> query)).failureProp - } - } - } - - private val dimensionsGen: Gen[Set[String]] = for { - unPrefixedSize <- Gen.choose(0, 3) - prefixedSize <- Gen.choose(0, 3) - if (unPrefixedSize + prefixedSize) > 0 - - unPrefixedDimensions <- Gen.containerOfN[Set, String](unPrefixedSize, Gen.identifier) - - prefixes <- Gen.containerOfN[Set, String](prefixedSize, Gen.identifier) - dimensions <- Gen.containerOfN[Set, String](prefixedSize, Gen.identifier) - } yield { - val prefixedDimensions = prefixes.zip(dimensions).map { - case (prefix, dimension) => s"$prefix.$dimension" - } - unPrefixedDimensions ++ prefixedDimensions - } - - private def multipleSortingQueryGen(validDimensions: Set[String]): Gen[String] = { - val validDimensionsSeq = validDimensions.toSeq - val indexGen = Gen.oneOf(validDimensionsSeq.indices) - val multipleDimensionsGen = Gen.nonEmptyContainerOf[Set, Int](indexGen).filter(_.size >= 2).map { indices => - indices.map(validDimensionsSeq.apply) - } - - for { - dimensions <- multipleDimensionsGen - isAscending <- Gen.containerOfN[Seq, Boolean](dimensions.size, arbitrary[Boolean]) - } yield { - isAscending - .zip(dimensions) - .map { - case (true, dimension) => dimension - case (false, dimension) => "-" + dimension - } - .mkString(",") - } - } - - private def singleSortingQueryGen(validDimensions: Set[String]): Gen[String] = - for { - isAscending <- arbitrary[Boolean] - dimensions <- Gen.oneOf(validDimensions.toSeq) - } yield - isAscending match { - case true => dimensions - case false => "-" + dimensions - } - -} diff --git a/src/test/scala/xyz/driver/pdsuicommon/parsers/TestUtils.scala b/src/test/scala/xyz/driver/pdsuicommon/parsers/TestUtils.scala deleted file mode 100644 index 8ab2131..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/parsers/TestUtils.scala +++ /dev/null @@ -1,53 +0,0 @@ -package xyz.driver.pdsuicommon.parsers - -import org.scalacheck.Prop -import org.scalacheck.Prop.BooleanOperators -import org.scalatest.matchers.{MatchResult, Matcher} -import xyz.driver.pdsuicommon.utils.Utils - -import scala.reflect.ClassTag -import scala.util.{Failure, Success, Try} - -object TestUtils { - - object success extends Matcher[Try[Any]] { - override def apply(left: Try[Any]) = { - MatchResult(left.isSuccess, s"$left did not fail", s"did fail with $left") - } - } - - class FailWith[ThrowableT <: Throwable](implicit ct: ClassTag[ThrowableT]) extends Matcher[Try[Any]] { - override def apply(left: Try[Any]): MatchResult = { - MatchResult( - left.isFailure && left.failed.get.getClass == ct.runtimeClass, - left match { - case Success(_) => s"$left did not fail" - case Failure(e) => - s"$left did fail with ${Utils.getClassSimpleName(e.getClass)}, " + - s"not ${Utils.getClassSimpleName(ct.runtimeClass)}" - }, - left match { - case Success(_) => s"$left failed with ${Utils.getClassSimpleName(ct.runtimeClass)}" - case Failure(e) => s"$left failed with ${Utils.getClassSimpleName(e.getClass)}" - } - ) - } - } - - def failWith[ThrowableT <: Throwable](implicit ct: ClassTag[ThrowableT]) = new FailWith[ThrowableT] - - final implicit class TryPropOps(val self: Try[Any]) extends AnyVal { - - def successProp: Prop = self match { - case Success(_) => true :| "ok" - case Failure(e) => false :| e.getMessage - } - - def failureProp: Prop = self match { - case Success(x) => false :| s"invalid: $x" - case Failure(_) => true - } - - } - -} diff --git a/src/test/scala/xyz/driver/pdsuicommon/utils/StringOpsSuite.scala b/src/test/scala/xyz/driver/pdsuicommon/utils/StringOpsSuite.scala deleted file mode 100644 index bd0bd2b..0000000 --- a/src/test/scala/xyz/driver/pdsuicommon/utils/StringOpsSuite.scala +++ /dev/null @@ -1,33 +0,0 @@ -package xyz.driver.pdsuicommon.utils - -import xyz.driver.pdsuicommon.utils.Implicits.toStringOps -import org.scalatest.FreeSpecLike - -class StringOpsSuite extends FreeSpecLike { - - "safeTrim" - { - "empty string" in { - assert("".safeTrim == "") - } - - "string with whitespace symbols" in { - assert("\u2002\u3000\r\u0085\u200A\u2005\u2000\u3000".safeTrim == "") - } - - "string with control symbols" in { - assert("\u001f\u007f\t\n".safeTrim == "") - } - - "whitespaces and control symbols from the left side" in { - assert("\u001f\u2002\u007f\nfoo".safeTrim == "foo") - } - - "whitespaces and control symbols from the right side" in { - assert("foo\u001f\u2002\u007f\n".safeTrim == "foo") - } - - "already trimmed string" in { - assert("foo".safeTrim == "foo") - } - } -} |