diff options
Diffstat (limited to 'src/test')
3 files changed, 297 insertions, 85 deletions
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala index 49abd48..e9a20db 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/FilteringProgramSpecs.scala | |||
@@ -310,89 +310,4 @@ class FilteringProgramSpec | |||
310 | 310 | ||
311 | import FilteringProgramSpec._ | 311 | import FilteringProgramSpec._ |
312 | 312 | ||
313 | "Queries" should "have distinct answer and bounded variables" in { | ||
314 | for (query <- queries) { | ||
315 | val program = new FilteringProgram(query, List()) | ||
316 | forAll(program.answer) { v => program.bounded should not contain v } | ||
317 | forAll(program.bounded) { v => program.answer should not contain v } | ||
318 | } | ||
319 | } | ||
320 | |||
321 | "Query 0" should "have {?obj, ?pred} as bounded variables" in { | ||
322 | val pred = Variable.create("obj") | ||
323 | val obj = Variable.create("pred") | ||
324 | val program = new FilteringProgram(query0, List()) | ||
325 | program.bounded should contain theSameElementsAs List(pred, obj) | ||
326 | } | ||
327 | |||
328 | "Query 1" should "have no bounded variable" in { | ||
329 | val program = new FilteringProgram(query1, List()) | ||
330 | program.bounded shouldBe empty | ||
331 | } | ||
332 | |||
333 | "Query 2" should "have no bounded variable" in { | ||
334 | val program = new FilteringProgram(query2, List()) | ||
335 | program.bounded shouldBe empty | ||
336 | } | ||
337 | |||
338 | "Query 3" should "have {?w, ?fp} as bounded variables" in { | ||
339 | val w = Variable.create("w") | ||
340 | val fp = Variable.create("fp") | ||
341 | val program = new FilteringProgram(query3, List()) | ||
342 | program.bounded should contain theSameElementsAs List(w, fp) | ||
343 | } | ||
344 | |||
345 | "Query 4" should "have no bounded variable" in { | ||
346 | val program = new FilteringProgram(query4, List()) | ||
347 | program.bounded shouldBe empty | ||
348 | } | ||
349 | |||
350 | "Query 5" should "have a non-empty bounded set" in { | ||
351 | val w = Variable.create("w") | ||
352 | val c_int = Variable.create("c_int") | ||
353 | val f_int = Variable.create("f_int") | ||
354 | val c_unit = Variable.create("c_unit") | ||
355 | val program = new FilteringProgram(query5, List()) | ||
356 | program.bounded should contain theSameElementsAs List( | ||
357 | w, | ||
358 | c_int, | ||
359 | f_int, | ||
360 | c_unit | ||
361 | ) | ||
362 | } | ||
363 | |||
364 | "Query 6" should "have a non-empty bounded set" in { | ||
365 | val w = Variable.create("w") | ||
366 | val int = Variable.create("int") | ||
367 | val program = new FilteringProgram(query6, List()) | ||
368 | program.bounded should contain theSameElementsAs List(w, int) | ||
369 | } | ||
370 | |||
371 | "Query 7" should "have a non-empty bounded set" in { | ||
372 | val w = Variable.create("w") | ||
373 | val z = Variable.create("z") | ||
374 | val u = Variable.create("u") | ||
375 | val strat_unit_name = Variable.create("strat_unit_name") | ||
376 | val wellbore = Variable.create("wellbore") | ||
377 | val cored_int = Variable.create("cored_int") | ||
378 | val c = Variable.create("c") | ||
379 | val sample_depth = Variable.create("sample_depth") | ||
380 | val p = Variable.create("p") | ||
381 | val top = Variable.create("top") | ||
382 | val bot = Variable.create("bot") | ||
383 | val program = new FilteringProgram(query7, List()) | ||
384 | program.bounded should contain theSameElementsAs List( | ||
385 | w, | ||
386 | z, | ||
387 | u, | ||
388 | strat_unit_name, | ||
389 | wellbore, | ||
390 | cored_int, | ||
391 | c, | ||
392 | sample_depth, | ||
393 | p, | ||
394 | top, | ||
395 | bot | ||
396 | ) | ||
397 | } | ||
398 | } | 313 | } |
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala new file mode 100644 index 0000000..65c3e29 --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQueryAnswerSpecs.scala | |||
@@ -0,0 +1,62 @@ | |||
1 | package uk.ac.ox.cs.rsacomb.sparql | ||
2 | |||
3 | import org.scalatest.flatspec.AnyFlatSpec | ||
4 | import org.scalatest.matchers.should.Matchers | ||
5 | import tech.oxfordsemantic.jrdfox.logic.expression.IRI | ||
6 | |||
7 | object ConjunctiveQueryAnswerSpec { | ||
8 | |||
9 | val iri1 = IRI.create("_:iri1") | ||
10 | val iri2 = IRI.create("_:iri2") | ||
11 | val iri3 = IRI.create("_:iri3") | ||
12 | |||
13 | val oneAnswer = new ConjunctiveQueryAnswers(false, Seq(Seq(iri1, iri2, iri3))) | ||
14 | val multipleAnswers = | ||
15 | new ConjunctiveQueryAnswers( | ||
16 | false, | ||
17 | Seq(Seq(iri1, iri1), Seq(iri1, iri2), Seq(iri1, iri3)) | ||
18 | ) | ||
19 | val noAnswer = new ConjunctiveQueryAnswers(false, Seq()) | ||
20 | val emptyAnswer = new ConjunctiveQueryAnswers(false, Seq(Seq())) | ||
21 | |||
22 | val falseAnswer = new ConjunctiveQueryAnswers(true, Seq()) | ||
23 | val trueAnswer1 = new ConjunctiveQueryAnswers(true, Seq(Seq())) | ||
24 | val trueAnswer2 = | ||
25 | new ConjunctiveQueryAnswers( | ||
26 | true, | ||
27 | Seq(Seq(iri1, iri1), Seq(iri1, iri2), Seq(iri1, iri3)) | ||
28 | ) | ||
29 | } | ||
30 | |||
31 | class ConjunctiveQueryAnswerSpec extends AnyFlatSpec with Matchers { | ||
32 | |||
33 | import ConjunctiveQueryAnswerSpec._ | ||
34 | |||
35 | "A conjunctive query" should "print a single line if it has a single answer" in { | ||
36 | oneAnswer.toString shouldBe s"($iri1, $iri2, $iri3)" | ||
37 | } | ||
38 | |||
39 | it should "print multiple answers on multiple lines" in { | ||
40 | multipleAnswers.toString shouldBe s"($iri1, $iri1)\n($iri1, $iri2)\n($iri1, $iri3)" | ||
41 | } | ||
42 | |||
43 | it should "print a special \"NO ANSWER\" string when it has no answer" in { | ||
44 | noAnswer.toString shouldBe "NO ANSWER" | ||
45 | } | ||
46 | |||
47 | it should "print an empty list when it has an empty answer" in { | ||
48 | emptyAnswer.toString shouldBe "()" | ||
49 | } | ||
50 | |||
51 | "A boolean conjunctive query" should "print \"FALSE\" when it has no answer" in { | ||
52 | falseAnswer.toString shouldBe "FALSE" | ||
53 | } | ||
54 | |||
55 | it should "print \"TRUE\" when it has a single empty answer" in { | ||
56 | trueAnswer1.toString shouldBe "TRUE" | ||
57 | } | ||
58 | |||
59 | it should "print \"TRUE\" when it has a non-empty collection of answers" in { | ||
60 | trueAnswer2.toString shouldBe "TRUE" | ||
61 | } | ||
62 | } | ||
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala new file mode 100644 index 0000000..e683d36 --- /dev/null +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/sparql/ConjunctiveQuerySpec.scala | |||
@@ -0,0 +1,235 @@ | |||
1 | package uk.ac.ox.cs.rsacomb.sparql | ||
2 | |||
3 | import org.scalatest.{Inspectors, OptionValues} | ||
4 | import org.scalatest.flatspec.AnyFlatSpec | ||
5 | import org.scalatest.matchers.should.Matchers | ||
6 | import tech.oxfordsemantic.jrdfox.logic.expression.Variable | ||
7 | |||
8 | object ConjunctiveQuerySpec { | ||
9 | |||
10 | val cq0 = """ | ||
11 | PREFIX : <http://example.com/rsa_example.owl#> | ||
12 | |||
13 | SELECT ?X | ||
14 | WHERE { | ||
15 | ?X a :D ; | ||
16 | :R ?Y . | ||
17 | ?Y :S ?Z . | ||
18 | ?Z a :D . | ||
19 | } | ||
20 | """ | ||
21 | |||
22 | val cq1 = """ | ||
23 | PREFIX : <http://example.com/rsa_example.owl#> | ||
24 | |||
25 | SELECT * | ||
26 | WHERE { | ||
27 | ?X a :D ; | ||
28 | :R ?Y . | ||
29 | ?Y :S ?Z . | ||
30 | ?Z a :D . | ||
31 | } | ||
32 | """ | ||
33 | |||
34 | val cq2 = """ | ||
35 | PREFIX : <http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#> | ||
36 | SELECT * | ||
37 | WHERE { | ||
38 | ?w a :Wellbore ; | ||
39 | :wellboreDocument ?doc . | ||
40 | ?doc :hasURL ?document_hyperlink | ||
41 | } | ||
42 | """ | ||
43 | |||
44 | val cq3 = """ | ||
45 | PREFIX : <http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#> | ||
46 | SELECT ?wellbore ?formation_pressure | ||
47 | WHERE { | ||
48 | ?w a :Wellbore ; | ||
49 | :name ?wellbore ; | ||
50 | :hasFormationPressure ?fp . | ||
51 | ?fp :valueInStandardUnit ?formation_pressure | ||
52 | } | ||
53 | """ | ||
54 | |||
55 | val cq4 = """ | ||
56 | PREFIX : <http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#> | ||
57 | SELECT * | ||
58 | WHERE { | ||
59 | ?w a :Wellbore ; | ||
60 | :hasGeochemicalMeasurement ?measurement . | ||
61 | ?measurement :cgType ?cgtype ; | ||
62 | :peakName ?peakType ; | ||
63 | :peakHeight ?peak_height ; | ||
64 | :peakAmount ?peak_amount | ||
65 | } | ||
66 | """ | ||
67 | |||
68 | val cq5 = """ | ||
69 | PREFIX : <http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#> | ||
70 | SELECT ?wellbore ?unit_name ?discovery | ||
71 | WHERE { | ||
72 | ?w a :Wellbore ; | ||
73 | :name ?wellbore ; | ||
74 | :hasWellboreInterval ?c_int ; | ||
75 | :hasWellboreInterval ?f_int . | ||
76 | ?c_int :hasUnit ?c_unit . | ||
77 | ?c_unit :name ?unit_name . | ||
78 | ?f_int a :FluidZone ; | ||
79 | :name ?discovery ; | ||
80 | :overlapsWellboreInterval ?c_int | ||
81 | } | ||
82 | """ | ||
83 | |||
84 | val cq6 = """ | ||
85 | PREFIX : <http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#> | ||
86 | SELECT DISTINCT ?wellbore ?content | ||
87 | WHERE { | ||
88 | ?w a :Wellbore ; | ||
89 | :name ?wellbore ; | ||
90 | :hasWellboreInterval ?int . | ||
91 | ?int a :FluidZone ; | ||
92 | :fluidZoneContent ?content | ||
93 | } | ||
94 | """ | ||
95 | |||
96 | val cq7 = """ | ||
97 | PREFIX : <http://slegger.gitlab.io/slegge-obda/ontology/subsurface-exploration#> | ||
98 | SELECT ?wName ?sample ?porosity ?top_depth_md ?bot_depth_md | ||
99 | WHERE { | ||
100 | ?w a :Wellbore ; | ||
101 | :name ?wName ; | ||
102 | :hasWellboreInterval ?z . | ||
103 | ?z :hasUnit ?u . | ||
104 | ?u :name ?strat_unit_name . | ||
105 | ?wellbore :hasWellboreInterval ?cored_int . | ||
106 | ?c :extractedFrom ?cored_int ; | ||
107 | :hasCoreSample ?sample . | ||
108 | ?sample :hasDepth ?sample_depth . | ||
109 | ?sample_depth | ||
110 | :inWellboreInterval ?z . | ||
111 | ?sample :hasPorosity ?p . | ||
112 | ?p :valueInStandardUnit ?porosity . | ||
113 | ?z :hasTopDepth ?top . | ||
114 | ?top a :MeasuredDepth ; | ||
115 | :valueInStandardUnit ?top_depth_md . | ||
116 | ?z :hasBottomDepth ?bot . | ||
117 | ?bot a :MeasuredDepth ; | ||
118 | :valueInStandardUnit ?bot_depth_md | ||
119 | } | ||
120 | """ | ||
121 | |||
122 | val bcq0 = """ | ||
123 | PREFIX : <http://example.com/scrubs/casting/> | ||
124 | ASK { | ||
125 | :turk a :Doctor ; | ||
126 | :married ?X . | ||
127 | ?X a :Nurse . | ||
128 | } | ||
129 | """ | ||
130 | |||
131 | val queries = | ||
132 | List(cq0, cq1, cq2, cq3, cq4, cq5, cq6, cq7, bcq0) | ||
133 | |||
134 | } | ||
135 | |||
136 | class ConjunctiveQuerySpec | ||
137 | extends AnyFlatSpec | ||
138 | with Matchers | ||
139 | with Inspectors | ||
140 | with OptionValues { | ||
141 | |||
142 | import ConjunctiveQuerySpec._ | ||
143 | |||
144 | "A conjunctive query" should "result in a `ConjunctiveQuery` instance" in { | ||
145 | ConjunctiveQuery(cq0) shouldBe defined | ||
146 | } | ||
147 | |||
148 | "A boolean conjunctive query" should "result in a `ConjunctiveQuery` instance" in { | ||
149 | ConjunctiveQuery(bcq0) shouldBe defined | ||
150 | } | ||
151 | |||
152 | "A query with proper SELECT defined" should "not be a BCQ" in { | ||
153 | ConjunctiveQuery(cq0).value should not be 'boolean | ||
154 | } | ||
155 | |||
156 | "A query with a \"*\" SELECT" should "not be a BCQ" in { | ||
157 | ConjunctiveQuery(cq1).value should not be 'boolean | ||
158 | } | ||
159 | |||
160 | "An ASK query" should "not be a BCQ" in { | ||
161 | ConjunctiveQuery(bcq0).value shouldBe 'boolean | ||
162 | } | ||
163 | |||
164 | "Queries" should "have distinct answer and bounded variables" in { | ||
165 | for (q <- queries) { | ||
166 | val cq = ConjunctiveQuery(q) | ||
167 | forAll(cq.value.answer) { v => cq.value.bounded should not contain v } | ||
168 | forAll(cq.value.bounded) { v => cq.value.answer should not contain v } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | "CQ0" should "have {?obj, ?pred} as bounded variables" in { | ||
173 | ConjunctiveQuery(cq0).value.bounded should contain theSameElementsAs | ||
174 | List( | ||
175 | Variable.create("Y"), | ||
176 | Variable.create("Z") | ||
177 | ) | ||
178 | } | ||
179 | |||
180 | "CQ1" should "have no bounded variable" in { | ||
181 | ConjunctiveQuery(cq1).value.bounded shouldBe empty | ||
182 | } | ||
183 | |||
184 | "CQ2" should "have no bounded variable" in { | ||
185 | ConjunctiveQuery(cq2).value.bounded shouldBe empty | ||
186 | } | ||
187 | |||
188 | "CQ3" should "have {?w, ?fp} as bounded variables" in { | ||
189 | ConjunctiveQuery(cq3).value.bounded should contain theSameElementsAs | ||
190 | List( | ||
191 | Variable.create("w"), | ||
192 | Variable.create("fp") | ||
193 | ) | ||
194 | } | ||
195 | |||
196 | "CQ4" should "have no bounded variable" in { | ||
197 | ConjunctiveQuery(cq4).value.bounded shouldBe empty | ||
198 | } | ||
199 | |||
200 | "CQ5" should "have a non-empty bounded set" in { | ||
201 | ConjunctiveQuery(cq5).value.bounded should contain theSameElementsAs | ||
202 | List( | ||
203 | Variable.create("w"), | ||
204 | Variable.create("c_int"), | ||
205 | Variable.create("f_int"), | ||
206 | Variable.create("c_unit") | ||
207 | ) | ||
208 | } | ||
209 | |||
210 | "CQ6" should "have a non-empty bounded set" in { | ||
211 | ConjunctiveQuery(cq6).value.bounded should contain theSameElementsAs | ||
212 | List( | ||
213 | Variable.create("w"), | ||
214 | Variable.create("int") | ||
215 | ) | ||
216 | } | ||
217 | |||
218 | "CQ7" should "have a non-empty bounded set" in { | ||
219 | ConjunctiveQuery(cq7).value.bounded should contain theSameElementsAs | ||
220 | List( | ||
221 | Variable.create("w"), | ||
222 | Variable.create("z"), | ||
223 | Variable.create("u"), | ||
224 | Variable.create("strat_unit_name"), | ||
225 | Variable.create("wellbore"), | ||
226 | Variable.create("cored_int"), | ||
227 | Variable.create("c"), | ||
228 | Variable.create("sample_depth"), | ||
229 | Variable.create("p"), | ||
230 | Variable.create("top"), | ||
231 | Variable.create("bot") | ||
232 | ) | ||
233 | } | ||
234 | |||
235 | } | ||