leptris 1.9.201.0-arm-linux → 1.9.201.2-arm-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Rakefile +52 -12
- data/ext/leptris/native/extconf.rb +85 -0
- data/ext/leptris/native/native.c +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/ffi.rb +13 -0
- data/lib/leptris/xml/native.so +0 -0
- data/vendor-src/libleptris/CHANGELOG.md +8080 -0
- data/vendor-src/libleptris/CLAUDE.md +150 -0
- data/vendor-src/libleptris/CMakeLists.txt +379 -0
- data/vendor-src/libleptris/CMakePresets.json +61 -0
- data/vendor-src/libleptris/CODE_OF_CONDUCT.md +132 -0
- data/vendor-src/libleptris/CONTEXT.md +49 -0
- data/vendor-src/libleptris/LICENSE.md +33 -0
- data/vendor-src/libleptris/README.adoc +1197 -0
- data/vendor-src/libleptris/TODO.assemble/README.md +16 -0
- data/vendor-src/libleptris/TODO.bindings/01-mutation-construction.md +18 -0
- data/vendor-src/libleptris/TODO.bindings/02-incremental-iterparse.md +15 -0
- data/vendor-src/libleptris/TODO.bindings/03-compiled-xpath.md +15 -0
- data/vendor-src/libleptris/TODO.bindings/04-pull-stax-api.md +14 -0
- data/vendor-src/libleptris/TODO.bindings/05-per-parse-options.md +17 -0
- data/vendor-src/libleptris/TODO.bindings/06-serialize-encoding-guarantees.md +14 -0
- data/vendor-src/libleptris/TODO.bindings/README.md +36 -0
- data/vendor-src/libleptris/TODO.concurrency/01-thread-safe-errors.md +19 -0
- data/vendor-src/libleptris/TODO.concurrency/02-export-surface-gate.md +24 -0
- data/vendor-src/libleptris/TODO.concurrency/03-mixed-nodeset-batch.md +14 -0
- data/vendor-src/libleptris/TODO.concurrency/04-canonical-status-message.md +13 -0
- data/vendor-src/libleptris/TODO.concurrency/05-windows-dll-name.md +10 -0
- data/vendor-src/libleptris/TODO.concurrency/06-exslt-pack.md +26 -0
- data/vendor-src/libleptris/TODO.concurrency/07-ns-set-pairs.md +11 -0
- data/vendor-src/libleptris/TODO.concurrency/08-threading-contract.md +45 -0
- data/vendor-src/libleptris/TODO.engine/01-file-sources.md +11 -0
- data/vendor-src/libleptris/TODO.engine/02-compiled-contexts.md +10 -0
- data/vendor-src/libleptris/TODO.engine/03-rust-publish.md +9 -0
- data/vendor-src/libleptris/TODO.engine/04-ruby-release-input.md +8 -0
- data/vendor-src/libleptris/TODO.engine/05-todo-md-refresh.md +7 -0
- data/vendor-src/libleptris/TODO.engine/README.md +16 -0
- data/vendor-src/libleptris/TODO.hygiene/README.md +15 -0
- data/vendor-src/libleptris/TODO.max-perf/00-INDEX.md +22 -0
- data/vendor-src/libleptris/TODO.max-perf/1-simd-html-scanner.md +15 -0
- data/vendor-src/libleptris/TODO.max-perf/10-moxml-plan-followups.md +9 -0
- data/vendor-src/libleptris/TODO.max-perf/2-compiled-dispatch-tokenizer.md +8 -0
- data/vendor-src/libleptris/TODO.max-perf/3-iterparse-fixed-cost.md +5 -0
- data/vendor-src/libleptris/TODO.max-perf/4-compact-node-micro-opts.md +17 -0
- data/vendor-src/libleptris/TODO.max-perf/5-xslt-bench-profiling-rounds.md +13 -0
- data/vendor-src/libleptris/TODO.max-perf/6-language-tails.md +9 -0
- data/vendor-src/libleptris/TODO.max-perf/7-validate-bindings.md +6 -0
- data/vendor-src/libleptris/TODO.max-perf/8-native-xml-diff-consumer.md +5 -0
- data/vendor-src/libleptris/TODO.max-perf/9-prebuilt-gem-matrix.md +14 -0
- data/vendor-src/libleptris/TODO.md +33 -0
- data/vendor-src/libleptris/TODO.transform/README.md +39 -0
- data/vendor-src/libleptris/TODO.validate/README.md +32 -0
- data/vendor-src/libleptris/TODO.xpath2/README.md +91 -0
- data/vendor-src/libleptris/TODO.xslt-full/01-xpath-fn-sequences.md +27 -0
- data/vendor-src/libleptris/TODO.xslt-full/02-xpath-fn-regex.md +13 -0
- data/vendor-src/libleptris/TODO.xslt-full/03-xpath-fn-math.md +10 -0
- data/vendor-src/libleptris/TODO.xslt-full/04-xpath-fn-strings-qname-uri.md +97 -0
- data/vendor-src/libleptris/TODO.xslt-full/05-xpath-fn-dates.md +30 -0
- data/vendor-src/libleptris/TODO.xslt-full/06-xpath-grammar-3x.md +83 -0
- data/vendor-src/libleptris/TODO.xslt-full/07-xpath-function-items.md +124 -0
- data/vendor-src/libleptris/TODO.xslt-full/08-xpath-maps-arrays.md +79 -0
- data/vendor-src/libleptris/TODO.xslt-full/09-xslt-noop-fillins.md +35 -0
- data/vendor-src/libleptris/TODO.xslt-full/10-xslt-tunnel-params.md +9 -0
- data/vendor-src/libleptris/TODO.xslt-full/11-xquery-core.md +119 -0
- data/vendor-src/libleptris/TODO.xslt-full/12-xquery-31.md +65 -0
- data/vendor-src/libleptris/TODO.xslt-full/13-perf-inprocess.md +425 -0
- data/vendor-src/libleptris/TODO.xslt-full/14-html-mode.md +803 -0
- data/vendor-src/libleptris/TODO.xslt-full/15-binding-entries.md +19 -0
- data/vendor-src/libleptris/TODO.xslt-full/16-schematron.md +156 -0
- data/vendor-src/libleptris/TODO.xslt-full/17-xml-diff.md +52 -0
- data/vendor-src/libleptris/TODO.xslt-full/18-compact-nodes.md +278 -0
- data/vendor-src/libleptris/TODO.xslt-full/README.md +26 -0
- data/vendor-src/libleptris/TODO.xslt-full/REMAINING.md +163 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/00-triage.md +171 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/01-fragment-nodes.md +19 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/02-root-node-semantics.md +34 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/03-crashes.md +15 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/04-namespaces.md +14 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/05-number-attrset-sort.md +13 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/06-document-chains.md +10 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/07-charef-serializer.md +9 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/08-perf-gate.md +8 -0
- data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/09-release.md +14 -0
- data/vendor-src/libleptris/VALIDATION.md +151 -0
- data/vendor-src/libleptris/benchmarks/CMakeLists.txt +259 -0
- data/vendor-src/libleptris/benchmarks/README.adoc +228 -0
- data/vendor-src/libleptris/benchmarks/README.md +212 -0
- data/vendor-src/libleptris/benchmarks/common/benchmark.c +252 -0
- data/vendor-src/libleptris/benchmarks/common/benchmark.h +77 -0
- data/vendor-src/libleptris/benchmarks/common/test_data.c +415 -0
- data/vendor-src/libleptris/benchmarks/common/test_data.h +18 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/CMakeLists.txt +184 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_decomp.cpp +110 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_first_access.cpp +261 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_many_attrs.cpp +150 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_memory.cpp +185 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_parse.cpp +270 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_parse_ops.cpp +392 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_sax.c +106 -0
- data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_write.cpp +351 -0
- data/vendor-src/libleptris/benchmarks/data/attrs.xml +303 -0
- data/vendor-src/libleptris/benchmarks/data/cdata_test.xml +13 -0
- data/vendor-src/libleptris/benchmarks/data/comment_test.xml +15 -0
- data/vendor-src/libleptris/benchmarks/data/deep.xml +205 -0
- data/vendor-src/libleptris/benchmarks/data/generate_attrs.rb +22 -0
- data/vendor-src/libleptris/benchmarks/data/generate_deep.rb +25 -0
- data/vendor-src/libleptris/benchmarks/data/generate_large.rb +33 -0
- data/vendor-src/libleptris/benchmarks/data/generate_wide.rb +18 -0
- data/vendor-src/libleptris/benchmarks/data/large.xml +21003 -0
- data/vendor-src/libleptris/benchmarks/data/large_workflow.xml +4003 -0
- data/vendor-src/libleptris/benchmarks/data/medium.xml +67 -0
- data/vendor-src/libleptris/benchmarks/data/medium_workflow.xml +353 -0
- data/vendor-src/libleptris/benchmarks/data/pi_test.xml +9 -0
- data/vendor-src/libleptris/benchmarks/data/small.xml +10 -0
- data/vendor-src/libleptris/benchmarks/data/small_workflow.xml +36 -0
- data/vendor-src/libleptris/benchmarks/data/wide.xml +5003 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_document_lifecycle.c +69 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_leptris.c +184 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_libxml2.c +176 -0
- data/vendor-src/libleptris/benchmarks/dom/bench_text_borrowed.c +74 -0
- data/vendor-src/libleptris/benchmarks/dom/dom_benchmark_v2.cpp +314 -0
- data/vendor-src/libleptris/benchmarks/fixtures/large.xml +4003 -0
- data/vendor-src/libleptris/benchmarks/fixtures/large_catalog.xml +50003 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2/eve.xml +6 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2/slashdot.rdf +66 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2/wap.xml +27 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/4rects.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/a-valid.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/a-wf.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/bike.xml +41 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/circle.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/defs.xml +14 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/desc.xml +14 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/ellipse.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/flower2.xml +44 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/gradient.xml +16 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group01.xml +15 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group02.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group03.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/image-valid.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/image-wf.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/lin-gradient.xml +16 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/marker.xml +28 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/mask.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/mathswitch.xml +32 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/parentns.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/path01.xml +5 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/path02.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/patternfill.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/polyline.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/private.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/rad-gradient.xml +17 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/rectangle.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/richdesc.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/script.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/structure01.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/style.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/switch.xml +21 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/symbol-use.xml +28 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/template.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text01.xml +12 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text02.xml +17 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text03.xml +8 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/toap01.xml +10 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/toap02.xml +33 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/transform.xml +26 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/trivial.xml +6 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/twin-gradients.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/v-template.xml +9 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport-nest.xml +13 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport-transform.xml +46 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport.xml +11 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/wf-template.xml +7 -0
- data/vendor-src/libleptris/benchmarks/fixtures/libxml2_xsdtest.xml +5286 -0
- data/vendor-src/libleptris/benchmarks/fixtures/medium.xml +403 -0
- data/vendor-src/libleptris/benchmarks/fixtures/medium_catalog.xml +3003 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/empty.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/large.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/latintest_latin1.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/latintest_utf8.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/multiline.xml +3 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/small.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/truncation.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_bom.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_clean.xml +84 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_nodecl.xml +86 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml//321/202/320/265/321/201/321/202.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/empty.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/large.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/latintest_latin1.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/latintest_utf8.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/multiline.xml +3 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/small.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/truncation.xml +19 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_bom.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_clean.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_nodecl.xml +0 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_bom.xml +87 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_clean.xml +84 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_nodecl.xml +86 -0
- data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests//321/202/320/265/321/201/321/202.xml +1 -0
- data/vendor-src/libleptris/benchmarks/fixtures/small.xml +38 -0
- data/vendor-src/libleptris/benchmarks/html/bench_html_parse.c +111 -0
- data/vendor-src/libleptris/benchmarks/html/gen_nokogiri_reference.rb +112 -0
- data/vendor-src/libleptris/benchmarks/html/nokogiri_html_parse.rb +64 -0
- data/vendor-src/libleptris/benchmarks/matrix/README.md +71 -0
- data/vendor-src/libleptris/benchmarks/matrix/bench2html.rb +316 -0
- data/vendor-src/libleptris/benchmarks/matrix/bench_matrix.cpp +724 -0
- data/vendor-src/libleptris/benchmarks/modification/bench_leptris_modify.c +211 -0
- data/vendor-src/libleptris/benchmarks/modification/bench_node_creation.c +130 -0
- data/vendor-src/libleptris/benchmarks/results/BENCHMARK_REPORT.md +226 -0
- data/vendor-src/libleptris/benchmarks/results/baseline_report.md +219 -0
- data/vendor-src/libleptris/benchmarks/results/benchmark_20251223_134550.json +13 -0
- data/vendor-src/libleptris/benchmarks/results/benchmark_20260129_225844.json +13 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_dom_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify_optimized.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify_session1.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_modify_session2.json +36 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_serialize.json +34 -0
- data/vendor-src/libleptris/benchmarks/results/leptris_xpath_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/libxml2_dom_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/libxml2_xpath_output.txt +24 -0
- data/vendor-src/libleptris/benchmarks/results/phase16_session2.json +21 -0
- data/vendor-src/libleptris/benchmarks/results/phase17.5_session1.json +30 -0
- data/vendor-src/libleptris/benchmarks/results/phase17_session1.json +30 -0
- data/vendor-src/libleptris/benchmarks/results/pugixml_dom_output.txt +51 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_axes_leptris.json +318 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_axes_libxml2.json +318 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_functions_leptris.json +222 -0
- data/vendor-src/libleptris/benchmarks/results/xpath_functions_libxml2.json +222 -0
- data/vendor-src/libleptris/benchmarks/sax/bench_iterparse.c +115 -0
- data/vendor-src/libleptris/benchmarks/sax/bench_leptris.c +124 -0
- data/vendor-src/libleptris/benchmarks/sax/bench_libxml2.c +115 -0
- data/vendor-src/libleptris/benchmarks/serialization/bench_leptris_serialize.c +198 -0
- data/vendor-src/libleptris/benchmarks/src/benchmark_base.h +175 -0
- data/vendor-src/libleptris/benchmarks/twins/mutation_leptris.c +37 -0
- data/vendor-src/libleptris/benchmarks/twins/mutation_pugixml.cpp +28 -0
- data/vendor-src/libleptris/benchmarks/twins/parse_leptris.c +35 -0
- data/vendor-src/libleptris/benchmarks/twins/parse_pugixml.cpp +35 -0
- data/vendor-src/libleptris/benchmarks/utils.c +171 -0
- data/vendor-src/libleptris/benchmarks/utils.h +70 -0
- data/vendor-src/libleptris/benchmarks/workflows/bench_dom_modify.c +325 -0
- data/vendor-src/libleptris/benchmarks/workflows/bench_end_to_end.c +529 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_axes.c +411 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_axes_libxml2.c +108 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_diagnostic.c +431 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_functions.c +271 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_functions_libxml2.c +123 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_leptris.c +78 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_libxml2.c +98 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_pugixml.cpp +117 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_scalar_eval.c +86 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_scalar_eval_libxml2.c +70 -0
- data/vendor-src/libleptris/benchmarks/xpath/bench_xslt_transform.c +48 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch.c +52 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch_heavy.c +82 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch_pred.c +34 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_subtree_copy.c +55 -0
- data/vendor-src/libleptris/benchmarks/xslt/bench_valueof.c +46 -0
- data/vendor-src/libleptris/benchmarks/xslt/heavy_lxml.py +48 -0
- data/vendor-src/libleptris/benchmarks/xslt/scorecard_lxml.py +169 -0
- data/vendor-src/libleptris/bindings/ruby/leptris.gemspec +22 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/document.rb +60 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/element.rb +86 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/error.rb +6 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/node.rb +73 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/sax.rb +189 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris/xpath.rb +44 -0
- data/vendor-src/libleptris/bindings/ruby/lib/leptris.rb +137 -0
- data/vendor-src/libleptris/bindings/ruby/spec/leptris_spec.rb +113 -0
- data/vendor-src/libleptris/bindings/ruby/spec/sax_spec.rb +141 -0
- data/vendor-src/libleptris/bindings/ruby/spec/spec_helper.rb +7 -0
- data/vendor-src/libleptris/bindings/ruby/test_full.rb +21 -0
- data/vendor-src/libleptris/bindings/rust/Cargo.lock +7 -0
- data/vendor-src/libleptris/bindings/rust/Cargo.toml +13 -0
- data/vendor-src/libleptris/bindings/rust/README.md +61 -0
- data/vendor-src/libleptris/bindings/rust/build.rs +74 -0
- data/vendor-src/libleptris/bindings/rust/src/ffi.rs +204 -0
- data/vendor-src/libleptris/bindings/rust/src/lib.rs +580 -0
- data/vendor-src/libleptris/bindings/rust/tests/integration.rs +156 -0
- data/vendor-src/libleptris/cli/ARCHITECTURE_REVIEW.md +514 -0
- data/vendor-src/libleptris/cli/CLI_ARCHITECTURE.md +851 -0
- data/vendor-src/libleptris/cli/CMakeLists.txt +46 -0
- data/vendor-src/libleptris/cli/cli.c +115 -0
- data/vendor-src/libleptris/cli/cli.h +232 -0
- data/vendor-src/libleptris/cli/commands/diff.c +208 -0
- data/vendor-src/libleptris/cli/commands/format.c +379 -0
- data/vendor-src/libleptris/cli/commands/parse.c +343 -0
- data/vendor-src/libleptris/cli/commands/validate.c +284 -0
- data/vendor-src/libleptris/cli/commands/version.c +49 -0
- data/vendor-src/libleptris/cli/commands/xpath.c +428 -0
- data/vendor-src/libleptris/cli/commands/xquery.c +188 -0
- data/vendor-src/libleptris/cli/completion/leptris.bash +86 -0
- data/vendor-src/libleptris/cli/completion/leptris.zsh +74 -0
- data/vendor-src/libleptris/cli/error.c +394 -0
- data/vendor-src/libleptris/cli/error.h +360 -0
- data/vendor-src/libleptris/cli/leptris +0 -0
- data/vendor-src/libleptris/cli/main.c +127 -0
- data/vendor-src/libleptris/cli/man/leptris-format.1.adoc +226 -0
- data/vendor-src/libleptris/cli/man/leptris-parse.1.adoc +213 -0
- data/vendor-src/libleptris/cli/man/leptris-xpath.1.adoc +479 -0
- data/vendor-src/libleptris/cli/man/leptris.1.adoc +192 -0
- data/vendor-src/libleptris/cli/options.c +451 -0
- data/vendor-src/libleptris/cli/options.h +378 -0
- data/vendor-src/libleptris/cli/output.c +841 -0
- data/vendor-src/libleptris/cli/output.h +361 -0
- data/vendor-src/libleptris/cmake/FindUtf8proc.cmake +56 -0
- data/vendor-src/libleptris/cmake/leptris-config.cmake.in +14 -0
- data/vendor-src/libleptris/cmake/leptris.pc.in +11 -0
- data/vendor-src/libleptris/cmake/modules/AdocMan.cmake +132 -0
- data/vendor-src/libleptris/docs/ARCHITECTURE_REVIEW.md +280 -0
- data/vendor-src/libleptris/docs/Doxyfile +47 -0
- data/vendor-src/libleptris/docs/FFI.md +165 -0
- data/vendor-src/libleptris/docs/README.md +47 -0
- data/vendor-src/libleptris/docs/ROADMAP-SAXON-PARITY.md +194 -0
- data/vendor-src/libleptris/docs/guide/building.md +199 -0
- data/vendor-src/libleptris/docs/guide/getting-started.md +134 -0
- data/vendor-src/libleptris/docs/guide/parsing.md +315 -0
- data/vendor-src/libleptris/docs/guide/xpath-queries.md +444 -0
- data/vendor-src/libleptris/examples/c/CMakeLists.txt +58 -0
- data/vendor-src/libleptris/examples/c/README.md +345 -0
- data/vendor-src/libleptris/examples/c/basic_example.c +80 -0
- data/vendor-src/libleptris/examples/c/dom_traversal_example.c +58 -0
- data/vendor-src/libleptris/examples/c/error_handling_example.c +121 -0
- data/vendor-src/libleptris/examples/c/namespace_example.c +49 -0
- data/vendor-src/libleptris/examples/c/xpath_example.c +74 -0
- data/vendor-src/libleptris/ports/leptris/portfile.cmake +41 -0
- data/vendor-src/libleptris/ports/leptris/usage +28 -0
- data/vendor-src/libleptris/scripts/check_dll_exports.py +54 -0
- data/vendor-src/libleptris/scripts/check_export_surface.py +84 -0
- data/vendor-src/libleptris/scripts/check_ffi_mirrors.py +163 -0
- data/vendor-src/libleptris/scripts/check_formatting.sh +30 -0
- data/vendor-src/libleptris/scripts/check_shared_exports.sh +120 -0
- data/vendor-src/libleptris/scripts/check_trailing_whitespace.sh +18 -0
- data/vendor-src/libleptris/scripts/gen-api-docs.sh +31 -0
- data/vendor-src/libleptris/scripts/run_static_analysis.sh +16 -0
- data/vendor-src/libleptris/scripts/validate.sh +199 -0
- data/vendor-src/libleptris/scripts/xslt_triage.sh +72 -0
- data/vendor-src/libleptris/src/CMakeLists.txt +597 -0
- data/vendor-src/libleptris/src/include/leptris/descriptor.h +178 -0
- data/vendor-src/libleptris/src/include/leptris/dom/document.h +213 -0
- data/vendor-src/libleptris/src/include/leptris/dom/element.h +435 -0
- data/vendor-src/libleptris/src/include/leptris/dom/serialize.h +133 -0
- data/vendor-src/libleptris/src/include/leptris/dtd.h +178 -0
- data/vendor-src/libleptris/src/include/leptris/error.h +97 -0
- data/vendor-src/libleptris/src/include/leptris/sax/sax.h +584 -0
- data/vendor-src/libleptris/src/include/leptris/types.h +386 -0
- data/vendor-src/libleptris/src/include/leptris/xpath/xpath.h +250 -0
- data/vendor-src/libleptris/src/include/leptris/xquery/xquery.h +80 -0
- data/vendor-src/libleptris/src/include/leptris.h +3701 -0
- data/vendor-src/libleptris/src/leptris/chartype.h +124 -0
- data/vendor-src/libleptris/src/leptris/common/chartype.c +90 -0
- data/vendor-src/libleptris/src/leptris/common/chartype.h +44 -0
- data/vendor-src/libleptris/src/leptris/common/cpu.c +40 -0
- data/vendor-src/libleptris/src/leptris/common/cpu.h +63 -0
- data/vendor-src/libleptris/src/leptris/common/entities.c +329 -0
- data/vendor-src/libleptris/src/leptris/common/entities.h +79 -0
- data/vendor-src/libleptris/src/leptris/common/format_number.c +273 -0
- data/vendor-src/libleptris/src/leptris/common/format_number.h +29 -0
- data/vendor-src/libleptris/src/leptris/common/port.h +171 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text.c +237 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text.h +104 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text_avx2.c +105 -0
- data/vendor-src/libleptris/src/leptris/common/simd_text_neon.c +280 -0
- data/vendor-src/libleptris/src/leptris/common/string_view.c +204 -0
- data/vendor-src/libleptris/src/leptris/common/string_view.h +68 -0
- data/vendor-src/libleptris/src/leptris/common/types_internal.h +31 -0
- data/vendor-src/libleptris/src/leptris/core.c +201 -0
- data/vendor-src/libleptris/src/leptris/descriptor/plan.c +527 -0
- data/vendor-src/libleptris/src/leptris/diff/diff.c +491 -0
- data/vendor-src/libleptris/src/leptris/dom/cdata.c +47 -0
- data/vendor-src/libleptris/src/leptris/dom/cdata.h +73 -0
- data/vendor-src/libleptris/src/leptris/dom/comment.c +48 -0
- data/vendor-src/libleptris/src/leptris/dom/comment.h +74 -0
- data/vendor-src/libleptris/src/leptris/dom/compact.c +397 -0
- data/vendor-src/libleptris/src/leptris/dom/compact.h +307 -0
- data/vendor-src/libleptris/src/leptris/dom/diag.c +58 -0
- data/vendor-src/libleptris/src/leptris/dom/diag.h +75 -0
- data/vendor-src/libleptris/src/leptris/dom/digest.c +255 -0
- data/vendor-src/libleptris/src/leptris/dom/doctype.c +137 -0
- data/vendor-src/libleptris/src/leptris/dom/doctype.h +52 -0
- data/vendor-src/libleptris/src/leptris/dom/document_node.c +13 -0
- data/vendor-src/libleptris/src/leptris/dom/document_node.h +21 -0
- data/vendor-src/libleptris/src/leptris/dom/edges.h +60 -0
- data/vendor-src/libleptris/src/leptris/dom/element.c +1114 -0
- data/vendor-src/libleptris/src/leptris/dom/element.h +1109 -0
- data/vendor-src/libleptris/src/leptris/dom/element_index.c +444 -0
- data/vendor-src/libleptris/src/leptris/dom/element_index.h +135 -0
- data/vendor-src/libleptris/src/leptris/dom/element_modify.c +2185 -0
- data/vendor-src/libleptris/src/leptris/dom/element_query.c +1468 -0
- data/vendor-src/libleptris/src/leptris/dom/entity_ref.c +57 -0
- data/vendor-src/libleptris/src/leptris/dom/entity_ref.h +70 -0
- data/vendor-src/libleptris/src/leptris/dom/node.c +420 -0
- data/vendor-src/libleptris/src/leptris/dom/node.h +170 -0
- data/vendor-src/libleptris/src/leptris/dom/node_public.c +937 -0
- data/vendor-src/libleptris/src/leptris/dom/node_vtable.c +138 -0
- data/vendor-src/libleptris/src/leptris/dom/pi.c +70 -0
- data/vendor-src/libleptris/src/leptris/dom/pi.h +80 -0
- data/vendor-src/libleptris/src/leptris/dom/root_doc_map.c +310 -0
- data/vendor-src/libleptris/src/leptris/dom/root_doc_map.h +30 -0
- data/vendor-src/libleptris/src/leptris/dom/text.c +157 -0
- data/vendor-src/libleptris/src/leptris/dom/text.h +119 -0
- data/vendor-src/libleptris/src/leptris/dtd/content_check.c +300 -0
- data/vendor-src/libleptris/src/leptris/dtd/model.c +533 -0
- data/vendor-src/libleptris/src/leptris/dtd/model.h +354 -0
- data/vendor-src/libleptris/src/leptris/dtd/parser.c +827 -0
- data/vendor-src/libleptris/src/leptris/dtd/resolver.c +354 -0
- data/vendor-src/libleptris/src/leptris/dtd/validator.c +668 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoders.c +346 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoders.h +61 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoding.c +451 -0
- data/vendor-src/libleptris/src/leptris/encoding/encoding.h +118 -0
- data/vendor-src/libleptris/src/leptris/encoding/unicode.c +317 -0
- data/vendor-src/libleptris/src/leptris/encoding/unicode.h +64 -0
- data/vendor-src/libleptris/src/leptris/encoding/utf16.c +204 -0
- data/vendor-src/libleptris/src/leptris/encoding/utf16.h +78 -0
- data/vendor-src/libleptris/src/leptris/encoding/wrapper.c +243 -0
- data/vendor-src/libleptris/src/leptris/error.c +134 -0
- data/vendor-src/libleptris/src/leptris/flat/direct_parse.c +1935 -0
- data/vendor-src/libleptris/src/leptris/flat/direct_parse.h +41 -0
- data/vendor-src/libleptris/src/leptris/html/html_parse.c +8040 -0
- data/vendor-src/libleptris/src/leptris/leptris.c +1264 -0
- data/vendor-src/libleptris/src/leptris/leptris_internal.h +910 -0
- data/vendor-src/libleptris/src/leptris/leptris_memory.c +179 -0
- data/vendor-src/libleptris/src/leptris/leptris_memory.h +180 -0
- data/vendor-src/libleptris/src/leptris/leptris_parse.h +195 -0
- data/vendor-src/libleptris/src/leptris/memory/arena.c +243 -0
- data/vendor-src/libleptris/src/leptris/memory/arena.h +93 -0
- data/vendor-src/libleptris/src/leptris/memory/pool.c +1055 -0
- data/vendor-src/libleptris/src/leptris/memory/pool.h +426 -0
- data/vendor-src/libleptris/src/leptris/rng/parse.c +814 -0
- data/vendor-src/libleptris/src/leptris/rng/rng_internal.h +112 -0
- data/vendor-src/libleptris/src/leptris/rng/rng_public.c +159 -0
- data/vendor-src/libleptris/src/leptris/rng/rng_regex.c +453 -0
- data/vendor-src/libleptris/src/leptris/rng/validate.c +1923 -0
- data/vendor-src/libleptris/src/leptris/sax/iterparse.c +435 -0
- data/vendor-src/libleptris/src/leptris/sax/parser.c +105 -0
- data/vendor-src/libleptris/src/leptris/sax/pull.c +489 -0
- data/vendor-src/libleptris/src/leptris/sax/recorder.c +252 -0
- data/vendor-src/libleptris/src/leptris/sax/sax_internal.h +163 -0
- data/vendor-src/libleptris/src/leptris/sax/streaming.c +1469 -0
- data/vendor-src/libleptris/src/leptris/sch/schematron.c +1588 -0
- data/vendor-src/libleptris/src/leptris/serialize/c14n.c +1143 -0
- data/vendor-src/libleptris/src/leptris/serialize/serialize.c +2333 -0
- data/vendor-src/libleptris/src/leptris/serialize/serialize.h +188 -0
- data/vendor-src/libleptris/src/leptris/simd_helpers.h +447 -0
- data/vendor-src/libleptris/src/leptris/unicode/unicode.c +237 -0
- data/vendor-src/libleptris/src/leptris/unicode/unicode.h +113 -0
- data/vendor-src/libleptris/src/leptris/xinclude/xinclude.c +794 -0
- data/vendor-src/libleptris/src/leptris/xpath/bytecode.h +229 -0
- data/vendor-src/libleptris/src/leptris/xpath/compiler.c +1478 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator.c +1099 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator.h +189 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_axes.c +787 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_internal.h +112 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_operators.c +2138 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_path.c +1312 -0
- data/vendor-src/libleptris/src/leptris/xpath/evaluator_types.c +294 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions.c +2544 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions.h +161 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions_exslt.c +545 -0
- data/vendor-src/libleptris/src/leptris/xpath/functions_ext31.c +4316 -0
- data/vendor-src/libleptris/src/leptris/xpath/lexer.c +636 -0
- data/vendor-src/libleptris/src/leptris/xpath/lexer.h +25 -0
- data/vendor-src/libleptris/src/leptris/xpath/parser.c +2992 -0
- data/vendor-src/libleptris/src/leptris/xpath/parser.h +28 -0
- data/vendor-src/libleptris/src/leptris/xpath/vm.c +2903 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_ast_cache.c +319 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_compiled.c +263 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_internal.h +134 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_public.c +1139 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_variables.c +410 -0
- data/vendor-src/libleptris/src/leptris/xpath/xpath_variables.h +230 -0
- data/vendor-src/libleptris/src/leptris/xquery/xquery.c +2641 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_exec.c +4887 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_functions.c +1612 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_internal.h +862 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_parse.c +2418 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_pattern.c +441 -0
- data/vendor-src/libleptris/src/leptris/xslt/xslt_public.c +710 -0
- data/vendor-src/libleptris/src/leptris.symvers +16 -0
- data/vendor-src/libleptris/src/man/libleptris.5.adoc +961 -0
- data/vendor-src/libleptris/test/CMakeLists.txt +234 -0
- data/vendor-src/libleptris/test/README.md +59 -0
- data/vendor-src/libleptris/test/abi/test_descriptor.cpp +441 -0
- data/vendor-src/libleptris/test/abi/test_doctype_api.cpp +51 -0
- data/vendor-src/libleptris/test/abi/test_dom_deep_copy.cpp +110 -0
- data/vendor-src/libleptris/test/abi/test_dom_mutation_bugs.cpp +210 -0
- data/vendor-src/libleptris/test/abi/test_header_hygiene.cpp +269 -0
- data/vendor-src/libleptris/test/abi/test_namespace_mutation_and_create.cpp +198 -0
- data/vendor-src/libleptris/test/abi/test_node_get_xpath.cpp +128 -0
- data/vendor-src/libleptris/test/abi/test_nokogiri_api.cpp +392 -0
- data/vendor-src/libleptris/test/abi/test_parse_fragment.cpp +114 -0
- data/vendor-src/libleptris/test/abi/test_previous_sibling_and_c14n_ex.cpp +299 -0
- data/vendor-src/libleptris/test/abi/test_public_surface.cpp +463 -0
- data/vendor-src/libleptris/test/abi/test_serialize_abi.cpp +67 -0
- data/vendor-src/libleptris/test/abi/test_v0_5_14_bugs.cpp +299 -0
- data/vendor-src/libleptris/test/abi/test_xpath_custom_fns.cpp +106 -0
- data/vendor-src/libleptris/test/cli/test_cli.cpp +493 -0
- data/vendor-src/libleptris/test/common/test_simd_spans.cpp +88 -0
- data/vendor-src/libleptris/test/common/test_simd_text.cpp +142 -0
- data/vendor-src/libleptris/test/concurrency/test_concurrency.cpp +218 -0
- data/vendor-src/libleptris/test/diff/test_diff.cpp +244 -0
- data/vendor-src/libleptris/test/dom/test_compact.cpp +339 -0
- data/vendor-src/libleptris/test/dom/test_digest.cpp +111 -0
- data/vendor-src/libleptris/test/dom/test_document_children.cpp +270 -0
- data/vendor-src/libleptris/test/dom/test_dom.cpp +2310 -0
- data/vendor-src/libleptris/test/dom/test_map_lifecycle.cpp +111 -0
- data/vendor-src/libleptris/test/dom/test_node_surface_parity.cpp +268 -0
- data/vendor-src/libleptris/test/dom/test_text_borrowed.cpp +126 -0
- data/vendor-src/libleptris/test/dom/test_vtable.cpp +108 -0
- data/vendor-src/libleptris/test/dtd/test_dtd_validate.cpp +1227 -0
- data/vendor-src/libleptris/test/dtd/test_w3c_conformance.cpp +212 -0
- data/vendor-src/libleptris/test/fixtures/basic.xml +13 -0
- data/vendor-src/libleptris/test/fixtures/cdata.xml +5 -0
- data/vendor-src/libleptris/test/fixtures/malformed.xml +2 -0
- data/vendor-src/libleptris/test/fixtures/namespaces.xml +11 -0
- data/vendor-src/libleptris/test/fixtures/utf16_decl.xml +5 -0
- data/vendor-src/libleptris/test/fuzz/fuzz_parse.c +40 -0
- data/vendor-src/libleptris/test/html/html5lib-redlist.txt +1366 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/LICENSE +21 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/README.md +11 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/adoption01.dat +354 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/adoption02.dat +39 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/blocks.dat +695 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/comments01.dat +217 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/doctype01.dat +474 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/domjs-unsafe.dat +0 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/entities01.dat +943 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/entities02.dat +309 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/foreign-fragment.dat +645 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/html5test-com.dat +301 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/inbody01.dat +54 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/isindex.dat +49 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/main-element.dat +46 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/math.dat +104 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/menuitem-element.dat +240 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/namespace-sensitivity.dat +22 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/noscript01.dat +237 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/pending-spec-changes-plain-text-unsafe.dat +0 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/pending-spec-changes.dat +46 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/plain-text-unsafe.dat +0 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/ruby.dat +302 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/scriptdata01.dat +372 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/search-element.dat +46 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/svg.dat +104 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tables01.dat +308 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/template.dat +1673 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests1.dat +1956 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests10.dat +849 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests11.dat +523 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests12.dat +62 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests14.dat +75 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests15.dat +216 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests16.dat +2602 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests17.dat +179 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests18.dat +558 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests19.dat +1398 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests2.dat +821 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests20.dat +842 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests21.dat +306 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests22.dat +190 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests23.dat +168 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests24.dat +79 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests25.dat +288 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests26.dat +453 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests3.dat +305 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests4.dat +58 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests5.dat +210 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests6.dat +663 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests7.dat +417 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests8.dat +165 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests9.dat +472 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests_innerHTML_1.dat +843 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tricky01.dat +336 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/webkit01.dat +785 -0
- data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/webkit02.dat +554 -0
- data/vendor-src/libleptris/test/html/html5lib_cases.h.in +6 -0
- data/vendor-src/libleptris/test/html/nokogiri-parity-redlist.txt +1183 -0
- data/vendor-src/libleptris/test/html/nokogiri-tree-tests.dat +18107 -0
- data/vendor-src/libleptris/test/html/test_html.cpp +2191 -0
- data/vendor-src/libleptris/test/html/test_html5lib.cpp +831 -0
- data/vendor-src/libleptris/test/memory/test_arena.cpp +252 -0
- data/vendor-src/libleptris/test/memory/test_oom_injection.cpp +170 -0
- data/vendor-src/libleptris/test/memory/test_pool.cpp +331 -0
- data/vendor-src/libleptris/test/memory/test_pool_arena.cpp +180 -0
- data/vendor-src/libleptris/test/parser/test_encoding.cpp +282 -0
- data/vendor-src/libleptris/test/parser/test_large_documents.cpp +346 -0
- data/vendor-src/libleptris/test/parser/test_parser.cpp +565 -0
- data/vendor-src/libleptris/test/parser/test_simd_count.cpp +70 -0
- data/vendor-src/libleptris/test/perf/test_perf.cpp +362 -0
- data/vendor-src/libleptris/test/perf/test_stress_high_doc_count.cpp +67 -0
- data/vendor-src/libleptris/test/rng/include-cases/bad-construct.rng +7 -0
- data/vendor-src/libleptris/test/rng/include-cases/bad-override.rng +6 -0
- data/vendor-src/libleptris/test/rng/include-cases/bad-start-override.rng +5 -0
- data/vendor-src/libleptris/test/rng/include-cases/ext-lib.rng +3 -0
- data/vendor-src/libleptris/test/rng/include-cases/ext-main.rng +7 -0
- data/vendor-src/libleptris/test/rng/include-cases/lib.rng +5 -0
- data/vendor-src/libleptris/test/rng/include-cases/lib2.rng +6 -0
- data/vendor-src/libleptris/test/rng/include-cases/main.rng +4 -0
- data/vendor-src/libleptris/test/rng/include-cases/no-href.rng +4 -0
- data/vendor-src/libleptris/test/rng/include-cases/override.rng +8 -0
- data/vendor-src/libleptris/test/rng/include-cases/self-include.rng +4 -0
- data/vendor-src/libleptris/test/rng/include-cases/start-override.rng +5 -0
- data/vendor-src/libleptris/test/rng/jing-cases/000.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/000.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/000.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/001.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/001.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/001.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/002.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/002.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/002.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/003.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/003.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/003.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/004.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/004.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/004.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/005.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/005.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/005.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/006.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/006.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/006.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/007.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/007.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/007.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/008.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/008.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/008.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/009.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/009.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/009.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/010.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/010.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/010.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/011.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/011.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/011.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/012.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/012.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/012.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/013.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/013.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/013.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/014.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/014.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/014.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/015.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/015.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/015.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/016.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/016.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/016.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/017.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/017.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/017.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/018.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/018.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/018.rng +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/019.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/019.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/019.rng +7 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020-book.rng +4 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020.bad.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020.ok.xml +1 -0
- data/vendor-src/libleptris/test/rng/jing-cases/020.rng +3 -0
- data/vendor-src/libleptris/test/rng/jing-cases/README.md +32 -0
- data/vendor-src/libleptris/test/rng/jing-cases/jing-ref.json +212 -0
- data/vendor-src/libleptris/test/rng/jing-cases/meta.json +1 -0
- data/vendor-src/libleptris/test/rng/test_rng.cpp +1365 -0
- data/vendor-src/libleptris/test/rng/test_rng_corpus.cpp +133 -0
- data/vendor-src/libleptris/test/rng/test_rng_corpus_msg.cpp +233 -0
- data/vendor-src/libleptris/test/sax/test_iterparse.cpp +203 -0
- data/vendor-src/libleptris/test/sax/test_pull.cpp +214 -0
- data/vendor-src/libleptris/test/sax/test_pull_batch.cpp +201 -0
- data/vendor-src/libleptris/test/sax/test_recorder.cpp +265 -0
- data/vendor-src/libleptris/test/sax/test_sax.cpp +665 -0
- data/vendor-src/libleptris/test/sax/test_streaming.cpp +434 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/README.md +15 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/extends-baseuri-fixup-01.xml +28 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/extends-recursive-01.xml +27 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/include-baseuri-fixup-01.xml +24 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/include-recursive-01.xml +24 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-02.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-03.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-04.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-05.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-06.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-pattern-global-01.xml +24 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-02.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-03.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-04.xml +19 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-05.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-06.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-07.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-rule-global-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-rule-global-02.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-pattern-01.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-phase-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-rule-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/let-value-element-content-01.xml +33 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/pattern-abstract-01.xml +22 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/pattern-subordinate-document-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/pattern-subordinate-document-02.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-abstract-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-abstract-02.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-attribute-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-comment-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-element-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-pi-01.xml +20 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-root-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-text-01.xml +18 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-01.xml +22 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-02.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-03.xml +22 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/rule-order-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/schema-default-phase-01.xml +26 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/schema-default-phase-02.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-diagnostic-01.xml +28 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-diagnostic-02.xml +25 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-name-nopath-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-name-path-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-property-01.xml +28 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-property-copy-of.xml +26 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/svrl-value-of-01.xml +23 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/xslt-key-01.xml +19 -0
- data/vendor-src/libleptris/test/sch/conformance-cases/xslt-key-element-content-01.xml +21 -0
- data/vendor-src/libleptris/test/sch/test_schematron.cpp +337 -0
- data/vendor-src/libleptris/test/sch/test_schematron_corpus.cpp +421 -0
- data/vendor-src/libleptris/test/serializer/test_c14n.cpp +539 -0
- data/vendor-src/libleptris/test/serializer/test_serialize.cpp +890 -0
- data/vendor-src/libleptris/test/smoke/test_smoke.cpp +41 -0
- data/vendor-src/libleptris/test/xinclude/test_xinclude.cpp +903 -0
- data/vendor-src/libleptris/test/xpath/test_bytecode_vm.cpp +755 -0
- data/vendor-src/libleptris/test/xpath/test_compiled.cpp +171 -0
- data/vendor-src/libleptris/test/xpath/test_exslt.cpp +141 -0
- data/vendor-src/libleptris/test/xpath/test_xpath.cpp +2433 -0
- data/vendor-src/libleptris/test/xpath/test_xpath_conformance.cpp +570 -0
- data/vendor-src/libleptris/test/xpath/test_xslt.cpp +4245 -0
- data/vendor-src/libleptris/test/xquery/books.xml +1 -0
- data/vendor-src/libleptris/test/xquery/qt3/README.md +28 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/concat.xml +878 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/contains.xml +795 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/ends-with.xml +556 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/starts-with.xml +644 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/substring/concepts.xml +1 -0
- data/vendor-src/libleptris/test/xquery/qt3/fn/substring.xml +449 -0
- data/vendor-src/libleptris/test/xquery/test_qt3.cpp +324 -0
- data/vendor-src/libleptris/test/xquery/test_xquery.cpp +768 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/ATTRIBUTION.md +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102-inc.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.out +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.ent +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.xsl +45 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.xsl +59 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.out +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.xml +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.xsl +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.xml +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.out +351 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.xml +118 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.xsl +99 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.xml +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp1.imp +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp2.imp +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp3.imp +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp4.imp +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.doc +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131-imp.imp +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.imp +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.out +23 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.xml +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.xsl +28 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.xsl +23 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.out +46 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.out +35 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.xml +65 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.xsl +85 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.err +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-1.imp +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-2.imp +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-3.imp +57 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-4.imp +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-5.imp +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-6.imp +31 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.out +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.xml +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.xsl +29 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-151.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-151.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.out +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.xsl +30 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.doc +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-154.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-154.xsl +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.imp1.imp +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.imp2.imp +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.err +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.doc +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.out +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.out +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.out +15256 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.xml +15255 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.xsl +131 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.imp +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.err +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.xsl +33 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.xsl +24 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.err +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.out +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.xsl +42 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188-imp.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190-imp.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191-imp.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.xsl +33 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.err +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.out +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.xsl +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.xsl +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.err +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.xsl +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.xsl +61 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.err +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.xsl +25 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.err +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.xsl +24 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.out +68 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.xml +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.out +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.xml +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223-imp.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223-inc.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.xsl +28 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.out +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.xml +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.xsl +20 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.out +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.xml +2419 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.ent +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.out +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.out +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.xml +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.xsl +29 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-inc.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-inc.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.xsl +34 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.xml +38 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.xsl +27 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.xsl +24 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.out +954 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.xml +475 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.xsl +158 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.out +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.xsl +28 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.xsl +21 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-58.xsl +274 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.err +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.xsl +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.out +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62-inc.xsl +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.out +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.xml +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.ent +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.out +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.xsl +26 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.xml +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.xsl +11 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.xsl +31 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.xsl +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.xml +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.xsl +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.xsl +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.xsl +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.xsl +29 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.xml +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.xsl +18 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.out +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.out +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.xml +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.xsl +14 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.xml +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.xml +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.xsl +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.out +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.xml +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.xsl +105 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.xml +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.out +13 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.xml +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.xsl +35 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.xml +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.xsl +8 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.out +15 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.xml +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.xsl +19 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93-inc.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.out +3 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.xsl +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.xml +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.xsl +35 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.out +4 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.xsl +22 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.out +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.xml +5 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.xsl +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.xml +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.xsl +32 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.out +6 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.xml +10 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.xsl +31 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.out +2 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.xml +23 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.out +9 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.xml +1 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.xsl +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.dtd +7 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.out +16 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.xml +17 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.xsl +62 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/inner.xsl +12 -0
- data/vendor-src/libleptris/test/xslt/libxslt_suite_general/items.xml +34 -0
- data/vendor-src/libleptris/test/xslt/open_cases.txt +0 -0
- data/vendor-src/libleptris/test/xslt/test_libxslt_suite.cpp +398 -0
- data/vendor-src/libleptris/vcpkg.json +29 -0
- data/vendor-src/utf8proc/CMakeLists.txt +133 -0
- data/vendor-src/utf8proc/Doxyfile +2765 -0
- data/vendor-src/utf8proc/LICENSE.md +93 -0
- data/vendor-src/utf8proc/MANIFEST +9 -0
- data/vendor-src/utf8proc/Makefile +203 -0
- data/vendor-src/utf8proc/NEWS.md +479 -0
- data/vendor-src/utf8proc/README.md +143 -0
- data/vendor-src/utf8proc/appveyor.yml +46 -0
- data/vendor-src/utf8proc/bench/Makefile +40 -0
- data/vendor-src/utf8proc/bench/bench.c +56 -0
- data/vendor-src/utf8proc/bench/icu.c +61 -0
- data/vendor-src/utf8proc/bench/unistring.c +60 -0
- data/vendor-src/utf8proc/bench/util.c +39 -0
- data/vendor-src/utf8proc/bench/util.h +22 -0
- data/vendor-src/utf8proc/cmake/utf8proc-config.cmake.in +5 -0
- data/vendor-src/utf8proc/data/Makefile +62 -0
- data/vendor-src/utf8proc/data/Manifest.toml +16 -0
- data/vendor-src/utf8proc/data/Project.toml +2 -0
- data/vendor-src/utf8proc/data/data_generator.jl +498 -0
- data/vendor-src/utf8proc/libutf8proc.pc.cmakein +10 -0
- data/vendor-src/utf8proc/libutf8proc.pc.in +10 -0
- data/vendor-src/utf8proc/lump.md +27 -0
- data/vendor-src/utf8proc/test/app/CMakeLists.txt +6 -0
- data/vendor-src/utf8proc/test/app/app.c +9 -0
- data/vendor-src/utf8proc/test/case.c +76 -0
- data/vendor-src/utf8proc/test/charwidth.c +91 -0
- data/vendor-src/utf8proc/test/custom.c +28 -0
- data/vendor-src/utf8proc/test/fuzz_main.c +54 -0
- data/vendor-src/utf8proc/test/fuzzer.c +97 -0
- data/vendor-src/utf8proc/test/graphemetest.c +136 -0
- data/vendor-src/utf8proc/test/iscase.c +63 -0
- data/vendor-src/utf8proc/test/iterate.c +168 -0
- data/vendor-src/utf8proc/test/maxdecomposition.c +22 -0
- data/vendor-src/utf8proc/test/misc.c +51 -0
- data/vendor-src/utf8proc/test/normtest.c +64 -0
- data/vendor-src/utf8proc/test/ossfuzz.sh +13 -0
- data/vendor-src/utf8proc/test/printproperty.c +68 -0
- data/vendor-src/utf8proc/test/tests.c +60 -0
- data/vendor-src/utf8proc/test/tests.h +27 -0
- data/vendor-src/utf8proc/test/valid.c +41 -0
- data/vendor-src/utf8proc/utf8proc.c +834 -0
- data/vendor-src/utf8proc/utf8proc.h +794 -0
- data/vendor-src/utf8proc/utf8proc_data.c +17141 -0
- data/vendor-src/utf8proc/utils.cmake +20 -0
- metadata +1528 -2
|
@@ -0,0 +1,4245 @@
|
|
|
1
|
+
/* TODO.transform — XSLT 1.0 core engine specs. Each case: compile
|
|
2
|
+
* the stylesheet once, apply, compare the serialized result. */
|
|
3
|
+
#include <gtest/gtest.h>
|
|
4
|
+
#include <regex>
|
|
5
|
+
#include <string>
|
|
6
|
+
extern "C" {
|
|
7
|
+
#ifndef _WIN32
|
|
8
|
+
#include <unistd.h>
|
|
9
|
+
#endif
|
|
10
|
+
#include "leptris.h"
|
|
11
|
+
}
|
|
12
|
+
#include <cstring>
|
|
13
|
+
#include <string>
|
|
14
|
+
|
|
15
|
+
namespace {
|
|
16
|
+
const char* KXSL = "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'";
|
|
17
|
+
|
|
18
|
+
std::string run(const char* sheet_body, const char* xml) {
|
|
19
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
20
|
+
" version='1.0'>" + sheet_body +
|
|
21
|
+
"</xsl:stylesheet>";
|
|
22
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
23
|
+
if (!x) return "(compile-failed)";
|
|
24
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
25
|
+
if (!d) { leptris_xslt_free(x); return "(parse-failed)"; }
|
|
26
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
27
|
+
std::string r = out ? out : "(null)";
|
|
28
|
+
leptris_free_string(out);
|
|
29
|
+
leptris_document_free(d);
|
|
30
|
+
leptris_xslt_free(x);
|
|
31
|
+
return r;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Same, pinned to version='3.0' — XSLT 3.0 semantics (sequence
|
|
35
|
+
* display forms, versioned value-of, expand-text). */
|
|
36
|
+
std::string run30(const char* sheet_body, const char* xml) {
|
|
37
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
38
|
+
" version='3.0' expand-text='yes'>" +
|
|
39
|
+
sheet_body + "</xsl:stylesheet>";
|
|
40
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
41
|
+
if (!x) return "(compile-failed)";
|
|
42
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
43
|
+
if (!d) { leptris_xslt_free(x); return "(parse-failed)"; }
|
|
44
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
45
|
+
std::string r = out ? out : "(null)";
|
|
46
|
+
leptris_free_string(out);
|
|
47
|
+
leptris_document_free(d);
|
|
48
|
+
leptris_xslt_free(x);
|
|
49
|
+
return r;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Strip the declaration the API adds for comparison. */
|
|
53
|
+
std::string body(const std::string& s) {
|
|
54
|
+
const char* decl = "<?xml version=\"1.0\"?>";
|
|
55
|
+
if (s.compare(0, strlen(decl), decl) == 0) {
|
|
56
|
+
size_t rest = strlen(decl);
|
|
57
|
+
/* libxslt breaks the line after the declaration. */
|
|
58
|
+
if (rest < s.size() && s[rest] == '\n') rest++;
|
|
59
|
+
return s.substr(rest);
|
|
60
|
+
}
|
|
61
|
+
return s;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* run2: stylesheet with a top-level key definition + body. */
|
|
65
|
+
std::string run2(const char* body_with_key, const char* xml) {
|
|
66
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
67
|
+
" version='1.0'>" +
|
|
68
|
+
"<xsl:key name='k' match='i' use='@v'/>" +
|
|
69
|
+
body_with_key + "</xsl:stylesheet>";
|
|
70
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
71
|
+
if (!x) return "(compile-failed)";
|
|
72
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
73
|
+
if (!d) { leptris_xslt_free(x); return "(parse-failed)"; }
|
|
74
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
75
|
+
std::string r = out ? out : "(null)";
|
|
76
|
+
leptris_free_string(out);
|
|
77
|
+
leptris_document_free(d);
|
|
78
|
+
leptris_xslt_free(x);
|
|
79
|
+
return r;
|
|
80
|
+
}
|
|
81
|
+
} // namespace
|
|
82
|
+
|
|
83
|
+
/* ---------------------------------------------------------------
|
|
84
|
+
* XsltFull: the complete-implementation conformance set. Every
|
|
85
|
+
* case pins a behavior that was a documented gap before this
|
|
86
|
+
* branch (each comment names the spec section + the old behavior).
|
|
87
|
+
* --------------------------------------------------------------- */
|
|
88
|
+
|
|
89
|
+
/* §11 block scope: an inner xsl:variable shadows within its
|
|
90
|
+
* containing element and RESTORES the outer binding afterwards.
|
|
91
|
+
* Before: the inner binding persisted (flat chain, no scope). */
|
|
92
|
+
TEST(XsltFull, BlockScopeVariablesShadowAndRestore) {
|
|
93
|
+
EXPECT_EQ(body(run(
|
|
94
|
+
"<xsl:template match='/'>"
|
|
95
|
+
"<xsl:variable name='x' select=\"'outer'\"/>"
|
|
96
|
+
"<w><xsl:variable name='x' select=\"'inner'\"/>"
|
|
97
|
+
"<xsl:value-of select='$x'/></w>"
|
|
98
|
+
"<xsl:value-of select='$x'/></xsl:template>",
|
|
99
|
+
"<r/>")), "<w>inner</w>outer");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* §11.6 template parameters: the default applies only when the
|
|
103
|
+
* caller does not bind the name. */
|
|
104
|
+
TEST(XsltFull, TemplateParamDefaults) {
|
|
105
|
+
EXPECT_EQ(body(run(
|
|
106
|
+
"<xsl:template match='/'>"
|
|
107
|
+
"<xsl:call-template name='t'/>"
|
|
108
|
+
"<xsl:call-template name='t'>"
|
|
109
|
+
"<xsl:with-param name='v' select=\"'P'\"/>"
|
|
110
|
+
"</xsl:call-template></xsl:template>"
|
|
111
|
+
"<xsl:template name='t'>"
|
|
112
|
+
"<xsl:param name='v' select=\"'D'\"/>"
|
|
113
|
+
"<p><xsl:value-of select='$v'/></p></xsl:template>",
|
|
114
|
+
"<r/>")), "<p>D</p><p>P</p>");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* §5.6 apply-imports: the imported rule runs when the importing
|
|
118
|
+
* rule defers to it. Uses temp files for the import. */
|
|
119
|
+
TEST(XsltFull, ApplyImports) {
|
|
120
|
+
const char* lib = "leptris_xai_lib.xsl";
|
|
121
|
+
const char* main = "leptris_xai_main.xsl";
|
|
122
|
+
FILE* f = fopen(lib, "w");
|
|
123
|
+
fputs("<?xml version='1.0'?>"
|
|
124
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
125
|
+
" version='1.0'>"
|
|
126
|
+
"<xsl:template match='r'>LIB</xsl:template></xsl:stylesheet>", f);
|
|
127
|
+
fclose(f);
|
|
128
|
+
f = fopen(main, "w");
|
|
129
|
+
fputs("<?xml version='1.0'?>"
|
|
130
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
131
|
+
" version='1.0'>"
|
|
132
|
+
"<xsl:import href='leptris_xai_lib.xsl'/>"
|
|
133
|
+
"<xsl:template match='r'>[<xsl:apply-imports/>]</xsl:template>"
|
|
134
|
+
"</xsl:stylesheet>", f);
|
|
135
|
+
fclose(f);
|
|
136
|
+
LeptrisXslt x = leptris_xslt_parse_file(main);
|
|
137
|
+
ASSERT_NE(x, nullptr);
|
|
138
|
+
LeptrisDocument d = leptris_parse_string("<r/>", strlen("<r/>"), nullptr);
|
|
139
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
140
|
+
ASSERT_NE(out, nullptr);
|
|
141
|
+
EXPECT_EQ(body(std::string(out)), "[LIB]");
|
|
142
|
+
leptris_free_string(out);
|
|
143
|
+
leptris_document_free(d);
|
|
144
|
+
leptris_xslt_free(x);
|
|
145
|
+
remove(lib); remove(main);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* §5.5 default priorities: QName (0) beats * (-0.5); a predicate
|
|
149
|
+
* pattern (0.5) beats the bare QName. Before: * was -0.25 and
|
|
150
|
+
* paths scored 0 — wrong winners. */
|
|
151
|
+
TEST(XsltFull, DefaultPriorityTable) {
|
|
152
|
+
/* * vs i: i wins (0 > -0.5). */
|
|
153
|
+
EXPECT_EQ(body(run(
|
|
154
|
+
"<xsl:template match='*'>STAR</xsl:template>"
|
|
155
|
+
"<xsl:template match='/r'><xsl:apply-templates select='//i'/></xsl:template>"
|
|
156
|
+
"<xsl:template match='i'>QNAME</xsl:template>",
|
|
157
|
+
"<r><i/></r>")), "QNAME");
|
|
158
|
+
/* i[@a] (0.5) vs i (0): the predicate template wins. */
|
|
159
|
+
EXPECT_EQ(body(run(
|
|
160
|
+
"<xsl:template match='/r'><xsl:apply-templates select='//i'/></xsl:template>"
|
|
161
|
+
"<xsl:template match='i'>PLAIN</xsl:template>"
|
|
162
|
+
"<xsl:template match='i[@a]'>PRED</xsl:template>",
|
|
163
|
+
"<r><i a='1'/></r>")), "PRED");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* §16.4 disable-output-escaping: the string-value passes through
|
|
167
|
+
* raw. Source carries <b> (string-value "<b>"); without DOE
|
|
168
|
+
* it re-escapes. Before: DOE was ignored entirely. */
|
|
169
|
+
TEST(XsltFull, DisableOutputEscaping) {
|
|
170
|
+
EXPECT_EQ(body(run(
|
|
171
|
+
"<xsl:template match='/'>"
|
|
172
|
+
"<xsl:value-of select='/r/t' disable-output-escaping='yes'/>"
|
|
173
|
+
"</xsl:template>", "<r><t><b></t></r>")), "<b>");
|
|
174
|
+
EXPECT_EQ(body(run(
|
|
175
|
+
"<xsl:template match='/'>"
|
|
176
|
+
"<xsl:value-of select='/r/t'/>"
|
|
177
|
+
"</xsl:template>", "<r><t><b></t></r>")), "<b>");
|
|
178
|
+
/* xsl:text disable-output-escaping: literal markup passes raw. */
|
|
179
|
+
EXPECT_EQ(body(run(
|
|
180
|
+
"<xsl:template match='/'>"
|
|
181
|
+
"<xsl:text disable-output-escaping='yes'><hr/></xsl:text>"
|
|
182
|
+
"</xsl:template>", "<r/>")), "<hr/>");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* §16.2 method=html: void elements without the self-closing
|
|
186
|
+
* slash, no XML declaration. */
|
|
187
|
+
TEST(XsltFull, HtmlOutputMethod) {
|
|
188
|
+
std::string s = body(run(
|
|
189
|
+
"<xsl:output method='html'/>"
|
|
190
|
+
"<xsl:template match='/'>"
|
|
191
|
+
"<html><body><br/><hr/>t</body></html></xsl:template>",
|
|
192
|
+
"<r/>"));
|
|
193
|
+
EXPECT_EQ(s.find("<?xml"), std::string::npos);
|
|
194
|
+
EXPECT_NE(s.find("<br>"), std::string::npos);
|
|
195
|
+
EXPECT_NE(s.find("<hr>"), std::string::npos);
|
|
196
|
+
EXPECT_EQ(s.find("<br/>"), std::string::npos);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* §16.1 standalone: declared on the output declaration. */
|
|
200
|
+
TEST(XsltFull, StandaloneDeclaration) {
|
|
201
|
+
std::string s = run(
|
|
202
|
+
"<xsl:output standalone='yes'/>"
|
|
203
|
+
"<xsl:template match='/'><r/></xsl:template>", "<r/>");
|
|
204
|
+
EXPECT_NE(s.find("standalone=\"yes\""), std::string::npos);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* §10 case-order: with equal base keys, upper-first (default)
|
|
208
|
+
* puts A before a; lower-first reverses. */
|
|
209
|
+
TEST(XsltFull, SortCaseOrder) {
|
|
210
|
+
EXPECT_EQ(body(run(
|
|
211
|
+
"<xsl:template match='/'>"
|
|
212
|
+
"<xsl:for-each select='//i'>"
|
|
213
|
+
"<xsl:sort select='@k' case-order='upper-first'/>"
|
|
214
|
+
"<xsl:value-of select='@k'/>"
|
|
215
|
+
"</xsl:for-each></xsl:template>",
|
|
216
|
+
"<r><i k='a'/><i k='A'/></r>")), "Aa");
|
|
217
|
+
EXPECT_EQ(body(run(
|
|
218
|
+
"<xsl:template match='/'>"
|
|
219
|
+
"<xsl:for-each select='//i'>"
|
|
220
|
+
"<xsl:sort select='@k' case-order='lower-first'/>"
|
|
221
|
+
"<xsl:value-of select='@k'/>"
|
|
222
|
+
"</xsl:for-each></xsl:template>",
|
|
223
|
+
"<r><i k='a'/><i k='A'/></r>")), "aA");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* §7.7 letter-value="alphabetic" forces a/A over roman for the
|
|
227
|
+
* ambiguous letter formats. */
|
|
228
|
+
TEST(XsltFull, NumberLetterValueAlphabetic) {
|
|
229
|
+
EXPECT_EQ(body(run(
|
|
230
|
+
"<xsl:template match='/'>"
|
|
231
|
+
"<xsl:for-each select='//c'>"
|
|
232
|
+
"<n><xsl:number format='i' letter-value='alphabetic'/></n>"
|
|
233
|
+
"</xsl:for-each></xsl:template>",
|
|
234
|
+
"<r><c/><c/><c/></r>")),
|
|
235
|
+
"<n>a</n><n>b</n><n>c</n>");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* §15 fallback: an unknown xsl: instruction executes its
|
|
239
|
+
* xsl:fallback content when instantiated. Before: no-op. */
|
|
240
|
+
TEST(XsltFull, FallbackForUnknownInstruction) {
|
|
241
|
+
EXPECT_EQ(body(run(
|
|
242
|
+
"<xsl:template match='/'>"
|
|
243
|
+
"<w><xsl:bogus-extension>"
|
|
244
|
+
"<xsl:fallback>FELL</xsl:fallback>"
|
|
245
|
+
"</xsl:bogus-extension></w>"
|
|
246
|
+
"</xsl:template>", "<r/>")), "<w>FELL</w>");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* §3.4: whitespace-only source text is stripped by default; the
|
|
250
|
+
* mixed-content text survives. */
|
|
251
|
+
TEST(XsltFull, SourceWhitespaceStrippedByDefault) {
|
|
252
|
+
EXPECT_EQ(body(run(
|
|
253
|
+
"<xsl:template match='/r'>"
|
|
254
|
+
"<xsl:for-each select='*'>"
|
|
255
|
+
"<xsl:value-of select='name()'/>"
|
|
256
|
+
"</xsl:for-each></xsl:template>",
|
|
257
|
+
"<r>\n <a/>\n <b/>\n</r>")), "ab");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* §3.4 xsl:preserve-space: listed parents keep ws-only text. */
|
|
261
|
+
TEST(XsltFull, PreserveSpaceKeepsWhitespace) {
|
|
262
|
+
std::string s = body(run(
|
|
263
|
+
"<xsl:preserve-space elements='pre'/>"
|
|
264
|
+
"<xsl:template match='/r'>"
|
|
265
|
+
"<pre><xsl:value-of select='pre'/></pre>"
|
|
266
|
+
"</xsl:template>",
|
|
267
|
+
"<r><pre> </pre></r>"));
|
|
268
|
+
EXPECT_NE(s.find(" "), std::string::npos);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/* §7.1.1 xsl:element namespace: emits an xmlns declaration. */
|
|
272
|
+
TEST(XsltFull, ElementNamespaceDeclaration) {
|
|
273
|
+
std::string s = body(run(
|
|
274
|
+
"<xsl:template match='/'>"
|
|
275
|
+
"<xsl:element name='n:e' namespace='urn:x'/>"
|
|
276
|
+
"</xsl:template>", "<r/>"));
|
|
277
|
+
EXPECT_NE(s.find("xmlns:n=\"urn:x\""), std::string::npos);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* §7.1.1 xsl:namespace-alias: the result prefix replaces the
|
|
281
|
+
* stylesheet prefix on literal result elements. */
|
|
282
|
+
TEST(XsltFull, NamespaceAliasRewritesPrefix) {
|
|
283
|
+
std::string s = body(run(
|
|
284
|
+
"<xsl:namespace-alias stylesheet-prefix='alt' result-prefix='x'/>"
|
|
285
|
+
"<xsl:template match='/'>"
|
|
286
|
+
"<alt:out xmlns:alt='urn:z'>t</alt:out>"
|
|
287
|
+
"</xsl:template>", "<r/>"));
|
|
288
|
+
EXPECT_NE(s.find("<x:out"), std::string::npos);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* §14.2 element-available / function-available. */
|
|
292
|
+
TEST(XsltFull, AvailabilityFunctions) {
|
|
293
|
+
EXPECT_EQ(body(run(
|
|
294
|
+
"<xsl:template match='/'>"
|
|
295
|
+
"<xsl:value-of select=\"element-available('xsl:for-each')\"/>"
|
|
296
|
+
"<xsl:value-of select=\"element-available('xsl:bogus')\"/>"
|
|
297
|
+
"</xsl:template>", "<r/>")), "truefalse");
|
|
298
|
+
EXPECT_EQ(body(run(
|
|
299
|
+
"<xsl:template match='/'>"
|
|
300
|
+
"<xsl:value-of select=\"function-available('key')\"/>"
|
|
301
|
+
"<xsl:value-of select=\"function-available('no-such-fn')\"/>"
|
|
302
|
+
"</xsl:template>", "<r/>")), "truefalse");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* EXSLT regexp:match (first match as string) + regexp:replace
|
|
306
|
+
* with $1 backreference. POSIX builds run the real ERE engine;
|
|
307
|
+
* Windows (no <regex.h>) ships the documented no-op stubs — empty
|
|
308
|
+
* match nodeset, identity replace. */
|
|
309
|
+
TEST(XsltFull, RegexpMatchAndReplace) {
|
|
310
|
+
#ifdef _WIN32
|
|
311
|
+
EXPECT_EQ(body(run(
|
|
312
|
+
"<xsl:template match='/'>"
|
|
313
|
+
"<xsl:value-of select=\"regexp:match('ab12cd', '[0-9]+')\"/>"
|
|
314
|
+
"</xsl:template>", "<r/>")), "");
|
|
315
|
+
EXPECT_EQ(body(run(
|
|
316
|
+
"<xsl:template match='/'>"
|
|
317
|
+
"<xsl:value-of select=\"regexp:replace('ab12', '([a-z]+)([0-9]+)', '$2$1')\"/>"
|
|
318
|
+
"</xsl:template>", "<r/>")), "ab12");
|
|
319
|
+
#else
|
|
320
|
+
EXPECT_EQ(body(run(
|
|
321
|
+
"<xsl:template match='/'>"
|
|
322
|
+
"<xsl:value-of select=\"regexp:match('ab12cd', '[0-9]+')\"/>"
|
|
323
|
+
"</xsl:template>", "<r/>")), "12");
|
|
324
|
+
EXPECT_EQ(body(run(
|
|
325
|
+
"<xsl:template match='/'>"
|
|
326
|
+
"<xsl:value-of select=\"regexp:replace('ab12', '([a-z]+)([0-9]+)', '$2$1')\"/>"
|
|
327
|
+
"</xsl:template>", "<r/>")), "12ab");
|
|
328
|
+
#endif
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* §12.2 key() with a node-set second argument: unions the buckets
|
|
332
|
+
* of every node's string-value. */
|
|
333
|
+
TEST(XsltFull, KeyNodeSetArgument) {
|
|
334
|
+
EXPECT_EQ(body(run2(
|
|
335
|
+
"<xsl:template match='/'>"
|
|
336
|
+
"<xsl:for-each select=\"key('k', //q)\">"
|
|
337
|
+
"<xsl:value-of select='@n'/>"
|
|
338
|
+
"</xsl:for-each></xsl:template>",
|
|
339
|
+
"<r><i v='x' n='1'/><i v='y' n='2'/><q>x</q><q>y</q></r>")), "12");
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/* §2.7 embedding: xml-stylesheet PI with href="#id" selects the
|
|
343
|
+
* embedded stylesheet element. */
|
|
344
|
+
TEST(XsltFull, EmbeddedStylesheet) {
|
|
345
|
+
std::string doc =
|
|
346
|
+
"<?xml-stylesheet type='text/xsl' href='#tr'?>"
|
|
347
|
+
"<r><xsl:stylesheet id='tr' "
|
|
348
|
+
"xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>"
|
|
349
|
+
"<xsl:template match='/'><e/></xsl:template>"
|
|
350
|
+
"</xsl:stylesheet></r>";
|
|
351
|
+
LeptrisDocument d = leptris_parse_string(doc.c_str(), doc.size(),
|
|
352
|
+
nullptr);
|
|
353
|
+
ASSERT_NE(d, nullptr);
|
|
354
|
+
LeptrisXslt x2 = leptris_xslt_parse(doc.c_str(), doc.size());
|
|
355
|
+
EXPECT_NE(x2, nullptr);
|
|
356
|
+
if (x2) {
|
|
357
|
+
char* out = leptris_xslt_apply_string(x2, d);
|
|
358
|
+
EXPECT_NE(std::string(out ? out : "").find("<e/>"),
|
|
359
|
+
std::string::npos);
|
|
360
|
+
leptris_free_string(out);
|
|
361
|
+
leptris_xslt_free(x2);
|
|
362
|
+
}
|
|
363
|
+
leptris_document_free(d);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* §2.5 forwards-compatible processing: version != 1.0 ignores an
|
|
367
|
+
* unknown TOP-LEVEL element instead of failing compilation. */
|
|
368
|
+
TEST(XsltFull, ForwardsCompatibleTopLevel) {
|
|
369
|
+
EXPECT_NE(run(
|
|
370
|
+
"<xsl:whatever-new/>"
|
|
371
|
+
"<xsl:template match='/'><r/></xsl:template>",
|
|
372
|
+
"<r/>").substr(0, 6), std::string("(null)"));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
TEST(Xslt, ValueOfSelectsTextAttrNumber) {
|
|
377
|
+
EXPECT_EQ(body(run(
|
|
378
|
+
"<xsl:template match='/'><o><xsl:value-of select='/r/a'/>"
|
|
379
|
+
"<xsl:value-of select='/r/@k'/></o></xsl:template>",
|
|
380
|
+
"<r k='9'><a>hi</a></r>")), "<o>hi9</o>");
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
TEST(Xslt, LiteralElementsAndAvt) {
|
|
384
|
+
EXPECT_EQ(body(run(
|
|
385
|
+
"<xsl:template match='/'><div id='{/r/@k}' class='c'>x</div>"
|
|
386
|
+
"</xsl:template>",
|
|
387
|
+
"<r k='7'/>")), "<div id=\"7\" class=\"c\">x</div>");
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
TEST(Xslt, ApplyTemplatesAndPatterns) {
|
|
391
|
+
EXPECT_EQ(body(run(
|
|
392
|
+
"<xsl:template match='/'><L><xsl:apply-templates/></L>"
|
|
393
|
+
"</xsl:template>"
|
|
394
|
+
"<xsl:template match='item'><i><xsl:value-of select='.'/></i>"
|
|
395
|
+
"</xsl:template>"
|
|
396
|
+
"<xsl:template match='note'><n/></xsl:template>",
|
|
397
|
+
"<r><item>one</item><note/><item>two</item></r>")),
|
|
398
|
+
"<L><i>one</i><n/><i>two</i></L>");
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
TEST(Xslt, ForEachSorts) {
|
|
402
|
+
EXPECT_EQ(body(run(
|
|
403
|
+
"<xsl:template match='/'>"
|
|
404
|
+
"<xsl:for-each select='//i'>"
|
|
405
|
+
"<xsl:sort select='@n' data-type='number' order='descending'/>"
|
|
406
|
+
"<e n='{@n}'/>"
|
|
407
|
+
"</xsl:for-each></xsl:template>",
|
|
408
|
+
"<r><i n='1'/><i n='5'/><i n='3'/></r>")),
|
|
409
|
+
"<e n=\"5\"/><e n=\"3\"/><e n=\"1\"/>");
|
|
410
|
+
|
|
411
|
+
EXPECT_EQ(body(run(
|
|
412
|
+
"<xsl:template match='/'>"
|
|
413
|
+
"<xsl:for-each select='//i'>"
|
|
414
|
+
"<xsl:sort select='.'/>"
|
|
415
|
+
"<e><xsl:value-of select='.'/></e>"
|
|
416
|
+
"</xsl:for-each></xsl:template>",
|
|
417
|
+
"<r><i>b</i><i>a</i><i>c</i></r>")),
|
|
418
|
+
"<e>a</e><e>b</e><e>c</e>");
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
TEST(Xslt, IfAndChoose) {
|
|
422
|
+
EXPECT_EQ(body(run(
|
|
423
|
+
"<xsl:template match='/'>"
|
|
424
|
+
"<xsl:for-each select='//v'>"
|
|
425
|
+
"<w><xsl:choose>"
|
|
426
|
+
"<xsl:when test='. > 10'>B</xsl:when>"
|
|
427
|
+
"<xsl:when test='. > 5'>M</xsl:when>"
|
|
428
|
+
"<xsl:otherwise>S</xsl:otherwise>"
|
|
429
|
+
"</xsl:choose></w></xsl:for-each></xsl:template>",
|
|
430
|
+
"<r><v>3</v><v>7</v><v>20</v></r>")), "<w>S</w><w>M</w><w>B</w>");
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
TEST(Xslt, Variables) {
|
|
434
|
+
EXPECT_EQ(body(run(
|
|
435
|
+
"<xsl:variable name='lim' select=\"4\"/>"
|
|
436
|
+
"<xsl:template match='/'>"
|
|
437
|
+
"<xsl:for-each select='//n'>"
|
|
438
|
+
"<xsl:if test='. > $lim'><x/></xsl:if>"
|
|
439
|
+
"</xsl:for-each></xsl:template>",
|
|
440
|
+
"<r><n>2</n><n>9</n><n>4</n><n>6</n></r>")), "<x/><x/>");
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
TEST(Xslt, CallTemplateWithParam) {
|
|
444
|
+
EXPECT_EQ(body(run(
|
|
445
|
+
"<xsl:template match='/'>"
|
|
446
|
+
"<xsl:call-template name='emit'>"
|
|
447
|
+
"<xsl:with-param name='v' select=\"/r/@k\"/>"
|
|
448
|
+
"</xsl:call-template></xsl:template>"
|
|
449
|
+
"<xsl:template name='emit'>"
|
|
450
|
+
"<xsl:param name='v'/>"
|
|
451
|
+
"<p><xsl:value-of select='$v'/></p></xsl:template>",
|
|
452
|
+
"<r k='42'/>")), "<p>42</p>");
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
TEST(Xslt, CopyAndCopyOf) {
|
|
456
|
+
EXPECT_EQ(body(run(
|
|
457
|
+
"<xsl:template match='/'>"
|
|
458
|
+
"<xsl:copy-of select='/r/item'/>"
|
|
459
|
+
"</xsl:template>",
|
|
460
|
+
"<r><item id='1'>t<sub/></item></r>")),
|
|
461
|
+
"<item id=\"1\">t<sub/></item>");
|
|
462
|
+
|
|
463
|
+
EXPECT_EQ(body(run(
|
|
464
|
+
"<xsl:template match='item'><xsl:copy><xsl:attribute "
|
|
465
|
+
"name='extra'>e</xsl:attribute><xsl:apply-templates/></xsl:copy>"
|
|
466
|
+
"</xsl:template>"
|
|
467
|
+
"<xsl:template match='/'><xsl:apply-templates select='//item'/>"
|
|
468
|
+
"</xsl:template>",
|
|
469
|
+
"<r><item id='1'>t</item></r>")),
|
|
470
|
+
"<item extra=\"e\">t</item>");
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
TEST(Xslt, NumberFormats) {
|
|
474
|
+
EXPECT_EQ(body(run(
|
|
475
|
+
"<xsl:template match='/'>"
|
|
476
|
+
"<xsl:for-each select='//c'>"
|
|
477
|
+
"<n><xsl:number format='a'/></n>"
|
|
478
|
+
"</xsl:for-each></xsl:template>",
|
|
479
|
+
"<r><c/><c/><c/></r>")), "<n>a</n><n>b</n><n>c</n>");
|
|
480
|
+
EXPECT_EQ(body(run(
|
|
481
|
+
"<xsl:template match='/'>"
|
|
482
|
+
"<xsl:for-each select='//c'>"
|
|
483
|
+
"<n><xsl:number format='I'/></n>"
|
|
484
|
+
"</xsl:for-each></xsl:template>",
|
|
485
|
+
"<r><c/><c/><c/></r>")), "<n>I</n><n>II</n><n>III</n>");
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
TEST(Xslt, ElementAttributeCommentPi) {
|
|
489
|
+
EXPECT_EQ(body(run(
|
|
490
|
+
"<xsl:template match='/'>"
|
|
491
|
+
"<xsl:element name='made'>"
|
|
492
|
+
"<xsl:attribute name='a'>v</xsl:attribute>"
|
|
493
|
+
"<xsl:comment> c </xsl:comment>"
|
|
494
|
+
"<xsl:processing-instruction name='pi'>d</xsl:processing-instruction>"
|
|
495
|
+
"t</xsl:element></xsl:template>",
|
|
496
|
+
"<r/>")),
|
|
497
|
+
"<made a=\"v\"><!-- c --><?pi d?>t</made>");
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
TEST(Xslt, TextOutputMethod) {
|
|
501
|
+
EXPECT_EQ(run(
|
|
502
|
+
"<xsl:output method='text'/>"
|
|
503
|
+
"<xsl:template match='/'>"
|
|
504
|
+
"<xsl:for-each select='//i'>"
|
|
505
|
+
"<xsl:value-of select='.'/><xsl:text> </xsl:text>"
|
|
506
|
+
"</xsl:for-each></xsl:template>",
|
|
507
|
+
"<r><i>a</i><i>b</i></r>"), "a b ");
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
TEST(Xslt, BuiltInTemplateTextRule) {
|
|
511
|
+
/* No template matches: built-in rule copies text through. */
|
|
512
|
+
EXPECT_EQ(body(run(
|
|
513
|
+
"<xsl:template match='never'>x</xsl:template>",
|
|
514
|
+
"<r>plain text</r>")), "plain text");
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
TEST(Xslt, InvalidStylesheets) {
|
|
518
|
+
/* Bad pattern in match= fails compilation of the whole sheet. */
|
|
519
|
+
EXPECT_EQ(run(
|
|
520
|
+
"<xsl:template match='['></xsl:template>", "<r/>"),
|
|
521
|
+
"(compile-failed)");
|
|
522
|
+
EXPECT_EQ(run(
|
|
523
|
+
"<xsl:template match='/'><xsl:value-of select='///bad'/></xsl:template>",
|
|
524
|
+
"<r/>"), "(compile-failed)");
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* ---------------------------------------------------------------
|
|
528
|
+
* Phase 02 / 04 conformance specs. Each spec exercises one board
|
|
529
|
+
* promise that landed in code; the falsifiability is in the
|
|
530
|
+
* assertion, not just a happy path.
|
|
531
|
+
* --------------------------------------------------------------- */
|
|
532
|
+
|
|
533
|
+
/* RTF variables bind the fragment's ROOT (document) node — the
|
|
534
|
+
* libxslt model: count($x)=1, relative paths walk the fragment
|
|
535
|
+
* ($x/a = the top-level <a/>), exsl:node-set($x) = same nodeset
|
|
536
|
+
* under any prefix binding of the EXSLT namespace. */
|
|
537
|
+
TEST(XsltConformance, NodeSetVariableTransport) {
|
|
538
|
+
EXPECT_EQ(body(run(
|
|
539
|
+
"<xsl:variable name='x'>"
|
|
540
|
+
"<a/><b/><c/>"
|
|
541
|
+
"</xsl:variable>"
|
|
542
|
+
"<xsl:template match='/'>"
|
|
543
|
+
"<xsl:value-of select='count($x)'/>|"
|
|
544
|
+
"<xsl:value-of select='count($x/b)'/>|"
|
|
545
|
+
"<xsl:value-of select='name($x/b)'/>"
|
|
546
|
+
"</xsl:template>",
|
|
547
|
+
"<r/>")), "1|1|b");
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/* use-attribute-sets precedence (§7.1.4): an explicit attr on
|
|
551
|
+
* the literal result element wins over the named set; the set
|
|
552
|
+
* contributes when no explicit value is given. */
|
|
553
|
+
TEST(XsltConformance, AttributeSetApplication) {
|
|
554
|
+
EXPECT_EQ(body(run(
|
|
555
|
+
"<xsl:attribute-set name='as'>"
|
|
556
|
+
"<xsl:attribute name='c'>set</xsl:attribute>"
|
|
557
|
+
"</xsl:attribute-set>"
|
|
558
|
+
"<xsl:template match='/'>"
|
|
559
|
+
"<x a='lit' xsl:use-attribute-sets='as'/>"
|
|
560
|
+
"</xsl:template>",
|
|
561
|
+
"<r/>")),
|
|
562
|
+
"<x a=\"lit\" c=\"set\"/>");
|
|
563
|
+
EXPECT_EQ(body(run(
|
|
564
|
+
"<xsl:attribute-set name='as'>"
|
|
565
|
+
"<xsl:attribute name='c'>from-set</xsl:attribute>"
|
|
566
|
+
"</xsl:attribute-set>"
|
|
567
|
+
"<xsl:template match='/'>"
|
|
568
|
+
"<x xsl:use-attribute-sets='as'/>"
|
|
569
|
+
"</xsl:template>",
|
|
570
|
+
"<r/>")),
|
|
571
|
+
"<x c=\"from-set\"/>");
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/* cdata-section-elements emits the parent's text content as
|
|
575
|
+
* CDATA instead of an escaped text node. */
|
|
576
|
+
TEST(XsltConformance, CDataSectionElements) {
|
|
577
|
+
EXPECT_NE(body(run(
|
|
578
|
+
"<xsl:output cdata-section-elements='x'/>"
|
|
579
|
+
"<xsl:template match='/'>"
|
|
580
|
+
"<x>1 < 2</x>"
|
|
581
|
+
"</xsl:template>",
|
|
582
|
+
"<r/>"))
|
|
583
|
+
.find("<![CDATA[1 < 2]]>"), std::string::npos);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* cdata-section-elements: a "]]>" inside (or ending) the text is
|
|
587
|
+
* split across sections — the only legal encoding inside CDATA
|
|
588
|
+
* (libxslt bug-132). The old scanner missed a close at the very END
|
|
589
|
+
* of a span and emitted it raw, terminating the section early. */
|
|
590
|
+
TEST(XsltConformance, CDataSectionSplitsAtCloseSequence) {
|
|
591
|
+
/* close in the middle */
|
|
592
|
+
EXPECT_NE(body(run(
|
|
593
|
+
"<xsl:output cdata-section-elements='x'/>"
|
|
594
|
+
"<xsl:template match='/'>"
|
|
595
|
+
"<x>abc]]>def</x>"
|
|
596
|
+
"</xsl:template>",
|
|
597
|
+
"<r/>"))
|
|
598
|
+
.find("<![CDATA[abc]]]]><![CDATA[>def]]>"), std::string::npos);
|
|
599
|
+
/* close at the very END of the content */
|
|
600
|
+
EXPECT_NE(body(run(
|
|
601
|
+
"<xsl:output cdata-section-elements='x'/>"
|
|
602
|
+
"<xsl:template match='/'>"
|
|
603
|
+
"<x>abc]]></x>"
|
|
604
|
+
"</xsl:template>",
|
|
605
|
+
"<r/>"))
|
|
606
|
+
.find("<![CDATA[abc]]]]><![CDATA[>]]>"), std::string::npos);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/* §16.3 method=text: the string-value of every text node in
|
|
610
|
+
* document order — elements never appear, no declaration, no
|
|
611
|
+
* escaping. Falsifiability: the v1 approximation kept the element
|
|
612
|
+
* structure ("<wrap>a<b/>c</wrap>"); the correct output is "ac". */
|
|
613
|
+
TEST(XsltConformance, OutputMethodTextStripsAllMarkup) {
|
|
614
|
+
std::string s = body(run(
|
|
615
|
+
"<xsl:output method='text'/>"
|
|
616
|
+
"<xsl:template match='/'>"
|
|
617
|
+
"<wrap>a<b/>c</wrap></xsl:template>",
|
|
618
|
+
"<r/>"));
|
|
619
|
+
EXPECT_EQ(s, "ac");
|
|
620
|
+
EXPECT_EQ(s.find('<'), std::string::npos);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/* Variable-scope shadowing. v1 doesn't track block-local variable
|
|
624
|
+
* scope frames: a name rebinding inside a containing element
|
|
625
|
+
* persists until the variable is popped (currently global-flat or
|
|
626
|
+
* call-template scope). Bind to whatever is currently on top —
|
|
627
|
+
* the full lexical-block model lands as a follow-up. */
|
|
628
|
+
TEST(XsltConformance, VariableScopeShadowsOuterDeferred) {
|
|
629
|
+
/* v1 doesn't track block-local scope — a name rebinding inside
|
|
630
|
+
* a containing element persists until the variable is popped.
|
|
631
|
+
* The lexical-block model lands as a follow-up; we capture the
|
|
632
|
+
* currently-shipped behavior (w sees outer). */
|
|
633
|
+
EXPECT_NE(body(run(
|
|
634
|
+
"<xsl:template match='/'>"
|
|
635
|
+
"<w><xsl:variable name='x' select=\"'outer'\"/>"
|
|
636
|
+
"<xsl:value-of select='$x'/></w></xsl:template>",
|
|
637
|
+
"<r/>")).find("<w>outer</w>"), std::string::npos);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/* Variable visibility across for-each: declared before the loop
|
|
641
|
+
* is seen inside the loop body on each iteration. */
|
|
642
|
+
TEST(XsltConformance, VariableVisibleInsideForEach) {
|
|
643
|
+
EXPECT_EQ(body(run(
|
|
644
|
+
"<xsl:template match='/'>"
|
|
645
|
+
"<xsl:variable name='sep' select=\"'|'\"/>"
|
|
646
|
+
"<root>"
|
|
647
|
+
"<xsl:for-each select='//i'>"
|
|
648
|
+
"<xsl:value-of select='.'/>"
|
|
649
|
+
"<xsl:value-of select='$sep'/>"
|
|
650
|
+
"</xsl:for-each>"
|
|
651
|
+
"</root>"
|
|
652
|
+
"</xsl:template>",
|
|
653
|
+
"<r><i>1</i><i>2</i><i>3</i></r>")),
|
|
654
|
+
"<root>1|2|3|</root>");
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/* xsl:number — full §7.7 (single, multiple, any; count, from;
|
|
658
|
+
* §7.7.1 format prefix/suffix; per-token grouping). */
|
|
659
|
+
TEST(XsltConformance, NumberFullS7Point7) {
|
|
660
|
+
EXPECT_EQ(body(run(
|
|
661
|
+
"<xsl:template match='/'>"
|
|
662
|
+
"<out><xsl:for-each select='//i'>"
|
|
663
|
+
"<n><xsl:number level='any' format='1' count='i'/></n>"
|
|
664
|
+
"</xsl:for-each></out>"
|
|
665
|
+
"</xsl:template>",
|
|
666
|
+
"<r><i/><i/><i/></r>")),
|
|
667
|
+
"<out><n>1</n><n>2</n><n>3</n></out>");
|
|
668
|
+
EXPECT_EQ(body(run(
|
|
669
|
+
"<xsl:template match='/'>"
|
|
670
|
+
"<out><xsl:for-each select='//b'>"
|
|
671
|
+
"<n><xsl:number level='multiple' format='1.1' count='b|a'/></n>"
|
|
672
|
+
"</xsl:for-each></out>"
|
|
673
|
+
"</xsl:template>",
|
|
674
|
+
"<r><a><b/><b/></a><a><b/></a></r>")),
|
|
675
|
+
"<out><n>1.1</n><n>1.2</n><n>2.1</n></out>");
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/* ---------------------------------------------------------------
|
|
679
|
+
* §12 function bridge (TODO.transform 04/05): key, current,
|
|
680
|
+
* format-number, generate-id, system-property, document +
|
|
681
|
+
* EXSLT node-set / regexp:test / date:date-time. The bridge
|
|
682
|
+
* registers through leptris_xpath_build_custom_registry while a
|
|
683
|
+
* transform is active on the source document (the custom-function
|
|
684
|
+
* path — the board's SSOT requirement).
|
|
685
|
+
* --------------------------------------------------------------- */
|
|
686
|
+
|
|
687
|
+
/* key(): lazy per-name index; match pattern selects the nodes,
|
|
688
|
+
* use expression produces the bucket key (§12.2). */
|
|
689
|
+
TEST(XsltBridge, KeyFunction) {
|
|
690
|
+
/* Top-level xsl:key (run() wraps the BODY only — key defs
|
|
691
|
+
* need a top-level slot, so build the sheet by hand here). */
|
|
692
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
693
|
+
" version='1.0'>"
|
|
694
|
+
"<xsl:key name='k' match='i' use='@v'/>"
|
|
695
|
+
"<xsl:template match='/'>"
|
|
696
|
+
"<xsl:for-each select=\"key('k','x')\">"
|
|
697
|
+
"<xsl:value-of select='@n'/>"
|
|
698
|
+
"</xsl:for-each></xsl:template></xsl:stylesheet>";
|
|
699
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
700
|
+
ASSERT_NE(x, nullptr);
|
|
701
|
+
const char* kxml = "<r><i v='x' n='1'/><i v='x' n='2'/><i v='y' n='3'/></r>";
|
|
702
|
+
LeptrisDocument d = leptris_parse_string(kxml, strlen(kxml), nullptr);
|
|
703
|
+
ASSERT_NE(d, nullptr);
|
|
704
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
705
|
+
ASSERT_NE(out, nullptr);
|
|
706
|
+
EXPECT_EQ(body(std::string(out)), "12");
|
|
707
|
+
leptris_free_string(out);
|
|
708
|
+
leptris_document_free(d);
|
|
709
|
+
leptris_xslt_free(x);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/* current(): the node being processed by the template rule or
|
|
713
|
+
* for-each (§12.4) — distinct from the predicate context. Before
|
|
714
|
+
* the fix this resolved empty because current_node was only
|
|
715
|
+
* tracked on the variable-carrying eval path. */
|
|
716
|
+
TEST(XsltBridge, CurrentFunction) {
|
|
717
|
+
EXPECT_EQ(body(run(
|
|
718
|
+
"<xsl:template match='/'>"
|
|
719
|
+
"<xsl:for-each select='//i'>"
|
|
720
|
+
"<xsl:value-of select='current()/@v'/>"
|
|
721
|
+
"</xsl:for-each></xsl:template>",
|
|
722
|
+
"<r><i v='1'/><i v='2'/></r>")), "12");
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/* format-number(): JDK1.1 pattern subset (§12.3). */
|
|
726
|
+
TEST(XsltBridge, FormatNumber) {
|
|
727
|
+
EXPECT_EQ(body(run(
|
|
728
|
+
"<xsl:template match='/'>"
|
|
729
|
+
"<xsl:value-of select=\"format-number(1234.567, '#,###.00')\"/>"
|
|
730
|
+
"</xsl:template>", "<r/>")), "1,234.57");
|
|
731
|
+
EXPECT_EQ(body(run(
|
|
732
|
+
"<xsl:template match='/'>"
|
|
733
|
+
"<xsl:value-of select=\"format-number(0.5, '0%')\"/>"
|
|
734
|
+
"</xsl:template>", "<r/>")), "50%");
|
|
735
|
+
EXPECT_EQ(body(run(
|
|
736
|
+
"<xsl:template match='/'>"
|
|
737
|
+
"<xsl:value-of select=\"format-number(-7, '0')\"/>"
|
|
738
|
+
"</xsl:template>", "<r/>")), "-7");
|
|
739
|
+
EXPECT_EQ(body(run(
|
|
740
|
+
"<xsl:template match='/'>"
|
|
741
|
+
"<xsl:value-of select=\"format-number(100000000000, '#,##0.##')\"/>"
|
|
742
|
+
"</xsl:template>", "<r/>")), "100,000,000,000");
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/* §16.2 HTML attribute escape: ' in input value renders as the
|
|
746
|
+
* apostrophe (not the literal entity reference) under method=html. */
|
|
747
|
+
TEST(XsltBridge, HtmlAttributeAposDecoded) {
|
|
748
|
+
EXPECT_EQ(body(run(
|
|
749
|
+
"<xsl:output method='html'/>"
|
|
750
|
+
"<xsl:template match='/'>"
|
|
751
|
+
"<x><input value=\""'"\"/></x>"
|
|
752
|
+
"</xsl:template>", "<r/>")), "<x><input value=\""'"\"></x>\n");
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/* §16.2 HTML output: inject <meta charset="..."> into <head> when no
|
|
756
|
+
* xsl:output meta declaration + no existing <meta charset> present.
|
|
757
|
+
* The encoder reports UTF-8 by default; absent any encoding attr we
|
|
758
|
+
* append the platform-standard <meta charset="UTF-8"/>. */
|
|
759
|
+
TEST(XsltBridge, HtmlInjectsMetaCharset) {
|
|
760
|
+
EXPECT_NE(body(run(
|
|
761
|
+
"<xsl:output method='html'/>"
|
|
762
|
+
"<xsl:template match='/'>"
|
|
763
|
+
"<html><head><title>t</title></head><body/></html>"
|
|
764
|
+
"</xsl:template>", "<r/>")).find("<meta charset=\"UTF-8\""),
|
|
765
|
+
std::string::npos);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/* §16.2 HTML indent rules (libxml2 HTMLtree.c parity):
|
|
769
|
+
* - newline after the opening tag of a block parent (≥2 children,
|
|
770
|
+
* first child not text, name not p*), between non-inline element
|
|
771
|
+
* siblings, and before the closing tag — but ZERO nesting spaces
|
|
772
|
+
* - single-child parents stay inline
|
|
773
|
+
* - inline elements (span/b/…) and p* never break lines
|
|
774
|
+
* - unknown elements never break lines
|
|
775
|
+
* - the injected <meta charset> participates as a normal child. */
|
|
776
|
+
TEST(XsltHtml, IndentBlockParentNewlinesNoSpaces) {
|
|
777
|
+
EXPECT_EQ(body(run(
|
|
778
|
+
"<xsl:output method='html'/>"
|
|
779
|
+
"<xsl:template match='/'>"
|
|
780
|
+
"<html><head><title>t</title></head>"
|
|
781
|
+
"<body><div><p>one</p><p>two</p></div></body></html>"
|
|
782
|
+
"</xsl:template>", "<r/>")),
|
|
783
|
+
"<html>\n"
|
|
784
|
+
"<head>\n"
|
|
785
|
+
"<meta charset=\"UTF-8\">\n"
|
|
786
|
+
"<title>t</title>\n"
|
|
787
|
+
"</head>\n"
|
|
788
|
+
"<body><div>\n"
|
|
789
|
+
"<p>one</p>\n"
|
|
790
|
+
"<p>two</p>\n"
|
|
791
|
+
"</div></body>\n"
|
|
792
|
+
"</html>\n");
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
TEST(XsltHtml, IndentSingleChildParentInline) {
|
|
796
|
+
/* body with exactly one child stays inline; its child may still
|
|
797
|
+
* indent internally. */
|
|
798
|
+
EXPECT_EQ(body(run(
|
|
799
|
+
"<xsl:output method='html'/>"
|
|
800
|
+
"<xsl:template match='/'>"
|
|
801
|
+
"<html><body><p>only</p></body></html>"
|
|
802
|
+
"</xsl:template>", "<r/>")),
|
|
803
|
+
"<html><body><p>only</p></body></html>\n");
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
TEST(XsltHtml, IndentInlineParentNeverBreaks) {
|
|
807
|
+
/* span is inline in the HTML element table; p* is excluded by the
|
|
808
|
+
* libxml2 first-byte rule — neither ever breaks lines. */
|
|
809
|
+
EXPECT_EQ(body(run(
|
|
810
|
+
"<xsl:output method='html'/>"
|
|
811
|
+
"<xsl:template match='/'>"
|
|
812
|
+
"<html><body><span><em>a</em><em>b</em></span></body></html>"
|
|
813
|
+
"</xsl:template>", "<r/>")),
|
|
814
|
+
"<html><body><span><em>a</em><em>b</em></span></body></html>\n");
|
|
815
|
+
EXPECT_EQ(body(run(
|
|
816
|
+
"<xsl:output method='html'/>"
|
|
817
|
+
"<xsl:template match='/'>"
|
|
818
|
+
"<html><body><p><div>a</div><div>b</div></p></body></html>"
|
|
819
|
+
"</xsl:template>", "<r/>")),
|
|
820
|
+
"<html><body><p><div>a</div><div>b</div></p></body></html>\n");
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
TEST(XsltHtml, IndentUnknownElementNeverBreaks) {
|
|
824
|
+
EXPECT_EQ(body(run(
|
|
825
|
+
"<xsl:output method='html'/>"
|
|
826
|
+
"<xsl:template match='/'>"
|
|
827
|
+
"<html><body><foo><f1>a</f1><f2>b</f2></foo></body></html>"
|
|
828
|
+
"</xsl:template>", "<r/>")),
|
|
829
|
+
"<html><body><foo><f1>a</f1><f2>b</f2></foo></body></html>\n");
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
TEST(XsltHtml, IndentInlineSiblingsCluster) {
|
|
833
|
+
/* A block parent breaks around its children, but inline children
|
|
834
|
+
* cluster together on one line (no newline after them); html and
|
|
835
|
+
* body here have a single child each and stay inline. */
|
|
836
|
+
EXPECT_EQ(body(run(
|
|
837
|
+
"<xsl:output method='html'/>"
|
|
838
|
+
"<xsl:template match='/'>"
|
|
839
|
+
"<html><body><div><span>a</span><p>p1</p><span>b</span></div></body></html>"
|
|
840
|
+
"</xsl:template>", "<r/>")),
|
|
841
|
+
"<html><body><div>\n"
|
|
842
|
+
"<span>a</span><p>p1</p>\n"
|
|
843
|
+
"<span>b</span>\n"
|
|
844
|
+
"</div></body></html>\n");
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
TEST(XsltHtml, MetaCharsetRespectsEncoding) {
|
|
848
|
+
/* xsl:output encoding flows into the injected meta. */
|
|
849
|
+
EXPECT_NE(body(run(
|
|
850
|
+
"<xsl:output method='html' encoding='iso-8859-1'/>"
|
|
851
|
+
"<xsl:template match='/'>"
|
|
852
|
+
"<html><head><title>t</title></head></html>"
|
|
853
|
+
"</xsl:template>", "<r/>")).find("<meta charset=\"iso-8859-1\">"),
|
|
854
|
+
std::string::npos);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/* position() must reflect the in-flight node-list position — in
|
|
858
|
+
* for-each bodies, in apply-templates, and inside AVTs (§4/§12.4;
|
|
859
|
+
* the libxslt suite's bug-2-/bug-20- shape). */
|
|
860
|
+
TEST(XsltCore, PositionInForEachAndAvt) {
|
|
861
|
+
EXPECT_EQ(body(run(
|
|
862
|
+
"<xsl:template match='foo'>"
|
|
863
|
+
"<xsl:for-each select='bar'>"
|
|
864
|
+
"<BAR INDEX='{position()}'>"
|
|
865
|
+
"<xsl:if test='position()=2'><MID/></xsl:if>"
|
|
866
|
+
"</BAR>"
|
|
867
|
+
"</xsl:for-each>"
|
|
868
|
+
"</xsl:template>", "<foo><bar/><bar/><bar/></foo>")),
|
|
869
|
+
"<BAR INDEX=\"1\"/><BAR INDEX=\"2\"><MID/></BAR><BAR INDEX=\"3\"/>");
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/* §3.4 xsl:strip-space elements='*': the wildcard matches every
|
|
873
|
+
* element — whitespace-only source text disappears (position() over
|
|
874
|
+
* the children counts only elements; no stray text reaches the
|
|
875
|
+
* result). libxslt suite bug-2-. */
|
|
876
|
+
TEST(XsltCore, StripSpaceWildcard) {
|
|
877
|
+
EXPECT_EQ(body(run(
|
|
878
|
+
"<xsl:strip-space elements='*'/>"
|
|
879
|
+
"<xsl:template match='foo'><FOO><xsl:apply-templates/></FOO></xsl:template>"
|
|
880
|
+
"<xsl:template match='bar'>"
|
|
881
|
+
"<BAR INDEX='{position()}'><xsl:value-of select='.'/></BAR>"
|
|
882
|
+
"</xsl:template>",
|
|
883
|
+
"<foo>\n <bar>b1</bar>\n <bar>b2</bar>\n</foo>")),
|
|
884
|
+
"<FOO><BAR INDEX=\"1\">b1</BAR><BAR INDEX=\"2\">b2</BAR></FOO>");
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/* §11 variable scoping: a called template sees the GLOBALS and its
|
|
888
|
+
* own locals — never the CALLER's locals. A caller-local shadowing
|
|
889
|
+
* a global must not leak into the callee (libxslt bug-40-). */
|
|
890
|
+
TEST(XsltCore, CallTemplateVariableScope) {
|
|
891
|
+
EXPECT_EQ(body(run(
|
|
892
|
+
"<xsl:variable name='foo' select=\"'SUCCESS'\"/>"
|
|
893
|
+
"<xsl:template name='test'><xsl:value-of select='$foo'/></xsl:template>"
|
|
894
|
+
"<xsl:template match='/'>"
|
|
895
|
+
"<xsl:variable name='foo' select=\"'FAILURE'\"/>"
|
|
896
|
+
"<xsl:call-template name='test'/>"
|
|
897
|
+
"</xsl:template>", "<doc/>")), "SUCCESS");
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* §11.3 xsl:copy-of: a node copies VERBATIM — every child kind in
|
|
901
|
+
* order (text/CDATA/comment/PI/element), not the string-value
|
|
902
|
+
* concatenated ahead of the child elements (libxslt bug-4-). */
|
|
903
|
+
TEST(XsltCore, CopyOfMixedContentVerbatim) {
|
|
904
|
+
EXPECT_EQ(body(run(
|
|
905
|
+
"<xsl:template match='/'>"
|
|
906
|
+
"<xsl:copy-of select='m'/>"
|
|
907
|
+
"</xsl:template>",
|
|
908
|
+
"<m name='M'>\n <c>inner</c>\n</m>")),
|
|
909
|
+
"<m name=\"M\">\n <c>inner</c>\n</m>");
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/* §16.1: an element-less result (only comment/PI nodes) still
|
|
913
|
+
* carries the XML declaration unless omitted — libxslt parity
|
|
914
|
+
* (bug-31-). */
|
|
915
|
+
TEST(XsltCore, FragmentResultKeepsDeclaration) {
|
|
916
|
+
EXPECT_EQ(run(
|
|
917
|
+
"<xsl:template match='processing-instruction()'>"
|
|
918
|
+
"<xsl:copy/>"
|
|
919
|
+
"</xsl:template>",
|
|
920
|
+
"<?xml-stylesheet type='text/css' href='s.css'?><d/>"),
|
|
921
|
+
"<?xml version=\"1.0\"?>\n<?xml-stylesheet type='text/css' "
|
|
922
|
+
"href='s.css'?>");
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/* EXSLT func:function (http://exslt.org/functions): stylesheet-
|
|
926
|
+
* defined extension functions callable from XPath. func:result
|
|
927
|
+
* yields the return (select value, or content as RTF string). The
|
|
928
|
+
* call runs with the CALLER's context node and its own variable
|
|
929
|
+
* scope (globals + locals). libxslt bug-212. */
|
|
930
|
+
TEST(XsltCore, ExsltUserFunction) {
|
|
931
|
+
const char* sheet =
|
|
932
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'"
|
|
933
|
+
" xmlns:func='http://exslt.org/functions'"
|
|
934
|
+
" xmlns:myf='urn:my' extension-element-prefixes='func'>"
|
|
935
|
+
"<xsl:output method='text'/>"
|
|
936
|
+
"<xsl:template match='/'>"
|
|
937
|
+
"<xsl:variable name='a' select='myf:twice()'/>"
|
|
938
|
+
"<xsl:value-of select='$a'/><xsl:text>,</xsl:text>"
|
|
939
|
+
"<xsl:value-of select='$a'/>"
|
|
940
|
+
"</xsl:template>"
|
|
941
|
+
"<func:function name='myf:twice'>"
|
|
942
|
+
"<func:result><xsl:text>a</xsl:text></func:result>"
|
|
943
|
+
"</func:function>"
|
|
944
|
+
"</xsl:stylesheet>";
|
|
945
|
+
LeptrisXslt x = leptris_xslt_parse(sheet, strlen(sheet));
|
|
946
|
+
ASSERT_NE(x, (LeptrisXslt) nullptr);
|
|
947
|
+
LeptrisDocument d = leptris_parse_string("<r/>", 4, nullptr);
|
|
948
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
949
|
+
ASSERT_NE(out, (char*) nullptr);
|
|
950
|
+
EXPECT_STREQ(out, "a,a");
|
|
951
|
+
leptris_free_string(out);
|
|
952
|
+
leptris_document_free(d);
|
|
953
|
+
leptris_xslt_free(x);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/* §16.2 raw text elements: script/style content (HTML5 rawtext,
|
|
957
|
+
* libxml2 dataMode >= DATA_RAWTEXT) emits VERBATIM under
|
|
958
|
+
* method=html — no < re-escaping (bug-33-). */
|
|
959
|
+
TEST(XsltHtml, ScriptContentRaw) {
|
|
960
|
+
/* head carries the injected meta → 2 children → line breaks
|
|
961
|
+
* (libxslt site-1 rule); the script text itself is verbatim. */
|
|
962
|
+
EXPECT_EQ(body(run(
|
|
963
|
+
"<xsl:output method='html'/>"
|
|
964
|
+
"<xsl:template match='/'>"
|
|
965
|
+
"<html><head><script>if (a < b) alert();</script></head></html>"
|
|
966
|
+
"</xsl:template>", "<r/>")),
|
|
967
|
+
"<html><head>\n<meta charset=\"UTF-8\">\n"
|
|
968
|
+
"<script>if (a < b) alert();</script>\n</head></html>\n");
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/* §16.2 HTML PIs have no trailing '?': <?php ... > (libxml2
|
|
972
|
+
* HTMLtree.c HTML_PI_NODE case). */
|
|
973
|
+
TEST(XsltHtml, PiDropsQuestionMark) {
|
|
974
|
+
/* Literal PIs in template bodies are dropped (xsltproc-verified)
|
|
975
|
+
* — the PI form is reachable through xsl:processing-instruction. */
|
|
976
|
+
EXPECT_NE(body(run(
|
|
977
|
+
"<xsl:output method='html'/>"
|
|
978
|
+
"<xsl:template match='/'>"
|
|
979
|
+
"<html><body><xsl:processing-instruction name='php'>"
|
|
980
|
+
"echo 1;</xsl:processing-instruction></body></html>"
|
|
981
|
+
"</xsl:template>", "<r/>")).find("<?php echo 1;>"),
|
|
982
|
+
std::string::npos);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/* §16.2 href URL-escaping: non-ASCII (and spaces) in href values
|
|
986
|
+
* percent-encode as UTF-8 (libxml2 htmlAttrDumpOutput, bug-83). */
|
|
987
|
+
TEST(XsltHtml, HrefUrlEscaped) {
|
|
988
|
+
EXPECT_NE(body(run(
|
|
989
|
+
"<xsl:output method='html'/>"
|
|
990
|
+
"<xsl:template match='/'>"
|
|
991
|
+
"<html><body><a href=\"a b c\">x</a></body></html>"
|
|
992
|
+
"</xsl:template>", "<r/>")).find("href=\"a%20b%20c\""),
|
|
993
|
+
std::string::npos);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
/* id() (XPath §4.1): an element matches when its ID-TYPED
|
|
997
|
+
* attribute — declared in the DTD internal subset, ANY QName —
|
|
998
|
+
* equals the argument (libxslt bug-163: myns:id). */
|
|
999
|
+
TEST(XsltCore, IdFindsDtdTypedIds) {
|
|
1000
|
+
EXPECT_EQ(body(run(
|
|
1001
|
+
"<xsl:template match='/'>"
|
|
1002
|
+
"<xsl:value-of select=\"id('indexme')/@some-attr\"/>"
|
|
1003
|
+
"</xsl:template>",
|
|
1004
|
+
"<!DOCTYPE my-root ["
|
|
1005
|
+
"<!ATTLIST my-root myns:id ID #IMPLIED>"
|
|
1006
|
+
"]>"
|
|
1007
|
+
"<my-root xmlns:myns='uri' myns:id='indexme' some-attr='findme'/>")),
|
|
1008
|
+
"findme");
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/* §11 variable scoping via apply-templates: the SELECTED template
|
|
1012
|
+
* also sees globals + own locals, never the caller's locals (the
|
|
1013
|
+
* apply-templates twin of CallTemplateVariableScope — bug-42-). */
|
|
1014
|
+
TEST(XsltCore, ApplyTemplatesVariableScope) {
|
|
1015
|
+
EXPECT_EQ(body(run(
|
|
1016
|
+
"<xsl:variable name='foo' select=\"'SUCCESS'\"/>"
|
|
1017
|
+
"<xsl:template match='doc'><xsl:value-of select='$foo'/></xsl:template>"
|
|
1018
|
+
"<xsl:template match='/'>"
|
|
1019
|
+
"<xsl:variable name='foo' select=\"'FAILURE'\"/>"
|
|
1020
|
+
"<xsl:apply-templates/>"
|
|
1021
|
+
"</xsl:template>", "<doc/>")), "SUCCESS");
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
/* XML 1.0 §3.3.2: ATTLIST DEFAULT values materialize on elements
|
|
1025
|
+
* that don't carry the attribute (libxslt bug-53). */
|
|
1026
|
+
TEST(XsltCore, DtdDefaultAttributes) {
|
|
1027
|
+
EXPECT_EQ(body(run(
|
|
1028
|
+
"<xsl:template match='doc'><xsl:value-of select='@defatt'/></xsl:template>",
|
|
1029
|
+
"<!DOCTYPE doc [<!ELEMENT doc EMPTY>"
|
|
1030
|
+
"<!ATTLIST doc defatt (SUCCESS|FAILURE) 'SUCCESS'>]>"
|
|
1031
|
+
"<doc/>")),
|
|
1032
|
+
"SUCCESS");
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/* §3.4 strip-space NameTests: "p:*" strips whitespace-only text
|
|
1036
|
+
* from every element in the namespace bound to p (bug-124). */
|
|
1037
|
+
TEST(XsltCore, StripSpacePrefixedWildcard) {
|
|
1038
|
+
/* run() wraps its body with only the xsl prefix; this case needs
|
|
1039
|
+
* a SECOND prefix bound on the stylesheet root — build directly. */
|
|
1040
|
+
const char* sheet =
|
|
1041
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1042
|
+
" xmlns:p='urn:x' version='1.0'>"
|
|
1043
|
+
"<xsl:strip-space elements='p:*'/>"
|
|
1044
|
+
"<xsl:template match='@*|node()'>"
|
|
1045
|
+
"<xsl:copy><xsl:apply-templates select='@*|node()'/></xsl:copy>"
|
|
1046
|
+
"</xsl:template></xsl:stylesheet>";
|
|
1047
|
+
const char* xml = "<r xmlns:p='urn:x'><p:a>\n <p:b/>\n</p:a></r>";
|
|
1048
|
+
LeptrisXslt x = leptris_xslt_parse(sheet, strlen(sheet));
|
|
1049
|
+
ASSERT_NE(x, (LeptrisXslt) nullptr);
|
|
1050
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
1051
|
+
ASSERT_NE(d, (LeptrisDocument) nullptr);
|
|
1052
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1053
|
+
ASSERT_NE(out, (char*) nullptr);
|
|
1054
|
+
EXPECT_EQ(body(std::string(out)),
|
|
1055
|
+
"<r xmlns:p=\"urn:x\"><p:a><p:b/></p:a></r>");
|
|
1056
|
+
leptris_free_string(out);
|
|
1057
|
+
leptris_document_free(d);
|
|
1058
|
+
leptris_xslt_free(x);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/* generate-id(): stable + unique per node (§12.5). */
|
|
1062
|
+
|
|
1063
|
+
TEST(XsltBridge, KeyUseCanReferenceCurrentNode) {
|
|
1064
|
+
EXPECT_EQ(body(run2(
|
|
1065
|
+
"<xsl:key name='by-current' match='i' use='current()/@k'/>"
|
|
1066
|
+
"<xsl:template match='/'>"
|
|
1067
|
+
"<xsl:value-of select=\"key('by-current', 'x')\"/>"
|
|
1068
|
+
"</xsl:template>",
|
|
1069
|
+
"<r><i k='x'>hit</i><i k='y'>miss</i></r>")), "hit");
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
TEST(XsltBridge, GenerateId) {
|
|
1073
|
+
std::string out = body(run(
|
|
1074
|
+
"<xsl:template match='/'>"
|
|
1075
|
+
"<xsl:variable name='a' select=\"generate-id(//i[1])\"/>"
|
|
1076
|
+
"<xsl:variable name='b' select=\"generate-id(//i[2])\"/>"
|
|
1077
|
+
"<xsl:value-of select='$a != $b'/>"
|
|
1078
|
+
"</xsl:template>", "<r><i/><i/></r>"));
|
|
1079
|
+
EXPECT_EQ(out, "true");
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/* system-property(): xsl:version / vendor (§12.7). */
|
|
1083
|
+
TEST(XsltBridge, SystemProperty) {
|
|
1084
|
+
EXPECT_EQ(body(run(
|
|
1085
|
+
"<xsl:template match='/'>"
|
|
1086
|
+
"<xsl:value-of select=\"system-property('xsl:version')\"/>"
|
|
1087
|
+
"</xsl:template>", "<r/>")), "1.0");
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/* EXSLT regexp:test + date:date-time via the same bridge. */
|
|
1091
|
+
TEST(XsltBridge, ExsltRegexpAndDate) {
|
|
1092
|
+
#ifdef _WIN32
|
|
1093
|
+
/* No <regex.h>: the documented Windows stub always reports
|
|
1094
|
+
* no-match. */
|
|
1095
|
+
EXPECT_EQ(body(run(
|
|
1096
|
+
"<xsl:template match='/'>"
|
|
1097
|
+
"<xsl:value-of select=\"regexp:test('leptris', '^lep')\"/>"
|
|
1098
|
+
"</xsl:template>", "<r/>")), "false");
|
|
1099
|
+
#else
|
|
1100
|
+
EXPECT_EQ(body(run(
|
|
1101
|
+
"<xsl:template match='/'>"
|
|
1102
|
+
"<xsl:value-of select=\"regexp:test('leptris', '^lep')\"/>"
|
|
1103
|
+
"</xsl:template>", "<r/>")), "true");
|
|
1104
|
+
#endif
|
|
1105
|
+
EXPECT_EQ(body(run(
|
|
1106
|
+
"<xsl:template match='/'>"
|
|
1107
|
+
"<xsl:value-of select=\"regexp:test('leptris', '^x')\"/>"
|
|
1108
|
+
"</xsl:template>", "<r/>")), "false");
|
|
1109
|
+
/* date:date-time() — ISO 8601 UTC, length 20 (YYYY-MM-DDTHH:MM:SSZ). */
|
|
1110
|
+
EXPECT_EQ(body(run(
|
|
1111
|
+
"<xsl:template match='/'>"
|
|
1112
|
+
"<xsl:value-of select=\"string-length(date:date-time()) = 20\"/>"
|
|
1113
|
+
"</xsl:template>", "<r/>")), "true");
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/* §16.2 xsl:output doctype-system / doctype-public (libxslt suite
|
|
1117
|
+
* bug-152, bug-166, bug-175, bug-206, bug-25-). The DOCTYPE leads
|
|
1118
|
+
* the body, right after the declaration; html method honors the
|
|
1119
|
+
* version="5" shorthand and omits the system id when only a public
|
|
1120
|
+
* id is given. */
|
|
1121
|
+
TEST(XsltOutput, DoctypePublicAndSystem) {
|
|
1122
|
+
std::string r = body(run(
|
|
1123
|
+
"<xsl:output method='xml' doctype-public='-//X//Y//EN'"
|
|
1124
|
+
" doctype-system='d.dtd'/>"
|
|
1125
|
+
"<xsl:template match='/'><doc/></xsl:template>",
|
|
1126
|
+
"<r/>"));
|
|
1127
|
+
EXPECT_EQ(r, "<!DOCTYPE doc PUBLIC \"-//X//Y//EN\" \"d.dtd\">\n<doc/>");
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
TEST(XsltOutput, DoctypeSystemOnly) {
|
|
1131
|
+
std::string r = body(run(
|
|
1132
|
+
"<xsl:output method='xml' doctype-system='d.dtd'/>"
|
|
1133
|
+
"<xsl:template match='/'><doc/></xsl:template>",
|
|
1134
|
+
"<r/>"));
|
|
1135
|
+
EXPECT_EQ(r, "<!DOCTYPE doc SYSTEM \"d.dtd\">\n<doc/>");
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
TEST(XsltOutput, DoctypePublicOnly) {
|
|
1139
|
+
std::string r = body(run(
|
|
1140
|
+
"<xsl:output method='xml' doctype-public='-//X//Y//EN'/>"
|
|
1141
|
+
"<xsl:template match='/'><doc/></xsl:template>",
|
|
1142
|
+
"<r/>"));
|
|
1143
|
+
EXPECT_EQ(r, "<!DOCTYPE doc PUBLIC \"-//X//Y//EN\">\n<doc/>");
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
TEST(XsltOutput, HtmlVersion5UsesBareDoctype) {
|
|
1147
|
+
std::string r = body(run(
|
|
1148
|
+
"<xsl:output method='html' version='5'/>"
|
|
1149
|
+
"<xsl:template match='/'><html/></xsl:template>",
|
|
1150
|
+
"<r/>"));
|
|
1151
|
+
EXPECT_EQ(r, "<!DOCTYPE html>\n<html></html>\n");
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
TEST(XsltOutput, HtmlPublicOnlyOmitsSystemId) {
|
|
1155
|
+
std::string r = body(run(
|
|
1156
|
+
"<xsl:output method='html' version='4.0'"
|
|
1157
|
+
" doctype-public='-//W3C//DTD HTML 4.01//EN'/>"
|
|
1158
|
+
"<xsl:template match='/'><html><body>x</body></html></xsl:template>",
|
|
1159
|
+
"<r/>"));
|
|
1160
|
+
EXPECT_EQ(r.substr(0, 51),
|
|
1161
|
+
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n");
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
/* No doctype attributes → no DOCTYPE (the default contract most
|
|
1165
|
+
* transforms rely on). */
|
|
1166
|
+
TEST(XsltOutput, NoDoctypeAttrsMeansNoDoctype) {
|
|
1167
|
+
EXPECT_EQ(body(run(
|
|
1168
|
+
"<xsl:template match='/'><doc/></xsl:template>", "<r/>")),
|
|
1169
|
+
"<doc/>");
|
|
1170
|
+
EXPECT_EQ(body(run(
|
|
1171
|
+
"<xsl:output method='html'/>"
|
|
1172
|
+
"<xsl:template match='/'><html/></xsl:template>", "<r/>")),
|
|
1173
|
+
"<html></html>\n");
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
/* libxml2 xmlIsXHTML (bug-152): an xml-method result whose doctype
|
|
1177
|
+
* ids EXACTLY match an XHTML 1.0 DTD serializes in XHTML mode — the
|
|
1178
|
+
* Content-Type meta is injected into the root html/head, the 13 HTML
|
|
1179
|
+
* empty names minimize as <x />, every other empty element expands. */
|
|
1180
|
+
TEST(XsltXhtml, InjectsMetaAndExpandsEmptyElements) {
|
|
1181
|
+
std::string r = run(
|
|
1182
|
+
"<xsl:output method='xml' indent='yes'"
|
|
1183
|
+
" doctype-public='-//W3C//DTD XHTML 1.0 Strict//EN'"
|
|
1184
|
+
" doctype-system='http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'/>"
|
|
1185
|
+
"<xsl:template match='/'><html xmlns='http://www.w3.org/1999/xhtml'>"
|
|
1186
|
+
"<head><title>t</title></head>"
|
|
1187
|
+
"<body><br/><div/><img src='x'/></body></html></xsl:template>",
|
|
1188
|
+
"<r/>");
|
|
1189
|
+
EXPECT_NE(r.find("<meta http-equiv=\"Content-Type\" "
|
|
1190
|
+
"content=\"text/html; charset=UTF-8\" />"),
|
|
1191
|
+
std::string::npos);
|
|
1192
|
+
EXPECT_NE(r.find("<br />"), std::string::npos);
|
|
1193
|
+
EXPECT_NE(r.find("<img src=\"x\" />"), std::string::npos);
|
|
1194
|
+
EXPECT_NE(r.find("<div></div>"), std::string::npos);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
/* An author-provided http-equiv=Content-Type meta wins — none is
|
|
1198
|
+
* injected (xmlGetProp + xmlStrcasecmp parity). */
|
|
1199
|
+
TEST(XsltXhtml, AuthorMetaWins) {
|
|
1200
|
+
std::string r = run(
|
|
1201
|
+
"<xsl:output method='xml' indent='yes'"
|
|
1202
|
+
" doctype-public='-//W3C//DTD XHTML 1.0 Strict//EN'/>"
|
|
1203
|
+
"<xsl:template match='/'><html xmlns='http://www.w3.org/1999/xhtml'>"
|
|
1204
|
+
"<head><meta http-equiv='Content-Type'"
|
|
1205
|
+
" content='text/html; charset=EUC-JP'/></head></html>"
|
|
1206
|
+
"</xsl:template>",
|
|
1207
|
+
"<r/>");
|
|
1208
|
+
EXPECT_EQ(r.find("charset=UTF-8"), std::string::npos);
|
|
1209
|
+
EXPECT_NE(r.find("charset=EUC-JP"), std::string::npos);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/* The id match is EXACT — a public id merely containing "XHTML"
|
|
1213
|
+
* keeps the plain xml serializer (no meta, collapsed empties). */
|
|
1214
|
+
TEST(XsltXhtml, NonExactPublicIdStaysPlainXml) {
|
|
1215
|
+
std::string r = run(
|
|
1216
|
+
"<xsl:output method='xml' indent='yes'"
|
|
1217
|
+
" doctype-public='-//W3C//DTD foo xhtml //EN'/>"
|
|
1218
|
+
"<xsl:template match='/'><html xmlns='http://www.w3.org/1999/xhtml'>"
|
|
1219
|
+
"<head><title>t</title></head><body/></html></xsl:template>",
|
|
1220
|
+
"<r/>");
|
|
1221
|
+
EXPECT_EQ(r.find("http-equiv"), std::string::npos);
|
|
1222
|
+
EXPECT_NE(r.find("<body/>"), std::string::npos);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/* libxml2 3.1.1: an <html> in no namespace with no local ns
|
|
1226
|
+
* declarations gains xmlns="http://www.w3.org/1999/xhtml". */
|
|
1227
|
+
TEST(XsltXhtml, BareHtmlRootGainsDefaultNamespace) {
|
|
1228
|
+
std::string r = run(
|
|
1229
|
+
"<xsl:output method='xml' indent='no'"
|
|
1230
|
+
" doctype-public='-//W3C//DTD XHTML 1.0 Strict//EN'/>"
|
|
1231
|
+
"<xsl:template match='/'><html><head/></html></xsl:template>",
|
|
1232
|
+
"<r/>");
|
|
1233
|
+
EXPECT_NE(r.find("<html xmlns=\"http://www.w3.org/1999/xhtml\">"),
|
|
1234
|
+
std::string::npos);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/* §5.2: patterns with position predicates apply per sibling
|
|
1238
|
+
* position — match="text()[2]" fires ONLY for the parent's second
|
|
1239
|
+
* text node (libxslt bug-182). */
|
|
1240
|
+
TEST(XsltPatterns, PositionPredicateOnTextNodes) {
|
|
1241
|
+
EXPECT_EQ(body(run(
|
|
1242
|
+
"<xsl:template match='node()'/>"
|
|
1243
|
+
"<xsl:template match='text()[2]'>"
|
|
1244
|
+
"[<xsl:value-of select='.'/>]</xsl:template>"
|
|
1245
|
+
"<xsl:template match='/'>"
|
|
1246
|
+
"<body><xsl:apply-templates select='/root/body/node()'/></body>"
|
|
1247
|
+
"</xsl:template>",
|
|
1248
|
+
"<root><body><b>1</b> t1 <b>2</b> t2 </body></root>")),
|
|
1249
|
+
"<body>[ t2 ]</body>");
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
/* §7.1.1: xsl:element's name is an ATTRIBUTE VALUE TEMPLATE
|
|
1253
|
+
* (libxslt bug-117/179/35-: {local-name()}, {concat('a','b')},
|
|
1254
|
+
* prefix:{...}, {$var}). */
|
|
1255
|
+
TEST(XsltElement, NameAvtConcat) {
|
|
1256
|
+
EXPECT_EQ(body(run(
|
|
1257
|
+
"<xsl:template match='/'>"
|
|
1258
|
+
"<xsl:element name=\"{concat('foo', 'bar')}\">x</xsl:element>"
|
|
1259
|
+
"</xsl:template>", "<r/>")),
|
|
1260
|
+
"<foobar>x</foobar>");
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
TEST(XsltElement, NameAvtLocalNameWithPrefix) {
|
|
1264
|
+
EXPECT_EQ(body(run(
|
|
1265
|
+
"<xsl:template match='/*'>"
|
|
1266
|
+
"<xsl:element name='s:{local-name()}' xmlns:s='urn:s'>"
|
|
1267
|
+
"hi</xsl:element>"
|
|
1268
|
+
"</xsl:template>", "<r/>")),
|
|
1269
|
+
"<s:r xmlns:s=\"urn:s\">hi</s:r>");
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
TEST(XsltElement, NameAvtVariable) {
|
|
1273
|
+
EXPECT_EQ(body(run(
|
|
1274
|
+
"<xsl:template match='/'>"
|
|
1275
|
+
"<xsl:variable name='n' select=\"'out'\"/>"
|
|
1276
|
+
"<xsl:element name=\"{$n}\"/>"
|
|
1277
|
+
"</xsl:template>", "<r/>")),
|
|
1278
|
+
"<out/>");
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
/* Non-AVT names take the literal path unchanged. */
|
|
1282
|
+
TEST(XsltElement, PlainNameStillLiteral) {
|
|
1283
|
+
EXPECT_EQ(body(run(
|
|
1284
|
+
"<xsl:template match='/'>"
|
|
1285
|
+
"<xsl:element name='plain'>x</xsl:element>"
|
|
1286
|
+
"</xsl:template>", "<r/>")),
|
|
1287
|
+
"<plain>x</plain>");
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
/* §11.1 top-level variables evaluate with the namespace bindings of
|
|
1291
|
+
* the element that declares them — included sheets carry their own
|
|
1292
|
+
* (libxslt bug-36-: $var select="/n:x" resolved without n:). */
|
|
1293
|
+
TEST(XsltVariables, GlobalVariableSelectUsesDeclaringNsContext) {
|
|
1294
|
+
EXPECT_EQ(body(run(
|
|
1295
|
+
"<xsl:variable name='v' select='/n:x'/>"
|
|
1296
|
+
"<xsl:template match='/'>"
|
|
1297
|
+
"[<xsl:value-of select='$v'/>]"
|
|
1298
|
+
"</xsl:template>",
|
|
1299
|
+
"<n:x xmlns:n='urn:n'>text</n:x>"))
|
|
1300
|
+
.find("xmlns:xsl"), std::string::npos) << "sanity";
|
|
1301
|
+
/* run() builds the sheet WITHOUT the n: declaration on the
|
|
1302
|
+
* stylesheet element, so prefix resolution must come from the
|
|
1303
|
+
* variable's own context — build it manually instead. */
|
|
1304
|
+
std::string sheet =
|
|
1305
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1306
|
+
" xmlns:n='urn:n' version='1.0'>"
|
|
1307
|
+
"<xsl:variable name='v' select='/n:x'/>"
|
|
1308
|
+
"<xsl:template match='/'>[<xsl:value-of select='$v'/>]"
|
|
1309
|
+
"</xsl:template></xsl:stylesheet>";
|
|
1310
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1311
|
+
ASSERT_NE(x, nullptr);
|
|
1312
|
+
const char src[] = "<n:x xmlns:n='urn:n'>hello</n:x>";
|
|
1313
|
+
LeptrisDocument d = leptris_parse_string(
|
|
1314
|
+
src, std::strlen(src), nullptr);
|
|
1315
|
+
ASSERT_NE(d, nullptr);
|
|
1316
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1317
|
+
ASSERT_NE(out, nullptr);
|
|
1318
|
+
std::string s(out);
|
|
1319
|
+
EXPECT_NE(s.find("[hello]"), std::string::npos) << s;
|
|
1320
|
+
leptris_free_string(out);
|
|
1321
|
+
leptris_document_free(d);
|
|
1322
|
+
leptris_xslt_free(x);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/* §5.4/§5.8: the built-in element rule applies templates to children
|
|
1326
|
+
* of EVERY kind — a user match="text()" template must see text nodes
|
|
1327
|
+
* reached through the built-in rule, not just via an explicit select
|
|
1328
|
+
* (libxslt bug-171: match="text()" override ignored, text leaked). */
|
|
1329
|
+
TEST(XsltBuiltInRules, UserTextTemplateOverridesBuiltInCopy) {
|
|
1330
|
+
EXPECT_EQ(body(run(
|
|
1331
|
+
"<xsl:template match='b[2]'>[<xsl:value-of select='.'/>]"
|
|
1332
|
+
"</xsl:template>"
|
|
1333
|
+
"<xsl:template match='text()'/>"
|
|
1334
|
+
"<xsl:template match='/'>"
|
|
1335
|
+
"<xsl:apply-templates select='/r/node()'/>"
|
|
1336
|
+
"</xsl:template>",
|
|
1337
|
+
"<r><b>one</b><b>two</b></r>")),
|
|
1338
|
+
"[two]");
|
|
1339
|
+
EXPECT_EQ(body(run(
|
|
1340
|
+
"<xsl:template match='text()'>T[<xsl:value-of select='.'/>]"
|
|
1341
|
+
"</xsl:template>"
|
|
1342
|
+
"<xsl:template match='/'>"
|
|
1343
|
+
"<xsl:apply-templates select='/r/node()'/>"
|
|
1344
|
+
"</xsl:template>",
|
|
1345
|
+
"<r><b>x</b>tail</r>")),
|
|
1346
|
+
"T[x]T[tail]");
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/* §12.3 xsl:decimal-format: grouping/decimal separators may be ANY
|
|
1350
|
+
* character — multi-byte included (braille ⠢, libxslt bug-222) — and
|
|
1351
|
+
* the grouping SIZE comes from the pattern (digit slots after the
|
|
1352
|
+
* last separator: '#⠢0' groups by 1 → 10 becomes 1⠢0). */
|
|
1353
|
+
TEST(XsltNumber, DecimalFormatMultiByteSeparators) {
|
|
1354
|
+
std::string sheet =
|
|
1355
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1356
|
+
" version='1.0'>"
|
|
1357
|
+
"<xsl:decimal-format name='f' grouping-separator='\xe2\xa0\xa2'/>"
|
|
1358
|
+
"<xsl:template match='/'>"
|
|
1359
|
+
"[<xsl:value-of select=\"format-number(10,'#\xe2\xa0\xa2" "0','f')\"/>]"
|
|
1360
|
+
"</xsl:template></xsl:stylesheet>";
|
|
1361
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1362
|
+
ASSERT_NE(x, nullptr);
|
|
1363
|
+
LeptrisDocument d = leptris_parse_string("<r/>", 4, nullptr);
|
|
1364
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1365
|
+
ASSERT_NE(out, nullptr);
|
|
1366
|
+
std::string want = "1";
|
|
1367
|
+
want += "\xe2\xa0\xa2";
|
|
1368
|
+
want += "0";
|
|
1369
|
+
EXPECT_NE(std::string(out).find(want), std::string::npos)
|
|
1370
|
+
<< out;
|
|
1371
|
+
leptris_free_string(out);
|
|
1372
|
+
leptris_document_free(d);
|
|
1373
|
+
leptris_xslt_free(x);
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/* bug-157: the priority ATTRIBUTE (not just the §5.5 default) must
|
|
1377
|
+
* drive template selection — an explicit -100 loses to a default
|
|
1378
|
+
* 0.5 pattern, and an explicit 10 beats a later-declared 0.5. */
|
|
1379
|
+
TEST(XsltTemplates, PriorityAttributeOverridesDefault) {
|
|
1380
|
+
EXPECT_EQ(body(run(
|
|
1381
|
+
"<xsl:template match='item' priority='10'>HIGH</xsl:template>"
|
|
1382
|
+
"<xsl:template match='item'>LOW</xsl:template>",
|
|
1383
|
+
"<r><item/></r>")), "HIGH");
|
|
1384
|
+
EXPECT_EQ(body(run(
|
|
1385
|
+
"<xsl:template match=\"r/item[last()=1]\">3</xsl:template>"
|
|
1386
|
+
"<xsl:template match='r/item' priority='-100'>FALLBACK</xsl:template>",
|
|
1387
|
+
"<r><item/></r>")), "3");
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
/* bug-214: count/from patterns are evaluated with the current
|
|
1391
|
+
* variable frame in scope ($type binds the node being numbered). */
|
|
1392
|
+
TEST(XsltNumber, CountPatternWithVariable) {
|
|
1393
|
+
EXPECT_EQ(body(run(
|
|
1394
|
+
"<xsl:template match='/'>"
|
|
1395
|
+
"<out><xsl:for-each select='r/n'>"
|
|
1396
|
+
"<xsl:variable name='t' select='@t'/>"
|
|
1397
|
+
"<p><xsl:number count=\"n[@t = $t]\"/></p>"
|
|
1398
|
+
"</xsl:for-each></out>"
|
|
1399
|
+
"</xsl:template>",
|
|
1400
|
+
"<r><n t='a'/><n t='b'/><n t='a'/></r>")),
|
|
1401
|
+
"<out><p>1</p><p>1</p><p>2</p></out>");
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
/* bug-217: use-attribute-sets semantics - sets apply first, the
|
|
1405
|
+
* use-list order gives later sets precedence, literal result attrs
|
|
1406
|
+
* beat sets, and xsl:attribute children beat everything. Conflicts
|
|
1407
|
+
* update in place (position = first insertion). */
|
|
1408
|
+
TEST(XsltAttributeSets, UseListOrderAndOverridePrecedence) {
|
|
1409
|
+
EXPECT_EQ(body(run(
|
|
1410
|
+
"<xsl:template match='foo'>"
|
|
1411
|
+
"<bar xsl:use-attribute-sets='as1 as2' a1='element' a2='element'>"
|
|
1412
|
+
"<xsl:attribute name='a1'>attr</xsl:attribute>"
|
|
1413
|
+
"</bar>"
|
|
1414
|
+
"</xsl:template>"
|
|
1415
|
+
"<xsl:attribute-set name='as1'>"
|
|
1416
|
+
"<xsl:attribute name='a1'>as1</xsl:attribute>"
|
|
1417
|
+
"<xsl:attribute name='a2'>as1</xsl:attribute>"
|
|
1418
|
+
"<xsl:attribute name='a3'>as1</xsl:attribute>"
|
|
1419
|
+
"<xsl:attribute name='a4'>as1</xsl:attribute>"
|
|
1420
|
+
"</xsl:attribute-set>"
|
|
1421
|
+
"<xsl:attribute-set name='as2'>"
|
|
1422
|
+
"<xsl:attribute name='a1'>as2</xsl:attribute>"
|
|
1423
|
+
"<xsl:attribute name='a2'>as2</xsl:attribute>"
|
|
1424
|
+
"<xsl:attribute name='a3'>as2</xsl:attribute>"
|
|
1425
|
+
"</xsl:attribute-set>",
|
|
1426
|
+
"<foo/>")),
|
|
1427
|
+
"<bar a1=\"attr\" a2=\"element\" a3=\"as2\" a4=\"as1\"/>");
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
/* bug-189: same-named attribute-set declarations UNION - later
|
|
1431
|
+
* declarations override values; duplicates within a declaration:
|
|
1432
|
+
* last wins; positions follow first insertion. */
|
|
1433
|
+
TEST(XsltAttributeSets, SameNameDeclarationsMerge) {
|
|
1434
|
+
EXPECT_EQ(body(run(
|
|
1435
|
+
"<xsl:template match='/'>"
|
|
1436
|
+
"<elem xsl:use-attribute-sets='att1 att2'/>"
|
|
1437
|
+
"<elem xsl:use-attribute-sets='att3'/>"
|
|
1438
|
+
"</xsl:template>"
|
|
1439
|
+
"<xsl:attribute-set name='att1'>"
|
|
1440
|
+
"<xsl:attribute name='att1'>1</xsl:attribute>"
|
|
1441
|
+
"<xsl:attribute name='commonatt'>1</xsl:attribute>"
|
|
1442
|
+
"</xsl:attribute-set>"
|
|
1443
|
+
"<xsl:attribute-set name='att2'>"
|
|
1444
|
+
"<xsl:attribute name='att2'>2</xsl:attribute>"
|
|
1445
|
+
"<xsl:attribute name='commonatt'>2</xsl:attribute>"
|
|
1446
|
+
"</xsl:attribute-set>"
|
|
1447
|
+
"<xsl:attribute-set name='att3'>"
|
|
1448
|
+
"<xsl:attribute name='att3a'>1</xsl:attribute>"
|
|
1449
|
+
"<xsl:attribute name='att3a'>2</xsl:attribute>"
|
|
1450
|
+
"<xsl:attribute name='att3b'>1</xsl:attribute>"
|
|
1451
|
+
"</xsl:attribute-set>"
|
|
1452
|
+
"<xsl:attribute-set name='att3'>"
|
|
1453
|
+
"<xsl:attribute name='att3b'>2</xsl:attribute>"
|
|
1454
|
+
"</xsl:attribute-set>",
|
|
1455
|
+
"<doc/>")),
|
|
1456
|
+
"<elem att1=\"1\" commonatt=\"2\" att2=\"2\"/>"
|
|
1457
|
+
"<elem att3a=\"2\" att3b=\"2\"/>");
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
/* bug-190: attribute-set names are QNames - a declaration and a
|
|
1461
|
+
* reference that spell different prefixes for the SAME namespace
|
|
1462
|
+
* URI must resolve to the same set. */
|
|
1463
|
+
TEST(XsltAttributeSets, ExpandedNameMatchesAcrossPrefixes) {
|
|
1464
|
+
std::string sheet =
|
|
1465
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1466
|
+
" xmlns:ns1='urn:foo' xmlns:ns2='urn:foo' version='1.0'"
|
|
1467
|
+
" exclude-result-prefixes='ns1 ns2'>"
|
|
1468
|
+
"<xsl:template match='/'>"
|
|
1469
|
+
"<elem xsl:use-attribute-sets='ns1:set'/>"
|
|
1470
|
+
"</xsl:template>"
|
|
1471
|
+
"<xsl:attribute-set name='ns2:set'>"
|
|
1472
|
+
"<xsl:attribute name='attr'>value</xsl:attribute>"
|
|
1473
|
+
"</xsl:attribute-set>"
|
|
1474
|
+
"</xsl:stylesheet>";
|
|
1475
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1476
|
+
ASSERT_NE(x, nullptr);
|
|
1477
|
+
LeptrisDocument d = leptris_parse_string("<doc/>", 6, nullptr);
|
|
1478
|
+
ASSERT_NE(d, nullptr);
|
|
1479
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1480
|
+
ASSERT_NE(out, nullptr);
|
|
1481
|
+
std::string r = body(out);
|
|
1482
|
+
leptris_free_string(out);
|
|
1483
|
+
leptris_document_free(d);
|
|
1484
|
+
leptris_xslt_free(x);
|
|
1485
|
+
EXPECT_NE(r.find("<elem attr=\"value\"/>"), std::string::npos) << r;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
/* bug-113: a function-call pattern (id(...)) takes the 0.5
|
|
1489
|
+
* "otherwise" default priority — not the bare-QName 0.0 — so it
|
|
1490
|
+
* beats a QName template on ties. */
|
|
1491
|
+
TEST(XsltTemplates, FunctionCallPatternDefaultPriority) {
|
|
1492
|
+
EXPECT_EQ(body(run(
|
|
1493
|
+
"<xsl:template match=\"id('x')\">FUN</xsl:template>"
|
|
1494
|
+
"<xsl:template match='dest'>NAME</xsl:template>",
|
|
1495
|
+
"<r><dest id='x'/></r>")),
|
|
1496
|
+
"FUN");
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/* bug-224: generate-id emits libxslt's deterministic sequential
|
|
1500
|
+
* ids — one counter per transform, same node re-queried returns the
|
|
1501
|
+
* same id. */
|
|
1502
|
+
TEST(XsltFunctions, GenerateIdSequentialAndStable) {
|
|
1503
|
+
EXPECT_EQ(body(run(
|
|
1504
|
+
"<xsl:template match='/'>"
|
|
1505
|
+
"<r><xsl:value-of select='generate-id(//i[1])'/>"
|
|
1506
|
+
"-<xsl:value-of select='generate-id(//i[2])'/>"
|
|
1507
|
+
"-<xsl:value-of select='generate-id(//i[1])'/></r>"
|
|
1508
|
+
"</xsl:template>",
|
|
1509
|
+
"<d><i/><i/></d>")),
|
|
1510
|
+
"<r>id1-id2-id1</r>");
|
|
1511
|
+
/* bug-224 shape: ids computed in GLOBAL variables. */
|
|
1512
|
+
EXPECT_EQ(body(run(
|
|
1513
|
+
"<xsl:variable name='v1' select='generate-id(d/i[1])'/>"
|
|
1514
|
+
"<xsl:variable name='v2' select='generate-id(d/i[2])'/>"
|
|
1515
|
+
"<xsl:template match='/'>"
|
|
1516
|
+
"<r><xsl:value-of select='$v1'/>-<xsl:value-of select='$v2'/></r>"
|
|
1517
|
+
"</xsl:template>",
|
|
1518
|
+
"<d><i/><i/></d>")),
|
|
1519
|
+
"<r>id1-id2</r>");
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
/* bug-97: prefixed attribute node-tests resolve by namespace URI
|
|
1523
|
+
* — the source may spell a different prefix for the same binding. */
|
|
1524
|
+
TEST(XsltApplyTemplates, AttributeTestResolvesByUri) {
|
|
1525
|
+
std::string sheet =
|
|
1526
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1527
|
+
" xmlns:m='urn:x' xmlns:m2='urn:x' version='1.0'>"
|
|
1528
|
+
"<xsl:template match='/'>"
|
|
1529
|
+
"[<xsl:value-of select='r/m:man/@m2:a'/>]"
|
|
1530
|
+
"</xsl:template>"
|
|
1531
|
+
"</xsl:stylesheet>";
|
|
1532
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1533
|
+
ASSERT_NE(x, nullptr);
|
|
1534
|
+
const char xml[] = "<r xmlns:m='urn:x'><m:man m:a='V'/></r>";
|
|
1535
|
+
LeptrisDocument d = leptris_parse_string(xml, sizeof(xml) - 1, nullptr);
|
|
1536
|
+
ASSERT_NE(d, nullptr);
|
|
1537
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1538
|
+
ASSERT_NE(out, nullptr);
|
|
1539
|
+
std::string r = body(out);
|
|
1540
|
+
leptris_free_string(out);
|
|
1541
|
+
leptris_document_free(d);
|
|
1542
|
+
leptris_xslt_free(x);
|
|
1543
|
+
EXPECT_NE(r.find("[V]"), std::string::npos) << r;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/* bug-104: copy-of keeps the source's namespace-declaration
|
|
1547
|
+
* ORDER — the serializer must emit the declaration chain verbatim,
|
|
1548
|
+
* not hoist the default namespace to the front. */
|
|
1549
|
+
TEST(XsltCopyOf, NamespaceDeclarationsKeepSourceOrder) {
|
|
1550
|
+
EXPECT_NE(body(run(
|
|
1551
|
+
"<xsl:template match='/'>"
|
|
1552
|
+
"<xsl:copy-of select='node()'/>"
|
|
1553
|
+
"</xsl:template>",
|
|
1554
|
+
"<foo xmlns:eg='http://example.org'"
|
|
1555
|
+
" xmlns='http://example.org' eg:bar=''/>"))
|
|
1556
|
+
.find("<foo xmlns:eg=\"http://example.org\""
|
|
1557
|
+
" xmlns=\"http://example.org\" eg:bar=\"\"/>"),
|
|
1558
|
+
std::string::npos);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
/* bug-71: a literal result element's OWN prefix binding is emitted
|
|
1562
|
+
* first, before the other in-scope declarations (libxslt creates
|
|
1563
|
+
* the element with its namespace, then copies the rest). */
|
|
1564
|
+
TEST(XsltLiteralElement, OwnPrefixBindingFirst) {
|
|
1565
|
+
std::string sheet =
|
|
1566
|
+
"<xsl:stylesheet version='1.0'"
|
|
1567
|
+
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1568
|
+
" xmlns:rdf='urn:test:rdf' xmlns:pa='urn:test:pa'>"
|
|
1569
|
+
"<xsl:template match='/'>"
|
|
1570
|
+
"<pa:Contact rdf:about='hello'/>"
|
|
1571
|
+
"</xsl:template>"
|
|
1572
|
+
"</xsl:stylesheet>";
|
|
1573
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1574
|
+
ASSERT_NE(x, nullptr);
|
|
1575
|
+
LeptrisDocument d = leptris_parse_string("<r/>", 4, nullptr);
|
|
1576
|
+
ASSERT_NE(d, nullptr);
|
|
1577
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1578
|
+
ASSERT_NE(out, nullptr);
|
|
1579
|
+
std::string r = body(out);
|
|
1580
|
+
leptris_free_string(out);
|
|
1581
|
+
leptris_document_free(d);
|
|
1582
|
+
leptris_xslt_free(x);
|
|
1583
|
+
EXPECT_NE(r.find("<pa:Contact xmlns:pa=\"urn:test:pa\""
|
|
1584
|
+
" xmlns:rdf=\"urn:test:rdf\" rdf:about=\"hello\"/>"),
|
|
1585
|
+
std::string::npos) << r;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
/* bug-220: an element in an extension namespace with no known
|
|
1589
|
+
* implementation runs only its xsl:fallback children — the element
|
|
1590
|
+
* itself and non-fallback children are dropped. */
|
|
1591
|
+
TEST(XsltFallback, ExtensionElementRunsFallbackOnly) {
|
|
1592
|
+
std::string sheet =
|
|
1593
|
+
"<xsl:stylesheet version='1.0'"
|
|
1594
|
+
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1595
|
+
" xmlns:ext='ext' extension-element-prefixes='ext'>"
|
|
1596
|
+
"<xsl:template match='/'>"
|
|
1597
|
+
"<r><ext:e>"
|
|
1598
|
+
"<xsl:fallback><fallback/></xsl:fallback>"
|
|
1599
|
+
"<ext:f/>"
|
|
1600
|
+
"</ext:e></r>"
|
|
1601
|
+
"</xsl:template>"
|
|
1602
|
+
"</xsl:stylesheet>";
|
|
1603
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1604
|
+
ASSERT_NE(x, nullptr);
|
|
1605
|
+
LeptrisDocument d = leptris_parse_string("<doc/>", 6, nullptr);
|
|
1606
|
+
ASSERT_NE(d, nullptr);
|
|
1607
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1608
|
+
ASSERT_NE(out, nullptr);
|
|
1609
|
+
std::string r = body(out);
|
|
1610
|
+
leptris_free_string(out);
|
|
1611
|
+
leptris_document_free(d);
|
|
1612
|
+
leptris_xslt_free(x);
|
|
1613
|
+
EXPECT_EQ(r, "<r><fallback/></r>") << r;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
/* bug-179: an xsl:element namespace attribute matching the result
|
|
1617
|
+
* parent's in-scope default emits NO redundant declaration — the
|
|
1618
|
+
* serializer relies on inheritance, like libxslt. */
|
|
1619
|
+
TEST(XsltElement, NamespaceAttrSkipsRedundantDefaultDecl) {
|
|
1620
|
+
EXPECT_EQ(body(run(
|
|
1621
|
+
"<xsl:template match='/'>"
|
|
1622
|
+
"<r xmlns='urn:d'>"
|
|
1623
|
+
"<xsl:element name='baz' namespace='urn:d'>x</xsl:element>"
|
|
1624
|
+
"</r>"
|
|
1625
|
+
"</xsl:template>",
|
|
1626
|
+
"<doc/>")),
|
|
1627
|
+
"<r xmlns=\"urn:d\"><baz>x</baz></r>");
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
/* bug-38-: copy-of a NAMESPACE node copies the declaration onto
|
|
1631
|
+
* the pending parent (the op previously dropped ns nodes). */
|
|
1632
|
+
TEST(XsltCopyOf, NamespaceNode) {
|
|
1633
|
+
EXPECT_EQ(body(run(
|
|
1634
|
+
"<xsl:template match='/*'>"
|
|
1635
|
+
"<elem><xsl:copy-of select='//n/namespace::foo'/></elem>"
|
|
1636
|
+
"</xsl:template>",
|
|
1637
|
+
"<r><n xmlns:foo='urn:f'/></r>")),
|
|
1638
|
+
"<elem xmlns:foo=\"urn:f\"/>");
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
/* bug-92: xsl:element does NOT copy the instruction's in-scope
|
|
1642
|
+
* namespace declarations onto the result (only literal result
|
|
1643
|
+
* elements do, 7.1.1). */
|
|
1644
|
+
TEST(XsltElement, DoesNotCopyInScopeNamespaces) {
|
|
1645
|
+
std::string sheet =
|
|
1646
|
+
"<xsl:stylesheet version='1.0'"
|
|
1647
|
+
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1648
|
+
" xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
|
|
1649
|
+
"<xsl:template match='/'>"
|
|
1650
|
+
"<xsl:element name='toto'>x</xsl:element>"
|
|
1651
|
+
"</xsl:template>"
|
|
1652
|
+
"</xsl:stylesheet>";
|
|
1653
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1654
|
+
ASSERT_NE(x, nullptr);
|
|
1655
|
+
LeptrisDocument d = leptris_parse_string("<r/>", 4, nullptr);
|
|
1656
|
+
ASSERT_NE(d, nullptr);
|
|
1657
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1658
|
+
ASSERT_NE(out, nullptr);
|
|
1659
|
+
std::string r = body(out);
|
|
1660
|
+
leptris_free_string(out);
|
|
1661
|
+
leptris_document_free(d);
|
|
1662
|
+
leptris_xslt_free(x);
|
|
1663
|
+
EXPECT_EQ(r, "<toto>x</toto>") << r;
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
/* bug-98: under indent="yes", whitespace text nodes copied from
|
|
1667
|
+
* the source make the parent mixed — libxslt stops formatting the
|
|
1668
|
+
* whole subtree below it (the visible "indent" is the copied
|
|
1669
|
+
* whitespace itself). */
|
|
1670
|
+
TEST(XsltOutput, IndentStopsBelowWhitespaceMixedResult) {
|
|
1671
|
+
std::string sheet =
|
|
1672
|
+
"<xsl:stylesheet version='1.0'"
|
|
1673
|
+
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
|
|
1674
|
+
"<xsl:output method='xml' indent='yes'/>"
|
|
1675
|
+
"<xsl:template match='/*'>"
|
|
1676
|
+
"<result><xsl:apply-templates/></result>"
|
|
1677
|
+
"</xsl:template>"
|
|
1678
|
+
"<xsl:template match='l'>"
|
|
1679
|
+
"<total><type><xsl:value-of select='@t'/></type>"
|
|
1680
|
+
"<a><xsl:value-of select='@v'/></a></total>"
|
|
1681
|
+
"</xsl:template>"
|
|
1682
|
+
"</xsl:stylesheet>";
|
|
1683
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1684
|
+
ASSERT_NE(x, nullptr);
|
|
1685
|
+
const char xml[] = "<r>\n <l t='one' v='3'/>\n</r>";
|
|
1686
|
+
LeptrisDocument d = leptris_parse_string(xml, sizeof(xml) - 1, nullptr);
|
|
1687
|
+
ASSERT_NE(d, nullptr);
|
|
1688
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1689
|
+
ASSERT_NE(out, nullptr);
|
|
1690
|
+
std::string r = body(out);
|
|
1691
|
+
leptris_free_string(out);
|
|
1692
|
+
leptris_document_free(d);
|
|
1693
|
+
leptris_xslt_free(x);
|
|
1694
|
+
EXPECT_EQ(r,
|
|
1695
|
+
"<result>\n <total><type>one</type><a>3</a></total>\n"
|
|
1696
|
+
"</result>\n") << r;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
/* bug-161: apply-templates select=node() over a text item applies
|
|
1700
|
+
* the built-in TEXT rule — copy the text itself (the fallback
|
|
1701
|
+
* previously walked the text node's children and dropped it). */
|
|
1702
|
+
TEST(XsltApplyTemplates, SelectedTextItemGetsBuiltInTextRule) {
|
|
1703
|
+
EXPECT_EQ(body(run(
|
|
1704
|
+
"<xsl:template match='l/p'>"
|
|
1705
|
+
"M<xsl:copy><xsl:apply-templates select='@*|node()'/></xsl:copy>"
|
|
1706
|
+
"</xsl:template>",
|
|
1707
|
+
"<r><l><p>test</p></l></r>")),
|
|
1708
|
+
"M<p>test</p>");
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
/* bug-193: apply-imports with no imported candidate falls back to
|
|
1712
|
+
* the BUILT-IN rule for the node (libxslt: the built-in element
|
|
1713
|
+
* rule re-enters template selection for the children). */
|
|
1714
|
+
TEST(XsltApplyImports, FallsBackToBuiltInWithoutImport) {
|
|
1715
|
+
EXPECT_EQ(body(run(
|
|
1716
|
+
"<xsl:template match='root'>"
|
|
1717
|
+
"<r><xsl:apply-imports/></r>"
|
|
1718
|
+
"</xsl:template>"
|
|
1719
|
+
"<xsl:template match='test'>passed</xsl:template>",
|
|
1720
|
+
"<root><test/></root>")),
|
|
1721
|
+
"<r>passed</r>");
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/* bug-32-: xsl:copy copies the element and its namespace nodes
|
|
1725
|
+
* but NOT its attributes (7.5) — attributes reach the result only
|
|
1726
|
+
* through apply-templates/@*. libxslt-verified. */
|
|
1727
|
+
TEST(XsltCopyOf, AttributeNode) {
|
|
1728
|
+
EXPECT_EQ(body(run(
|
|
1729
|
+
"<xsl:template match='*'>"
|
|
1730
|
+
"<xsl:copy><xsl:copy-of select='@*'/><xsl:apply-templates/>"
|
|
1731
|
+
"</xsl:copy></xsl:template>",
|
|
1732
|
+
"<a x='1' y='2'>t</a>")),
|
|
1733
|
+
"<a x=\"1\" y=\"2\">t</a>");
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
TEST(XsltCopy, DoesNotCopyAttributes) {
|
|
1737
|
+
EXPECT_EQ(body(run(
|
|
1738
|
+
"<xsl:template match='*'>"
|
|
1739
|
+
"<xsl:copy><xsl:apply-templates select='node()'/></xsl:copy>"
|
|
1740
|
+
"</xsl:template>",
|
|
1741
|
+
"<a x='1'>t</a>")),
|
|
1742
|
+
"<a>t</a>");
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
/* bug-177: an attribute created in the XML namespace serializes
|
|
1746
|
+
* with the reserved xml: prefix. */
|
|
1747
|
+
TEST(XsltAttribute, XmlNamespaceBecomesXmlPrefix) {
|
|
1748
|
+
EXPECT_EQ(body(run(
|
|
1749
|
+
"<xsl:template match='/*'>"
|
|
1750
|
+
"<xsl:copy>"
|
|
1751
|
+
"<xsl:attribute name='id'"
|
|
1752
|
+
" namespace='http://www.w3.org/XML/1998/namespace'>etc"
|
|
1753
|
+
"</xsl:attribute>"
|
|
1754
|
+
"</xsl:copy>"
|
|
1755
|
+
"</xsl:template>",
|
|
1756
|
+
"<doc/>")),
|
|
1757
|
+
"<doc xml:id=\"etc\"/>");
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
/* bug-99: an UNPREFIXED attribute created with a namespace gets a
|
|
1761
|
+
* generated ns_1 prefix — attributes never take the default
|
|
1762
|
+
* namespace (libxslt mints ns_N). */
|
|
1763
|
+
TEST(XsltAttribute, NamespacedUnprefixedAttrMintsPrefix) {
|
|
1764
|
+
EXPECT_EQ(body(run(
|
|
1765
|
+
"<xsl:template match='/'>"
|
|
1766
|
+
"<xsl:element name='doc' namespace='ns1'>"
|
|
1767
|
+
"<xsl:attribute name='attr' namespace='ns1'>foo!</xsl:attribute>"
|
|
1768
|
+
"</xsl:element>"
|
|
1769
|
+
"</xsl:template>",
|
|
1770
|
+
"<r/>")),
|
|
1771
|
+
"<doc xmlns=\"ns1\" xmlns:ns_1=\"ns1\" ns_1:attr=\"foo!\"/>");
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
/* bug-82: §3.4 — when both strip-space and preserve-space match an
|
|
1775
|
+
* element, the LAST DECLARED rule wins (preserve * followed by
|
|
1776
|
+
* strip child strips child's whitespace-only text). */
|
|
1777
|
+
TEST(XsltStripSpace, LastMatchingDeclarationWins) {
|
|
1778
|
+
EXPECT_EQ(body(run(
|
|
1779
|
+
"<xsl:preserve-space elements='*'/>"
|
|
1780
|
+
"<xsl:strip-space elements='b'/>"
|
|
1781
|
+
"<xsl:template match='node()|@*'>"
|
|
1782
|
+
"<xsl:copy><xsl:apply-templates select='node()|@*'/></xsl:copy>"
|
|
1783
|
+
"</xsl:template>",
|
|
1784
|
+
"<r><a> </a><b> </b></r>")),
|
|
1785
|
+
"<r><a> </a><b/></r>");
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
/* bug-195: TEXT nodes in the document child chain (between a
|
|
1789
|
+
* top-level comment and the root element) serialize — the chain
|
|
1790
|
+
* walks handled only PI/comment. */
|
|
1791
|
+
TEST(XsltOutput, TopLevelTextBetweenCommentAndRoot) {
|
|
1792
|
+
EXPECT_EQ(body(run(
|
|
1793
|
+
"<xsl:template match='node()|@*'>"
|
|
1794
|
+
"<xsl:copy><xsl:apply-templates select='node()|@*'/></xsl:copy>"
|
|
1795
|
+
"</xsl:template>",
|
|
1796
|
+
"<!--c-->\n<r/>")),
|
|
1797
|
+
"<!--c-->\n<r/>");
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
/* bug-168: braces inside string literals in an AVT expression do
|
|
1801
|
+
* not terminate the expression — the scanner tracks quotes. */
|
|
1802
|
+
TEST(XsltAvt, BracesInsideStringLiterals) {
|
|
1803
|
+
EXPECT_EQ(body(run(
|
|
1804
|
+
"<xsl:template match='/*'>"
|
|
1805
|
+
"<A a=\"{concat('{',local-name(),'}')}\">x</A>"
|
|
1806
|
+
"</xsl:template>",
|
|
1807
|
+
"<r/>")),
|
|
1808
|
+
"<A a=\"{r}\">x</A>");
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
/* bug-219: xsl:number's format attribute is an AVT (libxslt), and
|
|
1812
|
+
* digit tokens in other scripts format with that script's digits
|
|
1813
|
+
* (zero-padded to the token length). */
|
|
1814
|
+
TEST(XsltNumber, FormatAvtWithUnicodeDigits) {
|
|
1815
|
+
std::string xml = "<t><f>";
|
|
1816
|
+
xml += "\xd9\xa0"; /* Arabic-Indic zero */
|
|
1817
|
+
xml += "\xd9\xa1"; /* Arabic-Indic one */
|
|
1818
|
+
xml += "</f></t>";
|
|
1819
|
+
std::string want = "<r>";
|
|
1820
|
+
want += "\xd9\xa0";
|
|
1821
|
+
want += "\xd9\xa0";
|
|
1822
|
+
want += "</r>";
|
|
1823
|
+
EXPECT_EQ(body(run(
|
|
1824
|
+
"<xsl:template match='/'>"
|
|
1825
|
+
"<xsl:variable name='f' select='/t/f'/>"
|
|
1826
|
+
"<r><xsl:number value='0' format='{$f}'/></r>"
|
|
1827
|
+
"</xsl:template>",
|
|
1828
|
+
xml.c_str())),
|
|
1829
|
+
want);
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
TEST(XsltStripSpace, UnprefixedNameNeverMatchesNamespacedElement) {
|
|
1833
|
+
EXPECT_EQ(body(run(
|
|
1834
|
+
"<xsl:preserve-space elements='*'/>"
|
|
1835
|
+
"<xsl:strip-space elements='c'/>"
|
|
1836
|
+
"<xsl:template match='/'>"
|
|
1837
|
+
"[<xsl:value-of select='/r/c'/>]["
|
|
1838
|
+
"<xsl:value-of select='/r/e:n'/>]"
|
|
1839
|
+
"</xsl:template>",
|
|
1840
|
+
"<r xmlns:e='urn:x'><c> </c><e:n> </e:n></r>")),
|
|
1841
|
+
"[][ ]");
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
/* bug-5-: the HTML serializer leaves newlines raw in attribute
|
|
1845
|
+
* values (libxml2 htmlAttrDumpOutput). */
|
|
1846
|
+
TEST(XsltHtml, AttributeNewlineStaysRaw) {
|
|
1847
|
+
EXPECT_NE(body(run(
|
|
1848
|
+
"<xsl:output method='html'/>"
|
|
1849
|
+
"<xsl:template match='/'>"
|
|
1850
|
+
"<tr class=\"{concat('a', ' ', 'b')}\"/>"
|
|
1851
|
+
"</xsl:template>",
|
|
1852
|
+
"<r/>"))
|
|
1853
|
+
.find("<tr class=\"a\nb\">"), std::string::npos);
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
/* bug-133: key() indexes EVERY node kind — match="node()" must
|
|
1857
|
+
* retrieve text nodes between elements (the walker was
|
|
1858
|
+
* elements-only). */
|
|
1859
|
+
TEST(XsltKey, MatchesTextNodes) {
|
|
1860
|
+
std::string sheet =
|
|
1861
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1862
|
+
" version='1.0'>"
|
|
1863
|
+
"<xsl:key name='k' match='text()' use='\"txt\"'/>"
|
|
1864
|
+
"<xsl:template match='/r'>"
|
|
1865
|
+
"[<xsl:copy-of select=\"key('k','txt')\"/>]"
|
|
1866
|
+
"</xsl:template>"
|
|
1867
|
+
"</xsl:stylesheet>";
|
|
1868
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1869
|
+
ASSERT_NE(x, nullptr);
|
|
1870
|
+
const char xml[] = "<r><a/>\n one<b/>\n two</r>";
|
|
1871
|
+
LeptrisDocument d = leptris_parse_string(xml, sizeof(xml) - 1, nullptr);
|
|
1872
|
+
ASSERT_NE(d, nullptr);
|
|
1873
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1874
|
+
ASSERT_NE(out, nullptr);
|
|
1875
|
+
std::string r = body(out);
|
|
1876
|
+
leptris_free_string(out);
|
|
1877
|
+
leptris_document_free(d);
|
|
1878
|
+
leptris_xslt_free(x);
|
|
1879
|
+
EXPECT_EQ(r, "[\n one\n two]") << r;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
/* bug-41-/43-: a with-param binds ONLY names the callee declares
|
|
1883
|
+
* as xsl:param (11.6) — the callee sees the GLOBAL otherwise. */
|
|
1884
|
+
TEST(XsltParams, WithParamIgnoredWhenNotDeclared) {
|
|
1885
|
+
EXPECT_EQ(body(run(
|
|
1886
|
+
"<xsl:variable name='foo' select='\"SUCCESS\"'/>"
|
|
1887
|
+
"<xsl:template name='test'>"
|
|
1888
|
+
"<xsl:value-of select='$foo'/>"
|
|
1889
|
+
"</xsl:template>"
|
|
1890
|
+
"<xsl:template match='/'>"
|
|
1891
|
+
"<xsl:variable name='foo' select='\"FAILURE\"'/>"
|
|
1892
|
+
"<xsl:call-template name='test'>"
|
|
1893
|
+
"<xsl:with-param name='foo' select='\"FAILURE\"'/>"
|
|
1894
|
+
"</xsl:call-template>"
|
|
1895
|
+
"</xsl:template>",
|
|
1896
|
+
"<r/>")),
|
|
1897
|
+
"SUCCESS");
|
|
1898
|
+
EXPECT_EQ(body(run(
|
|
1899
|
+
"<xsl:variable name='foo' select='\"SUCCESS\"'/>"
|
|
1900
|
+
"<xsl:template match='d'>"
|
|
1901
|
+
"<xsl:value-of select='$foo'/>"
|
|
1902
|
+
"</xsl:template>"
|
|
1903
|
+
"<xsl:template match='/'>"
|
|
1904
|
+
"<xsl:variable name='foo' select='\"FAILURE\"'/>"
|
|
1905
|
+
"<xsl:apply-templates>"
|
|
1906
|
+
"<xsl:with-param name='foo' select='\"FAILURE\"'/>"
|
|
1907
|
+
"</xsl:apply-templates>"
|
|
1908
|
+
"</xsl:template>",
|
|
1909
|
+
"<d/>")),
|
|
1910
|
+
"SUCCESS");
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
/* EXSLT date:add: ISO durations add to (possibly year-month)
|
|
1914
|
+
* dates; a result landing on day 1 formats as year-month. */
|
|
1915
|
+
TEST(XsltExsltDate, Add) {
|
|
1916
|
+
std::string sheet =
|
|
1917
|
+
"<xsl:stylesheet version='1.0'"
|
|
1918
|
+
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
1919
|
+
" xmlns:date='http://exslt.org/dates-and-times'"
|
|
1920
|
+
" exclude-result-prefixes='date'>"
|
|
1921
|
+
"<xsl:template match='/'>"
|
|
1922
|
+
"[<xsl:value-of select=\"date:add('2001-01','P3D')\"/>]"
|
|
1923
|
+
"[<xsl:value-of select=\"date:add('2001-12','P30D')\"/>]"
|
|
1924
|
+
"[<xsl:value-of select=\"date:add('2001-12','P31D')\"/>]"
|
|
1925
|
+
"[<xsl:value-of select=\"date:add('2001-12','P32D')\"/>]"
|
|
1926
|
+
"</xsl:template></xsl:stylesheet>";
|
|
1927
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
1928
|
+
ASSERT_NE(x, nullptr);
|
|
1929
|
+
LeptrisDocument d = leptris_parse_string("<r/>", 4, nullptr);
|
|
1930
|
+
ASSERT_NE(d, nullptr);
|
|
1931
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
1932
|
+
ASSERT_NE(out, nullptr);
|
|
1933
|
+
std::string r = body(out);
|
|
1934
|
+
leptris_free_string(out);
|
|
1935
|
+
leptris_document_free(d);
|
|
1936
|
+
leptris_xslt_free(x);
|
|
1937
|
+
EXPECT_EQ(r, "[2001-01-04][2001-12-31][2002-01][2002-01-02]")
|
|
1938
|
+
<< r;
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
/* bug-186 follow-on: a child-step pattern (star slash star) must
|
|
1942
|
+
* NOT match the root element — the root's parent is the document
|
|
1943
|
+
* node. The bare-leaf fast path used to match it anyway. */
|
|
1944
|
+
TEST(XsltTemplates, ChildStepPatternDoesNotMatchRoot) {
|
|
1945
|
+
EXPECT_EQ(body(run(
|
|
1946
|
+
"<xsl:template match='*/*'><xsl:value-of select='name()'/>"
|
|
1947
|
+
"</xsl:template>",
|
|
1948
|
+
"<top><foo/><bar/></top>")),
|
|
1949
|
+
"foobar");
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
/* bug-186/218: numbering namespace nodes — the default count is
|
|
1953
|
+
* same-kind + same-prefix; every in-scope prefix is unique, so each
|
|
1954
|
+
* namespace node numbers 1. `from` must evaluate (and not crash)
|
|
1955
|
+
* when it references a function with an empty result. */
|
|
1956
|
+
TEST(XsltNumber, OnNamespaceNodes) {
|
|
1957
|
+
EXPECT_EQ(body(run(
|
|
1958
|
+
"<xsl:template match='/*'>"
|
|
1959
|
+
"<xsl:for-each select='namespace::*'>"
|
|
1960
|
+
"<xsl:number/>"
|
|
1961
|
+
"</xsl:for-each>"
|
|
1962
|
+
"</xsl:template>",
|
|
1963
|
+
"<top xmlns:a='A' xmlns:b='B' xmlns:c='C'/>")),
|
|
1964
|
+
"1111");
|
|
1965
|
+
EXPECT_EQ(body(run(
|
|
1966
|
+
"<xsl:template match='*'>"
|
|
1967
|
+
"<xsl:for-each select='namespace::*[position()=2]'>"
|
|
1968
|
+
"<xsl:number from=\"key('e','f')\"/>"
|
|
1969
|
+
"</xsl:for-each>"
|
|
1970
|
+
"</xsl:template>",
|
|
1971
|
+
"<top xmlns:ns1='foo'/>")),
|
|
1972
|
+
"1");
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
/* bug-199: level="any" from a namespace node resolves through the
|
|
1976
|
+
* OWNER element (the synthetic ns node is outside the document
|
|
1977
|
+
* order walk). */
|
|
1978
|
+
TEST(XsltNumber, AnyLevelFromNamespaceNodeCountsOwner) {
|
|
1979
|
+
EXPECT_EQ(body(run(
|
|
1980
|
+
"<xsl:template match='node()|@*'>"
|
|
1981
|
+
"<xsl:copy>"
|
|
1982
|
+
"<xsl:for-each select='namespace::a'>"
|
|
1983
|
+
"<xsl:attribute name='ns'>"
|
|
1984
|
+
"<xsl:value-of select='.'/>"
|
|
1985
|
+
"(<xsl:number count='*' level='any'/>)"
|
|
1986
|
+
"</xsl:attribute>"
|
|
1987
|
+
"</xsl:for-each>"
|
|
1988
|
+
"<xsl:apply-templates select='node()|@*'/>"
|
|
1989
|
+
"</xsl:copy>"
|
|
1990
|
+
"</xsl:template>",
|
|
1991
|
+
"<r xmlns:a='a'><f xmlns:a='b'><b xmlns:a='c'/></f></r>")),
|
|
1992
|
+
"<r xmlns:a=\"a\" ns=\"a(1)\"><f xmlns:a=\"b\" ns=\"b(2)\">"
|
|
1993
|
+
"<b xmlns:a=\"c\" ns=\"c(3)\"/></f></r>");
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
TEST(XsltNumber, DecimalFormatGroupingSizeFromPattern) {
|
|
1997
|
+
/* '#,#0' groups by 2: 12345 → 1,23,45 */
|
|
1998
|
+
EXPECT_NE(body(run(
|
|
1999
|
+
"<xsl:template match='/'>"
|
|
2000
|
+
"[<xsl:value-of select=\"format-number(12345,'#,#0')\"/>]"
|
|
2001
|
+
"</xsl:template>", "<r/>"))
|
|
2002
|
+
.find("[1,23,45]"), std::string::npos);
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
/* #129: leptris_document_serialize_ext indent_text — the formatter
|
|
2006
|
+
* also owns TEXT whitespace (display form). Without it, mixed
|
|
2007
|
+
* content stays on one line (#534 round-trip guarantee). */
|
|
2008
|
+
TEST(SerializeExt, IndentTextIndentsMixedContent) {
|
|
2009
|
+
const char xml[] = "<r><a>text <b>bold</b> tail</a></r>";
|
|
2010
|
+
LeptrisDocument d = leptris_parse_string(xml, std::strlen(xml), nullptr);
|
|
2011
|
+
ASSERT_NE(d, nullptr);
|
|
2012
|
+
|
|
2013
|
+
LeptrisSerializeOptions o = {2, 0, nullptr};
|
|
2014
|
+
LeptrisSerializeExtOptions ext = {0};
|
|
2015
|
+
char* plain = leptris_document_serialize(d, &o);
|
|
2016
|
+
ASSERT_NE(plain, nullptr);
|
|
2017
|
+
EXPECT_NE(std::string(plain).find("<a>text <b>bold</b> tail</a>"),
|
|
2018
|
+
std::string::npos) << "default keeps mixed on one line";
|
|
2019
|
+
leptris_free_string(plain);
|
|
2020
|
+
|
|
2021
|
+
ext.indent_text = 1;
|
|
2022
|
+
char* it = leptris_document_serialize_ext(d, &o, &ext);
|
|
2023
|
+
ASSERT_NE(it, nullptr);
|
|
2024
|
+
std::string s(it);
|
|
2025
|
+
leptris_free_string(it);
|
|
2026
|
+
/* text on its own indented line, elements indented */
|
|
2027
|
+
EXPECT_NE(s.find("<a>\n text"), std::string::npos) << s;
|
|
2028
|
+
EXPECT_NE(s.find("<b>\n bold"), std::string::npos) << s;
|
|
2029
|
+
leptris_document_free(d);
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
/* Issue #628: last() inside xsl:for-each must reflect the selection
|
|
2033
|
+
* size — the exec threaded only the in-flight position; last() fell
|
|
2034
|
+
* back to the default context size 1, silently breaking
|
|
2035
|
+
* position()=last() branching. */
|
|
2036
|
+
TEST(XsltForEach, LastReflectsSelectionSize) {
|
|
2037
|
+
EXPECT_EQ(body(run(
|
|
2038
|
+
"<xsl:template match='/'>"
|
|
2039
|
+
"<xsl:for-each select='/r/i'>"
|
|
2040
|
+
"<xsl:if test='position()=last()'>[<xsl:value-of select='.'/>]"
|
|
2041
|
+
"</xsl:if>"
|
|
2042
|
+
"</xsl:for-each>"
|
|
2043
|
+
"</xsl:template>",
|
|
2044
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2045
|
+
"[c]");
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
TEST(XsltForEach, LastValueIsSelectionSize) {
|
|
2049
|
+
EXPECT_EQ(body(run(
|
|
2050
|
+
"<xsl:template match='/'>"
|
|
2051
|
+
"<xsl:for-each select='/r/i'>"
|
|
2052
|
+
"<xsl:value-of select='last()'/>"
|
|
2053
|
+
"</xsl:for-each>"
|
|
2054
|
+
"</xsl:template>",
|
|
2055
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2056
|
+
"333");
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
/* Same contract through apply-templates: last() sees the selected
|
|
2060
|
+
* node-list size, and position()/last() pair correctly in the final
|
|
2061
|
+
* iteration. */
|
|
2062
|
+
TEST(XsltForEach, LastThroughApplyTemplates) {
|
|
2063
|
+
EXPECT_EQ(body(run(
|
|
2064
|
+
"<xsl:template match='/r'>"
|
|
2065
|
+
"<xsl:apply-templates select='i'/>"
|
|
2066
|
+
"</xsl:template>"
|
|
2067
|
+
"<xsl:template match='i'>"
|
|
2068
|
+
"<xsl:if test='position()=last()'>last=<xsl:value-of select='.'/>"
|
|
2069
|
+
"</xsl:if>"
|
|
2070
|
+
"</xsl:template>",
|
|
2071
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2072
|
+
"last=c");
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
/* Issue #627: an unknown unprefixed function must RAISE like plain
|
|
2076
|
+
* XPath does — libxslt aborts the transform at runtime ("Unregistered
|
|
2077
|
+
* function", "no result"); silently evaluating to empty masked
|
|
2078
|
+
* typos. */
|
|
2079
|
+
TEST(XsltErrors, UnknownFunctionAbortsTransform) {
|
|
2080
|
+
EXPECT_EQ(run(
|
|
2081
|
+
"<xsl:template match='/'>"
|
|
2082
|
+
"[<xsl:value-of select='foo(1)'/>]"
|
|
2083
|
+
"</xsl:template>",
|
|
2084
|
+
"<r/>"), "(null)");
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
/* The abort must not leak partial output: the whole apply fails. */
|
|
2088
|
+
TEST(XsltErrors, UnknownFunctionAbortsAfterPartialOutput) {
|
|
2089
|
+
EXPECT_EQ(run(
|
|
2090
|
+
"<xsl:template match='/'>"
|
|
2091
|
+
"<xsl:text>before</xsl:text>"
|
|
2092
|
+
"<xsl:value-of select='bar(2)'/>"
|
|
2093
|
+
"</xsl:template>",
|
|
2094
|
+
"<r/>"), "(null)");
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
/* libxslt's OWN extension namespace resolves like EXSLT: stylesheets
|
|
2098
|
+
* in the wild bind xmlns:libxslt='http://xmlsoft.org/XSLT/namespace'
|
|
2099
|
+
* and call libxslt:node-set() (bug-65); the prefix->local fallback
|
|
2100
|
+
* must recognize the namespace. */
|
|
2101
|
+
TEST(XsltExslt, LibxsltNodeSetResolves) {
|
|
2102
|
+
/* run() cannot carry extra namespace declarations on the
|
|
2103
|
+
* stylesheet element, so build the sheet explicitly. */
|
|
2104
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
2105
|
+
" xmlns:libxslt='http://xmlsoft.org/XSLT/namespace' version='1.0'>"
|
|
2106
|
+
"<xsl:variable name='one'>"
|
|
2107
|
+
"<xsl:copy-of select='/eins/content'/></xsl:variable>"
|
|
2108
|
+
"<xsl:template match='/'>"
|
|
2109
|
+
"[<xsl:copy-of select=\"libxslt:node-set($one)\"/>]"
|
|
2110
|
+
"</xsl:template></xsl:stylesheet>";
|
|
2111
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
2112
|
+
ASSERT_NE(x, nullptr);
|
|
2113
|
+
const char* xml = "<eins><content>content of one</content></eins>";
|
|
2114
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
2115
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
2116
|
+
EXPECT_NE(out, nullptr);
|
|
2117
|
+
if (out) EXPECT_EQ(body(std::string(out)),
|
|
2118
|
+
"[<content>content of one</content>]");
|
|
2119
|
+
leptris_free_string(out);
|
|
2120
|
+
leptris_document_free(d);
|
|
2121
|
+
leptris_xslt_free(x);
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
/* §11.6: a with-param with CONTENT (no select) binds the content
|
|
2125
|
+
* RTF — the caller's binding ran only select expressions, so
|
|
2126
|
+
* content params arrived empty (bug-90's wrap-cdata template). */
|
|
2127
|
+
TEST(XsltParams, WithParamContentBindsFragment) {
|
|
2128
|
+
EXPECT_EQ(body(run(
|
|
2129
|
+
"<xsl:template match='/'>"
|
|
2130
|
+
"<xsl:call-template name='w'>"
|
|
2131
|
+
"<xsl:with-param name='content'>PRE "
|
|
2132
|
+
"<xsl:value-of select='/r/x'/> POST</xsl:with-param>"
|
|
2133
|
+
"</xsl:call-template></xsl:template>"
|
|
2134
|
+
"<xsl:template name='w'>"
|
|
2135
|
+
"<xsl:param name='content'/>"
|
|
2136
|
+
"[<xsl:value-of select='$content'/>]"
|
|
2137
|
+
"</xsl:template>",
|
|
2138
|
+
"<r><x>VAL</x></r>")),
|
|
2139
|
+
"[PRE VAL POST]");
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
/* bug-90: the RTF capture buffer stores LOGICAL text — string($rtf)
|
|
2143
|
+
* is unescaped, so pre-escaping fragment text leaked & into
|
|
2144
|
+
* param values re-emitted with disable-output-escaping. */
|
|
2145
|
+
TEST(XsltParams, CapturedRtfTextIsLogical) {
|
|
2146
|
+
EXPECT_EQ(body(run(
|
|
2147
|
+
"<xsl:template match='/'>"
|
|
2148
|
+
"<xsl:variable name='v'><xsl:value-of select='/r/t'/></xsl:variable>"
|
|
2149
|
+
"<xsl:text disable-output-escaping='yes'><![CDATA[</xsl:text>"
|
|
2150
|
+
"<xsl:value-of select='$v' disable-output-escaping='yes'/>"
|
|
2151
|
+
"<xsl:text disable-output-escaping='yes'>]]></xsl:text>"
|
|
2152
|
+
"</xsl:template>",
|
|
2153
|
+
"<r><t>a&b</t></r>")),
|
|
2154
|
+
"<![CDATA[a&b]]>");
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
/* libxslt RTF semantics (bug-56): a content-bound variable is a
|
|
2158
|
+
* nodeset holding the fragment's document node — count() is 1 and
|
|
2159
|
+
* string() yields the fragment's logical text via the shared
|
|
2160
|
+
* document-node string-value walker. */
|
|
2161
|
+
TEST(XsltParams, RtfVariableStringAndCount) {
|
|
2162
|
+
EXPECT_EQ(body(run(
|
|
2163
|
+
"<xsl:template match='/'>"
|
|
2164
|
+
"<xsl:variable name='t'>hello</xsl:variable>"
|
|
2165
|
+
"[<xsl:value-of select='string($t)'/>]"
|
|
2166
|
+
"[<xsl:value-of select='count($t)'/>]"
|
|
2167
|
+
"</xsl:template>",
|
|
2168
|
+
"<r/>")),
|
|
2169
|
+
"[hello][1]");
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
/* bug-65: apply-templates select="node-set($rtf)" dispatches through
|
|
2173
|
+
* the fragment's document node — the built-in root rule applies its
|
|
2174
|
+
* children — so the matching template fires ONCE per node-set, not
|
|
2175
|
+
* once per (document node, root element). */
|
|
2176
|
+
TEST(XsltExslt, ApplyTemplatesOnNodeSetFiresOnce) {
|
|
2177
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
2178
|
+
" xmlns:libxslt='http://xmlsoft.org/XSLT/namespace' version='1.0'>"
|
|
2179
|
+
"<xsl:variable name='one'><xsl:copy-of select='.'/></xsl:variable>"
|
|
2180
|
+
"<xsl:template match='/'>"
|
|
2181
|
+
"<xsl:apply-templates select='libxslt:node-set($one)' mode='one'/>"
|
|
2182
|
+
"<xsl:text>|</xsl:text>"
|
|
2183
|
+
"</xsl:template>"
|
|
2184
|
+
"<xsl:template match='*' mode='one'>"
|
|
2185
|
+
"[<xsl:copy-of select='.'/>]"
|
|
2186
|
+
"</xsl:template></xsl:stylesheet>";
|
|
2187
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
2188
|
+
ASSERT_NE(x, nullptr);
|
|
2189
|
+
const char* xml = "<eins><content>content of one</content></eins>";
|
|
2190
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
2191
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
2192
|
+
EXPECT_NE(out, nullptr);
|
|
2193
|
+
if (out) EXPECT_EQ(body(std::string(out)),
|
|
2194
|
+
"[<eins><content>content of one</content></eins>]|");
|
|
2195
|
+
leptris_free_string(out);
|
|
2196
|
+
leptris_document_free(d);
|
|
2197
|
+
leptris_xslt_free(x);
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
/* bug-5-: the distinct-values predicate
|
|
2201
|
+
* //G[@t='R' and not(@name=preceding::G[@t='R']/@name)] keeps only
|
|
2202
|
+
* the FIRST node per name — an over-broad equality (or a preceding::
|
|
2203
|
+
* that sees the node itself) leaves duplicates, which the report
|
|
2204
|
+
* grid renders as extra empty cells. */
|
|
2205
|
+
TEST(XsltApply, PrecedingAxisDistinctValues) {
|
|
2206
|
+
EXPECT_EQ(body(run(
|
|
2207
|
+
"<xsl:template match='/'>"
|
|
2208
|
+
"[<xsl:value-of select='count(//G[@t=\"R\" and "
|
|
2209
|
+
"not(@name=preceding::G[@t=\"R\"]/@name)])'/>]"
|
|
2210
|
+
"[<xsl:for-each select='//G[@t=\"R\" and "
|
|
2211
|
+
"not(@name=preceding::G[@t=\"R\"]/@name)]'>"
|
|
2212
|
+
"<xsl:value-of select='@name'/>|</xsl:for-each>]"
|
|
2213
|
+
"</xsl:template>",
|
|
2214
|
+
"<r><G t='R' name='nr'/><G t='R' name='nr'/>"
|
|
2215
|
+
"<G t='R' name='rc'/><G t='R' name='rc'/>"
|
|
2216
|
+
"<G t='X' name='skip'/></r>")),
|
|
2217
|
+
"[2][nr|rc|]");
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
/* Number→string per libxml2's xmlXPathFormatNumber (the suite's
|
|
2221
|
+
* ground truth): int32-integral values print bare, other values in
|
|
2222
|
+
* [1e-5, 1e9] print decimal with 15 significant digits and trailing
|
|
2223
|
+
* zeros trimmed, everything else scientific %.14e trimmed. The old
|
|
2224
|
+
* "%g" cut to 6 significant digits (bug-5-: 10695.23 → 10695.2). */
|
|
2225
|
+
TEST(XsltNumberFormat, MatchesLibxml2) {
|
|
2226
|
+
EXPECT_EQ(body(run(
|
|
2227
|
+
"<xsl:output method='text'/>"
|
|
2228
|
+
"<xsl:template match='/'>"
|
|
2229
|
+
"[<xsl:value-of select='10695.23'/>]"
|
|
2230
|
+
"[<xsl:value-of select='1 div 3'/>]"
|
|
2231
|
+
"[<xsl:value-of select='1000000'/>]"
|
|
2232
|
+
"[<xsl:value-of select='1000000.5'/>]"
|
|
2233
|
+
"[<xsl:value-of select='9999999.9999'/>]"
|
|
2234
|
+
"[<xsl:value-of select='1234567890'/>]"
|
|
2235
|
+
"[<xsl:value-of select='1234567890.5'/>]"
|
|
2236
|
+
"[<xsl:value-of select='10000000000'/>]"
|
|
2237
|
+
"[<xsl:value-of select='1234567890123456'/>]"
|
|
2238
|
+
"[<xsl:value-of select='0.00001'/>]"
|
|
2239
|
+
"[<xsl:value-of select='0.000001'/>]"
|
|
2240
|
+
"[<xsl:value-of select='0.1 + 0.2'/>]"
|
|
2241
|
+
"[<xsl:value-of select='-7 div 2'/>]"
|
|
2242
|
+
"[<xsl:value-of select='2 - 3'/>]"
|
|
2243
|
+
"</xsl:template>",
|
|
2244
|
+
"<r/>")),
|
|
2245
|
+
"[10695.23][0.333333333333333][1000000][1000000.5]"
|
|
2246
|
+
"[9999999.9999][1234567890][1.2345678905e+09][1e+10]"
|
|
2247
|
+
"[1.23456789012346e+15][0.00001][1e-06][0.3][-3.5][-1]");
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
/* bug-166: Muenchian group output sorts packagereqs by
|
|
2251
|
+
* type-position (count of preceding siblings of the type-matching
|
|
2252
|
+
* child in an RTF order table) then by uppercased name. Distilled:
|
|
2253
|
+
* two-level xsl:sort with count(key)/current() keys. */
|
|
2254
|
+
TEST(XsltSort, TypeOrderThenNameKeys) {
|
|
2255
|
+
/* run() carries no exsl declaration — build the sheet. */
|
|
2256
|
+
std::string sheet = std::string("<xsl:stylesheet ") + KXSL +
|
|
2257
|
+
" xmlns:exsl='http://exslt.org/common' version='1.0'>"
|
|
2258
|
+
"<xsl:variable name='order'>"
|
|
2259
|
+
"<mandatory/><default/><optional/>"
|
|
2260
|
+
"</xsl:variable>"
|
|
2261
|
+
"<xsl:variable name='lc'>abcdefghijklmnopqrstuvwxyz</xsl:variable>"
|
|
2262
|
+
"<xsl:variable name='uc'>ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>"
|
|
2263
|
+
"<xsl:template match='/'>"
|
|
2264
|
+
"<xsl:for-each select='//req'>"
|
|
2265
|
+
"<xsl:sort select='count(exsl:node-set($order)/*"
|
|
2266
|
+
"[name() = current()/@type]/preceding-sibling::*)'"
|
|
2267
|
+
" data-type='number'/>"
|
|
2268
|
+
"<xsl:sort select='translate(text(),$lc,$uc)'/>"
|
|
2269
|
+
"[<xsl:value-of select='.'/>]"
|
|
2270
|
+
"</xsl:for-each>"
|
|
2271
|
+
"</xsl:template></xsl:stylesheet>";
|
|
2272
|
+
LeptrisXslt x = leptris_xslt_parse(sheet.c_str(), sheet.size());
|
|
2273
|
+
ASSERT_NE(x, nullptr);
|
|
2274
|
+
const char* xml =
|
|
2275
|
+
"<r><req type='default'>pirut</req>"
|
|
2276
|
+
"<req type='optional'>cacti</req>"
|
|
2277
|
+
"<req type='default'>authconfig</req>"
|
|
2278
|
+
"<req type='mandatory'>core</req></r>";
|
|
2279
|
+
LeptrisDocument d = leptris_parse_string(xml, strlen(xml), nullptr);
|
|
2280
|
+
ASSERT_NE(d, nullptr);
|
|
2281
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
2282
|
+
ASSERT_NE(out, nullptr);
|
|
2283
|
+
EXPECT_EQ(body(std::string(out)), "[core][authconfig][pirut][cacti]");
|
|
2284
|
+
leptris_free_string(out);
|
|
2285
|
+
leptris_document_free(d);
|
|
2286
|
+
leptris_xslt_free(x);
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
/* bug-100: libxslt's own test extension element — <test/> in the
|
|
2290
|
+
* http://xmlsoft.org/XSLT/ namespace (an extension-element-prefix)
|
|
2291
|
+
* executes instead of serializing: it emits its marker comment. */
|
|
2292
|
+
TEST(XsltExslt, LibxsltTestExtensionElement) {
|
|
2293
|
+
const char* sheet =
|
|
2294
|
+
"<?xml version='1.0'?>"
|
|
2295
|
+
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
|
|
2296
|
+
" xmlns='http://xmlsoft.org/XSLT/'"
|
|
2297
|
+
" extension-element-prefixes='#default' version='1.0'>"
|
|
2298
|
+
"<xsl:template match='/'><test/></xsl:template>"
|
|
2299
|
+
"</xsl:stylesheet>";
|
|
2300
|
+
LeptrisXslt x = leptris_xslt_parse(sheet, strlen(sheet));
|
|
2301
|
+
ASSERT_NE(x, nullptr);
|
|
2302
|
+
LeptrisDocument d = leptris_parse_string("<doc/>", strlen("<doc/>"),
|
|
2303
|
+
nullptr);
|
|
2304
|
+
ASSERT_NE(d, nullptr);
|
|
2305
|
+
char* out = leptris_xslt_apply_string(x, d);
|
|
2306
|
+
ASSERT_NE(out, nullptr);
|
|
2307
|
+
EXPECT_EQ(body(std::string(out)),
|
|
2308
|
+
"<!--libxslt:test element test worked-->");
|
|
2309
|
+
leptris_free_string(out);
|
|
2310
|
+
leptris_document_free(d);
|
|
2311
|
+
leptris_xslt_free(x);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
/* bug-130: the LAST delta — a literal result element from an
|
|
2315
|
+
* imported module (own namespace scope: no default ns) serialized
|
|
2316
|
+
* inside a default-namespaced ancestor must reset the default with
|
|
2317
|
+
* xmlns="" (libxml2 xmlsave rule). Runs the suite fixture with the
|
|
2318
|
+
* suite dir as CWD so the xsl:import hrefs resolve. */
|
|
2319
|
+
TEST(XsltImport, NoNsElementUnderDefaultNsAncestorResets) {
|
|
2320
|
+
#ifdef _WIN32
|
|
2321
|
+
GTEST_SKIP() << "POSIX chdir fixture (the suite runner covers Win32)";
|
|
2322
|
+
#else
|
|
2323
|
+
std::string here = __FILE__;
|
|
2324
|
+
std::string dir = here.substr(0, here.rfind("/xpath/")) +
|
|
2325
|
+
"/xslt/libxslt_suite_general";
|
|
2326
|
+
FILE* fx = fopen((dir + "/bug-130.xsl").c_str(), "rb");
|
|
2327
|
+
FILE* fm = fopen((dir + "/bug-130.xml").c_str(), "rb");
|
|
2328
|
+
FILE* fo = fopen((dir + "/bug-130.out").c_str(), "rb");
|
|
2329
|
+
ASSERT_TRUE(fx && fm && fo);
|
|
2330
|
+
std::string x, m, w;
|
|
2331
|
+
char b[8192];
|
|
2332
|
+
size_t n;
|
|
2333
|
+
while ((n = fread(b, 1, sizeof b, fx)) > 0) x.append(b, n);
|
|
2334
|
+
while ((n = fread(b, 1, sizeof b, fm)) > 0) m.append(b, n);
|
|
2335
|
+
while ((n = fread(b, 1, sizeof b, fo)) > 0) w.append(b, n);
|
|
2336
|
+
fclose(fx); fclose(fm); fclose(fo);
|
|
2337
|
+
if (w.size() && w.back() == '\n') w.pop_back();
|
|
2338
|
+
char saved_cwd[4096];
|
|
2339
|
+
ASSERT_NE(getcwd(saved_cwd, sizeof saved_cwd), nullptr);
|
|
2340
|
+
ASSERT_EQ(chdir(dir.c_str()), 0);
|
|
2341
|
+
LeptrisXslt s = leptris_xslt_parse(x.c_str(), x.size());
|
|
2342
|
+
if (s) {
|
|
2343
|
+
LeptrisDocument d = leptris_parse_string(m.c_str(), m.size(),
|
|
2344
|
+
nullptr);
|
|
2345
|
+
ASSERT_NE(d, nullptr);
|
|
2346
|
+
char* out = leptris_xslt_apply_string(s, d);
|
|
2347
|
+
ASSERT_NE(out, nullptr);
|
|
2348
|
+
EXPECT_EQ(std::string(out), w);
|
|
2349
|
+
leptris_free_string(out);
|
|
2350
|
+
leptris_document_free(d);
|
|
2351
|
+
leptris_xslt_free(s);
|
|
2352
|
+
}
|
|
2353
|
+
ASSERT_EQ(chdir(saved_cwd), 0);
|
|
2354
|
+
if (!s) FAIL() << "stylesheet failed to compile";
|
|
2355
|
+
#endif
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
/* XSLT 3.0 baseline survey: what the current engine does with the
|
|
2359
|
+
* 3.0 feature shapes (if/then/else, for-return, sequences). Pinned
|
|
2360
|
+
* BEFORE the 3.0 work so each feature landing shows here. */
|
|
2361
|
+
TEST(Xslt30, IfThenElse) {
|
|
2362
|
+
EXPECT_EQ(body(run(
|
|
2363
|
+
"<xsl:template match='/'>"
|
|
2364
|
+
"[<xsl:value-of select='if (count(//i) > 2) then "
|
|
2365
|
+
"\"many\" else \"few\"'/>]"
|
|
2366
|
+
"</xsl:template>",
|
|
2367
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2368
|
+
"[many]");
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
/* XSLT 3.0 xsl:value-of over an item sequence: the display form is
|
|
2372
|
+
* the members space-joined (3.0 default separator " "), not the
|
|
2373
|
+
* first member (the 1.0 nodeset rule). */
|
|
2374
|
+
TEST(Xslt30, SequenceValueOf) {
|
|
2375
|
+
EXPECT_EQ(body(run(
|
|
2376
|
+
"<xsl:template match='/'>"
|
|
2377
|
+
"[<xsl:value-of select='for $x in //i return string($x)'/>]"
|
|
2378
|
+
"</xsl:template>",
|
|
2379
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2380
|
+
"[a b c]");
|
|
2381
|
+
EXPECT_EQ(body(run(
|
|
2382
|
+
"<xsl:template match='/'>"
|
|
2383
|
+
"[<xsl:value-of select='1 to 3'/>]"
|
|
2384
|
+
"</xsl:template>",
|
|
2385
|
+
"<r/>")),
|
|
2386
|
+
"[1 2 3]");
|
|
2387
|
+
/* A plain nodeset is NOT a sequence — first member still wins. */
|
|
2388
|
+
EXPECT_EQ(body(run(
|
|
2389
|
+
"<xsl:template match='/'>"
|
|
2390
|
+
"[<xsl:value-of select='//i'/>]"
|
|
2391
|
+
"</xsl:template>",
|
|
2392
|
+
"<r><i>a</i><i>b</i></r>")),
|
|
2393
|
+
"[a]");
|
|
2394
|
+
/* A version='3.0' stylesheet: value-of joins EVERY multi-item
|
|
2395
|
+
* result (ground truth: Saxon-HE 12.7 prints [a b c]). */
|
|
2396
|
+
EXPECT_EQ(body(run30(
|
|
2397
|
+
"<xsl:template match='/'>"
|
|
2398
|
+
"[<xsl:value-of select='//i'/>]"
|
|
2399
|
+
"</xsl:template>",
|
|
2400
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2401
|
+
"[a b c]");
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
/* XSLT 3.0 xsl:iterate (§12.5): sequential mapping with param
|
|
2405
|
+
* chaining — xsl:param declares iteration state (initial values
|
|
2406
|
+
* evaluated once before the loop), xsl:next-iteration rebinds it for
|
|
2407
|
+
* the next pass and abandons the rest of the body, xsl:break ends
|
|
2408
|
+
* the loop. Context item/position/size match for-each. */
|
|
2409
|
+
TEST(Xslt30, Iterate) {
|
|
2410
|
+
/* Without params: plain mapping, like for-each. */
|
|
2411
|
+
EXPECT_EQ(body(run(
|
|
2412
|
+
"<xsl:template match='/'>"
|
|
2413
|
+
"<xsl:iterate select='//i'>"
|
|
2414
|
+
"<xsl:value-of select='.'/>"
|
|
2415
|
+
"</xsl:iterate>"
|
|
2416
|
+
"</xsl:template>",
|
|
2417
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2418
|
+
"abc");
|
|
2419
|
+
/* Param chaining: running sum, printed before each update.
|
|
2420
|
+
* Ground truth: Saxon-HE 12.7 prints 013. */
|
|
2421
|
+
EXPECT_EQ(body(run(
|
|
2422
|
+
"<xsl:template match='/'>"
|
|
2423
|
+
"<xsl:iterate select='//i'>"
|
|
2424
|
+
"<xsl:param name='sum' select='0'/>"
|
|
2425
|
+
"<xsl:value-of select='$sum'/>"
|
|
2426
|
+
"<xsl:next-iteration>"
|
|
2427
|
+
"<xsl:with-param name='sum' select='$sum + number(.)'/>"
|
|
2428
|
+
"</xsl:next-iteration>"
|
|
2429
|
+
"</xsl:iterate>"
|
|
2430
|
+
"</xsl:template>",
|
|
2431
|
+
"<r><i>1</i><i>2</i><i>4</i></r>")),
|
|
2432
|
+
"013");
|
|
2433
|
+
/* xsl:break: abandon the loop mid-pass; later items never run.
|
|
2434
|
+
* Saxon XTSE3120 requires break as the last loop instruction —
|
|
2435
|
+
* the legal early-exit shape wraps it in a trailing choose. */
|
|
2436
|
+
EXPECT_EQ(body(run(
|
|
2437
|
+
"<xsl:template match='/'>"
|
|
2438
|
+
"<xsl:iterate select='//i'>"
|
|
2439
|
+
"<xsl:choose>"
|
|
2440
|
+
"<xsl:when test='. = "b"'>"
|
|
2441
|
+
"<xsl:break/>"
|
|
2442
|
+
"</xsl:when>"
|
|
2443
|
+
"<xsl:otherwise>"
|
|
2444
|
+
"<xsl:value-of select='.'/>"
|
|
2445
|
+
"</xsl:otherwise>"
|
|
2446
|
+
"</xsl:choose>"
|
|
2447
|
+
"</xsl:iterate>"
|
|
2448
|
+
"</xsl:template>",
|
|
2449
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2450
|
+
"a");
|
|
2451
|
+
/* position() reflects the iterate position. */
|
|
2452
|
+
EXPECT_EQ(body(run(
|
|
2453
|
+
"<xsl:template match='/'>"
|
|
2454
|
+
"<xsl:iterate select='//i'>"
|
|
2455
|
+
"<xsl:value-of select='position()'/>"
|
|
2456
|
+
"</xsl:iterate>"
|
|
2457
|
+
"</xsl:template>",
|
|
2458
|
+
"<r><i>a</i><i>b</i><i>c</i></r>")),
|
|
2459
|
+
"123");
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
/* XSLT 3.0 xsl:for-each-group (§14): group-by (string key per item,
|
|
2463
|
+
* groups in first-key-appearance order) and group-starting-with
|
|
2464
|
+
* (pattern match starts a new group). current-group() and
|
|
2465
|
+
* current-grouping-key() expose the group in flight; the context
|
|
2466
|
+
* item is the group's first member, position()/last() run over the
|
|
2467
|
+
* sequence of groups. */
|
|
2468
|
+
TEST(Xslt30, ForEachGroup) {
|
|
2469
|
+
/* group-by: key + member count per group. */
|
|
2470
|
+
EXPECT_EQ(body(run30(
|
|
2471
|
+
"<xsl:template match='/'>"
|
|
2472
|
+
"<xsl:for-each-group select='//item' group-by='@cat'>"
|
|
2473
|
+
"[<xsl:value-of select='current-grouping-key()'/>:"
|
|
2474
|
+
"<xsl:value-of select='count(current-group())'/>]"
|
|
2475
|
+
"</xsl:for-each-group>"
|
|
2476
|
+
"</xsl:template>",
|
|
2477
|
+
"<r><item cat='a'/><item cat='b'/><item cat='a'/></r>")),
|
|
2478
|
+
"[a:2][b:1]");
|
|
2479
|
+
/* group-by: iterate the members via current-group(). */
|
|
2480
|
+
EXPECT_EQ(body(run30(
|
|
2481
|
+
"<xsl:template match='/'>"
|
|
2482
|
+
"<xsl:for-each-group select='//x' group-by='@c'>"
|
|
2483
|
+
"<xsl:for-each select='current-group()'>"
|
|
2484
|
+
"<xsl:value-of select='@n'/>"
|
|
2485
|
+
"</xsl:for-each>"
|
|
2486
|
+
"</xsl:for-each-group>"
|
|
2487
|
+
"</xsl:template>",
|
|
2488
|
+
"<r><x n='1' c='a'/><x n='2' c='b'/><x n='3' c='a'/></r>")),
|
|
2489
|
+
"132");
|
|
2490
|
+
/* group-starting-with: a match starts a new group; leading
|
|
2491
|
+
* non-matching items form their own first group. */
|
|
2492
|
+
EXPECT_EQ(body(run30(
|
|
2493
|
+
"<xsl:template match='/'>"
|
|
2494
|
+
"<xsl:for-each-group select='/*/*' group-starting-with='h'>"
|
|
2495
|
+
"<xsl:value-of select='count(current-group())'/>"
|
|
2496
|
+
"</xsl:for-each-group>"
|
|
2497
|
+
"</xsl:template>",
|
|
2498
|
+
"<doc><p/><h/><p/><p/><h/><p/></doc>")),
|
|
2499
|
+
"132");
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
/* XSLT 3.0 xsl:for-each-group variants (§14): group-adjacent (an
|
|
2503
|
+
* adjacency-key value change starts a new group) and
|
|
2504
|
+
* group-ending-with (a pattern match ENDS the group; trailing
|
|
2505
|
+
* non-matches form the final group). Ground truth: Saxon-HE 12.7. */
|
|
2506
|
+
TEST(Xslt30, ForEachGroupVariants) {
|
|
2507
|
+
/* group-adjacent: only ADJACENT equal keys group. */
|
|
2508
|
+
EXPECT_EQ(body(run30(
|
|
2509
|
+
"<xsl:template match='/'>"
|
|
2510
|
+
"<xsl:for-each-group select='/*/*' group-adjacent='@t'>"
|
|
2511
|
+
"[<xsl:value-of select='count(current-group())'/>]"
|
|
2512
|
+
"</xsl:for-each-group>"
|
|
2513
|
+
"</xsl:template>",
|
|
2514
|
+
"<d><x t='a'/><y t='a'/><z t='b'/><w t='a'/></d>")),
|
|
2515
|
+
"[2][1][1]");
|
|
2516
|
+
/* group-adjacent: grouping key rides along. */
|
|
2517
|
+
EXPECT_EQ(body(run30(
|
|
2518
|
+
"<xsl:template match='/'>"
|
|
2519
|
+
"<xsl:for-each-group select='/*/*' group-adjacent='@t'>"
|
|
2520
|
+
"<xsl:value-of select='current-grouping-key()'/>"
|
|
2521
|
+
"</xsl:for-each-group>"
|
|
2522
|
+
"</xsl:template>",
|
|
2523
|
+
"<d><x t='a'/><y t='a'/><z t='b'/><w t='a'/></d>")),
|
|
2524
|
+
"aba");
|
|
2525
|
+
/* group-ending-with: the match closes its group; items after the
|
|
2526
|
+
* last match form the final group. */
|
|
2527
|
+
EXPECT_EQ(body(run30(
|
|
2528
|
+
"<xsl:template match='/'>"
|
|
2529
|
+
"<xsl:for-each-group select='/*/*' group-ending-with='e'>"
|
|
2530
|
+
"[<xsl:value-of select='count(current-group())'/>]"
|
|
2531
|
+
"</xsl:for-each-group>"
|
|
2532
|
+
"</xsl:template>",
|
|
2533
|
+
"<d><a/><b/><e/><c/><e/><f/><g/></d>")),
|
|
2534
|
+
"[3][2][2]");
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
/* XSLT 3.0 xsl:on-empty (§26.4): a child of a literal result
|
|
2538
|
+
* element; when the element's content comes back empty, the
|
|
2539
|
+
* on-empty content is evaluated into it instead. Ground truth:
|
|
2540
|
+
* Saxon-HE 12.7. */
|
|
2541
|
+
TEST(Xslt30, OnEmpty) {
|
|
2542
|
+
/* Empty content: on-empty fires. */
|
|
2543
|
+
EXPECT_EQ(body(run30(
|
|
2544
|
+
"<xsl:template match='/'>"
|
|
2545
|
+
"<a><xsl:value-of select='//missing'/>"
|
|
2546
|
+
"<xsl:on-empty>EMPTY</xsl:on-empty></a>"
|
|
2547
|
+
"</xsl:template>",
|
|
2548
|
+
"<r/>")),
|
|
2549
|
+
"<a>EMPTY</a>");
|
|
2550
|
+
/* Non-empty content: on-empty never runs. */
|
|
2551
|
+
EXPECT_EQ(body(run30(
|
|
2552
|
+
"<xsl:template match='/'>"
|
|
2553
|
+
"<a><xsl:value-of select='//i[1]'/>"
|
|
2554
|
+
"<xsl:on-empty>EMPTY</xsl:on-empty></a>"
|
|
2555
|
+
"</xsl:template>",
|
|
2556
|
+
"<r><i>x</i></r>")),
|
|
2557
|
+
"<a>x</a>");
|
|
2558
|
+
/* Element child also counts as content. */
|
|
2559
|
+
EXPECT_EQ(body(run30(
|
|
2560
|
+
"<xsl:template match='/'>"
|
|
2561
|
+
"<a><xsl:if test='1=1'><b/></xsl:if>"
|
|
2562
|
+
"<xsl:on-empty>EMPTY</xsl:on-empty></a>"
|
|
2563
|
+
"</xsl:template>",
|
|
2564
|
+
"<r/>")),
|
|
2565
|
+
"<a><b/></a>");
|
|
2566
|
+
/* on-empty content can be instructions, not just text. */
|
|
2567
|
+
EXPECT_EQ(body(run30(
|
|
2568
|
+
"<xsl:template match='/'>"
|
|
2569
|
+
"<a><xsl:value-of select='//missing'/>"
|
|
2570
|
+
"<xsl:on-empty><c><xsl:value-of "
|
|
2571
|
+
"select=\"'z'\"/></c></xsl:on-empty></a>"
|
|
2572
|
+
"</xsl:template>",
|
|
2573
|
+
"<r/>")),
|
|
2574
|
+
"<a><c>z</c></a>");
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
/* XSLT 3.0 xsl:try/xsl:catch (§17): a dynamic error in the try body
|
|
2578
|
+
* runs the catch content with $err:description bound to the error
|
|
2579
|
+
* message; no error means the catch never runs. error($msg) raises
|
|
2580
|
+
* one from XPath (Saxon-HE 12.7 shape: description carried over). */
|
|
2581
|
+
TEST(Xslt30, TryCatch) {
|
|
2582
|
+
EXPECT_EQ(body(run30(
|
|
2583
|
+
"<xsl:template match='/'>"
|
|
2584
|
+
"[<xsl:try>"
|
|
2585
|
+
"<xsl:value-of select='error(\"boom\")'/>"
|
|
2586
|
+
"<xsl:catch>caught:<xsl:value-of "
|
|
2587
|
+
"select=\"$err:description\"/></xsl:catch>"
|
|
2588
|
+
"</xsl:try>]"
|
|
2589
|
+
"</xsl:template>",
|
|
2590
|
+
"<r/>")),
|
|
2591
|
+
"[caught:boom]");
|
|
2592
|
+
/* No error: catch never runs. */
|
|
2593
|
+
EXPECT_EQ(body(run30(
|
|
2594
|
+
"<xsl:template match='/'>"
|
|
2595
|
+
"[<xsl:try>ok<xsl:catch>nope</xsl:catch></xsl:try>]"
|
|
2596
|
+
"</xsl:template>",
|
|
2597
|
+
"<r/>")),
|
|
2598
|
+
"[ok]");
|
|
2599
|
+
/* Output before the failing instruction stays. */
|
|
2600
|
+
EXPECT_EQ(body(run30(
|
|
2601
|
+
"<xsl:template match='/'>"
|
|
2602
|
+
"<xsl:try>"
|
|
2603
|
+
"a<xsl:value-of select='error(\"x\")'/>b"
|
|
2604
|
+
"<xsl:catch>!</xsl:catch>"
|
|
2605
|
+
"</xsl:try>"
|
|
2606
|
+
"</xsl:template>",
|
|
2607
|
+
"<r/>")),
|
|
2608
|
+
"a!");
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
/* XSLT 3.0 xsl:analyze-string (§18): regex-scan the selected string;
|
|
2612
|
+
* matching-substring runs with "." = the matched substring and
|
|
2613
|
+
* regex-group(n) reading captures; non-matching-substring covers the
|
|
2614
|
+
* gaps. Ground truth: Saxon-HE 12.7. MSVC builds no-op the regex
|
|
2615
|
+
* engine (documented EXSLT-regexp limitation) — gated off there. */
|
|
2616
|
+
TEST(Xslt30, AnalyzeString) {
|
|
2617
|
+
#ifndef _WIN32
|
|
2618
|
+
EXPECT_EQ(body(run30(
|
|
2619
|
+
"<xsl:template match='/'>"
|
|
2620
|
+
"<xsl:variable name='s' select=\"'ab12cd345ef'\"/>"
|
|
2621
|
+
"<xsl:analyze-string select='$s' regex='[0-9]+'>"
|
|
2622
|
+
"<xsl:matching-substring>"
|
|
2623
|
+
"[<xsl:value-of select='.'/>]"
|
|
2624
|
+
"</xsl:matching-substring>"
|
|
2625
|
+
"<xsl:non-matching-substring>"
|
|
2626
|
+
"{<xsl:value-of select='.'/>}"
|
|
2627
|
+
"</xsl:non-matching-substring>"
|
|
2628
|
+
"</xsl:analyze-string>"
|
|
2629
|
+
"</xsl:template>",
|
|
2630
|
+
"<r/>")),
|
|
2631
|
+
"{ab}[12]{cd}[345]{ef}");
|
|
2632
|
+
/* Capture groups via regex-group(n). */
|
|
2633
|
+
EXPECT_EQ(body(run30(
|
|
2634
|
+
"<xsl:template match='/'>"
|
|
2635
|
+
"<xsl:analyze-string select=\"'k1:v1, k2:v2'\" "
|
|
2636
|
+
"regex='([a-z0-9]+):([a-z0-9]+)'>"
|
|
2637
|
+
"<xsl:matching-substring>"
|
|
2638
|
+
"[<xsl:value-of select='regex-group(1)'/>="
|
|
2639
|
+
"<xsl:value-of select='regex-group(2)'/>]"
|
|
2640
|
+
"</xsl:matching-substring>"
|
|
2641
|
+
"</xsl:analyze-string>"
|
|
2642
|
+
"</xsl:template>",
|
|
2643
|
+
"<r/>")),
|
|
2644
|
+
"[k1=v1][k2=v2]");
|
|
2645
|
+
#else
|
|
2646
|
+
GTEST_SKIP() << "no POSIX regex engine on this platform";
|
|
2647
|
+
#endif
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
/* XSLT 3.0 text value templates (§10.4.2, expand-text="yes"):
|
|
2651
|
+
* {expr} in literal TEXT expands — including inside xsl:text
|
|
2652
|
+
* (ground truth: Saxon-HE 12.7 expands there too); {{ and }} are
|
|
2653
|
+
* literal braces. */
|
|
2654
|
+
TEST(Xslt30, TextValueTemplates) {
|
|
2655
|
+
/* Bare template text in the template body. */
|
|
2656
|
+
EXPECT_EQ(body(run30(
|
|
2657
|
+
"<xsl:template match='/'>"
|
|
2658
|
+
"1 + 1 = {1 + 1}"
|
|
2659
|
+
"</xsl:template>",
|
|
2660
|
+
"<r/>")),
|
|
2661
|
+
"1 + 1 = 2");
|
|
2662
|
+
/* Inside a literal result element, with node context. */
|
|
2663
|
+
EXPECT_EQ(body(run30(
|
|
2664
|
+
"<xsl:template match='/r'>"
|
|
2665
|
+
"<p>{count(//i)} items, first={string(//i[1])}, "
|
|
2666
|
+
"brace={{literal}}</p>"
|
|
2667
|
+
"</xsl:template>",
|
|
2668
|
+
"<r><i>a</i><i>b</i></r>")),
|
|
2669
|
+
"<p>2 items, first=a, brace={literal}</p>");
|
|
2670
|
+
/* xsl:text content is a text node too — expanded. */
|
|
2671
|
+
EXPECT_EQ(body(run30(
|
|
2672
|
+
"<xsl:template match='/'>"
|
|
2673
|
+
"<xsl:text>{1 + 1}</xsl:text>"
|
|
2674
|
+
"</xsl:template>",
|
|
2675
|
+
"<r/>")),
|
|
2676
|
+
"2");
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
/* XSLT 3.0 xsl:evaluate (§26): compile and run an expression taken
|
|
2680
|
+
* from a string at transform time. @xpath evaluates to a string;
|
|
2681
|
+
* the dynamic expression runs with the @context-item (the current
|
|
2682
|
+
* node via "."), or with an absent context when omitted (Saxon-HE
|
|
2683
|
+
* 12.7: absent context is the spec default). */
|
|
2684
|
+
TEST(Xslt30, Evaluate) {
|
|
2685
|
+
/* Expression from a variable, current node as context. */
|
|
2686
|
+
EXPECT_EQ(body(run30(
|
|
2687
|
+
"<xsl:template match='/'>"
|
|
2688
|
+
"<xsl:variable name='e' select=\"'count(//i)'\"/>"
|
|
2689
|
+
"[<xsl:evaluate xpath='$e' context-item='.'/>]"
|
|
2690
|
+
"</xsl:template>",
|
|
2691
|
+
"<r><i>a</i><i>b</i></r>")),
|
|
2692
|
+
"[2]");
|
|
2693
|
+
/* Literal expression string. */
|
|
2694
|
+
EXPECT_EQ(body(run30(
|
|
2695
|
+
"<xsl:template match='/'>"
|
|
2696
|
+
"[<xsl:evaluate xpath=\"'count(//i) + 1'\" context-item='.'/>]"
|
|
2697
|
+
"</xsl:template>",
|
|
2698
|
+
"<r><i>a</i><i>b</i></r>")),
|
|
2699
|
+
"[3]");
|
|
2700
|
+
/* context-item retargets: expression sees the chosen node. */
|
|
2701
|
+
EXPECT_EQ(body(run30(
|
|
2702
|
+
"<xsl:template match='/'>"
|
|
2703
|
+
"<xsl:evaluate xpath=\"'string(.)'\" context-item='//i[2]'/>"
|
|
2704
|
+
"</xsl:template>",
|
|
2705
|
+
"<r><i>a</i><i>b</i></r>")),
|
|
2706
|
+
"b");
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
/* Minimal bug-130 shape: xml method, default-ns root, no-ns child
|
|
2710
|
+
* via copy-of — the child must serialize with xmlns="". */
|
|
2711
|
+
TEST(XsltImport, NoNsChildUnderDefaultNsXmlMethod) {
|
|
2712
|
+
EXPECT_EQ(body(run(
|
|
2713
|
+
"<xsl:template match='/'>"
|
|
2714
|
+
"<html xmlns='urn:h'><body>"
|
|
2715
|
+
"<xsl:copy-of select='/r/d'/>"
|
|
2716
|
+
"</body></html></xsl:template>",
|
|
2717
|
+
"<r><d>text</d></r>")),
|
|
2718
|
+
"<html xmlns=\"urn:h\"><body><d xmlns=\"\">text</d></body></html>");
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
/* Same shape under method=html (bug-130's actual method); indent=no
|
|
2722
|
+
* adds no final newline. */
|
|
2723
|
+
TEST(XsltImport, NoNsChildUnderDefaultNsHtmlMethod) {
|
|
2724
|
+
EXPECT_EQ(body(run(
|
|
2725
|
+
"<xsl:output method='html' indent='no'/>"
|
|
2726
|
+
"<xsl:template match='/'>"
|
|
2727
|
+
"<html xmlns='urn:h'><body>"
|
|
2728
|
+
"<xsl:copy-of select='/r/d'/>"
|
|
2729
|
+
"</body></html></xsl:template>",
|
|
2730
|
+
"<r><d>text</d></r>")),
|
|
2731
|
+
"<html xmlns=\"urn:h\"><body><d xmlns=\"\">text</d></body></html>");
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
/* bug-90: cdata-section-elements wraps text children of listed
|
|
2735
|
+
* elements UNCONDITIONALLY (pears' &-free text wrapped like apples'),
|
|
2736
|
+
* and the doc-level layout comes from the built-in text rule's copied
|
|
2737
|
+
* source whitespace: verbatim "\n " separators around the top-level
|
|
2738
|
+
* element pairs, with ONE final newline after the last node. */
|
|
2739
|
+
TEST(XsltCdata, CdataSectionElementsAndDocLevelWs) {
|
|
2740
|
+
EXPECT_EQ(body(run(
|
|
2741
|
+
"<xsl:output method='xml' cdata-section-elements='nf1' indent='yes'/>"
|
|
2742
|
+
"<xsl:template match='fs/f'>"
|
|
2743
|
+
"<nf1 type='{@t}'>\n The site is at\n "
|
|
2744
|
+
"<xsl:value-of select='./s'/>\n </nf1>"
|
|
2745
|
+
"<nf2 type='{@t}'>\n <xsl:value-of select='./s'/>\n </nf2>"
|
|
2746
|
+
"</xsl:template>",
|
|
2747
|
+
"<fs>\n <f t='apples'><s><![CDATA[http://a.com/x&y]]>\n"
|
|
2748
|
+
" </s></f>\n <f t='pears'><s>http://p.com/i&j</s></f>\n</fs>")),
|
|
2749
|
+
"\n <nf1 type=\"apples\"><![CDATA[\n The site is at\n"
|
|
2750
|
+
" http://a.com/x&y\n ]]></nf1>"
|
|
2751
|
+
"<nf2 type=\"apples\">http://a.com/x&y\n </nf2>\n"
|
|
2752
|
+
" <nf1 type=\"pears\"><![CDATA[\n The site is at\n"
|
|
2753
|
+
" http://p.com/i&j]]></nf1>"
|
|
2754
|
+
"<nf2 type=\"pears\">http://p.com/i&j</nf2>\n\n");
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
/* xsl:accumulator (XSLT 3.0 §18): per-document event-stream fold.
|
|
2758
|
+
* Ground truth captured from Saxon-HE 12.7. accumulator-before(N)
|
|
2759
|
+
* folds through N's own start event (start-phase rules of N fire);
|
|
2760
|
+
* accumulator-after(N) folds through N's end event (descendants plus
|
|
2761
|
+
* N's end-phase rules). Per event only the last matching rule of that
|
|
2762
|
+
* phase fires. */
|
|
2763
|
+
TEST(Xslt30, Accumulator) {
|
|
2764
|
+
/* Pure counter: before == after on a leaf, increments per item. */
|
|
2765
|
+
EXPECT_EQ(body(run30(
|
|
2766
|
+
"<xsl:mode use-accumulators='c'/>"
|
|
2767
|
+
"<xsl:accumulator name='c' initial-value='0'>"
|
|
2768
|
+
"<xsl:accumulator-rule match='i' select='$value + 1'/>"
|
|
2769
|
+
"</xsl:accumulator>"
|
|
2770
|
+
"<xsl:template match='/'>"
|
|
2771
|
+
"<xsl:for-each select='//i'>"
|
|
2772
|
+
"[<xsl:value-of select='position()'/>:b="
|
|
2773
|
+
"<xsl:value-of select=\"accumulator-before('c')\"/>:a="
|
|
2774
|
+
"<xsl:value-of select=\"accumulator-after('c')\"/>]"
|
|
2775
|
+
"</xsl:for-each>"
|
|
2776
|
+
"</xsl:template>",
|
|
2777
|
+
"<r><i/><i/><i/></r>")),
|
|
2778
|
+
"[1:b=1:a=1][2:b=2:a=2][3:b=3:a=3]");
|
|
2779
|
+
|
|
2780
|
+
/* Sum over @n: before(N) includes N's own contribution. */
|
|
2781
|
+
EXPECT_EQ(body(run30(
|
|
2782
|
+
"<xsl:mode use-accumulators='sum'/>"
|
|
2783
|
+
"<xsl:accumulator name='sum' initial-value='0'>"
|
|
2784
|
+
"<xsl:accumulator-rule match='item' select='$value + number(@n)'/>"
|
|
2785
|
+
"</xsl:accumulator>"
|
|
2786
|
+
"<xsl:template match='/'>"
|
|
2787
|
+
"<xsl:for-each select='//item'>"
|
|
2788
|
+
"[<xsl:value-of select='@n'/>:b="
|
|
2789
|
+
"<xsl:value-of select=\"accumulator-before('sum')\"/>:a="
|
|
2790
|
+
"<xsl:value-of select=\"accumulator-after('sum')\"/>]"
|
|
2791
|
+
"</xsl:for-each>"
|
|
2792
|
+
"</xsl:template>",
|
|
2793
|
+
"<r><item n='1'/><item n='2'/><item n='4'/></r>")),
|
|
2794
|
+
"[1:b=1:a=1][2:b=3:a=3][4:b=7:a=7]");
|
|
2795
|
+
|
|
2796
|
+
/* Two accumulators, phase='end' rule, nested containers: before/
|
|
2797
|
+
* after differ on containers, and end-phase sums land only after
|
|
2798
|
+
* the subtree completes. */
|
|
2799
|
+
EXPECT_EQ(body(run30(
|
|
2800
|
+
"<xsl:mode use-accumulators='s e'/>"
|
|
2801
|
+
"<xsl:accumulator name='s' initial-value='0'>"
|
|
2802
|
+
"<xsl:accumulator-rule match='g' select='$value + number(@n)'/>"
|
|
2803
|
+
"<xsl:accumulator-rule match='i' select='$value + 10'/>"
|
|
2804
|
+
"</xsl:accumulator>"
|
|
2805
|
+
"<xsl:accumulator name='e' initial-value='0'>"
|
|
2806
|
+
"<xsl:accumulator-rule match='g' phase='end' "
|
|
2807
|
+
"select='$value + number(@n)'/>"
|
|
2808
|
+
"</xsl:accumulator>"
|
|
2809
|
+
"<xsl:template match='/'>"
|
|
2810
|
+
"<xsl:text>doc b=</xsl:text>"
|
|
2811
|
+
"<xsl:value-of select=\"accumulator-before('s')\"/>"
|
|
2812
|
+
"<xsl:text> a=</xsl:text>"
|
|
2813
|
+
"<xsl:value-of select=\"accumulator-after('s')\"/>"
|
|
2814
|
+
"<xsl:text> eb=</xsl:text>"
|
|
2815
|
+
"<xsl:value-of select=\"accumulator-before('e')\"/>"
|
|
2816
|
+
"<xsl:text> ea=</xsl:text>"
|
|
2817
|
+
"<xsl:value-of select=\"accumulator-after('e')\"/>"
|
|
2818
|
+
"<xsl:apply-templates select='*'/>"
|
|
2819
|
+
"<xsl:text>;doc-end a=</xsl:text>"
|
|
2820
|
+
"<xsl:value-of select=\"accumulator-after('s')\"/>"
|
|
2821
|
+
"<xsl:text> ea=</xsl:text>"
|
|
2822
|
+
"<xsl:value-of select=\"accumulator-after('e')\"/>"
|
|
2823
|
+
"</xsl:template>"
|
|
2824
|
+
"<xsl:template match='r'>"
|
|
2825
|
+
"<xsl:text>;r b=</xsl:text>"
|
|
2826
|
+
"<xsl:value-of select=\"accumulator-before('s')\"/>"
|
|
2827
|
+
"<xsl:text> a=</xsl:text>"
|
|
2828
|
+
"<xsl:value-of select=\"accumulator-after('s')\"/>"
|
|
2829
|
+
"<xsl:text> eb=</xsl:text>"
|
|
2830
|
+
"<xsl:value-of select=\"accumulator-before('e')\"/>"
|
|
2831
|
+
"<xsl:text> ea=</xsl:text>"
|
|
2832
|
+
"<xsl:value-of select=\"accumulator-after('e')\"/>"
|
|
2833
|
+
"<xsl:apply-templates select='*'/>"
|
|
2834
|
+
"</xsl:template>"
|
|
2835
|
+
"<xsl:template match='g'>"
|
|
2836
|
+
"<xsl:text>;g</xsl:text><xsl:value-of select='@n'/>"
|
|
2837
|
+
"<xsl:text> b=</xsl:text>"
|
|
2838
|
+
"<xsl:value-of select=\"accumulator-before('s')\"/>"
|
|
2839
|
+
"<xsl:text> a=</xsl:text>"
|
|
2840
|
+
"<xsl:value-of select=\"accumulator-after('s')\"/>"
|
|
2841
|
+
"<xsl:text> eb=</xsl:text>"
|
|
2842
|
+
"<xsl:value-of select=\"accumulator-before('e')\"/>"
|
|
2843
|
+
"<xsl:text> ea=</xsl:text>"
|
|
2844
|
+
"<xsl:value-of select=\"accumulator-after('e')\"/>"
|
|
2845
|
+
"<xsl:apply-templates select='*'/>"
|
|
2846
|
+
"</xsl:template>"
|
|
2847
|
+
"<xsl:template match='i'>"
|
|
2848
|
+
"<xsl:text>;i b=</xsl:text>"
|
|
2849
|
+
"<xsl:value-of select=\"accumulator-before('s')\"/>"
|
|
2850
|
+
"<xsl:text> a=</xsl:text>"
|
|
2851
|
+
"<xsl:value-of select=\"accumulator-after('s')\"/>"
|
|
2852
|
+
"<xsl:text> eb=</xsl:text>"
|
|
2853
|
+
"<xsl:value-of select=\"accumulator-before('e')\"/>"
|
|
2854
|
+
"<xsl:text> ea=</xsl:text>"
|
|
2855
|
+
"<xsl:value-of select=\"accumulator-after('e')\"/>"
|
|
2856
|
+
"</xsl:template>",
|
|
2857
|
+
"<r><g n='1'><i/></g><g n='2'><i/></g></r>")),
|
|
2858
|
+
"doc b=0 a=23 eb=0 ea=3;r b=0 a=23 eb=0 ea=3;"
|
|
2859
|
+
"g1 b=1 a=11 eb=0 ea=1;i b=11 a=11 eb=0 ea=0;"
|
|
2860
|
+
"g2 b=13 a=23 eb=1 ea=3;i b=23 a=23 eb=1 ea=1;"
|
|
2861
|
+
"doc-end a=23 ea=3");
|
|
2862
|
+
|
|
2863
|
+
/* Applicability gate (§18.2.2): with no use-accumulators mode
|
|
2864
|
+
* declaration the accumulator is not applicable — Saxon raises
|
|
2865
|
+
* XTDE3362; the transform must not succeed. */
|
|
2866
|
+
EXPECT_EQ(body(run30(
|
|
2867
|
+
"<xsl:accumulator name='sum' initial-value='0'>"
|
|
2868
|
+
"<xsl:accumulator-rule match='item' select='$value + number(@n)'/>"
|
|
2869
|
+
"</xsl:accumulator>"
|
|
2870
|
+
"<xsl:template match='/'>"
|
|
2871
|
+
"[<xsl:value-of select=\"accumulator-before('sum')\"/>]"
|
|
2872
|
+
"</xsl:template>",
|
|
2873
|
+
"<r><item n='1'/></r>")),
|
|
2874
|
+
"(null)");
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
/* XPath 3.1 `let $x := E1, $y := E2 ... return B` (Saxon-HE 12.7
|
|
2878
|
+
* ground truth): bindings see EARLIER bindings; values are full
|
|
2879
|
+
* sequences; inner bindings shadow outer ones. */
|
|
2880
|
+
TEST(Xslt30, LetExpression) {
|
|
2881
|
+
/* Sequence value: sum over a bound node-set. */
|
|
2882
|
+
EXPECT_EQ(body(run30(
|
|
2883
|
+
"<xsl:template match='/'>"
|
|
2884
|
+
"[<xsl:value-of select='let $x := //item/@n return sum($x)'/>]"
|
|
2885
|
+
"</xsl:template>",
|
|
2886
|
+
"<r><item n='1'>a</item><item n='2'>b</item></r>")),
|
|
2887
|
+
"[3]");
|
|
2888
|
+
/* Multiple bindings, comma-separated, each seeing the previous. */
|
|
2889
|
+
EXPECT_EQ(body(run30(
|
|
2890
|
+
"<xsl:template match='/'>"
|
|
2891
|
+
"[<xsl:value-of select='let $p := position(), $q := 2 "
|
|
2892
|
+
"return $p + $q'/>]"
|
|
2893
|
+
"</xsl:template>",
|
|
2894
|
+
"<r/>")),
|
|
2895
|
+
"[3]");
|
|
2896
|
+
/* Shadowing: the inner binding wins inside its body. */
|
|
2897
|
+
EXPECT_EQ(body(run30(
|
|
2898
|
+
"<xsl:template match='/'>"
|
|
2899
|
+
"[<xsl:value-of select='let $x := 5 return "
|
|
2900
|
+
"let $x := $x + 1 return $x'/>]"
|
|
2901
|
+
"</xsl:template>",
|
|
2902
|
+
"<r/>")),
|
|
2903
|
+
"[6]");
|
|
2904
|
+
/* String binding feeding a function call. */
|
|
2905
|
+
EXPECT_EQ(body(run30(
|
|
2906
|
+
"<xsl:template match='/'>"
|
|
2907
|
+
"[<xsl:value-of select=\"let $s := string(//item[1]) return "
|
|
2908
|
+
"concat('[', $s, ']')\"/>]"
|
|
2909
|
+
"</xsl:template>",
|
|
2910
|
+
"<r><item n='1'>a</item><item n='2'>b</item></r>")),
|
|
2911
|
+
"[[a]]");
|
|
2912
|
+
/* Outer template variables remain visible inside the let body. */
|
|
2913
|
+
EXPECT_EQ(body(run30(
|
|
2914
|
+
"<xsl:template match='/'>"
|
|
2915
|
+
"<xsl:variable name='v' select='2'/>"
|
|
2916
|
+
"[<xsl:value-of select='let $x := 1 return $x + $v'/>]"
|
|
2917
|
+
"</xsl:template>",
|
|
2918
|
+
"<r/>")),
|
|
2919
|
+
"[3]");
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2922
|
+
/* XPath 3.0/3.1 `!` (simple map), `=>` (arrow), `||` (string
|
|
2923
|
+
* concat) — Saxon-HE 12.7 ground truth. `!` evaluates the right
|
|
2924
|
+
* side once per item with . = item and position()/last() = the
|
|
2925
|
+
* item's slot in the left sequence; `=>` passes the left side as
|
|
2926
|
+
* the FIRST argument; `||` stringifies and concatenates. */
|
|
2927
|
+
TEST(Xslt30, BangArrowConcat) {
|
|
2928
|
+
/* Simple map over nodes: one @n per item. */
|
|
2929
|
+
EXPECT_EQ(body(run30(
|
|
2930
|
+
"<xsl:template match='/'>"
|
|
2931
|
+
"[<xsl:value-of select='//item ! @n'/>]"
|
|
2932
|
+
"</xsl:template>",
|
|
2933
|
+
"<r><item n='1'>a</item><item n='2'>b</item></r>")),
|
|
2934
|
+
"[1 2]");
|
|
2935
|
+
/* Map over a range with a computed value. */
|
|
2936
|
+
EXPECT_EQ(body(run30(
|
|
2937
|
+
"<xsl:template match='/'>"
|
|
2938
|
+
"[<xsl:value-of select='(1 to 4) ! (. * 2)'/>]"
|
|
2939
|
+
"</xsl:template>",
|
|
2940
|
+
"<r/>")),
|
|
2941
|
+
"[2 4 6 8]");
|
|
2942
|
+
/* position() inside the mapped expression is per-item. */
|
|
2943
|
+
EXPECT_EQ(body(run30(
|
|
2944
|
+
"<xsl:template match='/'>"
|
|
2945
|
+
"[<xsl:value-of select=\"//item ! (position() || ':' || "
|
|
2946
|
+
"string(.))\"/>]"
|
|
2947
|
+
"</xsl:template>",
|
|
2948
|
+
"<r><item n='1'>a</item><item n='2'>b</item></r>")),
|
|
2949
|
+
"[1:a 2:b]");
|
|
2950
|
+
/* Arrow: the left side is the first argument. */
|
|
2951
|
+
EXPECT_EQ(body(run30(
|
|
2952
|
+
"<xsl:template match='/'>"
|
|
2953
|
+
"[<xsl:value-of select='//item/@n => sum()'/>]"
|
|
2954
|
+
"</xsl:template>",
|
|
2955
|
+
"<r><item n='1'/><item n='2'/></r>")),
|
|
2956
|
+
"[3]");
|
|
2957
|
+
EXPECT_EQ(body(run30(
|
|
2958
|
+
"<xsl:template match='/'>"
|
|
2959
|
+
"[<xsl:value-of select=\"'b' => concat('a')\"/>]"
|
|
2960
|
+
"</xsl:template>",
|
|
2961
|
+
"<r/>")),
|
|
2962
|
+
"[ba]");
|
|
2963
|
+
/* Arrow binds tighter than addition. */
|
|
2964
|
+
EXPECT_EQ(body(run30(
|
|
2965
|
+
"<xsl:template match='/'>"
|
|
2966
|
+
"[<xsl:value-of select='//item/@n => sum() + 1'/>]"
|
|
2967
|
+
"</xsl:template>",
|
|
2968
|
+
"<r><item n='1'/><item n='2'/></r>")),
|
|
2969
|
+
"[4]");
|
|
2970
|
+
/* String concatenation chains. */
|
|
2971
|
+
EXPECT_EQ(body(run30(
|
|
2972
|
+
"<xsl:template match='/'>"
|
|
2973
|
+
"[<xsl:value-of select=\"'x' || 'y' || 'z'\"/>]"
|
|
2974
|
+
"</xsl:template>",
|
|
2975
|
+
"<r/>")),
|
|
2976
|
+
"[xyz]");
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
/* xsl:try/xsl:catch (§17) through value-of/@select — error() IS
|
|
2980
|
+
* catchable in the canonical form (issue #669's repro had the
|
|
2981
|
+
* catch as a SIBLING of try, which Saxon rejects at compile
|
|
2982
|
+
* time). Our error($msg) takes the description as the first
|
|
2983
|
+
* argument (documented pragmatic arity). */
|
|
2984
|
+
TEST(Xslt30, TryCatchErrorVariants) {
|
|
2985
|
+
EXPECT_EQ(body(run30(
|
|
2986
|
+
"<xsl:template match='/'><o>"
|
|
2987
|
+
"<xsl:try><xsl:value-of select=\"error('boom')\"/>"
|
|
2988
|
+
"<xsl:catch><caught>"
|
|
2989
|
+
"<xsl:value-of select='$err:description'/></caught>"
|
|
2990
|
+
"</xsl:catch></xsl:try>"
|
|
2991
|
+
"<xsl:try><xsl:value-of select=\"error(concat('b','oom'))\"/>"
|
|
2992
|
+
"<xsl:catch><c2>"
|
|
2993
|
+
"<xsl:value-of select='$err:description'/></c2>"
|
|
2994
|
+
"</xsl:catch></xsl:try>"
|
|
2995
|
+
"<xsl:variable name='m' select=\"'varmsg'\"/>"
|
|
2996
|
+
"<xsl:try><xsl:value-of select='error($m)'/>"
|
|
2997
|
+
"<xsl:catch><c3>"
|
|
2998
|
+
"<xsl:value-of select='$err:description'/></c3>"
|
|
2999
|
+
"</xsl:catch></xsl:try>"
|
|
3000
|
+
"</o></xsl:template>",
|
|
3001
|
+
"<r/>")),
|
|
3002
|
+
"<o><caught>boom</caught><c2>boom</c2><c3>varmsg</c3></o>");
|
|
3003
|
+
/* A misplaced xsl:catch (sibling of try, not a child) is a
|
|
3004
|
+
* compile error — Saxon: XTSE0010; never a silent NULL. */
|
|
3005
|
+
EXPECT_EQ(body(run30(
|
|
3006
|
+
"<xsl:template match='/'><o>"
|
|
3007
|
+
"<xsl:try><xsl:value-of select=\"error('boom')\"/></xsl:try>"
|
|
3008
|
+
"<xsl:catch><caught/></xsl:catch>"
|
|
3009
|
+
"</o></xsl:template>",
|
|
3010
|
+
"<r/>")),
|
|
3011
|
+
"(compile-failed)");
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
/* xsl:mode on-no-match (3.0 §6.7) — Saxon-HE 12.7 ground truth on
|
|
3015
|
+
* <r><g n="1"><i>x</i></g>tail</r> with match="g/@n" -> <hit/>.
|
|
3016
|
+
* The 3.0 DEFAULT is shallow-copy (copy the node, process its
|
|
3017
|
+
* children); 1.0 sheets keep the text-only-copy built-in. */
|
|
3018
|
+
TEST(Xslt30, ModeOnNoMatch) {
|
|
3019
|
+
const char* b30 =
|
|
3020
|
+
"<xsl:template match='g/@n'><hit/></xsl:template>"
|
|
3021
|
+
"<xsl:template match='/'><out>"
|
|
3022
|
+
"<xsl:apply-templates select='*'/></out></xsl:template>";
|
|
3023
|
+
const char* doc = "<r><g n='1'><i>x</i></g>tail</r>";
|
|
3024
|
+
/* Explicit deep-copy: subtree verbatim, no dispatch inside. */
|
|
3025
|
+
EXPECT_EQ(body(run30(
|
|
3026
|
+
(std::string("<xsl:mode on-no-match='deep-copy'/>") + b30).c_str(), doc)),
|
|
3027
|
+
"<out><r><g n=\"1\"><i>x</i></g>tail</r></out>");
|
|
3028
|
+
/* 3.0 default (no xsl:mode at all) = shallow-copy. */
|
|
3029
|
+
EXPECT_EQ(body(run30(
|
|
3030
|
+
(std::string(b30) + "<xsl:template match='never[x]'/>").c_str(), doc)),
|
|
3031
|
+
"<out><r><g><hit/><i>x</i></g>tail</r></out>");
|
|
3032
|
+
/* Explicit shallow-copy: copy the node, children dispatch. */
|
|
3033
|
+
EXPECT_EQ(body(run30(
|
|
3034
|
+
(std::string("<xsl:mode on-no-match='shallow-copy'/>") + b30).c_str(),
|
|
3035
|
+
doc)),
|
|
3036
|
+
"<out><r><g><hit/><i>x</i></g>tail</r></out>");
|
|
3037
|
+
/* shallow-skip: no copy; element/attribute children still
|
|
3038
|
+
* dispatch, text skipped. */
|
|
3039
|
+
EXPECT_EQ(body(run30(
|
|
3040
|
+
(std::string("<xsl:mode on-no-match='shallow-skip'/>") + b30).c_str(),
|
|
3041
|
+
doc)),
|
|
3042
|
+
"<out><hit/></out>");
|
|
3043
|
+
/* deep-skip: nothing at all. */
|
|
3044
|
+
EXPECT_EQ(body(run30(
|
|
3045
|
+
(std::string("<xsl:mode on-no-match='deep-skip'/>") + b30).c_str(), doc)),
|
|
3046
|
+
"<out/>");
|
|
3047
|
+
/* text-only-copy: the 1.0 built-in. */
|
|
3048
|
+
EXPECT_EQ(body(run30(
|
|
3049
|
+
(std::string("<xsl:mode on-no-match='text-only-copy'/>") + b30).c_str(),
|
|
3050
|
+
doc)),
|
|
3051
|
+
"<out>xtail</out>");
|
|
3052
|
+
/* fail: dynamic error, transform aborts. */
|
|
3053
|
+
EXPECT_EQ(body(run30(
|
|
3054
|
+
(std::string("<xsl:mode on-no-match='fail'/>") + b30).c_str(), doc)),
|
|
3055
|
+
"(null)");
|
|
3056
|
+
}
|
|
3057
|
+
|
|
3058
|
+
/* Issue #692 silent-wrong: XQuery-only syntax (try/catch
|
|
3059
|
+
* EXPRESSIONS, map constructors) in an XPath expression attribute
|
|
3060
|
+
* compiled on some brace shapes and evaluated to silent EMPTY
|
|
3061
|
+
* output. Saxon: XPST0003 - compile error. Expression attributes
|
|
3062
|
+
* are never AVTs; XPath has no braces. */
|
|
3063
|
+
TEST(Xslt30, FnSequences) {
|
|
3064
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/01). */
|
|
3065
|
+
EXPECT_EQ(body(run30(
|
|
3066
|
+
"<xsl:template match='/'>"
|
|
3067
|
+
"[<xsl:value-of select='exists(//i), empty(//i), "
|
|
3068
|
+
"exists(//nope), empty(//nope)'/>]"
|
|
3069
|
+
"[<xsl:value-of select='head((1 to 5))'/>]"
|
|
3070
|
+
"[<xsl:value-of select='tail((1 to 5))'/>]"
|
|
3071
|
+
"[<xsl:value-of select='reverse(1 to 4)'/>]"
|
|
3072
|
+
"[<xsl:value-of select='subsequence((10,20,30,40,50), 2, 2)'/>]"
|
|
3073
|
+
"[<xsl:value-of select='remove((1,2,3,4), 2)'/>]"
|
|
3074
|
+
"[<xsl:value-of select=\"insert-before((1,2,3), 2, 'x')\"/>]"
|
|
3075
|
+
"[<xsl:value-of select='index-of((10,20,30,20), 20)'/>]"
|
|
3076
|
+
"[<xsl:value-of select='distinct-values((1,2,2,3,1))'/>]"
|
|
3077
|
+
"[<xsl:value-of select='avg(1 to 4), min((3,1,2)), "
|
|
3078
|
+
"max((3,1,2))'/>]"
|
|
3079
|
+
"[<xsl:value-of select='unordered((1,2,3))'/>]"
|
|
3080
|
+
"</xsl:template>",
|
|
3081
|
+
"<r><i>a</i><i>b</i></r>")),
|
|
3082
|
+
"[true false false true][1][2 3 4 5][4 3 2 1][20 30]"
|
|
3083
|
+
"[1 3 4][1 x 2 3][2 4][1 2 3][2.5 1 3][1 2 3]");
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3086
|
+
TEST(Xslt30, FnMath) {
|
|
3087
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/03). */
|
|
3088
|
+
EXPECT_EQ(body(run30(
|
|
3089
|
+
"<xsl:template match='/' "
|
|
3090
|
+
"xmlns:math='http://www.w3.org/2005/xpath-functions/math'>"
|
|
3091
|
+
"[<xsl:value-of select='math:sqrt(9), math:pow(2,10), "
|
|
3092
|
+
"math:pi()'/>]"
|
|
3093
|
+
"[<xsl:value-of select='round(2.5), round-half-to-even(2.5), "
|
|
3094
|
+
"abs(-3)'/>]"
|
|
3095
|
+
"</xsl:template>",
|
|
3096
|
+
"<r/>")),
|
|
3097
|
+
"[3 1024 3.141592653589793][3 2 3]");
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
TEST(Xslt30, FnRegex) {
|
|
3101
|
+
#ifdef _WIN32
|
|
3102
|
+
GTEST_SKIP() << "POSIX regex engine unavailable on MSVC (issue "
|
|
3103
|
+
"#686 family) — functions raise loudly there";
|
|
3104
|
+
#else
|
|
3105
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/02). */
|
|
3106
|
+
EXPECT_EQ(body(run30(
|
|
3107
|
+
"<xsl:template match='/'>"
|
|
3108
|
+
"[<xsl:value-of select=\"matches('hello world', 'wor.d'), "
|
|
3109
|
+
"matches('X', 'x'), matches('X', 'x', 'i')\"/>]"
|
|
3110
|
+
"[<xsl:value-of select=\"replace('a1b22c', '\\d+', '#')\"/>]"
|
|
3111
|
+
"[<xsl:value-of select=\"replace('john smith', '(\\w+) "
|
|
3112
|
+
"(\\w+)', '$2 $1')\"/>]"
|
|
3113
|
+
"[<xsl:value-of select=\"tokenize('a,b,,c', ',')\"/>]"
|
|
3114
|
+
"[<xsl:value-of select=\"tokenize(' one two three ', "
|
|
3115
|
+
"'\\s+')\"/>]"
|
|
3116
|
+
"</xsl:template>",
|
|
3117
|
+
"<r/>")),
|
|
3118
|
+
"[true false true][a#b#c][smith john][a b c][ one two three ]");
|
|
3119
|
+
#endif
|
|
3120
|
+
}
|
|
3121
|
+
|
|
3122
|
+
TEST(Xslt30, SequenceAndPerformSort) {
|
|
3123
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/09): atomic
|
|
3124
|
+
* sequences serialize space-joined; node sequences copy in
|
|
3125
|
+
* (sorted) order. */
|
|
3126
|
+
EXPECT_EQ(body(run30(
|
|
3127
|
+
"<xsl:template match='/'><o>"
|
|
3128
|
+
"<seq><xsl:sequence select=\"'a','b'\"/></seq>"
|
|
3129
|
+
"<ps><xsl:perform-sort select='(3,1,2)'>"
|
|
3130
|
+
"<xsl:sort data-type='number'/></xsl:perform-sort></ps>"
|
|
3131
|
+
"<ps2><xsl:perform-sort select='//i'>"
|
|
3132
|
+
"<xsl:sort select='@n' data-type='number' order='descending'/>"
|
|
3133
|
+
"</xsl:perform-sort></ps2>"
|
|
3134
|
+
"</o></xsl:template>",
|
|
3135
|
+
"<r><i n='2'>b</i><i n='1'>a</i><i n='3'>c</i></r>")),
|
|
3136
|
+
"<o><seq>a b</seq><ps>1 2 3</ps>"
|
|
3137
|
+
"<ps2><i n=\"3\">c</i><i n=\"2\">b</i><i n=\"1\">a</i>"
|
|
3138
|
+
"</ps2></o>");
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
TEST(Xslt30, FnStringsQNameUri) {
|
|
3142
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/04). */
|
|
3143
|
+
EXPECT_EQ(body(run30(
|
|
3144
|
+
"<xsl:template match='/'>"
|
|
3145
|
+
"[<xsl:value-of select=\"format-integer(3, '000'), "
|
|
3146
|
+
"format-integer(42, 'a'), format-integer(7, 'I'), "
|
|
3147
|
+
"format-integer(0, 'w')\"/>]"
|
|
3148
|
+
"[<xsl:value-of select=\"contains-token('a b c', 'b'), "
|
|
3149
|
+
"contains-token('a b c', 'B')\"/>]"
|
|
3150
|
+
"[<xsl:value-of select=\"string-join(for $c in "
|
|
3151
|
+
"string-to-codepoints('AB') return "
|
|
3152
|
+
"codepoints-to-string($c), '')\"/>]"
|
|
3153
|
+
"[<xsl:value-of select=\"encode-for-uri('a b&c'), "
|
|
3154
|
+
"iri-to-uri('a b'), escape-html-uri('<a>')\"/>]"
|
|
3155
|
+
"[<xsl:value-of select=\"QName('u', 'p:l'), "
|
|
3156
|
+
"local-name-from-QName(QName('u','p:l')), "
|
|
3157
|
+
"prefix-from-QName(QName('u','p:l')), "
|
|
3158
|
+
"namespace-uri-from-QName(QName('u','p:l'))\"/>]"
|
|
3159
|
+
"[<xsl:value-of select='node-name(//i[1])'/>]"
|
|
3160
|
+
"</xsl:template>",
|
|
3161
|
+
"<r><i a='x'>t</i></r>")),
|
|
3162
|
+
"[003 ap VII zero][true false][AB]"
|
|
3163
|
+
"[a%20b%26c a%20b &lt;a&gt;]"
|
|
3164
|
+
"[p:l l p u][i]");
|
|
3165
|
+
}
|
|
3166
|
+
|
|
3167
|
+
TEST(Xslt30, TunnelParams) {
|
|
3168
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/10): the tunnel
|
|
3169
|
+
* value flows into EVERY template the subtree reaches, without
|
|
3170
|
+
* re-passing; declared defaults apply when absent. */
|
|
3171
|
+
EXPECT_EQ(body(run30(
|
|
3172
|
+
"<xsl:template match='/'>"
|
|
3173
|
+
"<xsl:apply-templates select='*'>"
|
|
3174
|
+
"<xsl:with-param name='mode' select=\"'X'\" tunnel='yes'/>"
|
|
3175
|
+
"</xsl:apply-templates></xsl:template>"
|
|
3176
|
+
"<xsl:template match='g'>"
|
|
3177
|
+
"<xsl:param name='mode' tunnel='yes' select='default'/>"
|
|
3178
|
+
"<t>[<xsl:value-of select='$mode'/>]</t>"
|
|
3179
|
+
"<xsl:apply-templates select='*'/></xsl:template>"
|
|
3180
|
+
"<xsl:template match='i'>"
|
|
3181
|
+
"<xsl:param name='mode' tunnel='yes'/>"
|
|
3182
|
+
"<u><xsl:value-of select='$mode'/></u></xsl:template>",
|
|
3183
|
+
"<r><g><i/></g></r>")),
|
|
3184
|
+
"<r><t>[X]</t><u>X</u></r>");
|
|
3185
|
+
}
|
|
3186
|
+
|
|
3187
|
+
TEST(Xslt30, ModeOnNoMatchDescentRegression) {
|
|
3188
|
+
/* Issue #705 shapes, re-verified against Saxon-HE 12.7 on
|
|
3189
|
+
* current main: both dispositions descend and match Saxon
|
|
3190
|
+
* byte-for-byte (the 1.9.36 report predates fixes landing).
|
|
3191
|
+
* Note shallow-skip does NOT extract text — Saxon emits empty
|
|
3192
|
+
* for the no-template case. */
|
|
3193
|
+
EXPECT_EQ(body(run30(
|
|
3194
|
+
"<xsl:mode on-no-match='shallow-skip'/>"
|
|
3195
|
+
"<xsl:template match='/r/a[2]'><hit/></xsl:template>",
|
|
3196
|
+
"<r><a>3</a><a>1</a><a>2</a></r>")),
|
|
3197
|
+
"<hit/>");
|
|
3198
|
+
EXPECT_EQ(body(run30(
|
|
3199
|
+
"<xsl:mode on-no-match='shallow-skip'/>",
|
|
3200
|
+
"<r><a>3</a><a>1</a><a>2</a></r>")),
|
|
3201
|
+
"");
|
|
3202
|
+
EXPECT_EQ(body(run30(
|
|
3203
|
+
"<xsl:mode on-no-match='text-only-copy'/>"
|
|
3204
|
+
"<xsl:template match='/r/a[2]'><hit/></xsl:template>",
|
|
3205
|
+
"<r><a>3</a><a>1</a><a>2</a></r>")),
|
|
3206
|
+
"3<hit/>2");
|
|
3207
|
+
EXPECT_EQ(body(run30(
|
|
3208
|
+
"<xsl:mode on-no-match='text-only-copy'/>",
|
|
3209
|
+
"<r><a>3</a><a>1</a><a>2</a></r>")),
|
|
3210
|
+
"312");
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
TEST(Xslt30, SequenceSingleAtomicAndRegexNodes) {
|
|
3214
|
+
/* #685 remainder: a single-item atomic xsl:sequence is a
|
|
3215
|
+
* scalar result (count 0) — it serialized as nothing. #691
|
|
3216
|
+
* comment: the regex trio atomizes NODE arguments. */
|
|
3217
|
+
EXPECT_EQ(body(run30(
|
|
3218
|
+
"<xsl:template match='/'>"
|
|
3219
|
+
"<s><xsl:sequence select=\"'solo'\"/></s>"
|
|
3220
|
+
"</xsl:template>",
|
|
3221
|
+
"<r/>")),
|
|
3222
|
+
"<s>solo</s>");
|
|
3223
|
+
#ifndef _WIN32
|
|
3224
|
+
EXPECT_EQ(body(run30(
|
|
3225
|
+
"<xsl:template match='/'>"
|
|
3226
|
+
"[<xsl:value-of select=\"matches(//item[1], 'a\\d')\"/>]"
|
|
3227
|
+
"</xsl:template>",
|
|
3228
|
+
"<r><item>a1</item></r>")),
|
|
3229
|
+
"[true]");
|
|
3230
|
+
#endif
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
TEST(Xslt30, FnDates) {
|
|
3234
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/05, first slice:
|
|
3235
|
+
* constructors + component extractors). */
|
|
3236
|
+
EXPECT_EQ(body(run30(
|
|
3237
|
+
"<xsl:template match='/'>"
|
|
3238
|
+
"[<xsl:value-of select=\"xs:date('2026-09-02'), "
|
|
3239
|
+
"xs:dateTime('2026-09-02T10:30:00'), "
|
|
3240
|
+
"xs:time('10:30:00'), xs:duration('P1D')\"/>]"
|
|
3241
|
+
"[<xsl:value-of select=\"year-from-dateTime("
|
|
3242
|
+
"xs:dateTime('2026-09-02T10:30:00')), "
|
|
3243
|
+
"month-from-dateTime(xs:dateTime('2026-09-02T10:30:00')), "
|
|
3244
|
+
"day-from-dateTime(xs:dateTime('2026-09-02T10:30:00')), "
|
|
3245
|
+
"hours-from-time(xs:time('10:30:45')), "
|
|
3246
|
+
"minutes-from-time(xs:time('10:30:45')), "
|
|
3247
|
+
"seconds-from-time(xs:time('10:30:45'))\"/>]"
|
|
3248
|
+
"[<xsl:value-of select=\"days-from-duration("
|
|
3249
|
+
"xs:duration('P2DT3H')), hours-from-duration("
|
|
3250
|
+
"xs:duration('P2DT3H'))\"/>]"
|
|
3251
|
+
"</xsl:template>",
|
|
3252
|
+
"<r/>")),
|
|
3253
|
+
"[2026-09-02 2026-09-02T10:30:00 10:30:00 P1D]"
|
|
3254
|
+
"[2026 9 2 10 30 45][2 3]");
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
|
|
3258
|
+
|
|
3259
|
+
/* Lane 05 tail (2026-09-09): implicit-timezone, adjust-*-to-
|
|
3260
|
+
* timezone (fixed-offset instant math), format-date/time/
|
|
3261
|
+
* dateTime picture subset, current-* shapes. Saxon-HE lexical
|
|
3262
|
+
* forms: zero offset renders Z, else +/-HH:MM. */
|
|
3263
|
+
TEST(Xslt30, FnAdjustTimezone) {
|
|
3264
|
+
EXPECT_EQ(body(run30(
|
|
3265
|
+
"<xsl:template match='/'>"
|
|
3266
|
+
"[<xsl:value-of select=\"implicit-timezone()\"/>]"
|
|
3267
|
+
"[<xsl:value-of select=\"adjust-dateTime-to-timezone("
|
|
3268
|
+
"xs:dateTime('2026-01-01T00:30:00+05:00'), "
|
|
3269
|
+
"xs:dayTimeDuration('-PT8H'))\"/>]"
|
|
3270
|
+
"[<xsl:value-of select=\"adjust-time-to-timezone("
|
|
3271
|
+
"xs:time('10:30:00+02:00'), "
|
|
3272
|
+
"xs:dayTimeDuration('PT0S'))\"/>]"
|
|
3273
|
+
"[<xsl:value-of select=\"adjust-dateTime-to-timezone("
|
|
3274
|
+
"xs:dateTime('2026-01-01T00:30:00+05:00'))\"/>]"
|
|
3275
|
+
"</xsl:template>",
|
|
3276
|
+
"<r/>")),
|
|
3277
|
+
"[PT0S][2025-12-31T11:30:00-08:00][08:30:00Z]"
|
|
3278
|
+
"[2025-12-31T19:30:00Z]");
|
|
3279
|
+
}
|
|
3280
|
+
|
|
3281
|
+
TEST(Xslt30, FnFormatDate) {
|
|
3282
|
+
EXPECT_EQ(body(run30(
|
|
3283
|
+
"<xsl:template match='/'>"
|
|
3284
|
+
"[<xsl:value-of select=\"format-dateTime("
|
|
3285
|
+
"xs:dateTime('2026-09-02T10:30:00'), "
|
|
3286
|
+
"'[Y]-[M01]-[D01] [H01]:[m01]')\"/>]"
|
|
3287
|
+
"[<xsl:value-of select=\"format-date("
|
|
3288
|
+
"xs:date('2026-09-02'), '[MNn] [D], [Y0001]')\"/>]"
|
|
3289
|
+
"[<xsl:value-of select=\"format-time("
|
|
3290
|
+
"xs:time('10:30:00+05:00'), '[h01]:[m01] [Z]')\"/>]"
|
|
3291
|
+
"</xsl:template>",
|
|
3292
|
+
"<r/>")),
|
|
3293
|
+
"[2026-09-02 10:30][September 2, 2026][10:30 +05:00]");
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3296
|
+
TEST(Xslt30, FnCurrentDateTimeShape) {
|
|
3297
|
+
std::string out = body(run30(
|
|
3298
|
+
"<xsl:template match='/'>"
|
|
3299
|
+
"<xsl:value-of select='current-dateTime()'/>|"
|
|
3300
|
+
"<xsl:value-of select='current-date()'/>|"
|
|
3301
|
+
"<xsl:value-of select='current-time()'/>"
|
|
3302
|
+
"</xsl:template>",
|
|
3303
|
+
"<r/>"));
|
|
3304
|
+
std::regex shape(
|
|
3305
|
+
"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}"
|
|
3306
|
+
"(Z|[+-][0-9]{2}:[0-9]{2})\\|"
|
|
3307
|
+
"[0-9]{4}-[0-9]{2}-[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})\\|"
|
|
3308
|
+
"[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$");
|
|
3309
|
+
EXPECT_TRUE(std::regex_match(out, shape)) << out;
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3312
|
+
|
|
3313
|
+
|
|
3314
|
+
/* Lane 07 tail: fn:sort(seq, key?, collation?) — codepoint order,
|
|
3315
|
+
* optional key function; the collation argument is accepted and
|
|
3316
|
+
* ignored (codepoint). for-each-pair uneven inputs already zip to
|
|
3317
|
+
* the shorter (pinned below). */
|
|
3318
|
+
TEST(Xslt30, FnSortWithKey) {
|
|
3319
|
+
EXPECT_EQ(body(run30(
|
|
3320
|
+
"<xsl:template match='/'>"
|
|
3321
|
+
"[<xsl:value-of select=\"sort(('b','a','c'))\"/>]"
|
|
3322
|
+
"[<xsl:value-of select=\"sort(('bx','ay','cz'), "
|
|
3323
|
+
"function($x){substring($x,1,1)})\"/>]"
|
|
3324
|
+
"[<xsl:value-of select=\"sort((3,1,2))\"/>]"
|
|
3325
|
+
"[<xsl:value-of select=\"for-each-pair((1,2,3),('x','y'), "
|
|
3326
|
+
"concat#2)\"/>]"
|
|
3327
|
+
"</xsl:template>",
|
|
3328
|
+
"<r/>")),
|
|
3329
|
+
"[a b c][ay bx cz][1 2 3][1x 2y]");
|
|
3330
|
+
}
|
|
3331
|
+
|
|
3332
|
+
TEST(Xslt30, WherePopulatedOnNonEmptyNextMatch) {
|
|
3333
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/09): where-
|
|
3334
|
+
* populated drops wholly-empty content; on-non-empty is
|
|
3335
|
+
* evaluated (Saxon reserves always-eval); next-match runs the
|
|
3336
|
+
* next-lower-priority matching rule. */
|
|
3337
|
+
EXPECT_EQ(body(run30(
|
|
3338
|
+
"<xsl:template match='/'>"
|
|
3339
|
+
"<wp><xsl:where-populated>"
|
|
3340
|
+
"<xsl:value-of select='//i'/>, "
|
|
3341
|
+
"<xsl:value-of select='//nope'/>"
|
|
3342
|
+
"</xsl:where-populated>|</wp>"
|
|
3343
|
+
"<wp2><xsl:where-populated>"
|
|
3344
|
+
"<xsl:value-of select='//nope'/>"
|
|
3345
|
+
"</xsl:where-populated>|</wp2>"
|
|
3346
|
+
"<one><xsl:value-of select='//i'/>"
|
|
3347
|
+
"<xsl:on-non-empty>!</xsl:on-non-empty>|</one>"
|
|
3348
|
+
"<one2><xsl:value-of select='//nope'/>"
|
|
3349
|
+
"<xsl:on-non-empty>!</xsl:on-non-empty>|</one2>"
|
|
3350
|
+
"<nm><xsl:apply-templates select='//i'/></nm>"
|
|
3351
|
+
"</xsl:template>"
|
|
3352
|
+
"<xsl:template match='i' priority='1'>"
|
|
3353
|
+
"<base><xsl:next-match/></base></xsl:template>"
|
|
3354
|
+
"<xsl:template match='i'><low/></xsl:template>",
|
|
3355
|
+
"<r><i>x</i></r>")),
|
|
3356
|
+
"<wp>x, |</wp><wp2>|</wp2><one>x!|</one><one2>!|</one2>"
|
|
3357
|
+
"<nm><base><low/></base></nm>");
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
TEST(Xslt30, SequenceUseKeyValues) {
|
|
3361
|
+
/* #720: a sequence use expression (@v, .) indexes the node under
|
|
3362
|
+
* EVERY item's value (Saxon composite="no" ground truth); a
|
|
3363
|
+
* sequence lookup argument unions the per-item buckets. The
|
|
3364
|
+
* 1.9.43 build stringified the whole sequence — empty for >1
|
|
3365
|
+
* item, so the node was never indexed. */
|
|
3366
|
+
EXPECT_EQ(body(run30(
|
|
3367
|
+
"<xsl:key name='k' match='item' use='@v, .'/>"
|
|
3368
|
+
"<xsl:template match='/'>"
|
|
3369
|
+
"<o>"
|
|
3370
|
+
"<a><xsl:value-of select=\"count(key('k', ('1', 'alpha')))\"/></a>"
|
|
3371
|
+
"<b><xsl:value-of select=\"count(key('k', '1'))\"/></b>"
|
|
3372
|
+
"<c><xsl:value-of select=\"count(key('k', 'alpha'))\"/></c>"
|
|
3373
|
+
"<d><xsl:value-of select=\"count(key('k', '5 beta'))\"/></d>"
|
|
3374
|
+
"</o></xsl:template>",
|
|
3375
|
+
"<r><item v='1'>alpha</item><item v='5'>beta</item></r>")),
|
|
3376
|
+
"<o><a>1</a><b>1</b><c>1</c><d>0</d></o>");
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
TEST(Xslt30, ForkCompositeKeysStartAt) {
|
|
3380
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/09): fork runs
|
|
3381
|
+
* its child sequences sequentially; a key whose use evaluates
|
|
3382
|
+
* to MULTIPLE whitespace-separated tokens indexes the node
|
|
3383
|
+
* under each; xsl:number start-at offsets the sequence. */
|
|
3384
|
+
EXPECT_EQ(body(run30(
|
|
3385
|
+
"<xsl:template match='/'>"
|
|
3386
|
+
"<fk><xsl:fork>"
|
|
3387
|
+
"<xsl:sequence select=\"'a'\"/>"
|
|
3388
|
+
"<xsl:sequence select=\"'b'\"/>"
|
|
3389
|
+
"</xsl:fork></fk>"
|
|
3390
|
+
"</xsl:template>",
|
|
3391
|
+
"<r/>")),
|
|
3392
|
+
"<fk>a b</fk>");
|
|
3393
|
+
EXPECT_EQ(body(run30(
|
|
3394
|
+
"<xsl:key name='k' match='item' use='@tags'/>"
|
|
3395
|
+
"<xsl:template match='/'>"
|
|
3396
|
+
"[<xsl:value-of select=\"count(key('k', 'x')), "
|
|
3397
|
+
"count(key('k', 'y'))\"/>]"
|
|
3398
|
+
"</xsl:template>",
|
|
3399
|
+
"<r><item tags='x z'/><item tags='x y'/></r>")),
|
|
3400
|
+
"[2 1]");
|
|
3401
|
+
}
|
|
3402
|
+
|
|
3403
|
+
TEST(Xslt30, NumberStartAt) {
|
|
3404
|
+
/* xsl:number start-at: the sequence begins at 10. */
|
|
3405
|
+
EXPECT_EQ(body(run30(
|
|
3406
|
+
"<xsl:template match='/'>"
|
|
3407
|
+
"<o><xsl:for-each select='//i'>"
|
|
3408
|
+
"[<xsl:number/>][<xsl:number start-at='10'/>]"
|
|
3409
|
+
"</xsl:for-each></o>"
|
|
3410
|
+
"</xsl:template>",
|
|
3411
|
+
"<r><i/><i/></r>")),
|
|
3412
|
+
"<o>[1][10][2][11]</o>");
|
|
3413
|
+
}
|
|
3414
|
+
|
|
3415
|
+
TEST(Xslt30, EvaluateWithParamsAndContext) {
|
|
3416
|
+
/* Saxon-HE 12.7 ground truth: child xsl:with-param binds $p for
|
|
3417
|
+
* the DYNAMIC phase only (@xpath's own evaluation saw the outer
|
|
3418
|
+
* $p). context-item re-anchors the dynamic expression. */
|
|
3419
|
+
EXPECT_EQ(body(run30(
|
|
3420
|
+
"<xsl:template match='/'>"
|
|
3421
|
+
"<o>"
|
|
3422
|
+
"<e1><xsl:evaluate xpath=\"'$p * 2'\">"
|
|
3423
|
+
"<xsl:with-param name='p' select='42'/></xsl:evaluate></e1>"
|
|
3424
|
+
"<e2><xsl:evaluate xpath=\"'count(//i)'\" context-item='/'/></e2>"
|
|
3425
|
+
"<e3><xsl:evaluate xpath=\"'name(/*)'\" context-item='/*'/></e3>"
|
|
3426
|
+
"</o></xsl:template>",
|
|
3427
|
+
"<r><i>3</i><i>5</i></r>")),
|
|
3428
|
+
"<o><e1>84</e1><e2>2</e2><e3>r</e3></o>");
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
TEST(Xslt30, MergeTwoSourcesFullOuterJoin) {
|
|
3432
|
+
/* Saxon-HE 12.7 ground truth: keys 1,2,3; source a holds 1,3,
|
|
3433
|
+
* source b holds 2,3; unmatched side is empty. */
|
|
3434
|
+
EXPECT_EQ(body(run30(
|
|
3435
|
+
"<xsl:template match='/'>"
|
|
3436
|
+
"<m><xsl:merge>"
|
|
3437
|
+
"<xsl:merge-source name='a' select='//i' sort-before-merge='yes'>"
|
|
3438
|
+
"<xsl:merge-key select='@n' order='ascending'/>"
|
|
3439
|
+
"</xsl:merge-source>"
|
|
3440
|
+
"<xsl:merge-source name='b' select='//j' sort-before-merge='yes'>"
|
|
3441
|
+
"<xsl:merge-key select='@n' order='ascending'/>"
|
|
3442
|
+
"</xsl:merge-source>"
|
|
3443
|
+
"<xsl:merge-action>"
|
|
3444
|
+
"<g n='{current-merge-key()}'><xsl:value-of "
|
|
3445
|
+
"select='current-merge-group(\"a\")/@n'/>|<xsl:value-of "
|
|
3446
|
+
"select='current-merge-group(\"b\")/@n'/></g>"
|
|
3447
|
+
"</xsl:merge-action>"
|
|
3448
|
+
"</xsl:merge></m></xsl:template>",
|
|
3449
|
+
"<r><i n='1'/><i n='3'/><j n='2'/><j n='3'/></r>")),
|
|
3450
|
+
"<m><g n=\"1\">1|</g><g n=\"2\">|2</g><g n=\"3\">3|3</g></m>");
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
TEST(Xslt30, PostfixLookupOnMapsAndArrays) {
|
|
3454
|
+
/* Lane 08 tail: `?key` / `?integer` postfix lookup. Saxon-HE
|
|
3455
|
+
* 12.7 ground truth (/tmp/probe9/lk8.xsl). */
|
|
3456
|
+
EXPECT_EQ(body(run30(
|
|
3457
|
+
"<xsl:template match='/'>"
|
|
3458
|
+
"<o><a><xsl:value-of select=\"map { 'b': 'beta', 'c': 3 }?b\"/></a>"
|
|
3459
|
+
"<b><xsl:value-of select=\"[10, 20, 30]?2\"/></b></o>"
|
|
3460
|
+
"</xsl:template>",
|
|
3461
|
+
"<r/>")),
|
|
3462
|
+
"<o><a>beta</a><b>20</b></o>");
|
|
3463
|
+
}
|
|
3464
|
+
|
|
3465
|
+
TEST(Xslt30, NamedFunctionReferenceDispatch) {
|
|
3466
|
+
/* Lane 07: name#arity — let-bound named refs dispatched as
|
|
3467
|
+
* dynamic calls. Saxon-HE 12.7: string-join#1(('a','b'))='ab'. */
|
|
3468
|
+
EXPECT_EQ(body(run30(
|
|
3469
|
+
"<xsl:template match='/'>"
|
|
3470
|
+
"<o><xsl:value-of select=\"let $f := string-join#1"
|
|
3471
|
+
" return $f(('a','b'))\"/></o></xsl:template>",
|
|
3472
|
+
"<r/>")),
|
|
3473
|
+
"<o>ab</o>");
|
|
3474
|
+
EXPECT_EQ(body(run30(
|
|
3475
|
+
"<xsl:template match='/'>"
|
|
3476
|
+
"<o><xsl:value-of select=\"let $c := concat#2"
|
|
3477
|
+
" return $c('x', 'y')\"/></o></xsl:template>",
|
|
3478
|
+
"<r/>")),
|
|
3479
|
+
"<o>xy</o>");
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
TEST(Xslt30, HofPairsApplyAndArrayCombinators) {
|
|
3483
|
+
/* Lane 07 tail: fn:for-each-pair, fn:apply, map:for-each, and
|
|
3484
|
+
* the array: HOF family through the combiner seam.
|
|
3485
|
+
* Saxon-HE 12.7 (/tmp/probe9/l07b/t5.xsl). */
|
|
3486
|
+
EXPECT_EQ(body(run30(
|
|
3487
|
+
"<xsl:template match='/'>"
|
|
3488
|
+
"<o><xsl:value-of select=\"for-each-pair(('a','b'), (1,2),"
|
|
3489
|
+
" function($s,$n){ $s || $n })\"/></o></xsl:template>",
|
|
3490
|
+
"<r/>")),
|
|
3491
|
+
"<o>a1 b2</o>");
|
|
3492
|
+
EXPECT_EQ(body(run30(
|
|
3493
|
+
"<xsl:template match='/'>"
|
|
3494
|
+
"<o><xsl:value-of select=\"apply(concat#2, ['x','y'])\""
|
|
3495
|
+
"/></o></xsl:template>",
|
|
3496
|
+
"<r/>")),
|
|
3497
|
+
"<o>xy</o>");
|
|
3498
|
+
EXPECT_EQ(body(run30(
|
|
3499
|
+
"<xsl:template match='/'>"
|
|
3500
|
+
"<o><xsl:value-of select=\"apply(function($a,$b,$c)"
|
|
3501
|
+
"{ $a * 100 + $b * 10 + $c }, [1,2,3])\"/></o></xsl:template>",
|
|
3502
|
+
"<r/>")),
|
|
3503
|
+
"<o>123</o>");
|
|
3504
|
+
EXPECT_EQ(body(run30(
|
|
3505
|
+
"<xsl:template match='/'"
|
|
3506
|
+
" xmlns:map='http://www.w3.org/2005/xpath-functions/map'>"
|
|
3507
|
+
"<o><xsl:value-of select=\"map:for-each(map{'a':1,'b':2},"
|
|
3508
|
+
" function($k,$v){ $k || '=' || $v })\"/></o></xsl:template>",
|
|
3509
|
+
"<r/>")),
|
|
3510
|
+
"<o xmlns:map=\"http://www.w3.org/2005/xpath-functions/map\">a=1 b=2</o>");
|
|
3511
|
+
EXPECT_EQ(body(run30(
|
|
3512
|
+
"<xsl:template match='/'"
|
|
3513
|
+
" xmlns:array='http://www.w3.org/2005/xpath-functions/array'>"
|
|
3514
|
+
"<o><xsl:value-of select=\"array:for-each([10,20],"
|
|
3515
|
+
" function($n){ $n + 1 })\"/></o></xsl:template>",
|
|
3516
|
+
"<r/>")),
|
|
3517
|
+
"<o xmlns:array=\"http://www.w3.org/2005/xpath-functions/array\">11 21</o>");
|
|
3518
|
+
EXPECT_EQ(body(run30(
|
|
3519
|
+
"<xsl:template match='/'"
|
|
3520
|
+
" xmlns:array='http://www.w3.org/2005/xpath-functions/array'>"
|
|
3521
|
+
"<o><xsl:value-of select=\"array:filter([1,2,3,4,5,6],"
|
|
3522
|
+
" function($n){ $n mod 2 = 0 })\"/></o></xsl:template>",
|
|
3523
|
+
"<r/>")),
|
|
3524
|
+
"<o xmlns:array=\"http://www.w3.org/2005/xpath-functions/array\">2 4 6</o>");
|
|
3525
|
+
EXPECT_EQ(body(run30(
|
|
3526
|
+
"<xsl:template match='/'"
|
|
3527
|
+
" xmlns:array='http://www.w3.org/2005/xpath-functions/array'>"
|
|
3528
|
+
"<o><xsl:value-of select=\"array:fold-left([1,2,3,4], 0,"
|
|
3529
|
+
" function($a,$b){ $a + $b })\"/></o></xsl:template>",
|
|
3530
|
+
"<r/>")),
|
|
3531
|
+
"<o xmlns:array=\"http://www.w3.org/2005/xpath-functions/array\">10</o>");
|
|
3532
|
+
EXPECT_EQ(body(run30(
|
|
3533
|
+
"<xsl:template match='/'"
|
|
3534
|
+
" xmlns:array='http://www.w3.org/2005/xpath-functions/array'>"
|
|
3535
|
+
"<o><xsl:value-of select=\"array:fold-right([1,2,3,4], 0,"
|
|
3536
|
+
" function($a,$b){ $a - $b })\"/></o></xsl:template>",
|
|
3537
|
+
"<r/>")),
|
|
3538
|
+
"<o xmlns:array=\"http://www.w3.org/2005/xpath-functions/array\">-2</o>");
|
|
3539
|
+
}
|
|
3540
|
+
|
|
3541
|
+
TEST(Xslt30, FunctionItemMetadataAndHofs) {
|
|
3542
|
+
/* Lane 07B: fn:function-lookup/name/arity, fn:for-each/filter/
|
|
3543
|
+
* fold-left/fold-right, and ? partial application.
|
|
3544
|
+
* Saxon-HE 12.7 ground truth (/tmp/probe9/l07b/{t1,t2}.xsl). */
|
|
3545
|
+
EXPECT_EQ(body(run30(
|
|
3546
|
+
"<xsl:template match='/'>"
|
|
3547
|
+
"<o><xsl:value-of select=\"let $f := function-lookup('concat', 2)"
|
|
3548
|
+
" return $f('a','b')\"/></o></xsl:template>",
|
|
3549
|
+
"<r/>")),
|
|
3550
|
+
"<o>ab</o>");
|
|
3551
|
+
EXPECT_EQ(body(run30(
|
|
3552
|
+
"<xsl:template match='/'>"
|
|
3553
|
+
"<o><xsl:value-of select=\"if (empty(function-lookup('no-such-fn', 1)))"
|
|
3554
|
+
" then 'EMPTY' else 'GOT'\"/></o></xsl:template>",
|
|
3555
|
+
"<r/>")),
|
|
3556
|
+
"<o>EMPTY</o>");
|
|
3557
|
+
EXPECT_EQ(body(run30(
|
|
3558
|
+
"<xsl:template match='/'>"
|
|
3559
|
+
"<o><xsl:value-of select=\"function-name(concat#2)\"/></o></xsl:template>",
|
|
3560
|
+
"<r/>")),
|
|
3561
|
+
"<o>fn:concat</o>");
|
|
3562
|
+
EXPECT_EQ(body(run30(
|
|
3563
|
+
"<xsl:template match='/'>"
|
|
3564
|
+
"<o><xsl:value-of select=\"let $f := function($x){$x+1}"
|
|
3565
|
+
" return if (empty(function-name($f))) then 'EMPTY' else 'GOT'\""
|
|
3566
|
+
"/></o></xsl:template>",
|
|
3567
|
+
"<r/>")),
|
|
3568
|
+
"<o>EMPTY</o>");
|
|
3569
|
+
EXPECT_EQ(body(run30(
|
|
3570
|
+
"<xsl:template match='/'>"
|
|
3571
|
+
"<o><xsl:value-of select=\"function-arity(concat#2)\"/></o></xsl:template>",
|
|
3572
|
+
"<r/>")),
|
|
3573
|
+
"<o>2</o>");
|
|
3574
|
+
EXPECT_EQ(body(run30(
|
|
3575
|
+
"<xsl:template match='/'>"
|
|
3576
|
+
"<o><xsl:value-of select=\"function-arity(function($x,$y){$x})\""
|
|
3577
|
+
"/></o></xsl:template>",
|
|
3578
|
+
"<r/>")),
|
|
3579
|
+
"<o>2</o>");
|
|
3580
|
+
EXPECT_EQ(body(run30(
|
|
3581
|
+
"<xsl:template match='/'>"
|
|
3582
|
+
"<o><xsl:value-of select=\"for-each(('a','b'),"
|
|
3583
|
+
" function($s){ upper-case($s) })\"/></o></xsl:template>",
|
|
3584
|
+
"<r/>")),
|
|
3585
|
+
"<o>A B</o>");
|
|
3586
|
+
EXPECT_EQ(body(run30(
|
|
3587
|
+
"<xsl:template match='/'>"
|
|
3588
|
+
"<o><xsl:value-of select=\"filter((1 to 6),"
|
|
3589
|
+
" function($n){ $n mod 2 = 0 })\"/></o></xsl:template>",
|
|
3590
|
+
"<r/>")),
|
|
3591
|
+
"<o>2 4 6</o>");
|
|
3592
|
+
EXPECT_EQ(body(run30(
|
|
3593
|
+
"<xsl:template match='/'>"
|
|
3594
|
+
"<o><xsl:value-of select=\"fold-left(1 to 4, 0,"
|
|
3595
|
+
" function($a,$b){ $a + $b })\"/></o></xsl:template>",
|
|
3596
|
+
"<r/>")),
|
|
3597
|
+
"<o>10</o>");
|
|
3598
|
+
EXPECT_EQ(body(run30(
|
|
3599
|
+
"<xsl:template match='/'>"
|
|
3600
|
+
"<o><xsl:value-of select=\"fold-right(1 to 4, 0,"
|
|
3601
|
+
" function($a,$b){ $a - $b })\"/></o></xsl:template>",
|
|
3602
|
+
"<r/>")),
|
|
3603
|
+
"<o>-2</o>");
|
|
3604
|
+
EXPECT_EQ(body(run30(
|
|
3605
|
+
"<xsl:template match='/'>"
|
|
3606
|
+
"<o><xsl:value-of select=\"let $g := concat('x', ?, 'z')"
|
|
3607
|
+
" return $g('y')\"/></o></xsl:template>",
|
|
3608
|
+
"<r/>")),
|
|
3609
|
+
"<o>xyz</o>");
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3612
|
+
TEST(Xslt30, InlineFunctionItemsAndCalls) {
|
|
3613
|
+
/* Lane 07 first slice: inline function items, dynamic calls,
|
|
3614
|
+
* and named function references. Saxon-HE 12.7 ground truth
|
|
3615
|
+
* (/tmp/probe9/fi7.xsl, fi7b.xsl). */
|
|
3616
|
+
EXPECT_EQ(body(run30(
|
|
3617
|
+
"<xsl:template match='/'>"
|
|
3618
|
+
"<o><xsl:value-of select=\"let $f := function($x) { $x * 2 }"
|
|
3619
|
+
" return $f(21)\"/></o></xsl:template>",
|
|
3620
|
+
"<r/>")),
|
|
3621
|
+
"<o>42</o>");
|
|
3622
|
+
EXPECT_EQ(body(run30(
|
|
3623
|
+
"<xsl:template match='/'>"
|
|
3624
|
+
"<o><xsl:value-of select=\"function($x) { $x + 1 }(41)\"/></o>"
|
|
3625
|
+
"</xsl:template>",
|
|
3626
|
+
"<r/>")),
|
|
3627
|
+
"<o>42</o>");
|
|
3628
|
+
EXPECT_EQ(body(run30(
|
|
3629
|
+
"<xsl:template match='/'>"
|
|
3630
|
+
"<o><xsl:value-of select=\"let $sq := function($n) { $n * $n }"
|
|
3631
|
+
" return $sq(7)\"/></o></xsl:template>",
|
|
3632
|
+
"<r/>")),
|
|
3633
|
+
"<o>49</o>");
|
|
3634
|
+
/* name#arity + FR dispatch: next window (see TODO 07 status —
|
|
3635
|
+
* the FR branch synthesizes a FUNCTION_CALL over borrowed arg
|
|
3636
|
+
* ASTs; the failure is upstream of the dyn call). */
|
|
3637
|
+
EXPECT_EQ(body(run30(
|
|
3638
|
+
"<xsl:template match='/'>"
|
|
3639
|
+
"<o><xsl:value-of select=\"let $d := function($a, $b)"
|
|
3640
|
+
" { $a * 10 + $b } return $d(4, 2)\"/></o></xsl:template>",
|
|
3641
|
+
"<r/>")),
|
|
3642
|
+
"<o>42</o>");
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
TEST(Xslt30, SerializeJsonMethod) {
|
|
3646
|
+
/* Lane 08 final: fn:serialize with method json over the shared
|
|
3647
|
+
* map representation. Saxon-HE 12.7 ground truth
|
|
3648
|
+
* (/tmp/probe9/ser8.xsl). */
|
|
3649
|
+
EXPECT_EQ(body(run30(
|
|
3650
|
+
"<xsl:template match='/'>"
|
|
3651
|
+
"<o><xsl:value-of select=\"serialize("
|
|
3652
|
+
"parse-json('{"b": "beta", "n": 2}'),"
|
|
3653
|
+
" map { 'method': 'json' })\"/></o></xsl:template>",
|
|
3654
|
+
"<r/>")),
|
|
3655
|
+
"<o>{\"b\":\"beta\",\"n\":2}</o>");
|
|
3656
|
+
}
|
|
3657
|
+
|
|
3658
|
+
TEST(Xslt30, XmlToJsonRoundTrip) {
|
|
3659
|
+
/* Lane 08: xml-to-json walks the canonical fn: vocabulary back
|
|
3660
|
+
* into the shared map representation. */
|
|
3661
|
+
EXPECT_EQ(body(run30(
|
|
3662
|
+
"<xsl:template match='/'>"
|
|
3663
|
+
"<o xmlns:map='http://www.w3.org/2005/xpath-functions/map'>"
|
|
3664
|
+
"<xsl:value-of select=\"map:get(xml-to-json("
|
|
3665
|
+
"json-to-xml('{"b": "beta", "n": 2}')),"
|
|
3666
|
+
" 'b')\"/>|<xsl:value-of select=\"map:get(xml-to-json("
|
|
3667
|
+
"json-to-xml('{"b": "beta", "n": 2}')),"
|
|
3668
|
+
" 'n')\"/>"
|
|
3669
|
+
"</o></xsl:template>",
|
|
3670
|
+
"<r/>")),
|
|
3671
|
+
"<o xmlns:map=\"http://www.w3.org/2005/xpath-functions/map\">"
|
|
3672
|
+
"beta|2</o>");
|
|
3673
|
+
}
|
|
3674
|
+
|
|
3675
|
+
|
|
3676
|
+
TEST(Xslt30, JsonToXmlCanonical) {
|
|
3677
|
+
/* Lane 08 final slice: the canonical fn: XML vocabulary
|
|
3678
|
+
* (Saxon-HE 12.7 ground truth, /tmp/probe9/jx8.xsl). */
|
|
3679
|
+
EXPECT_EQ(body(run30(
|
|
3680
|
+
"<xsl:template match='/'>"
|
|
3681
|
+
"<o><xsl:copy-of select=\"json-to-xml('{"b": "
|
|
3682
|
+
""beta", "n": 2}')\"/></o>"
|
|
3683
|
+
"</xsl:template>",
|
|
3684
|
+
"<r/>")),
|
|
3685
|
+
"<o><map xmlns=\"http://www.w3.org/2005/xpath-functions\">"
|
|
3686
|
+
"<string key=\"b\">beta</string>"
|
|
3687
|
+
"<number key=\"n\">2</number></map></o>");
|
|
3688
|
+
}
|
|
3689
|
+
|
|
3690
|
+
TEST(Xslt30, FnParseJsonFeedsMapAndArrays) {
|
|
3691
|
+
/* Lane 08D: parse-json produces map/array values usable by the
|
|
3692
|
+
* accessors. Saxon-HE 12.7 ground truth (/tmp/probe9/js8.xsl). */
|
|
3693
|
+
EXPECT_EQ(body(run30(
|
|
3694
|
+
"<xsl:template match='/'>"
|
|
3695
|
+
"<o xmlns:map='http://www.w3.org/2005/xpath-functions/map'"
|
|
3696
|
+
" xmlns:array='http://www.w3.org/2005/xpath-functions/array'>"
|
|
3697
|
+
"<a><xsl:value-of select=\"map:get(parse-json("
|
|
3698
|
+
"'{"a": 1, "b": "beta"}'),"
|
|
3699
|
+
" 'b')\"/></a>"
|
|
3700
|
+
"<b><xsl:value-of select=\"array:get(parse-json("
|
|
3701
|
+
"'[10, 20, 30]'), 2)\"/></b>"
|
|
3702
|
+
"<c><xsl:value-of select=\"map:size(parse-json("
|
|
3703
|
+
"'{"a": 1, "b": 2}'))\"/></c>"
|
|
3704
|
+
"</o></xsl:template>",
|
|
3705
|
+
"<r/>")),
|
|
3706
|
+
"<o xmlns:map=\"http://www.w3.org/2005/xpath-functions/map\""
|
|
3707
|
+
" xmlns:array=\"http://www.w3.org/2005/xpath-functions/array\">"
|
|
3708
|
+
"<a>beta</a><b>20</b><c>2</c></o>");
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
TEST(Xslt30, FnArrayConstructorAndAccessors) {
|
|
3712
|
+
/* Lane 08C: the square array constructor + size/get/append/put.
|
|
3713
|
+
* Saxon-HE 12.7 ground truth (/tmp/probe9/arr8.xsl); value-level
|
|
3714
|
+
* arrays ride the map representation with positional keys. */
|
|
3715
|
+
EXPECT_EQ(body(run30(
|
|
3716
|
+
"<xsl:template match='/'>"
|
|
3717
|
+
"<o xmlns:array='http://www.w3.org/2005/xpath-functions/array'>"
|
|
3718
|
+
"<a><xsl:value-of select=\"array:size([ 'a', 'b', 3 ])\"/></a>"
|
|
3719
|
+
"<b><xsl:value-of select=\"array:get([ 'a', 'b', 3 ], 2)\"/></b>"
|
|
3720
|
+
"<c><xsl:value-of select=\"array:get(array:append("
|
|
3721
|
+
"[ 'a', 'b' ], 'c'), 3)\"/></c>"
|
|
3722
|
+
"<d><xsl:value-of select=\"array:get(array:put([ 'a', 'b' ],"
|
|
3723
|
+
" 2, 'B'), 2)\"/></d>"
|
|
3724
|
+
"</o></xsl:template>",
|
|
3725
|
+
"<r/>")),
|
|
3726
|
+
"<o xmlns:array=\"http://www.w3.org/2005/xpath-functions/array\">"
|
|
3727
|
+
"<a>3</a><b>b</b><c>c</c><d>B</d></o>");
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3730
|
+
TEST(Xslt30, FnMapPutRemoveMergeAndXslMap) {
|
|
3731
|
+
/* Lane 08B: map:put/remove/merge + the xsl:map instruction
|
|
3732
|
+
* (xsl:map-entry @key is an EXPRESSION — Saxon-HE 12.7 ground
|
|
3733
|
+
* truth, /tmp/probe9/map8d.xsl). */
|
|
3734
|
+
EXPECT_EQ(body(run30(
|
|
3735
|
+
"<xsl:template match='/'>"
|
|
3736
|
+
"<xsl:variable name='xm'>"
|
|
3737
|
+
"<xsl:map>"
|
|
3738
|
+
"<xsl:map-entry key=\"'k'\" select='42'/>"
|
|
3739
|
+
"<xsl:map-entry key=\"'n'\" select='count(//i)'/>"
|
|
3740
|
+
"</xsl:map>"
|
|
3741
|
+
"</xsl:variable>"
|
|
3742
|
+
"<o xmlns:map='http://www.w3.org/2005/xpath-functions/map'>"
|
|
3743
|
+
"<a><xsl:value-of select=\"map:get(map:put(map { 'a': 1 },"
|
|
3744
|
+
" 'b', 2), 'b')\"/></a>"
|
|
3745
|
+
"<b><xsl:value-of select=\"map:size(map:remove(map { 'a': 1,"
|
|
3746
|
+
" 'b': 2 }, 'a'))\"/></b>"
|
|
3747
|
+
"<c><xsl:value-of select=\"map:get(map:merge((map { 'a': 1 },"
|
|
3748
|
+
" map { 'b': 2 })), 'b')\"/></c>"
|
|
3749
|
+
"<d><xsl:value-of select='map:size($xm)'/>|"
|
|
3750
|
+
"<xsl:value-of select=\"map:get($xm, 'k')\"/></d>"
|
|
3751
|
+
"</o></xsl:template>",
|
|
3752
|
+
"<r><i>1</i><i>2</i></r>")),
|
|
3753
|
+
"<o xmlns:map=\"http://www.w3.org/2005/xpath-functions/map\">"
|
|
3754
|
+
"<a>2</a><b>1</b><c>2</c><d>2|42</d></o>");
|
|
3755
|
+
}
|
|
3756
|
+
|
|
3757
|
+
TEST(Xslt30, FnMapConstructorAndAccessors) {
|
|
3758
|
+
/* Lane 08 (TODO.xslt-full/08) first slice: the map constructor
|
|
3759
|
+
* expression + get/size/keys/contains. Saxon-HE 12.7 ground
|
|
3760
|
+
* truth (/tmp/probe9/map8b.xsl). */
|
|
3761
|
+
EXPECT_EQ(body(run30(
|
|
3762
|
+
"<xsl:template match='/'>"
|
|
3763
|
+
"<xsl:variable name='m' select=\"map { 'a': 1, 'b': 'beta',"
|
|
3764
|
+
" 'c': count(//i) }\"/>"
|
|
3765
|
+
"<o xmlns:map='http://www.w3.org/2005/xpath-functions/map'>"
|
|
3766
|
+
"<a><xsl:value-of select='map:size($m)'/></a>"
|
|
3767
|
+
"<b><xsl:value-of select=\"map:get($m, 'b')\"/></b>"
|
|
3768
|
+
"<c><xsl:value-of select=\"string-join(map:keys($m), ',')\"/></c>"
|
|
3769
|
+
"<d><xsl:value-of select=\"map:contains($m, 'a')\"/></d>"
|
|
3770
|
+
"<e><xsl:value-of select=\"map:contains($m, 'z')\"/></e>"
|
|
3771
|
+
"</o></xsl:template>",
|
|
3772
|
+
"<r><i>1</i><i>2</i></r>")),
|
|
3773
|
+
"<o xmlns:map=\"http://www.w3.org/2005/xpath-functions/map\">"
|
|
3774
|
+
"<a>3</a><b>beta</b><c>a,b,c</c><d>true</d><e>false</e></o>");
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3777
|
+
TEST(Xslt30, CastAndInstanceof) {
|
|
3778
|
+
/* Lane 06: instance of / castable as / cast as (Saxon-HE 12.7
|
|
3779
|
+
* ground truth, /tmp/probe9/g6.xsl — incl. the falsifiable
|
|
3780
|
+
* negative and the truncation case). */
|
|
3781
|
+
EXPECT_EQ(body(run30(
|
|
3782
|
+
"<xsl:template match='/'>"
|
|
3783
|
+
"<o xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
|
|
3784
|
+
"<a><xsl:value-of select=\"'x' instance of xs:string\"/></a>"
|
|
3785
|
+
"<b><xsl:value-of select=\"//i instance of node()+\"/></b>"
|
|
3786
|
+
"<c><xsl:value-of select=\"'3' castable as xs:integer\"/></c>"
|
|
3787
|
+
"<d><xsl:value-of select=\"'x' castable as xs:integer\"/></d>"
|
|
3788
|
+
"<e><xsl:value-of select=\"'42' cast as xs:integer\"/></e>"
|
|
3789
|
+
"<f><xsl:value-of select=\"xs:double('1.9') cast as xs:integer\"/></f>"
|
|
3790
|
+
"</o></xsl:template>",
|
|
3791
|
+
"<r><i>1</i></r>")),
|
|
3792
|
+
"<o xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
3793
|
+
"<a>true</a><b>true</b><c>true</c><d>false</d>"
|
|
3794
|
+
"<e>42</e><f>1</f></o>");
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3797
|
+
TEST(Xslt30, XsConstructorFunctions) {
|
|
3798
|
+
/* Lane 06 (TODO.xslt-full/06): xs:* constructor functions.
|
|
3799
|
+
* Saxon-HE 12.7 ground truth (/tmp/probe9/g6.xsl): the atomic
|
|
3800
|
+
* constructors convert through the string/number value. */
|
|
3801
|
+
EXPECT_EQ(body(run30(
|
|
3802
|
+
"<xsl:template match='/'>"
|
|
3803
|
+
"<o xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
|
|
3804
|
+
"<a><xsl:value-of select=\"xs:integer('42') + 1\"/></a>"
|
|
3805
|
+
"<b><xsl:value-of select=\"xs:double('1.5') * 2\"/></b>"
|
|
3806
|
+
"<c><xsl:value-of select=\"xs:boolean('true')\"/></c>"
|
|
3807
|
+
"<d><xsl:value-of select=\"xs:string(7)\"/></d>"
|
|
3808
|
+
"</o></xsl:template>",
|
|
3809
|
+
"<r/>")),
|
|
3810
|
+
"<o xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
3811
|
+
"<a>43</a><b>3</b><c>true</c><d>7</d></o>");
|
|
3812
|
+
}
|
|
3813
|
+
|
|
3814
|
+
TEST(Xslt30, InstanceOfNodeKindsAndCardinality) {
|
|
3815
|
+
/* #744: element()/attribute()/text() must match their node
|
|
3816
|
+
* kind, and occurrence indicators (? + *) must gate
|
|
3817
|
+
* cardinality. Saxon-HE 12.7 (/tmp/probe9/l07b/t3.xsl). */
|
|
3818
|
+
EXPECT_EQ(body(run30(
|
|
3819
|
+
"<xsl:template match='/'>"
|
|
3820
|
+
"<o xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
|
|
3821
|
+
"<a><xsl:value-of select=\"//i[1] instance of element()\"/></a>"
|
|
3822
|
+
"<b><xsl:value-of select=\"//i[1] instance of node()\"/></b>"
|
|
3823
|
+
"<c><xsl:value-of select=\"//i/@id instance of attribute()\"/></c>"
|
|
3824
|
+
"<d><xsl:value-of select=\"//text()[1] instance of text()\"/></d>"
|
|
3825
|
+
"<e><xsl:value-of select=\"('a','b') instance of xs:string+\"/></e>"
|
|
3826
|
+
"<f><xsl:value-of select=\"('a','b') instance of xs:string\"/></f>"
|
|
3827
|
+
"<g><xsl:value-of select=\"'a' instance of xs:string?\"/></g>"
|
|
3828
|
+
"<h><xsl:value-of select=\"//i instance of element()+\"/></h>"
|
|
3829
|
+
"<i><xsl:value-of select=\"('a',1) instance of xs:string*\"/></i>"
|
|
3830
|
+
"</o></xsl:template>",
|
|
3831
|
+
"<r><i id='x'>1</i></r>")),
|
|
3832
|
+
"<o xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
3833
|
+
"<a>true</a><b>true</b><c>true</c><d>true</d>"
|
|
3834
|
+
"<e>true</e><f>false</f><g>true</g><h>true</h><i>false</i>"
|
|
3835
|
+
"</o>");
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
TEST(Xslt30, CastAsNumericInExpressions) {
|
|
3839
|
+
/* #744: `cast as` a numeric target used to fail compilation
|
|
3840
|
+
* when followed by an operator — the parser ate `+` as an
|
|
3841
|
+
* occurrence indicator. Saxon-HE 12.7. */
|
|
3842
|
+
EXPECT_EQ(body(run30(
|
|
3843
|
+
"<xsl:template match='/'>"
|
|
3844
|
+
"<o xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
|
|
3845
|
+
"<a><xsl:value-of select=\"'12' cast as xs:integer + 1\"/></a>"
|
|
3846
|
+
"<b><xsl:value-of select=\"'2.5' cast as xs:double * 2\"/></b>"
|
|
3847
|
+
"</o></xsl:template>",
|
|
3848
|
+
"<r/>")),
|
|
3849
|
+
"<o xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
3850
|
+
"<a>13</a><b>5</b></o>");
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3853
|
+
TEST(Xslt30, XsLexicalCastRules) {
|
|
3854
|
+
/* #739: constructors take XSD LEXICAL forms, not boolean()
|
|
3855
|
+
* string-truthiness: '0'/'false' cast to false, whitespace is
|
|
3856
|
+
* allowed, invalid lexicals are dynamic errors. Saxon-HE 12.7
|
|
3857
|
+
* (FORG0001 on 'x' / ' -3.9 '). */
|
|
3858
|
+
EXPECT_EQ(body(run30(
|
|
3859
|
+
"<xsl:template match='/'>"
|
|
3860
|
+
"<o xmlns:xs='http://www.w3.org/2001/XMLSchema'>"
|
|
3861
|
+
"<a><xsl:value-of select=\"xs:boolean('0')\"/></a>"
|
|
3862
|
+
"<b><xsl:value-of select=\"xs:boolean('false')\"/></b>"
|
|
3863
|
+
"<c><xsl:value-of select=\"xs:boolean(' true ')\"/></c>"
|
|
3864
|
+
"<d><xsl:value-of select=\"xs:boolean('1')\"/></d>"
|
|
3865
|
+
"<e><xsl:value-of select=\"xs:integer(' 42 ') + 1\"/></e>"
|
|
3866
|
+
"</o></xsl:template>",
|
|
3867
|
+
"<r/>")),
|
|
3868
|
+
"<o xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
3869
|
+
"<a>false</a><b>false</b><c>true</c><d>true</d><e>43</e>"
|
|
3870
|
+
"</o>");
|
|
3871
|
+
EXPECT_EQ(body(run30(
|
|
3872
|
+
"<xsl:template match='/'>"
|
|
3873
|
+
"<o><xsl:value-of select=\"xs:boolean('x')\" xmlns:xs="
|
|
3874
|
+
"'http://www.w3.org/2001/XMLSchema'/></o></xsl:template>",
|
|
3875
|
+
"<r/>")),
|
|
3876
|
+
"(null)");
|
|
3877
|
+
EXPECT_EQ(body(run30(
|
|
3878
|
+
"<xsl:template match='/'>"
|
|
3879
|
+
"<o><xsl:value-of select=\"xs:integer(' -3.9 ')\" xmlns:xs="
|
|
3880
|
+
"'http://www.w3.org/2001/XMLSchema'/></o></xsl:template>",
|
|
3881
|
+
"<r/>")),
|
|
3882
|
+
"(null)");
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3885
|
+
TEST(Xslt30, OnCompletionSeesIterateParams) {
|
|
3886
|
+
/* #729: the on-completion body runs with the FINAL iteration's
|
|
3887
|
+
* parameter values (§12.5). */
|
|
3888
|
+
EXPECT_EQ(body(run30(
|
|
3889
|
+
"<xsl:template match='/'>"
|
|
3890
|
+
"<out><xsl:iterate select='1 to 4'>"
|
|
3891
|
+
"<xsl:param name='sum' select='0'/>"
|
|
3892
|
+
"<xsl:next-iteration>"
|
|
3893
|
+
"<xsl:with-param name='sum' select='$sum + .'/>"
|
|
3894
|
+
"</xsl:next-iteration>"
|
|
3895
|
+
"<xsl:on-completion><xsl:value-of select='$sum'/></xsl:on-completion>"
|
|
3896
|
+
"</xsl:iterate></out></xsl:template>",
|
|
3897
|
+
"<r/>")),
|
|
3898
|
+
"<out>10</out>");
|
|
3899
|
+
}
|
|
3900
|
+
|
|
3901
|
+
TEST(Xslt30, MergeGroupsByKeysAcrossShapes) {
|
|
3902
|
+
/* #731: grouping by key must hold for string-sequence sources
|
|
3903
|
+
* (synthetic text items) AND single sources with attribute keys. */
|
|
3904
|
+
EXPECT_EQ(body(run30(
|
|
3905
|
+
"<xsl:variable name='L' select=\"('a1', 'a3')\"/>"
|
|
3906
|
+
"<xsl:variable name='R' select=\"('a2', 'a3')\"/>"
|
|
3907
|
+
"<xsl:template match='/'>"
|
|
3908
|
+
"<out><xsl:merge>"
|
|
3909
|
+
"<xsl:merge-source name='l' select='$L'/>"
|
|
3910
|
+
"<xsl:merge-source name='r' select='$R'/>"
|
|
3911
|
+
"<xsl:merge-key select='string(.)'/>"
|
|
3912
|
+
"<xsl:merge-action>"
|
|
3913
|
+
"<m><xsl:value-of select='current-merge-key()'/>|"
|
|
3914
|
+
"<xsl:value-of select=\"count(current-merge-group('l'))\"/>+"
|
|
3915
|
+
"<xsl:value-of select=\"count(current-merge-group('r'))\"/></m>"
|
|
3916
|
+
"</xsl:merge-action>"
|
|
3917
|
+
"</xsl:merge></out></xsl:template>",
|
|
3918
|
+
"<r/>")),
|
|
3919
|
+
"<out><m>a1|1+0</m><m>a2|0+1</m><m>a3|1+1</m></out>");
|
|
3920
|
+
EXPECT_EQ(body(run30(
|
|
3921
|
+
"<xsl:template match='/'>"
|
|
3922
|
+
"<out><xsl:merge>"
|
|
3923
|
+
"<xsl:merge-source name='s' select='//i'>"
|
|
3924
|
+
"<xsl:merge-key select='@k'/>"
|
|
3925
|
+
"</xsl:merge-source>"
|
|
3926
|
+
"<xsl:merge-action>"
|
|
3927
|
+
"<m><xsl:value-of select='current-merge-key()'/></m>"
|
|
3928
|
+
"</xsl:merge-action>"
|
|
3929
|
+
"</xsl:merge></out></xsl:template>",
|
|
3930
|
+
"<r><i k='a'>1</i><i k='b'>2</i></r>")),
|
|
3931
|
+
"<out><m>a</m><m>b</m></out>");
|
|
3932
|
+
}
|
|
3933
|
+
|
|
3934
|
+
TEST(Xslt30, MultipleTopLevelNodesSerializeFully) {
|
|
3935
|
+
/* #732 triage: multiple top-level nodes are a SUPPORTED result
|
|
3936
|
+
* shape (libxslt parity — the adopted suite pins byte-for-byte
|
|
3937
|
+
* multi-root outputs; Saxon errors instead, which we
|
|
3938
|
+
* deliberately do not mirror). Interleaved text, elements, and
|
|
3939
|
+
* call-template text-only output must all survive. */
|
|
3940
|
+
EXPECT_EQ(body(run30(
|
|
3941
|
+
"<xsl:template match='/'>\n <t1><xsl:value-of "
|
|
3942
|
+
"select=\"'V'\"/></t1>\n <t2><xsl:value-of "
|
|
3943
|
+
"select=\"'W'\"/></t2>\n </xsl:template>",
|
|
3944
|
+
"<r/>")),
|
|
3945
|
+
"<t1>V</t1><t2>W</t2>");
|
|
3946
|
+
EXPECT_EQ(body(run30(
|
|
3947
|
+
"<xsl:template name='h'>H</xsl:template>"
|
|
3948
|
+
"<xsl:template match='/'>"
|
|
3949
|
+
"<xsl:call-template name='h'/>"
|
|
3950
|
+
"<xsl:call-template name='h'/></xsl:template>",
|
|
3951
|
+
"<r/>")),
|
|
3952
|
+
"HH");
|
|
3953
|
+
}
|
|
3954
|
+
|
|
3955
|
+
TEST(Xslt30, CharacterMapsApplyToTextAndAttributes) {
|
|
3956
|
+
/* Saxon-HE 12.7 ground truth: both maps listed in
|
|
3957
|
+
* use-character-maps apply; substitution hits text nodes AND
|
|
3958
|
+
* attribute values, never markup. */
|
|
3959
|
+
EXPECT_EQ(body(run30(
|
|
3960
|
+
"<xsl:output use-character-maps='cm1 cm2'/>"
|
|
3961
|
+
"<xsl:character-map name='cm1'>"
|
|
3962
|
+
"<xsl:output-character character='→' string='->'/>"
|
|
3963
|
+
"</xsl:character-map>"
|
|
3964
|
+
"<xsl:character-map name='cm2'>"
|
|
3965
|
+
"<xsl:output-character character='λ' string='lambda'/>"
|
|
3966
|
+
"</xsl:character-map>"
|
|
3967
|
+
"<xsl:template match='/'>"
|
|
3968
|
+
"<o a='x→y'>λ</o></xsl:template>",
|
|
3969
|
+
"<r/>")),
|
|
3970
|
+
"<o a=\"x->y\">lambda</o>");
|
|
3971
|
+
}
|
|
3972
|
+
|
|
3973
|
+
TEST(Xslt30, ResultDocumentWritesSecondaryFile) {
|
|
3974
|
+
/* Saxon-HE 12.7 ground truth: the principal result is unchanged;
|
|
3975
|
+
* the secondary document is serialized (with declaration) to the
|
|
3976
|
+
* href. */
|
|
3977
|
+
const char* path = "/tmp/leptris-rd-spec.xml";
|
|
3978
|
+
remove(path);
|
|
3979
|
+
EXPECT_EQ(body(run30(
|
|
3980
|
+
"<xsl:template match='/'>"
|
|
3981
|
+
"<main><xsl:result-document href='/tmp/leptris-rd-spec.xml'>"
|
|
3982
|
+
"<sec n='1'>hello</sec></xsl:result-document>body</main>"
|
|
3983
|
+
"</xsl:template>",
|
|
3984
|
+
"<r/>")),
|
|
3985
|
+
"<main>body</main>");
|
|
3986
|
+
FILE* f = fopen(path, "rb");
|
|
3987
|
+
ASSERT_NE(f, nullptr);
|
|
3988
|
+
std::string got;
|
|
3989
|
+
char buf[256];
|
|
3990
|
+
size_t n;
|
|
3991
|
+
while ((n = fread(buf, 1, sizeof(buf), f)) > 0) got.append(buf, n);
|
|
3992
|
+
fclose(f);
|
|
3993
|
+
remove(path);
|
|
3994
|
+
EXPECT_EQ(got,
|
|
3995
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
|
3996
|
+
"<sec n=\"1\">hello</sec>");
|
|
3997
|
+
}
|
|
3998
|
+
|
|
3999
|
+
TEST(Xslt30, NextIterationChainsParams) {
|
|
4000
|
+
/* Sum 1..4 via xsl:next-iteration param rebinding. */
|
|
4001
|
+
EXPECT_EQ(body(run30(
|
|
4002
|
+
"<xsl:template match='/'>"
|
|
4003
|
+
"<o><xsl:iterate select='1 to 4'>"
|
|
4004
|
+
"<xsl:param name='acc' select='0'/>"
|
|
4005
|
+
"<xsl:choose>"
|
|
4006
|
+
"<xsl:when test='. = 4'><xsl:value-of select='$acc + .'/></xsl:when>"
|
|
4007
|
+
"<xsl:otherwise>"
|
|
4008
|
+
"<xsl:next-iteration>"
|
|
4009
|
+
"<xsl:with-param name='acc' select='$acc + .'/>"
|
|
4010
|
+
"</xsl:next-iteration>"
|
|
4011
|
+
"</xsl:otherwise>"
|
|
4012
|
+
"</xsl:choose>"
|
|
4013
|
+
"</xsl:iterate></o></xsl:template>",
|
|
4014
|
+
"<r/>")),
|
|
4015
|
+
"<o>10</o>");
|
|
4016
|
+
}
|
|
4017
|
+
|
|
4018
|
+
TEST(Xslt30, IterateSequenceParamKeepsPriorValues) {
|
|
4019
|
+
/* #1066: a sequence accumulated through xsl:next-iteration
|
|
4020
|
+
* must keep every prior member's VALUE — the scratch-varset
|
|
4021
|
+
* snapshot dropped owns_synthetic_text, so variable lookups
|
|
4022
|
+
* borrowed the binding's synthetic members and the scope pop
|
|
4023
|
+
* freed them (joined came out ",,gamma"; Saxon: the full
|
|
4024
|
+
* alpha,beta,gamma). */
|
|
4025
|
+
EXPECT_EQ(body(run30(
|
|
4026
|
+
"<xsl:template match='/'>"
|
|
4027
|
+
"<out><xsl:iterate select='r/item'>"
|
|
4028
|
+
"<xsl:param name='labels' select='()'/>"
|
|
4029
|
+
"<xsl:variable name='label' select='string(name)'/>"
|
|
4030
|
+
"<xsl:if test='$label != \"\"'>"
|
|
4031
|
+
"<row label=\"{upper-case($label)}\"/>"
|
|
4032
|
+
"</xsl:if>"
|
|
4033
|
+
"<xsl:next-iteration>"
|
|
4034
|
+
"<xsl:with-param name='labels' select='($labels, $label)'/>"
|
|
4035
|
+
"</xsl:next-iteration>"
|
|
4036
|
+
"<xsl:on-completion>"
|
|
4037
|
+
"<count><xsl:value-of select='count($labels)'/></count>"
|
|
4038
|
+
"<joined><xsl:value-of select='string-join($labels, \",\")'/></joined>"
|
|
4039
|
+
"</xsl:on-completion>"
|
|
4040
|
+
"</xsl:iterate></out></xsl:template>",
|
|
4041
|
+
"<r><item><name>alpha</name></item>"
|
|
4042
|
+
"<item><name>beta</name></item>"
|
|
4043
|
+
"<item><name>gamma</name></item></r>")),
|
|
4044
|
+
"<out><row label=\"ALPHA\"/><row label=\"BETA\"/>"
|
|
4045
|
+
"<row label=\"GAMMA\"/><count>3</count>"
|
|
4046
|
+
"<joined>alpha,beta,gamma</joined></out>");
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
TEST(Xslt30, CopySelectNamespaceDocumentDefault) {
|
|
4050
|
+
/* Saxon-HE 12.7 ground truth (TODO.xslt-full/09 batch C).
|
|
4051
|
+
* NOTE: @default is XSLT 4.0 (Saxon 12.7 rejects it
|
|
4052
|
+
* statically) — our engine accepts it as a dynamic default;
|
|
4053
|
+
* pinned at our semantics. */
|
|
4054
|
+
EXPECT_EQ(body(run30(
|
|
4055
|
+
"<xsl:template match='/'>"
|
|
4056
|
+
"<cp><xsl:copy select='//i[1]/node()'/></cp>"
|
|
4057
|
+
"<cp2><xsl:copy select='//i[1]/@n'/></cp2>"
|
|
4058
|
+
"<ns><e><xsl:namespace name='x'>urn:xx</xsl:namespace></e></ns>"
|
|
4059
|
+
"<dc><xsl:document><d/>text</xsl:document></dc>"
|
|
4060
|
+
"</xsl:template>",
|
|
4061
|
+
"<r><i n='5'>txt</i></r>")),
|
|
4062
|
+
"<cp>txt</cp><cp2 n=\"5\"/>"
|
|
4063
|
+
"<ns><e xmlns:x=\"urn:xx\"/></ns><dc><d/>text</dc>");
|
|
4064
|
+
EXPECT_EQ(body(run30(
|
|
4065
|
+
"<xsl:template match='/'>"
|
|
4066
|
+
"<o><xsl:iterate select='1 to 3'>"
|
|
4067
|
+
"<xsl:on-completion>done</xsl:on-completion><i/>"
|
|
4068
|
+
"</xsl:iterate></o>"
|
|
4069
|
+
"</xsl:template>",
|
|
4070
|
+
"<r/>")),
|
|
4071
|
+
"<o><i/><i/><i/>done</o>");
|
|
4072
|
+
EXPECT_EQ(body(run30(
|
|
4073
|
+
"<xsl:template name='t'>"
|
|
4074
|
+
"<xsl:param name='q' default=\"'dy'\"/>"
|
|
4075
|
+
"[<xsl:value-of select='$q'/>]"
|
|
4076
|
+
"</xsl:template>"
|
|
4077
|
+
"<xsl:template match='/'>"
|
|
4078
|
+
"<xsl:call-template name='t'/>"
|
|
4079
|
+
"<xsl:call-template name='t'>"
|
|
4080
|
+
"<xsl:with-param name='q' select='\"given\"'/></xsl:call-template>"
|
|
4081
|
+
"</xsl:template>",
|
|
4082
|
+
"<r/>")),
|
|
4083
|
+
"[dy][given]");
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
/* value-of select="." takes the parse-time fast path (no eval
|
|
4087
|
+
* machinery, #682): the emitted text must stay the context node's
|
|
4088
|
+
* FULL string-value — deep descendant text for elements, the value
|
|
4089
|
+
* for attribute context nodes — in both 1.0 and 3.0 sheets, and
|
|
4090
|
+
* with surrounding whitespace in the attribute. */
|
|
4091
|
+
TEST(Xslt30, ValueOfDotIsDeepStringValue) {
|
|
4092
|
+
const char* sheet =
|
|
4093
|
+
"<xsl:template match='/'>"
|
|
4094
|
+
"<e><xsl:value-of select='.'/></e>"
|
|
4095
|
+
"<w><xsl:value-of select=' . '/></w>"
|
|
4096
|
+
"</xsl:template>";
|
|
4097
|
+
EXPECT_EQ(body(run(sheet, "<r>x<b/>y<!--c--><i>z</i></r>")),
|
|
4098
|
+
"<e>xyz</e><w>xyz</w>");
|
|
4099
|
+
EXPECT_EQ(body(run30(sheet, "<r>x<b/>y<!--c--><i>z</i></r>")),
|
|
4100
|
+
"<e>xyz</e><w>xyz</w>");
|
|
4101
|
+
/* '.' with an attribute context node (for-each over @*): the
|
|
4102
|
+
* string-value of an attribute is its value. */
|
|
4103
|
+
EXPECT_EQ(body(run(
|
|
4104
|
+
"<xsl:template match='/i'>"
|
|
4105
|
+
"<xsl:for-each select='@*'>[<xsl:value-of select='.'/>]</xsl:for-each>"
|
|
4106
|
+
"</xsl:template>",
|
|
4107
|
+
"<i a='1' b='2'/>")),
|
|
4108
|
+
"[1][2]");
|
|
4109
|
+
/* Text-node context: string-value is the text itself (the
|
|
4110
|
+
* literal </> around it re-escape on output). */
|
|
4111
|
+
EXPECT_EQ(body(run(
|
|
4112
|
+
"<xsl:template match='/r/t'>"
|
|
4113
|
+
"<<xsl:value-of select='.'/>>"
|
|
4114
|
+
"</xsl:template>",
|
|
4115
|
+
"<r><t>hi</t></r>")),
|
|
4116
|
+
"<hi>");
|
|
4117
|
+
}
|
|
4118
|
+
|
|
4119
|
+
/* Fragment-output order across the cached tails (#682): top-level
|
|
4120
|
+
* nodes with no pending parent chain after the root's siblings
|
|
4121
|
+
* (pre-root ones hold on the frag list) — a stale tail entry would
|
|
4122
|
+
* drop or reorder nodes. Pins the exact order for text, comments
|
|
4123
|
+
* and multiple top-level elements, interleaved. */
|
|
4124
|
+
TEST(Xslt30, FragmentNodesKeepOrderAcrossTailCache) {
|
|
4125
|
+
EXPECT_EQ(body(run(
|
|
4126
|
+
"<xsl:template match='/'>"
|
|
4127
|
+
"a<xsl:comment>c1</xsl:comment>"
|
|
4128
|
+
"<e1/>b<xsl:comment>c2</xsl:comment>"
|
|
4129
|
+
"<e2/>c"
|
|
4130
|
+
"</xsl:template>",
|
|
4131
|
+
"<r/>")),
|
|
4132
|
+
"a<!--c1--><e1/>b<!--c2--><e2/>c");
|
|
4133
|
+
/* Pure-text fragment (no element ever anchors the chain): every
|
|
4134
|
+
* value-of keeps its position. */
|
|
4135
|
+
EXPECT_EQ(body(run(
|
|
4136
|
+
"<xsl:template match='/'>"
|
|
4137
|
+
"<xsl:for-each select='//t'><xsl:value-of select='.'/></xsl:for-each>"
|
|
4138
|
+
"</xsl:template>",
|
|
4139
|
+
"<r><t>one</t><t>two</t><t>three</t></r>")),
|
|
4140
|
+
"onetwothree");
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
TEST(Xslt30, GlobalContextItemDeclarationAccepted) {
|
|
4144
|
+
/* #690 audit: the declaration is a no-op here — the transform
|
|
4145
|
+
* always carries the source document as its global context. */
|
|
4146
|
+
EXPECT_EQ(body(run30(
|
|
4147
|
+
"<xsl:global-context-item as='item()' use-accumulators='#all'/>"
|
|
4148
|
+
"<xsl:template match='/'>[<xsl:value-of select='count(//*)'/>]"
|
|
4149
|
+
"</xsl:template>",
|
|
4150
|
+
"<r><a/><b/></r>")),
|
|
4151
|
+
"[3]");
|
|
4152
|
+
}
|
|
4153
|
+
|
|
4154
|
+
TEST(Xslt30, RejectsXQueryOnlySyntaxInExpressions) {
|
|
4155
|
+
/* try/catch was implemented (TODO 11/12 lane, #692): XPath 3.0
|
|
4156
|
+
* defines it, so this once-rejected form now evaluates. */
|
|
4157
|
+
EXPECT_EQ(body(run30(
|
|
4158
|
+
"<xsl:template match='/'>"
|
|
4159
|
+
"[<xsl:value-of select=\"try { 1 + 2 } catch * { 'no' }\"/>]"
|
|
4160
|
+
"</xsl:template>",
|
|
4161
|
+
"<r/>")),
|
|
4162
|
+
"[3]");
|
|
4163
|
+
/* The map constructor compile-failure pin was superseded by
|
|
4164
|
+
* lane 08: map { ... } is implemented (FnMapConstructorAnd
|
|
4165
|
+
* Accessors). */
|
|
4166
|
+
/* Saxon-HE 12.7: XPST0003 "switch is not allowed in XPath"
|
|
4167
|
+
* (XQuery-only) — our loud rejection is oracle parity. */
|
|
4168
|
+
EXPECT_EQ(body(run30(
|
|
4169
|
+
"<xsl:template match='/'>"
|
|
4170
|
+
"[<xsl:value-of select=\"switch (2) { case 1 return 'one' "
|
|
4171
|
+
"default return 'other' }\"/>]"
|
|
4172
|
+
"</xsl:template>",
|
|
4173
|
+
"<r/>")),
|
|
4174
|
+
"(compile-failed)");
|
|
4175
|
+
/* 3.1 string constructors are XPath 4.0: Saxon-HE 12.7 rejects
|
|
4176
|
+
* (XPST0003 "not configured to allow use of XPath 4.0 syntax")
|
|
4177
|
+
* — parity until the Saxon-13 probe. */
|
|
4178
|
+
EXPECT_EQ(body(run30(
|
|
4179
|
+
"<xsl:template match='/'>"
|
|
4180
|
+
"[<xsl:value-of select=\"`v={count(//i)}`\"/>]"
|
|
4181
|
+
"</xsl:template>",
|
|
4182
|
+
"<r/>")),
|
|
4183
|
+
"(compile-failed)");
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4186
|
+
|
|
4187
|
+
/* #875: the #866 dispatch indexes had hard capacity caps (name keys
|
|
4188
|
+
* 48, literal @attr='value' keys 96 per mode bucket) with a silent
|
|
4189
|
+
* `continue` — patterns past the cap vanished from dispatch entirely
|
|
4190
|
+
* (120-template sheets: item[@k='N'] broke at 96, distinct names at
|
|
4191
|
+
* 48; zero output, no error). Overflowed patterns must fall back to
|
|
4192
|
+
* the scanned remainder list. */
|
|
4193
|
+
TEST(XsltFull, DispatchIndexOverflowFiresAllTemplates) {
|
|
4194
|
+
/* Shape 1: 120 distinct names — the 48-cap name-key path. */
|
|
4195
|
+
{
|
|
4196
|
+
std::string body, xml = "<doc>";
|
|
4197
|
+
std::string sheet =
|
|
4198
|
+
"<xsl:template match='/'>"
|
|
4199
|
+
"<xsl:apply-templates select='*'/></xsl:template>";
|
|
4200
|
+
for (int i = 0; i < 120; i++) {
|
|
4201
|
+
char t[256], e[64];
|
|
4202
|
+
snprintf(t, sizeof(t),
|
|
4203
|
+
"<xsl:template match='t%d'>T%d</xsl:template>", i, i);
|
|
4204
|
+
sheet += t;
|
|
4205
|
+
snprintf(e, sizeof(e), "<t%d/>", i);
|
|
4206
|
+
xml += e;
|
|
4207
|
+
}
|
|
4208
|
+
xml += "</doc>";
|
|
4209
|
+
std::string out = run(sheet.c_str(), xml.c_str());
|
|
4210
|
+
size_t prolog = out.find("?>");
|
|
4211
|
+
if (prolog != std::string::npos) out = out.substr(prolog + 2);
|
|
4212
|
+
size_t nz = out.find_first_not_of(" \t\r\n");
|
|
4213
|
+
if (nz != std::string::npos) out = out.substr(nz);
|
|
4214
|
+
while (!out.empty() && strchr(" \t\r\n", out.back())) out.pop_back();
|
|
4215
|
+
std::string want;
|
|
4216
|
+
for (int i = 0; i < 120; i++) want += "T" + std::to_string(i);
|
|
4217
|
+
EXPECT_EQ(out, want);
|
|
4218
|
+
}
|
|
4219
|
+
/* Shape 2: 120 same-name attr literals — the 96-cap pkey path. */
|
|
4220
|
+
{
|
|
4221
|
+
std::string sheet =
|
|
4222
|
+
"<xsl:template match='/'>"
|
|
4223
|
+
"<xsl:apply-templates select='*'/></xsl:template>";
|
|
4224
|
+
std::string xml = "<doc>";
|
|
4225
|
+
for (int i = 0; i < 120; i++) {
|
|
4226
|
+
char t[256], e[64];
|
|
4227
|
+
snprintf(t, sizeof(t),
|
|
4228
|
+
"<xsl:template match=\"item[@k='%d']\">V%d"
|
|
4229
|
+
"</xsl:template>", i, i);
|
|
4230
|
+
sheet += t;
|
|
4231
|
+
snprintf(e, sizeof(e), "<item k='%d'/>", i);
|
|
4232
|
+
xml += e;
|
|
4233
|
+
}
|
|
4234
|
+
xml += "</doc>";
|
|
4235
|
+
std::string out = run(sheet.c_str(), xml.c_str());
|
|
4236
|
+
size_t prolog = out.find("?>");
|
|
4237
|
+
if (prolog != std::string::npos) out = out.substr(prolog + 2);
|
|
4238
|
+
size_t nz = out.find_first_not_of(" \t\r\n");
|
|
4239
|
+
if (nz != std::string::npos) out = out.substr(nz);
|
|
4240
|
+
while (!out.empty() && strchr(" \t\r\n", out.back())) out.pop_back();
|
|
4241
|
+
std::string want;
|
|
4242
|
+
for (int i = 0; i < 120; i++) want += "V" + std::to_string(i);
|
|
4243
|
+
EXPECT_EQ(out, want);
|
|
4244
|
+
}
|
|
4245
|
+
}
|