# Features covered: XSLT transformation
#
# This file contains a collection of tests for the XSLT engine of
# tDOM. It is focused mainly on the tcl interface of the engine; the
# vaste majority of xslt compliance tests are done outside the tcltest
# framework.
#
# Tested commands and object commands:
# xslt-1.*: xpath Lexer/parser tests
# xslt-2.*: xslt method command variants, -parameters option
# xslt-3.*: xslt vars, scope, parameters
# xslt-4.*: xslt transformations on modified/created from the scratch docs
# xslt-5.*: xslt document()
# xslt-6.*: xsl:output
# xslt-7.*: tests related to the created result doc
# xslt-8.*: Additional xslt rec compliance tests (details not covered by
# by the external xslt compliance test suite).
#
# Copyright (c) 2002 Rolf Ade.
#
# RCS: @(#) $Id: xslt.test,v 1.20 2004/07/28 03:44:10 rolf Exp $
source [file join [file dir [info script]] loadtdom.tcl]
test xslt-1.1 {unicode chars outside of US-ASCII in var name} {need_i18n} {
set xml [dom parse {}]
set xslt [dom parse [tDOM::xmlReadFile [file join [pwd] [file dir [info script]] data/xslt_1.xsl]]]
set xmlroot [$xml documentElement]
$xmlroot xslt $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {foo}
test xslt-1.2 {xpath parse real number} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {0.12345}
test xslt-1.3 {xpath parse real number} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {-0.12345}
test xslt-1.4 {pattern IsFQElement with FillNodeList} {
set xml [dom parse {}]
set xslt [dom parse {
}]
$xml xslt $xslt resultDoc
set result [$resultDoc asXML -indent none]
$xslt delete
$xml delete
$resultDoc delete
set result
} {m:elem}
test xslt-2.1 {xslt top level parameter: use default value} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {parameter1Value}
test xslt-2.2 {xslt top level parameter: overwrite default value with -parameters} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {parameter1 startValue} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {startValue}
test xslt-2.3 {xslt top level parameter: overwrite default value with -parameters} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {parameter1 startValue} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {startValue parameter2Value}
test xslt-2.4 {xslt top level parameter: overwrite default value with -parameters} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {parameter1 startValue1 parameter2 startValue2} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {startValue1 startValue2}
test xslt-2.5 {xslt top level parameter: try to set nonexisted param} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
catch {$xmlroot xslt -parameters {nonExistend foo} $xslt resultDoc} errMsg
$xml delete
$xslt delete
set errMsg
} {There isn't a parameter named "nonExistend" defined at top level in the stylesheet.}
test xslt-2.6 {xslt top level parameter: try to set variable} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
catch {$xmlroot xslt -parameters {variable1 foo} $xslt resultDoc} errMsg
$xml delete
$xslt delete
set errMsg
} {"variable1" is defined as variable, not as parameter.}
test xslt-2.7 {xslt top level parameter} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
catch {$xmlroot xslt -parameters {parameter2 foo} $xslt resultDoc} errMsg
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {variable1Value foo}
test xslt-2.8 {xslt top level parameter: wrong usage of -parameters option} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
catch {$xmlroot xslt -parameters $xslt resultDoc} errMsg
$xml delete
$xslt delete
set errMsg
} {parameter value missing: the -parameters option needs a list of parameter name and parameter value pairs}
test xslt-2.9 {xslt top level parameter: wrong usage of -parameters option} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
catch {$xmlroot xslt -parameters {foo bar baz} $xslt resultDoc} errMsg
$xml delete
$xslt delete
set errMsg
} {parameter value missing: the -parameters option needs a list of parameter name and parameter value pairs}
test xslt-2.10 {no resultDoc variable name} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
set resultDoc [$xmlroot xslt $xslt]
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {parameter1Value}
test xslt-2.11 {xslt top level parameter: set with 'strange' value} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {parameter1 foo\"'<>bar} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {foo"'<>bar}
# emacs: "
test xslt-2.12 {xslt top level parameter: set FQ top-level param} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {foo:parameter1 setValue} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {setValue}
test xslt-2.13 {xslt top level parameter: set FQ top-level param} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {foo:parameter1 setValue} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {setValue}
test xslt-2.14 {xslt top level parameter: set FQ top-level param} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -parameters {foo:parameter1 setValue} $xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot asXML]
$xml delete
$xslt delete
$resultDoc delete
set result
} {setValue}
test xslt-2.15 {xslt top level parameter:\
try to set nonexisted param with ignore} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
set result [catch {$xmlroot xslt -ignoreUndeclaredParameters\
-parameters {nonExistend foo}\
$xslt resultDoc} errMsg]
$resultDoc delete
$xml delete
$xslt delete
set result
} {0}
test xslt-2.16 {xslt top level parameter: try to set nonexisted param with ignore} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
set xmlroot [$xml documentElement]
$xmlroot xslt -ignoreUndeclaredParameters \
-parameters {nonExistend foo parameter2 givenValue} \
$xslt resultDoc
set resultroot [$resultDoc documentElement]
set result [$resultroot nodeValue]
$resultDoc delete
$xml delete
$xslt delete
set result
} {parameter1Value givenValue}
proc xsltmessagecmd {msg terminate} {
global xsltMsgs
global terminatingMsg
append xsltMsgs "$msg terminate: $terminate "
if {$terminate} {
set terminatingMsg 1
} else {
set terminatingMsg 0
}
}
test xslt-2.17 {xslt - to less arguments to the method} {
set xml [dom parse {}]
set result [catch {$xml xslt}]
$xml delete
set result
} {1}
test xslt-2.18 {xslt -xsltmessagecmd} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
some text
1. call
2. call
3. call
}]
set xmlroot [$xml documentElement]
set ::xsltMsgs ""
$xmlroot xslt -xsltmessagecmd xsltmessagecmd $xslt resultDoc
$resultDoc delete
$xml delete
$xslt delete
set ::xsltMsgs
} {1. call terminate: 0 2. call terminate: 0 3. call terminate: 0 }
test xslt-2.19 {xslt -xsltmessagecmd} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
some text
1. call
2. call
3. call
}]
set xmlroot [$xml documentElement]
set ::xsltMsgs ""
catch {$xmlroot xslt -xsltmessagecmd xsltmessagecmd $xslt resultDoc}
$xml delete
$xslt delete
set ::terminatingMsg
} {1}
test xslt-2.20 {xslt top level parameter: use top level param to set a top level var} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
$xml xslt -parameters {sortentity "the parameter value"} $xslt resultDoc
set result [$resultDoc asXML -indent none]
$resultDoc delete
$xml delete
$xslt delete
set result
} {the parameter value}
test xslt-3.1 {xslt variable scope} {
set xml [dom parse {}]
set xslt [dom parse {
}]
set xmlroot [$xml documentElement]
catch {$xmlroot xslt $xslt resultDoc} errMsg
$xml delete
$xslt delete
set errMsg
} {Variable "main" has not been declared.}
test xslt-3.2 {xslt error msg of variable redeclaration in one template} {
set xml [dom parse {}]
set xslt [dom parse {
}]
catch {$xml xslt $xslt resultDoc} errMsg
$xml delete
$xslt delete
set errMsg
} {Variable 'var' is already declared in this template}
test xslt-3.3 {use top level var to set a top level var} {
set xml [dom parse -keepEmpties {}]
set xslt [dom parse -keepEmpties {
}]
$xml xslt $xslt resultDoc
set result [$resultDoc asXML -indent none]
$resultDoc delete
$xml delete
$xslt delete
set result
} {var1Value}
test xslt-4.1 {xslt transformation of a source which was modifed after parsing} {
dom parse -baseurl file:///tmp/abc.xml {} doc
$doc documentElement root
$root appendXML
dom parse {
} xslDoc
$root xslt $xslDoc newDoc
set result [$newDoc asXML -indent none]
$doc delete
$xslDoc delete
$newDoc delete
set result
} {}
set xslt {
Data stored in the stylesheet
}
proc 5.1-extref {baseURI systemId publicId} {
if {$baseURI != ""} {
error "baseURI not empty"
}
if {$systemId != ""} {
error "systemId not empty"
}
return [list string "" $::xslt]
}
test xslt-5.1 {xslt document('') with empty baseURI} {
dom parse xmldoc
dom parse -externalentitycommand 5.1-extref $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set result [$resultDoc asXML -indent none]
$resultDoc delete
$xsltdoc delete
$xmldoc delete
set result
} {Data stored in the stylesheet}
proc xslt-5.2 {args} {
error "script error in xslt-5.2 external enitity resolver"
}
set xslt {
}
test xslt-5.2 {xslt document() with script error in -externalentitycommand} {
dom parse xmldoc
dom parse -externalentitycommand xslt-5.2 $xslt xsltdoc
set result [catch {$xmldoc xslt $xsltdoc resultDoc} errMsg]
$xmldoc delete
$xsltdoc delete
lappend result $errMsg
} {1 {script error in xslt-5.2 external enitity resolver}}
proc xslt-5.3 {args} {
return [list string file://some/base " xmldoc
dom parse -externalentitycommand xslt-5.3 $xslt xsltdoc
set result [catch {$xmldoc xslt $xsltdoc resultDoc} errMsg]
$xmldoc delete
$xsltdoc delete
lappend result $errMsg
} {1 {Error while processing external entity "foo":
At line 1 character 15: not well-formed (invalid token)}}
proc xslt-5.4 {base systemId publicId} {
switch $systemId {
"firstlevel" {
return [list string file://some/base/first {
}]
}
"secondlevel" {
return [list string file://some/base/second "
foo
}
test xslt-5.4 {xslt document() with script error in -externalentitycommand} {
dom parse xmldoc
dom parse -externalentitycommand xslt-5.4 $xslt xsltdoc
set result [catch {$xmldoc xslt $xsltdoc resultDoc} errMsg]
$xmldoc delete
$xsltdoc delete
lappend result $errMsg
} {1 {Error while processing external entity "secondlevel":
At line 1 character 15: not well-formed (invalid token)}}
set xslt {
}
test xslt-6.1 {xsl:output} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set result [$resultDoc indent]
lappend result [$resultDoc omit-xml-declaration]
lappend result [$resultDoc encoding]
lappend result [$resultDoc mediaType]
lappend result [$resultDoc standalone]
lappend result [$resultDoc getDefaultOutputMethod]
$resultDoc delete
$xsltdoc delete
$xmldoc delete
set result
} {1 0 ISO-8859-1 text/foo 1 text}
set xslt {
}
test xslt-7.1 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set nodes [$resultDoc getElementsByTagNameNS "http://my.uri" element]
set result ""
foreach node $nodes {
lappend result [$node nodeName]
}
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {my:element}
test xslt-7.2 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set result [$resultDoc asXML -indent none]
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {}
test xslt-7.3 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
$resultDoc documentElement root
set my:element [$root firstChild]
set result [${my:element} namespaceURI]
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {http://my.uri}
set xslt {
}
test xslt-7.4 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set nodes [$resultDoc getElementsByTagNameNS "" element]
set result ""
foreach node $nodes {
lappend result [$node nodeName]
}
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {element}
test xslt-7.5 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set nodes [$resultDoc getElementsByTagName element]
set result ""
foreach node $nodes {
lappend result [$node nodeName]
}
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {element}
set xslt {
}
test xslt-7.6 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set nodes [$resultDoc getElementsByTagNameNS "element.uri" *]
set result ""
foreach node $nodes {
lappend result [$node nodeName]
}
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {element}
test xslt-7.7 {parent of the result doc documentElement} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set resultRoot [$resultDoc documentElement]
set result [$resultRoot parentNode]
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {}
set xslt {
}
test xslt-7.8 {namespaces in the result doc} {
dom parse xmldoc
dom parse $xslt xsltdoc
$xmldoc xslt $xsltdoc resultDoc
set nodes [$resultDoc getElementsByTagNameNS "http://my.uri" *]
set result ""
foreach node $nodes {
lappend result [$node nodeName]
}
$resultDoc delete
$xmldoc delete
$xsltdoc delete
set result
} {my:element my:foo}
set xslt {
}
set xml {}
test xslt-8.1 {current() not allowed in pattern} {
dom parse $xml xmldoc
dom parse $xslt xsltdoc
catch {$xmldoc xslt $xsltdoc resultDoc} errMsg
$xmldoc delete
$xsltdoc delete
set errMsg
} {The 'current' function is not allowed in Pattern. for '*[current() != 'notthis']'
Parsed symbols:
0 WCARDNAME 0 0.000 0 *
1 LBRACKET 0 0.000 1
2 FUNCTION 0 0.000 8 current
3 LPAR 0 0.000 9
4 RPAR 0 0.000 10
5 NOTEQ 0 0.000 13
6 LITERAL 0 0.000 23 notthis
7 RBRACKET 0 0.000 24 }
# Below is code, which replaces the dom cmd with a version, which parses
# the xml into a dom tree, then transformations this dom tree with the
# xslt identity transformation and returns the result tree of that
# transformation. This is used to test, that the result tree of an xslt
# transformation could be used as any 'ordinary' tree created with
# [dom parse]. It is here, because I didn't want to hold it seperated.
# It is commented out, because some of the tests in the sourced test files
# need line/column or baseURI information, to work correctly, and this
# information is not preserved by an xslt identity transformation and
# I was up to now too lazy, to trick around this few tests with some
# test constraints.
#
# set identityTransformation [dom parse {
#
#
#
#
#
# }]
# rename dom _dom
# proc dom {args} {
# global identityTransformation
# switch [lindex $args 0] {
# "parse" {
# set resultdoc [uplevel 1 [linsert $args 0 _dom]]
# return [$resultdoc xslt $identityTransformation]
# }
# default {
# return [uplevel 1 [linsert $args 0 _dom]]
# }
# }
# }
# source [file join [file dir [info script]] i18n.test]
# source [file join [file dir [info script]] dom.test]
# rename dom {}
# rename _dom dom
# cleanup
::tcltest::cleanupTests
return