guile-rdf/test-modules/online.scm

online.scm

1
;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu>
2
;;;; 
3
;;;; This library is free software; you can redistribute it and/or
4
;;;; modify it under the terms of the GNU Lesser General Public
5
;;;; License as published by the Free Software Foundation; either
6
;;;; version 3 of the License, or (at your option) any later version.
7
;;;; 
8
;;;; This library is distributed in the hope that it will be useful,
9
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
;;;; Lesser General Public License for more details.
12
;;;; 
13
;;;; You should have received a copy of the GNU Lesser General Public
14
;;;; License along with this library; if not, write to the Free Software
15
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
;;;; 
17
18
(define-module (test-modules online)
19
  #:use-module (ice-9 match)
20
  #:use-module (rnrs bytevectors)
21
  #:use-module (srfi srfi-1)
22
  #:use-module (test-modules result)
23
  #:use-module ((rdf entailment simple) #:prefix simple:)
24
  #:use-module (rdf rdf)
25
  #:use-module (srfi srfi-1)
26
  #:use-module (turtle tordf)
27
  #:use-module (web client)
28
  #:use-module (web response)
29
  #:export (run-test-suite
30
            run-test-suites))
31
32
(define (get-objects triples predicate)
33
  (map
34
    rdf-triple-object
35
    (filter
36
      (lambda (t)
37
        (equal? (rdf-triple-predicate t) predicate))
38
      triples)))
39
40
(define (lexical->value value)
41
  (cond
42
    ((rdf-literal? value)
43
     (rdf-literal-lexical-form value))
44
    ((blank-node? value)
45
     (string-append "_:" (number->string value)))
46
    (else value)))
