aboutsummaryrefslogtreecommitdiff
path: root/tests/unit/util/sxml-namespaced.scm
blob: b2d55028556f753aaba8405e8b1101d22a6a625d (plain)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
(define-module (test sxml-namespaced)
  :use-module (srfi srfi-64)
  :use-module (srfi srfi-64 test-error)
  :use-module (srfi srfi-88)
  :use-module (ice-9 match)
  :use-module (sxml namespaced)
  :use-module (hnh util state-monad)
  )

;;; TODO tests with attributes

(define (ns x)
  (string->symbol (format #f "http://example.com/~a" x)))

(define (namespaced-symbol ns symb)
  (string->symbol (format #f "~a:~a" ns symb)))



(test-group "XML constructor utility procedure"
  (test-equal "3 args"
    (make-xml-element 'tagname 'namespace 'attributes)
    (xml 'namespace 'tagname 'attributes))

  (test-equal "2 args"
    (make-xml-element 'tagname 'namespace '())
    (xml 'namespace 'tagname))

  (test-equal "1 args"
    (make-xml-element 'tagname #f '())
    (xml 'tagname)))



(test-group "xml->namespaced-sxml"

  (test-equal
      `(*TOP* (,(xml 'tag)))
    (xml->namespaced-sxml "<tag/>"))

  (test-equal
      `(*TOP* (,(xml 'ns1 'tag)))
    (xml->namespaced-sxml "<tag xmlns='ns1'/>"))

  (test-equal
      `(*TOP* (,(xml 'ns2 'tag)))
    (xml->namespaced-sxml "<x:tag xmlns='ns1' xmlns:x='ns2'/>"))

  (test-equal
      `(*TOP* (,(xml 'ns2 'tag)
               (,(xml 'ns1 'tag))))
    (xml->namespaced-sxml "<x:tag xmlns='ns1' xmlns:x='ns2'><tag/></x:tag>"))

  (test-equal "PI are passed directly"
      `(*TOP* ,(make-pi-element 'xml "encoding=\"utf-8\" version=\"1.0\"")
              (,(xml 'tag)))
      (xml->namespaced-sxml "<?xml encoding=\"utf-8\" version=\"1.0\"?><tag/>"))

  (test-equal "Document with whitespace in it"
    `(*TOP* ,(make-pi-element 'xml "")
            (,(xml 'root)
             " "
             (,(xml 'a))
             ))
    (xml->namespaced-sxml "<?xml?><root> <a/></root>"
                          trim-whitespace?: #f))

  ;; TODO is this expected? xml->sxml discards it.
  (test-equal "Whitespace before root is kept"
    `(*TOP* ,(make-pi-element 'xml "")
            (,(xml 'root)))
    (xml->namespaced-sxml "<?xml?> <root/>")))



;;; NOTE that sxml->namespaced-sxml currently ignores any existing xmlns
;;; attributes, since xml->sxml doesn't have those.
(test-group "sxml->namespaced-sxml"
  (test-equal "Simplest"
    `(,(xml 'a)) (sxml->namespaced-sxml '(a) '()))
  (test-equal "With *TOP*"
    `(*TOP* (,(xml 'a))) (sxml->namespaced-sxml '(*TOP* (a)) '()))
  (test-equal "Simplest with namespace"
    `(,(xml (ns 1) 'a))
    (sxml->namespaced-sxml '(x:a)
                           `((x . ,(ns 1)))))
  (test-equal "With pi"
    `(*TOP* ,(make-pi-element 'xml "test")
            (,(xml 'a)))
    (sxml->namespaced-sxml
     `(*TOP*
       (*PI* xml "test")
       (a))
     '()))
  (test-error "With unknown namespace"
    'missing-namespace
    (sxml->namespaced-sxml '(x:a) '())))



(test-group "namespaced-sxml->*"

  ;; /namespaces is the most "primitive" one
  (test-group "/namespaces"
   (test-group "Without namespaces"
       (call-with-values
           (lambda ()
             (namespaced-sxml->sxml/namespaces
              `(*TOP*
                (,(xml 'a)))))
         (lambda (tree namespaces)
           (test-equal `(*TOP* (a)) tree)
           (test-equal '() namespaces))))

   (test-group "With namespaces"
     (call-with-values
         (lambda ()
           (namespaced-sxml->sxml/namespaces
            `(*TOP*
              (,(xml (ns 1) 'a)
               (,(xml (ns 2) 'a))
               (,(xml 'a))))))
       (lambda (tree nss)
         (test-eqv 2 (length nss))
         (test-equal
             `(*TOP*
               (,(namespaced-symbol (assoc-ref nss (ns 1)) 'a)
                (,(namespaced-symbol (assoc-ref nss (ns 2)) 'a))
                (a)))
           tree))))

   (test-group "*PI*"
     (call-with-values
         (lambda ()
           (namespaced-sxml->sxml/namespaces
            `(*TOP*
              ,(make-pi-element 'xml "test")
              (,(xml 'a)))))
       (lambda (tree namespaces)
         (test-equal '() namespaces)
         (test-equal `(*TOP* (*PI* xml "test")
                             (a))
           tree)))))

  (test-group "namespaced-sxml->sxml"
    (test-equal "Without namespaces"
      '(*TOP* (a (@)))
      (namespaced-sxml->sxml `(*TOP* (,(xml 'a)))))

    (test-group "With namespaces"
     (match (namespaced-sxml->sxml `(*TOP* (,(xml (ns 1) 'a))))
       ;; (ns 1) hard coded to work with match
       (`(*TOP* (,el (@ (,key "http://example.com/1"))))
        (let ((el-pair  (string-split (symbol->string el) #\:))
              (key-pair (string-split (symbol->string key) #\:)))
          (test-equal "a" (cadr el-pair))
          (test-equal "xmlns" (car key-pair))
          (test-equal (car el-pair) (cadr key-pair))))
       (any
        (test-assert (format #f "Match failed: ~s" any) #f))))))

;; (namespaced-sxml->xml)
;; Literal strings


(test-error "Namespaces x is missing, note error"
  'parser-error
  (xml->namespaced-sxml "<x:a xmlns:y=\"http://example.com/1\"><x:b/></x:a>"
                        ; `((x . ,(ns 1)))
                        ))

'((sxml namespaced))