guile-rdf/test-modules/test-case.scm

test-case.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 test-case)
19
  #:use-module (ice-9 match)
20
  #:use-module (rdf rdf)
21
  #:use-module ((rdf xsd) #:prefix xsd:)
22
  #:use-module (srfi srfi-9)
23
  #:export (test-case
24
            make-test-case
25
            test-case?
26
            test-case-id
27
            test-case-name
28
            test-case-regime
29
            test-case-recognized
30
            test-case-unrecognized
31
            test-case-action
32
            test-case-result
33
34
            rdf->test-plan))
35
36
;; A test case is the result of running a test.  It has an identifier, a name
37
;; and a description.  Its result is a symbol, which can be 'skiped, 'pass,
38
;; 'fail, 'xpass, or 'xfail.  The reason is a string or #f that explains the
39
;; result
40
(define-record-type test-case
41
  (make-test-case type name regime recognized unrecognized action result)
42
  test-case?
43
  (type         test-case-type)
44
  (name         test-case-name)
45
  (regime       test-case-regime)
46
  (recognized   test-case-recognized)
47
  (unrecognized test-case-unrecognized)
48
  (action       test-case-action)
49
  (result       test-case-result))
50
51
(define (find-rest node graph)
52
  (rdf-triple-object
53
    (car
54
      (filter
55
        (lambda (triple)
56
          (and (equal? (rdf-triple-subject triple) node)
57
               (equal? (rdf-triple-predicate triple)
58
                       (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns"
59
                                      "#rest"))))
60
        graph))))
61
62
(define (find-first node graph)
63
  (rdf-triple-object
64
    (car
65
      (filter
66
        (lambda (triple)
67
          (and (equal? (rdf-triple-subject triple) node)
68
               (equal? (rdf-triple-predicate triple)
69
                       (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns"
70
                                      "#first"))))
71
        graph))))
72
73
(define (find-list node graph)
74
  "When @var{node} represents a list, traverse it to find all its elements, and
75
return a list of nodes corresponding to the elements of the list."
76
  (if (blank-node? node)
77
      (let loop ((node node) (result '()))
78
        (let ((first (find-first node graph))
79
              (node (find-rest node graph)))
80
          (if (blank-node? node)
81
              (loop node (cons first result))
82
              (cons first result))))
83
      '()))
84
85
(define (get-objects triples predicate)
86
  "Return every objects in the @var{triples} that use @var{predicate}."
87
  (map
88
    rdf-triple-object
89
    (filter
90
      (lambda (t)
91
        (equal? (rdf-triple-predicate t) predicate))
92
      triples)))
93
94
(define (get-object triples predicate)
95
  "Return the only object in the @var{triples} that uses @var{predicate}."
96
  (match (get-objects triples predicate)
97
    ((object) object)
98
    (() #f)
99
    (objects (throw 'too-many objects))))
100
101
(define (lexical->value value)
102
  (cond
103
    ((and (rdf-literal? value)
104
          (equal? (rdf-literal-type value)
105
                  "http://www.w3.org/2001/XMLSchema#boolean"))
106
     (equal? (rdf-literal-lexical-form value) "true"))
107
    ((rdf-literal? value)
108
     (rdf-literal-lexical-form value))
109
    ((blank-node? value)
110
     (string-append "_:" (number->string value)))
111
    (else value)))
112
113
(define (mf v)
114
  (string-append "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#"
115
                 v))
116
(define (qt v)
117
  (string-append "http://www.w3.org/2001/sw/DataAccess/tests/test-query#" v))
118
(define (rdf v)
119
  (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns#" v))
120
(define (rdfs v)
121
  (string-append "http://www.w3.org/2000/01/rdf-schema#" v))
122
123
(define (subgraph-at graph node)
124
  "When @var{graph} is a list of triples, find the triples whose subjects is
125
@var{node}, or the objects these triples, recursively.  Return the subgraph
126
that is rooted at @var{node}."
127
  (let ((nodes (filter
128
                 (lambda (t)
129
                   (equal? (rdf-triple-subject t) node))
130
                 graph)))
131
    (if (null? nodes)
132
        '()
133
        (apply append nodes
134
               (map
135
                 (lambda (n)
136
                   (subgraph-at graph (rdf-triple-object n)))
137
                 nodes)))))
138
139
(define (rdf->test-plan manifest url)
140
  "Return a list of test-case objects from @var{manifest}, an rdf document that
141
was downloaded from @var{url}."
142
  (define tests-node
143
    (get-object manifest (mf "entries")))
144
145
  ;;The list of test node IDs
146
  (define tests
147
    (find-list tests-node manifest))
148
149
  (map
150
    (lambda (test-id)
151
      (let* ((subgraph (subgraph-at manifest test-id))
152
             (name (get-object subgraph (mf "name")))
153
             (type (get-object subgraph (rdf "type")))
154
             (action (get-object subgraph (mf "action")))
155
             (regime (get-object subgraph (mf "entailmentRegime")))
156
             (recognized (get-object subgraph (mf "recognizedDatatypes")))
157
             (unrecognized (get-object subgraph (mf "unrecognizedDatatypes")))
158
             (result (get-object subgraph (mf "result"))))
159
        (make-test-case
160
          (car (reverse (string-split type #\#)))
161
          (lexical->value name)
162
          (if regime (lexical->value regime) #f)
163
          (if recognized
164
              (map
165
                (lambda (iri)
166
                  ;; find types to recognize from the list of types below
167
                  (let loop ((types (cons* rdf:XMLLiteral rdf:langString
168
                                           xsd:datatypes)))
169
                    (match types
170
                      (() (throw 'didnotrecognize iri))
171
                      ((type types ...)
172
                       (if (member iri (rdf-datatype-iris type))
173
                           type
174
                           (loop types))))))
175
                (find-list recognized subgraph))
176
              '())
177
          '(); XXX: unrecognized
178
          (lexical->value action)
179
          (lexical->value result))))
180
    tests))
181