1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
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
}
}
|