-
Notifications
You must be signed in to change notification settings - Fork 0
/
xspec.rnc
304 lines (267 loc) · 12.4 KB
/
xspec.rnc
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# XSpec = XSLT Specifications
# This schema is for XSpec documents, which can be used to describe the behaviour
# of an XSLT application. They are similar to the RSpec documents used in RoR
# testing, but for XSLT
default namespace = "http://www.jenitennison.com/xslt/xspec"
datatypes xs = "http://www.w3.org/2001/XMLSchema-datatypes"
start = description
description =
## A description is a description of a stylesheet application.
## It must have a stylesheet and/or a query it's associated with.
## It may also have a version to aid development over time.
element description {
common-attributes,
attribute stylesheet { xs:anyURI }?,
attribute query { xs:anyURI }?,
attribute xslt-version { xs:NMTOKEN }?,
attribute query-at { xs:anyURI }?,
attribute version { xs:NMTOKEN }?,
attribute preserve-space { xs:NMTOKENS }?,
attribute schematron { xs:anyURI }?,
(global-param | import | scenario | pending)+ }
import =
## An import brings in all the scenarios from the referenced file (which must
## itself be an XSpec description). All the unshared scenarios in that imported
## XSpec will be run on the stylesheet that this XSpec document describes.
## Importing is recursive and may be circular (although only one copy of a given
## imported document will actually be imported).
element import { common-attributes,
## The document URI (location) of the imported document.
attribute href { xs:anyURI } }
pending =
## Anything that is within a <pending> element will remain untested, but will be
## reported as (eventual) desired behaviour. This is a good way of commenting out
## a set of behaviours that haven't been implemented yet, or scenarios whose
## desired behaviour hasn't been determined, or tests for code that you're not
## currently working on, to make the testing process faster.
##
## An optional label attribute can be used to describe why the scenario or
## assertion should not be tested.
element pending { common-attributes, label?, (scenario | assertion | schematron-assertion)* }
scenario =
## A scenario defines the environment in which a piece of processing takes place.
##
## Any parameters defined within a scenario equate to global (stylesheet)
## parameters.
##
## If a scenario has a pending attribute, this has the same semantics as
## wrapping the scenario in a <pending> element with a label equal to the value
## of the pending attribute.
##
## If any scenario has a focus attribute, any scenarios without a focus
## attribute will be classed as pending.
element scenario { common-scenario-attributes, shared?,
label,
( matching-scenario |
function-scenario |
named-scenario |
schematron-scenario ) }
common-scenario-attributes = common-attributes,
## Anything which has the @pending attribute will remain untested, but will be
## reported as (eventual) desired behaviour. This is a good way of commenting out
## a set of behaviours that haven't been implemented yet, or scenarios whose
## desired behaviour hasn't been determined, or tests for code that you're not
## currently working on, to make the testing process faster.
##
## The attribute value can be used to describe why the scenario or
## assertion should not be tested.
attribute pending { text }?,
## If any scenario has a focus attribute, any scenarios without a focus
## attribute will be classed as pending.
attribute focus { text }?
label =
## A scenario's label should describe the context that the scenario sets. Top-
## level scenarios' labels should be of the form "the square of a number" or
## "the XHTML for a <P1> element". Nested scenario labels will usually start with
## the word "with"; it should make sense if the labels of ancestor scenarios are
## concatenated with this one. For example "with a Type attribute".
attribute label { text } |
element label { any-content }
shared =
## There are shared scenarios (shared="yes") and unshared scenarios (shared="no",
## the default). Shared scenarios can be referenced and reused by other scenarios
## with the <like> element. Unshared scenarios are simply run.
attribute shared { "yes" | "no" }
like =
## The <like> element pulls a shared scenario into this one (which may be shared
## or unshared). Any environment set within the shared scenario is merged with
## this one, and any tests in the shared scenario are run in addition to the
## ones in this scenario. This allows for modular, reusable sets of tests which
## can be applied in multiple contexts.
element like { common-attributes, label }
## A matching scenario is one based on the application of templates to a
## particular node. The <context> element defines <xsl:apply-templates> used to
## process the node, and the <assertion> elements define the tests on that node.
## Child scenarios can override the parameters in the context, and can provide
## any missing values in the <context> (for example, if the context on the parent
## scenario doesn't provide a mode, that could be provided by the child scenario).
matching-scenario = context?,
like*,
(pending | assertion)*,
(pending |
element scenario { common-scenario-attributes,
label, matching-scenario })*
## A function scenario is one based on a call to a stylesheet function. The
## <call> element defines the function call and the paraemeters passed to it
## and the <assertion> elements test the result of the function. Child scenarios
## can override the parameters in the function call.
function-scenario = function-call?,
like*,
(pending | assertion)*,
(pending |
element scenario { common-scenario-attributes,
label, function-scenario })*
## A named scenario is one based on a call to a named template. The <call>
## element defines the template call and the parameters passed to it and the
## <assertion> elements test the result of the template call. Child scenarios
## can override the parameters in the template call.
named-scenario = context?,
template-call?,
like*,
(pending | assertion)*,
(pending |
element scenario { common-scenario-attributes,
label, named-scenario })*
context =
## The <context> element defines a context node, the mode in which templates
## are applied to it, and any parameters included in the apply templates.
element context {
common-attributes,
## The mode in which templates are applied to it, and any parameters included in the apply templates.
attribute mode { xs:QName }?,
template-param*,
node-selection
}
function-call =
## A <call> element either defines a function call or a template call and the
## parameters passed to it.
element call {
common-attributes,
## The qualified name of the function which should get called.
attribute function { xs:QName }?,
function-param*
}
template-call =
## A <call> element either defines a function call or a template call and the
## parameters passed to it.
element call {
common-attributes,
## The qualified name of the template which should get called.
attribute template { xs:QName }?,
template-param*
}
global-param =
## Global parameters are set globally, for the entire unit test suite. There's
## no way to set global parameters within a particular scenario (due to
## constraints on implementation).
element param { name, selection }
template-param = element param { common-attributes,
name, as?,
attribute tunnel { "yes" | "no" }?, selection }
function-param = element param { common-attributes,
name?, as?, position?, selection }
name = attribute name { xs:QName }
position = attribute position { xs:integer }
as = attribute as { text }
selection = node-selection | value-selection
node-selection =
## The document URI (location) of the imported document.
attribute href { xs:anyURI }?,
## The XPath expression to access the selected node.
attribute select { xpath }?,
any-content
value-selection =
## The XPath expression to access the selected node.
attribute select { xpath }
xpath = text
assertion =
## An assertion's test XPath can either return a boolean value, in which case the
## assertion succeeds only if the test is true; or a node, in which case the
## assertion succeeds only if the node is equal to the one specified with the
## href and select attributes or content of the <expect> element.
element expect { common-attributes,
label, test?, selection }
test = attribute test { xpath }
common-attributes = attribute xml:* { text }*
any-content = mixed { any-element* }
any-element = element * { attribute * { text }*, any-content }
schematron-scenario = context?,
like*,
(pending | schematron-assertion | assertion)*,
(pending |
element scenario { common-scenario-attributes,
label, schematron-scenario })*
schematron-assertion =
expect-assert | expect-not-assert |
expect-report | expect-not-report |
expect-valid | expect-rule
expect-valid =
## In a Schematron test, verify that the Schematron is executed and the XML
## that is provided as context passes validation.
##
## In the Schematron an <assert> or <report> can have a <role> attribute
## specifying that it is a warning or informational message and these are
## considered to be allowed for a passing validation.
element expect-valid { empty }
expect-assert =
## In a Schematron test, verify that an <assert> is thrown.
##
## The attributes id, role, and location can be used in combination to
## identify a specific <assert>.
element expect-assert {
schematron-common-expect,
schematron-count-expect
}
expect-report =
## In a Schematron test, verify that a <report> is thrown.
##
## The attributes id, role, and location can be used in combination to
## identify a specific <report>.
element expect-report {
schematron-common-expect,
schematron-count-expect
}
expect-not-assert =
## In a Schematron test, verify that an <assert> is not thrown.
##
## The attributes id, role, and location can be used in combination to
## identify a specific <assert>.
element expect-not-assert {
schematron-common-expect
}
expect-not-report =
## In a Schematron test, verify that a <report> is not thrown.
##
## The attributes id, role, and location can be used in combination to
## identify a specific <report>.
element expect-not-report {
schematron-common-expect
}
expect-rule =
## In a Schematron test, verify that a <rule> is fired.
element expect-rule {
## Optional label to describe the expectation.
attribute label { text }?,
## Identify a specific <rule> using its id attribute.
attribute id { xs:NCName }?,
## Match a specific context attribute value of a <rule>.
attribute context { text }?,
schematron-count-expect
}
schematron-common-expect =
## Optional label to describe the expectation.
attribute label { text }?,
## Identify a specific <assert> or <report> using its id attribute or
## the id attribute of the parent <rule>.
attribute id { xs:NCName }?,
## Match a specific role attribute value of an <assert> or <report> or
## the parent <rule>. Role attribute values are often used to specify
## 'error', 'fatal', 'warn', 'warning', 'info', 'information'.
attribute role { text }?,
## XPath of a location in the context XML that the <assert> or <report>
## is expected to find. Namespace prefixes that are defined in Schematron
## using ns elements can be used.
attribute location { xpath }?
schematron-count-expect =
## Number of times an <assert> or <report> is expected to be thrown.
attribute count { xs:nonNegativeInteger }?