# Commands covered: ::dom::DOMimplementation parse # # This file contains a collection of tests for one or more of the # TclDOM commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1998-2003 Zveno Pty Ltd. # # $Id: parse.test,v 1.8 2003/01/26 04:35:15 balls Exp $ package require tcltest ; namespace import -force ::tcltest::* source testutils.tcl testPackage dom testConstraint sa [file exists $::tcltest::testsDirectory/sa] # checkTree -- # # Checks a DOM tree structure against an expected tree # structure, given as a nested Tcl list. # # Arguments: # token DOM node token of document # s structure given as nested Tcl list # # Results: # Returns 1 if structure matches, 0 otherwise proc checkTree {token s} { return 1 } proc readUtfOrUnicode {name} { set f [open $name r] fconfigure $f -encoding binary set prefix [read $f 2] seek $f 0 start if {[string equal $prefix \u00ff\u00fe]} { fconfigure $f -encoding identity } else { fconfigure $f -encoding utf-8 } set xml [read $f] close $f return $xml } proc readBinary {name} { set f [open $name r] fconfigure $f -encoding binary set data [read $f] close $f return $data } proc makeUnicode {data} { return [encoding convertfrom identity [encoding convertto unicode $data]] } test parse-1.1 {single element document} -body { set result [::dom::DOMImplementation parse { }] checkTree $result { {pi xml} {pi DOCTYPE} {element Test {} {}} } } -result 1 test parse-1.2 {nested element document} -body { set result [::dom::DOMImplementation parse { }] checkTree $result { {pi xml} {pi DOCTYPE} {element Test {} { {element Nested {} { {element Deeper {} {}} }} {element Nested {} {}} } } {element Test {} {}} } } -result 1 test parse-1.3 {elements with attributes} -body { set result [::dom::DOMImplementation parse { }] checkTree $result { {pi xml} {pi DOCTYPE} {element Test {} { {element Nested {depth 1} { {element Nested {depth 2} {}} }} } } } } -result 1 test parse-1.4 {elements with text content} -body { set result [::dom::DOMImplementation parse { Inside DeeperSecond Nested}] checkTree $result { {pi xml} {pi DOCTYPE} {element Test {} { {element Nested {} { {element Deeper {} { {text {Inside Deeper}} }} }} {element Nested {} { {text {Second Nested}} }} } } {element Test {} {}} } } -result 1 test parse-1.5 {incremental parse} -constraints {!dom_libxml2} -body { set part1 {} set part2 {} set result1 [catch {::dom::DOMImplementation parse $part1 -final 0} m1] set result2 [catch {::dom::DOMImplementation parse $part2 -final 1} m2] catch {::dom::DOMImplementation destroy $m2} list $result1 $result2 } -result {0 0} test parse-1.6 {incremental parse -- parsingComplete flag} -constraints {dom_c} -body { set part1 {abcdefxyz} set part2 {} # parse xml that contains ... set doc [::dom::DOMImplementation parse $part1 -final 0] set top [::dom::node cget $doc -firstChild] set child [::dom::node cget $top -firstChild] set textNode [::dom::node cget $child -lastChild] set value [::dom::node cget $child -nodeName] # get completion flags for first chunk of xml set flag1 [::dom::node cget $top -parsingComplete] set flag2 [::dom::node cget $child -parsingComplete] set flag3 [::dom::node cget $textNode -parsingComplete] # parse rest of xml -- close tag for top node ::dom::DOMImplementation parse $part2 -final 1 # get completion flags for completely parsed xml set flag4 [::dom::node cget $top -parsingComplete] set flag5 [::dom::node cget $child -parsingComplete] set flag6 [::dom::node cget $textNode -parsingComplete] ::dom::DOMImplementation destroy $doc list $flag1 $flag2 $flag3 $flag4 $flag5 $flag6 } -result {0 1 1 1 1 1} test parse-2.1 {expat test suite; tests UTF-16 compliance} -constraints {sa} -body { set compositeResult 0 foreach fname [glob $::tcltest::testsDirectory/sa/*.xml] { set xml [readUtfOrUnicode $fname] set result [catch {::dom::DOMImplementation parse $xml} doc] if {$result == 0} { ::dom::DOMImplementation destroy $doc } else { if {$compositeResult == 0} { set compositeResult "" } lappend compositeResult [file tail $fname] } } set compositeResult } -result {0} test parse-2.2 {expat test suite with incrmental parsing} -constraints {sa} -body { set compositeResult 0 foreach fname [glob $::tcltest::testsDirectory/sa/*.xml] { set xml [readUtfOrUnicode $fname] set xml1 [string range $xml 0 10] set xml2 [string range $xml 11 end] catch {::dom::DOMImplementation parse $xml1 -final 0} set result [catch {::dom::DOMImplementation parse $xml2 -final 1} doc] if {$result == 0} { ::dom::DOMImplementation destroy $doc } else { if {$compositeResult == 0} { set compositeResult "" } lappend compositeResult [file tail $fname] } } set compositeResult } -result {0} test parse-2.3 {expat test suite with incremental parsing errors} -constraints {sa} -body { set count 0 set passCount 0 foreach fname [glob $::tcltest::testsDirectory/sa/*.xml] { set xml [readUtfOrUnicode $fname] set xml1 [string range $xml 0 10] set xml2 [string range $xml 11 end] catch {::dom::DOMImplementation parse $xml1 -final 0} # intentionally bad xml -- all parsing should fail set result [catch {::dom::DOMImplementation parse $xml1 -final 1} doc] if {$result == 0} { ::dom::DOMImplementation destroy $doc incr passCount } else { incr count } } list $count $passCount } -result {119 0} test parse-2.4 {incremental parsing errors -- error on first parse} -constraints {sa} -body { set count 0 set passCount 0 foreach fname [glob $::tcltest::testsDirectory/sa/*.xml] { set xml [readUtfOrUnicode $fname] set xml1 [string range $xml 0 10] set xml2 [string range $xml 11 end] set result [catch {::dom::DOMImplementation parse xx${xml1} -final 0}] if {$result == 1} { incr count continue } # intentionally bad xml -- all parsing should fail set result [catch {::dom::DOMImplementation parse $xml2 -final 1} doc] if {$result == 0} { ::dom::DOMImplementation destroy $doc incr passCount } else { incr count } } list $count $passCount } -result {119 0} test parse-3.1 {parse error reporting} -constraints {!dom_libxml2} -body { set result [catch {::dom::DOMImplementation parse { Here is some text }} msg] list $result $msg } -result {1 {error "mismatched tag" at line 7 character 2; at "A>" within "e text <"}} test parse-3.1 {parse error reporting} -constraints {dom_libxml2} -body { set result [catch {::dom::DOMImplementation parse { Here is some text }} msg] list $result $msg } -result {1 {Entity: line 7: error: Opening and ending tag mismatch: B and A ^ Entity: line 8: error: Opening and ending tag mismatch: A and B ^ }} test parse-3.2 {parse error reporting; error at char pos 0} -constraints {!dom_libxml2} -body { set result [catch {::dom::DOMImplementation parse {>?xml version="1.0"?> Here is some text }} msg] list $result $msg } -result {1 {error "syntax error" at line 1 character 0}} test parse-3.2 {parse error reporting; error at char pos 0} -constraints {dom_libxml2} -body { set result [catch {::dom::DOMImplementation parse {>?xml version="1.0"?> Here is some text }} msg] list $result $msg } -result {1 {Entity: line 1: error: Start tag expected, '<' not found >?xml version="1.0"?> ^ }} test parse-3.3 {parse error reporting -- error at last char} -constraints {!dom_libxml2} -body { expectError { ::dom::DOMImplementation parse { Here is some text Here is some text "] } else { append badXML [makeUnicode "\u3c00\u5a00\u3e00"] } append badXML [encoding convertfrom identity $part2] expectError { ::dom::DOMImplementation parse $badXML } {error "not well-formed*} ok } -result {} test parse-3.5 {parse error reporting, UTF-16 source, error at first char} -constraints {sa} -body { set fname $::tcltest::testsDirectory/sa/049.xml set xml [readBinary $fname] set badXML [encoding convertfrom identity [string range $xml 0 1]] if {$tcl_platform(byteOrder) == "littleEndian"} { append badXML [makeUnicode ">"] } else { append badXML [makeUnicode "\u3e00"] } append badXML [encoding convertfrom identity [string range $xml 2 end]] set result [catch {::dom::DOMImplementation parse $badXML} msg] list $result $msg } -result {1 {error "syntax error" at line 1 character 1; at ">£Z"}} test parse-3.8 {parse error reporting, UTF-16 source, error is CR} -constraints {sa} -body { set fname $::tcltest::testsDirectory/sa/049.xml set xml [readBinary $fname] set badXML [encoding convertfrom identity [string range $xml 0 9]] set part2 [string range $xml 10 end] if {$tcl_platform(byteOrder) == "littleEndian"} { append badXML [makeUnicode "\n"] } else { append badXML [makeUnicode "\u0a00"] } append badXML [encoding convertfrom identity $part2] set result [catch {::dom::DOMImplementation parse $badXML} msg] list $result $msg } -result {1 {error "syntax error" at line 1 character 1; at " Here is some text }} msg] list $result $msg } -result {1 {error "syntax error" at line 2 character 0; at " Here is some text }} msg] list $result $msg } -result {1 {Entity: line 2: error: xmlParseStartTag: invalid element name abc def xyz} set part2 { } # parse xml that contains ... set doc [::dom::DOMImplementation parse $part1 -final 0 -trim] # parse rest of xml -- close tag for top node ::dom::DOMImplementation parse $part2 -final 1 -trim set result [::dom::DOMImplementation serialize $doc] ::dom::DOMImplementation destroy $doc set result } -result { abc def xyz } # # Test processing instruction parsing. # set piparse_text "" test piparse-1.0 {Processing instruction parsing} -body { set doc [dom::DOMImplementation parse $piparse_text] set root [dom::document cget $doc -documentElement] dom::node cget $root -nodeName } -result {test} test piparse-1.1 {PI present} -body { set children [dom::node children $root] set pinode [lindex $children 0] llength $children } -result {1} test piparse-1.2 {PI right type} -body { dom::node cget $pinode -nodeType } -result {processingInstruction} test piparse-1.3 {PI node name} -body { dom::node cget $pinode -nodeName } -result {PITGT} test piparse-1.4 {PI node value} -body { dom::node cget $pinode -nodeValue } -result {processing instruction data} test piparse-1.5 {PI serialization} -constraints {!dom_libxml2} -body { dom::DOMImplementation serialize $root } -result $piparse_text # cleanup ::tcltest::cleanupTests return