47
48
(define (execute-test test)
49
  (let* ((predicates (test-case-document test))
50
         (type (car (get-objects predicates "http://www.w3.org/1999/02/22-rdf-syntax-ns#type")))
51
         (type (car (reverse (string-split type #\#))))
52
         (action (car (get-objects predicates "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#action"))))
53
    (turtle->rdf (get-test-doc action) action)))
54
55
(define (run-test test)
56
  (let* ((predicates (test-case-document test))
57
         (type (car (get-objects predicates "http://www.w3.org/1999/02/22-rdf-syntax-ns#type")))
58
         (type (car (reverse (string-split type #\#))))
59
         (result
60
           (catch #t
61
             (lambda ()
62
               (execute-test test))
63
             (lambda (key . value)
64
               (cons key value)))))
65
    (cond
66
      ((member type '("TestTurtlePositiveSyntax" "TestTriGPositiveSyntax"
67
                      "TestNTriplesPositiveSyntax" "TestNQuadsPositiveSyntax"))
68
       (match result
69
         (((? symbol? key) . value)
70
          (update-test-case test
71
            #:result 'fail
72
            #:reason (format #f "failed with ~a: ~a" key value)))
73
         (_ (update-test-case test #:result 'pass))))
74
      ((member type '("TestTurtleNegativeSyntax" "TestTriGNegativeSyntax"
75
                      "TestNTriplesNegativeSyntax" "TestNQuadsNegativeSyntax"
76
                      "TestXMLNegativeSyntax" "TestTurtleNegativeEval"))
77
       (match result
78
         (((? symbol? key) . value) (update-test-case test #:result 'pass))
79
         (_ (update-test-case test
80
              #:result 'fail
81
              #:reason "Expected failure but got success"))))
82
      ((equal? type "TestTurtleEval")
83
       (let* ((expected (car (get-objects predicates "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#result")))
84
              (expected
85
                (catch #t
86
                  (lambda ()
87
                    (if expected
88
                        (turtle->rdf (get-test-doc expected) expected)
89
                        #f))
90
                  (lambda (key . value)
91
                    (cons key value)))))
92
         (match result
93
           (((? symbol? key) . value)
94
            (update-test-case test
95
              #:result 'fail
96
              #:reason (format #f "failed with ~a: ~a" key value)))
97
           (_
98
             (if (rdf-isomorphic? result expected)
99
                 (update-test-case test #:result 'pass)
100
                 (update-test-case test
101
                   #:result 'fail
102
                   #:reason (format #f "expected ~a but got ~a"
103
                                    expected result)))))))
104
      ((member type '("PositiveEntailmentTest" "NegativeEntailmentTest"))
105
       (let* ((regime (rdf-literal-lexical-form
106
                        (car
107
                          (get-objects
108
                            predicates
109
                            (string-append
110
                              "http://www.w3.org/2001/sw/DataAccess/tests/"
111
                              "test-manifest#entailmentRegime")))))
112
              (expected
113
                (car
114
                  (get-objects
115
                    predicates
116
                    (string-append "http://www.w3.org/2001/sw/DataAccess/tests/"
117
                                   "test-manifest#result"))))
118
              (expected
119
                (catch #t
120
                  (lambda ()
121
                    (if expected
122
                        (turtle->rdf (get-test-doc expected) expected)
123
                        #f))
124
                  (lambda (key . value)
125
                    (cons key value)))))
126
         (match regime
127
           ("simple"
128
            (if (if (equal? expected #f)
129
                    (simple:consistent-graph? result)
130
                    (simple:entails? result expected))
131
                (if (equal? type "PositiveEntailmentTest")
132
                    (update-test-case test #:result 'pass)
133
                    (update-test-case test
134
                      #:result 'fail
135
                      #:reason "Expected negative result, got positive"))
136
                (if (equal? type "PositiveEntailmentTest")
137
                    (update-test-case test
138
                      #:result 'fail
139
                      #:reason (format #f "Expected positive result, got negative"))
140
                    (update-test-case test #:result 'pass))))
141
           (_ (update-test-case test
142
                #:result 'skip
143
                #:reason (format #f "Unrecognized entailment regime: ~a"
144
                                 regime))))))
145
      (else
146
        (update-test-case test
147
          #:result 'skip
148
          #:reason (format #f "Unrecognized test type: ~a" type))))))
149
150
(define (run-tests tests expected-failures driver)
151
  "Run all the tests of the @var{tests} test suite, using identifiers starting
152
from @var{id}.  Return is undefined."
153
  (fold
154
    (lambda (test results)
155
      (let* ((result (run-test test))
156
             (result
157
               (if (assoc-ref expected-failures (test-case-id test))
158
                   (update-test-case result
159
                     #:result (cond
160
                                ((equal? 'skip (test-case-result result))
161
                                 'skip)
162
                                ((equal? 'fail (test-case-result result))
163
                                 'xfail)
164
                                ((equal? 'pass (test-case-result result))
165
                                 'xpass))
166
                     #:reason (assoc-ref expected-failures (test-case-id test)))
167
                   result)))
168
        ((test-driver-print driver) result)
169
        (cons result results)))
170
    '()
171
    tests))
172
173
(define (get-test-doc url)
174
  "Get a test suite object from the manifest at @var{url}."
175
  (call-with-values
176
    (lambda ()
177
      (http-get url))
178
    (lambda (hdr body)
179
      (if (equal? (response-code hdr) 200)
180
          (if (string? body)
181
              body
182
              (utf8->string body))
183
          (throw 'error-fetching-test-manifest (response-code hdr))))))
184
185
(define* (get-test-plan url #:key (num 1))
186
  (define document (get-test-doc url))
187
188
  (define manifest (turtle->rdf document url))
189
190
  (define tests-node
191
    (rdf-triple-object
192
      (car
193
        (filter
194
          (lambda (triple)
195
            (and (equal? (rdf-triple-subject triple) url)
196
                 (equal? (rdf-triple-predicate triple)
197
                         (string-append "http://www.w3.org/2001/sw/DataAccess/"
198
                                        "tests/test-manifest#entries"))))
199
          manifest))))
200
201
  (define (find-rest node)
202
    (rdf-triple-object
203
      (car
204
        (filter
205
          (lambda (triple)
206
            (and (equal? (rdf-triple-subject triple) node)
207
                 (equal? (rdf-triple-predicate triple)
208
                         (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns"
209
                                        "#rest"))))
210
          manifest))))
211
212
  (define (find-first node)
213
    (rdf-triple-object
214
      (car
215
        (filter
216
          (lambda (triple)
217
            (and (equal? (rdf-triple-subject triple) node)
218
                 (equal? (rdf-triple-predicate triple)
219
                         (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns"
220
                                        "#first"))))
221
          manifest))))
222
223
  (define tests
224
    (let loop ((tests-node tests-node) (tests '()))
225
      (let ((first (find-first tests-node))
226
            (tests-node (find-rest tests-node)))
227
        (if (blank-node? tests-node)
228
            (loop tests-node (cons first tests))
229
            tests))))
230
231
  (cdr
232
    (fold
233
      (lambda (test result)
234
        (let* ((num (car result))
235
               (result (cdr result))
236
               (test-predicates (filter
237
                                  (lambda (t)
238
                                    (equal? (rdf-triple-subject t) test))
239
                                  manifest))
240
               (name (lexical->value (car (get-objects test-predicates "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#name"))))
241
               (description (lexical->value (car (get-objects test-predicates "http://www.w3.org/2000/01/rdf-schema#comment")))))
242
          (cons (+ 1 num)
243
                (cons (make-test-case test num name description
244
                                      (filter
245
                                        (lambda (t)
246
                                          (equal? (rdf-triple-subject t) test))
247
                                        manifest)
248
                                      #f #f)
249
                      result))))
250
      `(,num . ())
251
      tests)))
252
253
(define (run-test-suite manifest expected-failures driver)
254
  "Run a test suite described by @var{manifest}."
255
  (let* ((plan (reverse (get-test-plan manifest))))
256
    ((test-driver-init driver) plan)
257
    ((test-driver-finalize driver) (run-tests plan expected-failures driver))))
258
259
(define (run-test-suites manifests expected-failures driver)
260
  "Run multiple test suites described by @var{manifests}."
261
  (let* ((plan
262
           (fold
263
             (lambda (manifest plan)
264
               (append plan (reverse (get-test-plan
265
                                       manifest #:num (+ (length plan) 1)))))
266
             '()
267
             manifests)))
268
    ((test-driver-init driver) plan)
269
    ((test-driver-finalize driver) (run-tests plan expected-failures driver))))
270