-
Notifications
You must be signed in to change notification settings - Fork 31
External Transformation
XSpec v2.0 introduced a new, experimental feature that invokes the tested templates and functions indirectly via fn:transform()
instead of by importing them directly. This feature is controlled by /x:description/@run-as
. This table compares the options for this attribute:
@run-as="import" or Attribute Omitted |
@run-as="external" |
|
---|---|---|
XSpec Imports Tested Stylesheet with xsl:import ? |
Yes | No |
How XSpec Invokes Tested Templates and Functions | Directly | Indirectly, via fn:transform()
|
@run-as="external"
is currently an experimental feature and subject to change. Any feedback is welcome.
@run-as="external"
is only for XSLT and Schematron. The @run-as
attribute is ignored in tests for XQuery.
@run-as="external"
will help when you need to
- test an XSLT package
- test different scenarios with different global XSLT parameters (
//x:scenario/x:param
) - test with a static parameter (
/x:description/x:param/@static
) - expect
x:context
to be the global context item - test a stylesheet containing
xsl:result-document
(requires a Saxon bug fix) - specify a Saxon configuration per scenario (
$x:saxon-config
) - test with
@default-mode
Set /x:description/@run-as
= external
.
Examples can be found in test/external_*.xspec
.
Do not think that @run-as="external"
is universally better just because it's newer. You might find that some of your existing tests cannot use this option.
- You can't test components in a package unless they are exposed or are made accessible via another component.
- Note, in particular, that functions are not exposed by default even if they are in a classic stylesheet (
xsl:stylesheet
orxsl:transform
). If the test usesx:call/@function
with functions that don't declare any visibility, the test will issue an error likeXTDE0041: Cannot invoke function foo#1 externally, because it is not public
. - To test private components, you may want to
- wrap them in an explicit package and expose them using
xsl:expose
, if they are in a classic stylesheet (xsl:stylesheet
orxsl:transform
). - temporarily change their visibility using static parameters, if they are in an explicit package.
- wrap them in an explicit package and expose them using
- Note, in particular, that functions are not exposed by default even if they are in a classic stylesheet (
- In XPath expressions in XSpec files (such as
x:expect/@select
), you can't access variables, functions, keys, or accumulators defined in the tested stylesheet. - You can't override global variables defined in the tested stylesheet.
- Saxon 9.8.0.8 or later is required, because of a breaking change in
vendor-options
offn:transform()
.
The global context item is a context item where global xsl:param
and xsl:variable
are evaluated.
When @run-as
does not exist or it is @run-as="import"
, the global context item is always absent.
When @run-as="external"
, every XSpec scenario has a different global context item depending on how the tested component is invoked:
- If
x:context
is a single node, the root node of thex:context
tree becomes the global context item. - If
x:context
is not a single node, the global context item is absent.
- If
x:call
is preceded byx:context
, the template (@template
) or the function (@function
) is invoked once for each item inx:context
. Each item inx:context
is the global context item of each invocation. - If
x:call
is not preceded byx:context
, the global context item is absent.
XSpec global parameters (/x:description/x:param
) and scenario-level parameters (//x:scenario/x:param
)
They take effect in the tested stylesheet, overriding a global xsl:param
element declared there. XSpec tests that use external transformations cannot override global xsl:variable
elements in the tested stylesheet.
They do not take effect in the tested stylesheet. They can be used only in XPath expressions in XSpec files (such as x:expect/@select
).
If you need to configure Saxon options for the external transform, you can use x:variable
in your XSpec file to create a variable named $x:saxon-config
. When the test invokes fn:transform
, the input map that defines transformation options includes a vendor-options
map entry whose key is QName('http://saxon.sf.net/', 'configuration')
and whose value is your value of $x:saxon-config
.
Note:
- On Saxon 9.9.1.6 or earlier, URI in
$x:saxon-config
may need to be absolute due to a Saxon bug. - When you use
$x:saxon-config
, the tested stylesheet can't call a function passed as a parameter. (example)
Code Coverage does not support xsl:use-package
. Stylesheets specified by xsl:use-package
do not appear in the coverage report.
The @run-as
attribute determines whether an XSLT stylesheet's @default-mode
attribute takes effect during testing of template rules.
When @run-as
does not exist or it is @run-as="import"
, x:context
elements without a @mode
attribute use the unnamed mode, even if the XSLT stylesheet specifies a default mode.
When @run-as="external"
, x:context
elements without a @mode
attribute use the mode specified in the stylesheet's @default-mode
attribute.
If you have any questions about XSpec or want to discuss, contribute, and share information with the XSpec community, please go to our issue tracker.
For historical searches, the Google group might also be useful.
- Writing Scenarios
- Nesting Scenarios
- Focusing Your Efforts
- Global Context Item
- Selecting Nodes
- Whitespace-only Text Nodes
- Attribute Value Templates
- Text Value Templates
- Special Names
- Code Coverage
- XML Catalog Support
- Environment Variables
- Testing Dynamic Errors
- Integrating Your Own Test Helpers
- External Transformation
- Getting Started with XSpec and Schematron
- Writing Scenarios for Schematron
- Testing Schematron with Text Nodes
- Testing Schematron with Attributes
- Using Another Implementation of Schematron