github.com/matislovas/ratago@v0.0.0-20240408115641-cc0857415a7a/xslt/stylesheet_test.go (about) 1 package xslt 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path" 8 "testing" 9 10 "github.com/matislovas/gokogiri/xml" 11 ) 12 13 // Simple naive test; primarily exists as a canary in case test helpers break 14 func TestNaive(t *testing.T) { 15 xslFile := "testdata/test.xsl" 16 inputXml := "testdata/test.xml" 17 outputXml := "testdata/test.out" 18 19 runXslTest(t, xslFile, inputXml, outputXml) 20 } 21 22 // Helper where actual checking occurs 23 func runXslTestWithOptions(t *testing.T, xslFile, inputXmlFile, outputXmlFile string, testOptions StylesheetOptions) bool { 24 style, _ := xml.ReadFile(xslFile, xml.StrictParseOption) 25 input, _ := xml.ReadFile(inputXmlFile, xml.StrictParseOption) 26 outData, _ := ioutil.ReadFile(outputXmlFile) 27 expected := string(outData) 28 stylesheet, _ := ParseStylesheet(style, xslFile) 29 output, _ := stylesheet.Process(input, testOptions) 30 if output != expected { 31 t.Error(xslFile, "failed") 32 fmt.Println("---- EXPECTED ", xslFile, "----") 33 fmt.Println(expected) 34 fmt.Println("---- ACTUAL ", xslFile, "----") 35 fmt.Println(output) 36 return false 37 } 38 return true 39 } 40 41 func runXslTest(t *testing.T, xslFile, inputXmlFile, outputXmlFile string) bool { 42 testOptions := StylesheetOptions{false, nil} 43 return runXslTestWithOptions(t, xslFile, inputXmlFile, outputXmlFile, testOptions) 44 } 45 46 // check whether a file exists 47 func exists(path string) (bool, error) { 48 _, err := os.Stat(path) 49 if err == nil { 50 return true, nil 51 } 52 if os.IsNotExist(err) { 53 return false, nil 54 } 55 return false, err 56 } 57 58 // Runs the tests derived from the XSLT 1.0 specification examples 59 func TestXsltREC(t *testing.T) { 60 var passed []string 61 d, _ := os.Open("testdata/REC") 62 fi, _ := d.Readdir(-1) 63 for _, f := range fi { 64 if f.Mode().IsRegular() && path.Ext(f.Name()) == ".xsl" { 65 if f.Name() == "test-7.1.1.xsl" { 66 fmt.Println("skipping REC/test-7.1.1 due to inconsistent namespace declaration ordering") 67 continue 68 } 69 xslname := path.Join("testdata/REC", f.Name()) 70 b := xslname[0 : len(xslname)-4] 71 inName := b + ".xml" 72 outName := b + ".out" 73 ii, _ := exists(inName) 74 oo, _ := exists(outName) 75 if ii && oo { 76 ok := runXslTest(t, xslname, inName, outName) 77 if ok { 78 passed = append(passed, xslname) 79 } 80 } else { 81 // can use this to debug if tests suddenly disappear 82 //fmt.Println("Cannot test", xslname) 83 } 84 } 85 } 86 fmt.Println("passed", len(passed), "tests") 87 } 88 89 // Tests the first full example presented in the XSLT 1.0 spec 90 func TestXsltRECexample1(t *testing.T) { 91 xslFile := "testdata/REC1/doc.xsl" 92 inputXml := "testdata/REC1/doc.xml" 93 outputXml := "testdata/REC1/result.xml" 94 95 runXslTest(t, xslFile, inputXml, outputXml) 96 } 97 98 // Tests the second full example presented in the XSLT 1.0 spec 99 func TestXsltRECexample2(t *testing.T) { 100 inputXml := "testdata/REC2/data.xml" 101 102 runXslTest(t, "testdata/REC2/html.xsl", inputXml, "testdata/REC2/html.xml") 103 runXslTest(t, "testdata/REC2/svg.xsl", inputXml, "testdata/REC2/svg.xml") 104 runXslTest(t, "testdata/REC2/vrml.xsl", inputXml, "testdata/REC2/vrml.xml") 105 } 106 107 // Test the handling of global parameters 108 func TestXsltParameters(t *testing.T) { 109 testOptions := StylesheetOptions{false, map[string]interface{}{ 110 "numberVal": 1.0, 111 "stringVal": "abcdef", 112 }} 113 inputXml := "testdata/parameters/data.xml" 114 runXslTestWithOptions(t, "testdata/parameters/basic.xsl", inputXml, "testdata/parameters/basic.xml", testOptions) 115 } 116 117 var genRun = 0 118 119 // convenience function to fix up the paths before running a test 120 func runGeneralXslTest(t *testing.T, xslFile string) bool { 121 //we change into the general directory to duplicate env of libxslt test run 122 // unparsed-entity-uri() in particular returns a result relative to the 123 // current working directory. 124 pwd, _ := os.Getwd() 125 defer os.Chdir(pwd) 126 _ = os.Chdir("testdata/general") 127 xslf := fmt.Sprintf("%v.xsl", xslFile) 128 ii := fmt.Sprintf("../docs/%v.xml", xslFile) 129 oo := fmt.Sprintf("%v.out", xslFile) 130 genRun = genRun + 1 131 return runXslTest(t, xslf, ii, oo) 132 } 133 134 // Runs the general suite of libxslt regression tests 135 func TestXsltGeneral(t *testing.T) { 136 //runGeneralXslTest(t, "items") //doesn't match pattern - how do we run test? 137 138 runGeneralXslTest(t, "array") // document('') 139 runGeneralXslTest(t, "character") 140 //runGeneralXslTest(t, "date_add") // EXSL date functions 141 runGeneralXslTest(t, "bug-1-") 142 runGeneralXslTest(t, "bug-2-") 143 runGeneralXslTest(t, "bug-3-") 144 runGeneralXslTest(t, "bug-4-") 145 //runGeneralXslTest(t, "bug-5-") // rounding issues outputting numbers; UTF-8 casing? 146 runGeneralXslTest(t, "bug-6-") 147 runGeneralXslTest(t, "bug-7-") 148 runGeneralXslTest(t, "bug-8-") //issue resolving namespaces in imported stylesheet 149 runGeneralXslTest(t, "bug-9-") 150 runGeneralXslTest(t, "bug-10-") 151 runGeneralXslTest(t, "bug-11-") 152 runGeneralXslTest(t, "bug-12-") 153 runGeneralXslTest(t, "bug-13-") 154 runGeneralXslTest(t, "bug-14-") 155 runGeneralXslTest(t, "bug-15-") 156 runGeneralXslTest(t, "bug-16-") 157 runGeneralXslTest(t, "bug-17-") 158 runGeneralXslTest(t, "bug-18-") 159 runGeneralXslTest(t, "bug-19-") 160 runGeneralXslTest(t, "bug-20-") 161 runGeneralXslTest(t, "bug-21-") // unparsed-entity-uri() 162 runGeneralXslTest(t, "bug-22-") 163 runGeneralXslTest(t, "bug-23-") 164 runGeneralXslTest(t, "bug-24-") 165 runGeneralXslTest(t, "bug-25-") // encoding attr when UTF-8 explicitly specified in doc 166 runGeneralXslTest(t, "bug-26-") 167 runGeneralXslTest(t, "bug-27-") 168 runGeneralXslTest(t, "bug-28-") 169 runGeneralXslTest(t, "bug-29-") // document('href'); need to resolve to new source document 170 runGeneralXslTest(t, "bug-30-") 171 runGeneralXslTest(t, "bug-31-") 172 runGeneralXslTest(t, "bug-32-") 173 runGeneralXslTest(t, "bug-33-") 174 runGeneralXslTest(t, "bug-35-") 175 runGeneralXslTest(t, "bug-36-") //xsl:include 176 runGeneralXslTest(t, "bug-37-") //xsl:include 177 //runGeneralXslTest(t, "bug-38-") // handle copy-of() for namespace nodes 178 runGeneralXslTest(t, "bug-39-") 179 runGeneralXslTest(t, "bug-40-") //variable scope is global when call-template is invoked 180 runGeneralXslTest(t, "bug-41-") //also avoid overwriting global variable using with-param 181 runGeneralXslTest(t, "bug-42-") //as 40 but for apply-templates 182 runGeneralXslTest(t, "bug-43-") //as 41 but for apply-templates 183 runGeneralXslTest(t, "bug-44-") // with-param 184 runGeneralXslTest(t, "bug-45-") // ensure params/variables resolve in correct order 185 runGeneralXslTest(t, "bug-46-") 186 runGeneralXslTest(t, "bug-47-") 187 runGeneralXslTest(t, "bug-48-") 188 runGeneralXslTest(t, "bug-49-") // global variable defined in terms of inner variable 189 runGeneralXslTest(t, "bug-50-") 190 runGeneralXslTest(t, "bug-52") //unparsed-entity-uri with nodeset argument 191 runGeneralXslTest(t, "bug-53") // depends on DTD processing of ATTLIST with default attribute 192 //runGeneralXslTest(t, "bug-54") //fails intermittently due to ordering of namespaces 193 runGeneralXslTest(t, "bug-55") 194 //runGeneralXslTest(t, "bug-56") // unsure what's going on here 195 runGeneralXslTest(t, "bug-57") 196 runGeneralXslTest(t, "bug-59") 197 runGeneralXslTest(t, "bug-60") // fallback for unknown XSL element 198 //runGeneralXslTest(t, "bug-61") // format-number outputs NaN correctly 199 runGeneralXslTest(t, "bug-62") 200 //runGeneralXslTest(t, "bug-63") //resolve namespace nodes and relative paths 201 runGeneralXslTest(t, "bug-64") 202 //runGeneralXslTest(t, "bug-65") // libxslt:node-set 203 runGeneralXslTest(t, "bug-66") //current() 204 runGeneralXslTest(t, "bug-68") 205 runGeneralXslTest(t, "bug-69") // stylesheet and input in iso-8859-1 206 runGeneralXslTest(t, "bug-70") // key() - nodeset as arg 2 207 //runGeneralXslTest(t, "bug-71") //only fails due to order of NS declarations; need to review spec on that 208 runGeneralXslTest(t, "bug-72") //variables declared in RVT 209 runGeneralXslTest(t, "bug-73") 210 runGeneralXslTest(t, "bug-74") 211 //runGeneralXslTest(t, "bug-75") //format-number() 212 runGeneralXslTest(t, "bug-76") //issue with count? or variable resolution? 213 runGeneralXslTest(t, "bug-77") //handle spaces around OR 214 runGeneralXslTest(t, "bug-78") 215 runGeneralXslTest(t, "bug-79") 216 runGeneralXslTest(t, "bug-80") //fails due to ordering of attributes; review, possibly edit test 217 runGeneralXslTest(t, "bug-81") //rounding error in XPath calculation; might be caused by CGO conversion 218 //runGeneralXslTest(t, "bug-82") //whitespace interactions; possibly not honoring global preserve-space 219 runGeneralXslTest(t, "bug-83") 220 runGeneralXslTest(t, "bug-84") 221 runGeneralXslTest(t, "bug-86") //getting some unnecessary duplication of namespaces declarations using copy-of 222 //runGeneralXslTest(t, "bug-87") //matching on namespace node 223 runGeneralXslTest(t, "bug-88") 224 runGeneralXslTest(t, "bug-89") //fails with stricter parser 225 runGeneralXslTest(t, "bug-90") // CDATA handling 226 runGeneralXslTest(t, "bug-91") // disable-output-escaping attribute 227 //runGeneralXslTest(t, "bug-92") //libxml2 doesn't output the xs namespace here; why not? 228 //runGeneralXslTest(t, "bug-93") // presence of xsl:output in imported stylesheets should cause effective merge 229 runGeneralXslTest(t, "bug-94") //variable/param confusion 230 //runGeneralXslTest(t, "bug-95") //format-number 231 runGeneralXslTest(t, "bug-96") //cdata-section-elements 232 runGeneralXslTest(t, "bug-97") 233 runGeneralXslTest(t, "bug-98") 234 //runGeneralXslTest(t, "bug-99") // expects multiple namespace declarations 235 //runGeneralXslTest(t, "bug-100") // libxslt:test extension element 236 runGeneralXslTest(t, "bug-101") // xsl:element with default namespace 237 //runGeneralXslTest(t, "bug-102") // imported xsl:attribute-set 238 runGeneralXslTest(t, "bug-103") //copy-of needs to explicitly set empty namespace when needed 239 //runGeneralXslTest(t, "bug-104") //copy-of should preserve attr prefix if plausible 240 runGeneralXslTest(t, "bug-105") 241 runGeneralXslTest(t, "bug-106") //copy-of 242 runGeneralXslTest(t, "bug-107") 243 runGeneralXslTest(t, "bug-108") 244 runGeneralXslTest(t, "bug-109") // disable-output-escaping 245 runGeneralXslTest(t, "bug-110") //generate-id() 246 runGeneralXslTest(t, "bug-111") //exsl:node-set() 247 runGeneralXslTest(t, "bug-112") //exsl:node-set() 248 runGeneralXslTest(t, "bug-113") // stylesheet and parser in ISO-8859-1 249 runGeneralXslTest(t, "bug-114") 250 runGeneralXslTest(t, "bug-115") //exsl:node-set() 251 runGeneralXslTest(t, "bug-116") 252 runGeneralXslTest(t, "bug-117") //exsl declaration should not be in output 253 runGeneralXslTest(t, "bug-118") //copy-of 254 runGeneralXslTest(t, "bug-119") 255 //runGeneralXslTest(t, "bug-120") //xsl:sort with data-type; interaction with copy-of? 256 runGeneralXslTest(t, "bug-121") 257 //runGeneralXslTest(t, "bug-122") //namespace nodes 258 runGeneralXslTest(t, "bug-123") 259 //runGeneralXslTest(t, "bug-124") //namespace declared with multiple prefixes; really a bug? 260 //runGeneralXslTest(t, "bug-125") //unclear; needs further investigation 261 //runGeneralXslTest(t, "bug-126") //tests for bugs in AVT parsing 262 runGeneralXslTest(t, "bug-127") 263 //runGeneralXslTest(t, "bug-128") //multiple keys with the same name; need to look at spec 264 runGeneralXslTest(t, "bug-129") //cdata-section-elements 265 //runGeneralXslTest(t, "bug-130") //document('href') and import; different default namespace in imported stylesheet 266 //runGeneralXslTest(t, "bug-131") // attribute-set combine import defs 267 runGeneralXslTest(t, "bug-132") 268 //runGeneralXslTest(t, "bug-133") // interaction between key, generate-id? 269 //runGeneralXslTest(t, "bug-134") // xsl:key match "node()[self::sect]" should be same as match "sect" but is not; context issue?? 270 //runGeneralXslTest(t, "bug-135") // same as 134 271 runGeneralXslTest(t, "bug-136") 272 //runGeneralXslTest(t, "bug-137") // EXSLT func 273 runGeneralXslTest(t, "bug-138") 274 //runGeneralXslTest(t, "bug-139") //extra output of entity definitions (why?) 275 runGeneralXslTest(t, "bug-140") // failed due to standalone 276 runGeneralXslTest(t, "bug-141") 277 //runGeneralXslTest(t, "bug-142") //lang() function doing strange things? 278 //runGeneralXslTest(t, "bug-143") //exposes a timing bug in global variable definitions 279 runGeneralXslTest(t, "bug-144") 280 runGeneralXslTest(t, "bug-145") //should result in no output (calling template that doesn't exist) 281 //runGeneralXslTest(t, "bug-146") // funny looking key definition plus encoding issue 282 //runGeneralXslTest(t, "bug-147") //looks like import precedence related 283 runGeneralXslTest(t, "bug-148") 284 runGeneralXslTest(t, "bug-149") 285 //runGeneralXslTest(t, "bug-150") //scoping of namespace definitions on literal result elements 286 runGeneralXslTest(t, "bug-151") // outputs just the declaration; should be nothing 287 //runGeneralXslTest(t, "bug-152") //libxml2 inserts a content-type meta tag; unsure why 288 runGeneralXslTest(t, "bug-153") //document('href') and current() 289 runGeneralXslTest(t, "bug-154") //should have no output 290 runGeneralXslTest(t, "bug-155") 291 runGeneralXslTest(t, "bug-156") 292 runGeneralXslTest(t, "bug-157") 293 runGeneralXslTest(t, "bug-158") 294 //runGeneralXslTest(t, "bug-159") //escape entities appropriately if encoding=ascii 295 //runGeneralXslTest(t, "bug-160") // match criteria seems to be the issue here 296 runGeneralXslTest(t, "bug-161") 297 runGeneralXslTest(t, "bug-163") 298 runGeneralXslTest(t, "bug-164") 299 //runGeneralXslTest(t, "bug-165") //xpath with unresolvable variable in predicate; differs in number of blank lines produced 300 //runGeneralXslTest(t, "bug-166") //need to look closer; slow and much output! 301 runGeneralXslTest(t, "bug-167") 302 //runGeneralXslTest(t, "bug-168") //looks like AVT torture test 303 //runGeneralXslTest(t, "bug-169") // not selecting correct output encoding? 304 runGeneralXslTest(t, "bug-170") 305 runGeneralXslTest(t, "bug-171") 306 runGeneralXslTest(t, "bug-172") //seems to be bug in xsl:choose (matches when test but no output) 307 //runGeneralXslTest(t, "bug-173") //extra newline on output? 308 //runGeneralXslTest(t, "bug-174") //exslt:func 309 //runGeneralXslTest(t, "bug-175") //wrong output encoding/doctype for html output 310 runGeneralXslTest(t, "bug-176") 311 runGeneralXslTest(t, "bug-177") //should not create namespace declaration for built-in xml namespace 312 //runGeneralXslTest(t, "bug-178") //exslt:func 313 //runGeneralXslTest(t, "bug-179") // xsl:element/@namespace don't need to explicitly create namespace already in scope 314 //runGeneralXslTest(t, "bug-180") //expects no output 315 //runGeneralXslTest(t, "bug-181") //this appears to be template priority bug 316 //runGeneralXslTest(t, "bug-182") //text()[2] should match something 317 fmt.Println("passed", genRun, "tests") 318 } 319 320 // sample usage for parse stylesheet 321 func ExampleParseStylesheet() { 322 //parse the stylesheet 323 style, _ := xml.ReadFile("testdata/test.xsl", xml.StrictParseOption) 324 stylesheet, _ := ParseStylesheet(style, "testdata/test.xsl") 325 326 //process the input 327 input, _ := xml.ReadFile("testdata/test.xml", xml.StrictParseOption) 328 output, _ := stylesheet.Process(input, StylesheetOptions{false, nil}) 329 fmt.Println(output) 330 }