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.
Files changed (1535) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Rakefile +52 -12
  4. data/ext/leptris/native/extconf.rb +85 -0
  5. data/ext/leptris/native/native.c +1 -1
  6. data/lib/leptris/version.rb +1 -1
  7. data/lib/leptris/xml/ffi.rb +13 -0
  8. data/lib/leptris/xml/native.so +0 -0
  9. data/vendor-src/libleptris/CHANGELOG.md +8080 -0
  10. data/vendor-src/libleptris/CLAUDE.md +150 -0
  11. data/vendor-src/libleptris/CMakeLists.txt +379 -0
  12. data/vendor-src/libleptris/CMakePresets.json +61 -0
  13. data/vendor-src/libleptris/CODE_OF_CONDUCT.md +132 -0
  14. data/vendor-src/libleptris/CONTEXT.md +49 -0
  15. data/vendor-src/libleptris/LICENSE.md +33 -0
  16. data/vendor-src/libleptris/README.adoc +1197 -0
  17. data/vendor-src/libleptris/TODO.assemble/README.md +16 -0
  18. data/vendor-src/libleptris/TODO.bindings/01-mutation-construction.md +18 -0
  19. data/vendor-src/libleptris/TODO.bindings/02-incremental-iterparse.md +15 -0
  20. data/vendor-src/libleptris/TODO.bindings/03-compiled-xpath.md +15 -0
  21. data/vendor-src/libleptris/TODO.bindings/04-pull-stax-api.md +14 -0
  22. data/vendor-src/libleptris/TODO.bindings/05-per-parse-options.md +17 -0
  23. data/vendor-src/libleptris/TODO.bindings/06-serialize-encoding-guarantees.md +14 -0
  24. data/vendor-src/libleptris/TODO.bindings/README.md +36 -0
  25. data/vendor-src/libleptris/TODO.concurrency/01-thread-safe-errors.md +19 -0
  26. data/vendor-src/libleptris/TODO.concurrency/02-export-surface-gate.md +24 -0
  27. data/vendor-src/libleptris/TODO.concurrency/03-mixed-nodeset-batch.md +14 -0
  28. data/vendor-src/libleptris/TODO.concurrency/04-canonical-status-message.md +13 -0
  29. data/vendor-src/libleptris/TODO.concurrency/05-windows-dll-name.md +10 -0
  30. data/vendor-src/libleptris/TODO.concurrency/06-exslt-pack.md +26 -0
  31. data/vendor-src/libleptris/TODO.concurrency/07-ns-set-pairs.md +11 -0
  32. data/vendor-src/libleptris/TODO.concurrency/08-threading-contract.md +45 -0
  33. data/vendor-src/libleptris/TODO.engine/01-file-sources.md +11 -0
  34. data/vendor-src/libleptris/TODO.engine/02-compiled-contexts.md +10 -0
  35. data/vendor-src/libleptris/TODO.engine/03-rust-publish.md +9 -0
  36. data/vendor-src/libleptris/TODO.engine/04-ruby-release-input.md +8 -0
  37. data/vendor-src/libleptris/TODO.engine/05-todo-md-refresh.md +7 -0
  38. data/vendor-src/libleptris/TODO.engine/README.md +16 -0
  39. data/vendor-src/libleptris/TODO.hygiene/README.md +15 -0
  40. data/vendor-src/libleptris/TODO.max-perf/00-INDEX.md +22 -0
  41. data/vendor-src/libleptris/TODO.max-perf/1-simd-html-scanner.md +15 -0
  42. data/vendor-src/libleptris/TODO.max-perf/10-moxml-plan-followups.md +9 -0
  43. data/vendor-src/libleptris/TODO.max-perf/2-compiled-dispatch-tokenizer.md +8 -0
  44. data/vendor-src/libleptris/TODO.max-perf/3-iterparse-fixed-cost.md +5 -0
  45. data/vendor-src/libleptris/TODO.max-perf/4-compact-node-micro-opts.md +17 -0
  46. data/vendor-src/libleptris/TODO.max-perf/5-xslt-bench-profiling-rounds.md +13 -0
  47. data/vendor-src/libleptris/TODO.max-perf/6-language-tails.md +9 -0
  48. data/vendor-src/libleptris/TODO.max-perf/7-validate-bindings.md +6 -0
  49. data/vendor-src/libleptris/TODO.max-perf/8-native-xml-diff-consumer.md +5 -0
  50. data/vendor-src/libleptris/TODO.max-perf/9-prebuilt-gem-matrix.md +14 -0
  51. data/vendor-src/libleptris/TODO.md +33 -0
  52. data/vendor-src/libleptris/TODO.transform/README.md +39 -0
  53. data/vendor-src/libleptris/TODO.validate/README.md +32 -0
  54. data/vendor-src/libleptris/TODO.xpath2/README.md +91 -0
  55. data/vendor-src/libleptris/TODO.xslt-full/01-xpath-fn-sequences.md +27 -0
  56. data/vendor-src/libleptris/TODO.xslt-full/02-xpath-fn-regex.md +13 -0
  57. data/vendor-src/libleptris/TODO.xslt-full/03-xpath-fn-math.md +10 -0
  58. data/vendor-src/libleptris/TODO.xslt-full/04-xpath-fn-strings-qname-uri.md +97 -0
  59. data/vendor-src/libleptris/TODO.xslt-full/05-xpath-fn-dates.md +30 -0
  60. data/vendor-src/libleptris/TODO.xslt-full/06-xpath-grammar-3x.md +83 -0
  61. data/vendor-src/libleptris/TODO.xslt-full/07-xpath-function-items.md +124 -0
  62. data/vendor-src/libleptris/TODO.xslt-full/08-xpath-maps-arrays.md +79 -0
  63. data/vendor-src/libleptris/TODO.xslt-full/09-xslt-noop-fillins.md +35 -0
  64. data/vendor-src/libleptris/TODO.xslt-full/10-xslt-tunnel-params.md +9 -0
  65. data/vendor-src/libleptris/TODO.xslt-full/11-xquery-core.md +119 -0
  66. data/vendor-src/libleptris/TODO.xslt-full/12-xquery-31.md +65 -0
  67. data/vendor-src/libleptris/TODO.xslt-full/13-perf-inprocess.md +425 -0
  68. data/vendor-src/libleptris/TODO.xslt-full/14-html-mode.md +803 -0
  69. data/vendor-src/libleptris/TODO.xslt-full/15-binding-entries.md +19 -0
  70. data/vendor-src/libleptris/TODO.xslt-full/16-schematron.md +156 -0
  71. data/vendor-src/libleptris/TODO.xslt-full/17-xml-diff.md +52 -0
  72. data/vendor-src/libleptris/TODO.xslt-full/18-compact-nodes.md +278 -0
  73. data/vendor-src/libleptris/TODO.xslt-full/README.md +26 -0
  74. data/vendor-src/libleptris/TODO.xslt-full/REMAINING.md +163 -0
  75. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/00-triage.md +171 -0
  76. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/01-fragment-nodes.md +19 -0
  77. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/02-root-node-semantics.md +34 -0
  78. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/03-crashes.md +15 -0
  79. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/04-namespaces.md +14 -0
  80. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/05-number-attrset-sort.md +13 -0
  81. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/06-document-chains.md +10 -0
  82. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/07-charef-serializer.md +9 -0
  83. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/08-perf-gate.md +8 -0
  84. data/vendor-src/libleptris/TODO.xslt-full/legacy-v19/09-release.md +14 -0
  85. data/vendor-src/libleptris/VALIDATION.md +151 -0
  86. data/vendor-src/libleptris/benchmarks/CMakeLists.txt +259 -0
  87. data/vendor-src/libleptris/benchmarks/README.adoc +228 -0
  88. data/vendor-src/libleptris/benchmarks/README.md +212 -0
  89. data/vendor-src/libleptris/benchmarks/common/benchmark.c +252 -0
  90. data/vendor-src/libleptris/benchmarks/common/benchmark.h +77 -0
  91. data/vendor-src/libleptris/benchmarks/common/test_data.c +415 -0
  92. data/vendor-src/libleptris/benchmarks/common/test_data.h +18 -0
  93. data/vendor-src/libleptris/benchmarks/comprehensive/CMakeLists.txt +184 -0
  94. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_decomp.cpp +110 -0
  95. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_first_access.cpp +261 -0
  96. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_many_attrs.cpp +150 -0
  97. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_memory.cpp +185 -0
  98. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_parse.cpp +270 -0
  99. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_parse_ops.cpp +392 -0
  100. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_sax.c +106 -0
  101. data/vendor-src/libleptris/benchmarks/comprehensive/benchmark_write.cpp +351 -0
  102. data/vendor-src/libleptris/benchmarks/data/attrs.xml +303 -0
  103. data/vendor-src/libleptris/benchmarks/data/cdata_test.xml +13 -0
  104. data/vendor-src/libleptris/benchmarks/data/comment_test.xml +15 -0
  105. data/vendor-src/libleptris/benchmarks/data/deep.xml +205 -0
  106. data/vendor-src/libleptris/benchmarks/data/generate_attrs.rb +22 -0
  107. data/vendor-src/libleptris/benchmarks/data/generate_deep.rb +25 -0
  108. data/vendor-src/libleptris/benchmarks/data/generate_large.rb +33 -0
  109. data/vendor-src/libleptris/benchmarks/data/generate_wide.rb +18 -0
  110. data/vendor-src/libleptris/benchmarks/data/large.xml +21003 -0
  111. data/vendor-src/libleptris/benchmarks/data/large_workflow.xml +4003 -0
  112. data/vendor-src/libleptris/benchmarks/data/medium.xml +67 -0
  113. data/vendor-src/libleptris/benchmarks/data/medium_workflow.xml +353 -0
  114. data/vendor-src/libleptris/benchmarks/data/pi_test.xml +9 -0
  115. data/vendor-src/libleptris/benchmarks/data/small.xml +10 -0
  116. data/vendor-src/libleptris/benchmarks/data/small_workflow.xml +36 -0
  117. data/vendor-src/libleptris/benchmarks/data/wide.xml +5003 -0
  118. data/vendor-src/libleptris/benchmarks/dom/bench_document_lifecycle.c +69 -0
  119. data/vendor-src/libleptris/benchmarks/dom/bench_leptris.c +184 -0
  120. data/vendor-src/libleptris/benchmarks/dom/bench_libxml2.c +176 -0
  121. data/vendor-src/libleptris/benchmarks/dom/bench_text_borrowed.c +74 -0
  122. data/vendor-src/libleptris/benchmarks/dom/dom_benchmark_v2.cpp +314 -0
  123. data/vendor-src/libleptris/benchmarks/fixtures/large.xml +4003 -0
  124. data/vendor-src/libleptris/benchmarks/fixtures/large_catalog.xml +50003 -0
  125. data/vendor-src/libleptris/benchmarks/fixtures/libxml2/eve.xml +6 -0
  126. data/vendor-src/libleptris/benchmarks/fixtures/libxml2/slashdot.rdf +66 -0
  127. data/vendor-src/libleptris/benchmarks/fixtures/libxml2/wap.xml +27 -0
  128. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/4rects.xml +11 -0
  129. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/a-valid.xml +10 -0
  130. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/a-wf.xml +9 -0
  131. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/bike.xml +41 -0
  132. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/circle.xml +11 -0
  133. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/defs.xml +14 -0
  134. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/desc.xml +14 -0
  135. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/ellipse.xml +10 -0
  136. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/flower2.xml +44 -0
  137. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/gradient.xml +16 -0
  138. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group01.xml +15 -0
  139. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group02.xml +13 -0
  140. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/group03.xml +13 -0
  141. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/image-valid.xml +11 -0
  142. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/image-wf.xml +11 -0
  143. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/lin-gradient.xml +16 -0
  144. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/marker.xml +28 -0
  145. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/mask.xml +13 -0
  146. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/mathswitch.xml +32 -0
  147. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/parentns.xml +12 -0
  148. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/path01.xml +5 -0
  149. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/path02.xml +10 -0
  150. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/patternfill.xml +12 -0
  151. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/polyline.xml +9 -0
  152. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/private.xml +19 -0
  153. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/rad-gradient.xml +17 -0
  154. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/rectangle.xml +10 -0
  155. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/richdesc.xml +12 -0
  156. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/script.xml +13 -0
  157. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/structure01.xml +10 -0
  158. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/style.xml +11 -0
  159. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/switch.xml +21 -0
  160. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/symbol-use.xml +28 -0
  161. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/template.xml +9 -0
  162. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text01.xml +12 -0
  163. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text02.xml +17 -0
  164. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/text03.xml +8 -0
  165. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/toap01.xml +10 -0
  166. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/toap02.xml +33 -0
  167. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/transform.xml +26 -0
  168. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/trivial.xml +6 -0
  169. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/twin-gradients.xml +19 -0
  170. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/v-template.xml +9 -0
  171. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport-nest.xml +13 -0
  172. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport-transform.xml +46 -0
  173. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/viewport.xml +11 -0
  174. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_svg/wf-template.xml +7 -0
  175. data/vendor-src/libleptris/benchmarks/fixtures/libxml2_xsdtest.xml +5286 -0
  176. data/vendor-src/libleptris/benchmarks/fixtures/medium.xml +403 -0
  177. data/vendor-src/libleptris/benchmarks/fixtures/medium_catalog.xml +3003 -0
  178. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/empty.xml +0 -0
  179. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/large.xml +1 -0
  180. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/latintest_latin1.xml +1 -0
  181. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/latintest_utf8.xml +1 -0
  182. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/multiline.xml +3 -0
  183. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/small.xml +1 -0
  184. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/truncation.xml +19 -0
  185. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be.xml +0 -0
  186. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_bom.xml +0 -0
  187. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_clean.xml +0 -0
  188. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_be_nodecl.xml +0 -0
  189. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le.xml +0 -0
  190. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_bom.xml +0 -0
  191. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_clean.xml +0 -0
  192. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf16_le_nodecl.xml +0 -0
  193. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be.xml +0 -0
  194. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_bom.xml +0 -0
  195. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_clean.xml +0 -0
  196. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_be_nodecl.xml +0 -0
  197. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le.xml +0 -0
  198. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_bom.xml +0 -0
  199. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_clean.xml +0 -0
  200. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf32_le_nodecl.xml +0 -0
  201. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8.xml +87 -0
  202. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_bom.xml +87 -0
  203. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_clean.xml +84 -0
  204. data/vendor-src/libleptris/benchmarks/fixtures/pugixml/utftest_utf8_nodecl.xml +86 -0
  205. data/vendor-src/libleptris/benchmarks/fixtures/pugixml//321/202/320/265/321/201/321/202.xml +1 -0
  206. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/empty.xml +0 -0
  207. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/large.xml +1 -0
  208. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/latintest_latin1.xml +1 -0
  209. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/latintest_utf8.xml +1 -0
  210. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/multiline.xml +3 -0
  211. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/small.xml +1 -0
  212. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/truncation.xml +19 -0
  213. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be.xml +0 -0
  214. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_bom.xml +0 -0
  215. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_clean.xml +0 -0
  216. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_be_nodecl.xml +0 -0
  217. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le.xml +0 -0
  218. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_bom.xml +0 -0
  219. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_clean.xml +0 -0
  220. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf16_le_nodecl.xml +0 -0
  221. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be.xml +0 -0
  222. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_bom.xml +0 -0
  223. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_clean.xml +0 -0
  224. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_be_nodecl.xml +0 -0
  225. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le.xml +0 -0
  226. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_bom.xml +0 -0
  227. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_clean.xml +0 -0
  228. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf32_le_nodecl.xml +0 -0
  229. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8.xml +87 -0
  230. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_bom.xml +87 -0
  231. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_clean.xml +84 -0
  232. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests/utftest_utf8_nodecl.xml +86 -0
  233. data/vendor-src/libleptris/benchmarks/fixtures/pugixml_tests//321/202/320/265/321/201/321/202.xml +1 -0
  234. data/vendor-src/libleptris/benchmarks/fixtures/small.xml +38 -0
  235. data/vendor-src/libleptris/benchmarks/html/bench_html_parse.c +111 -0
  236. data/vendor-src/libleptris/benchmarks/html/gen_nokogiri_reference.rb +112 -0
  237. data/vendor-src/libleptris/benchmarks/html/nokogiri_html_parse.rb +64 -0
  238. data/vendor-src/libleptris/benchmarks/matrix/README.md +71 -0
  239. data/vendor-src/libleptris/benchmarks/matrix/bench2html.rb +316 -0
  240. data/vendor-src/libleptris/benchmarks/matrix/bench_matrix.cpp +724 -0
  241. data/vendor-src/libleptris/benchmarks/modification/bench_leptris_modify.c +211 -0
  242. data/vendor-src/libleptris/benchmarks/modification/bench_node_creation.c +130 -0
  243. data/vendor-src/libleptris/benchmarks/results/BENCHMARK_REPORT.md +226 -0
  244. data/vendor-src/libleptris/benchmarks/results/baseline_report.md +219 -0
  245. data/vendor-src/libleptris/benchmarks/results/benchmark_20251223_134550.json +13 -0
  246. data/vendor-src/libleptris/benchmarks/results/benchmark_20260129_225844.json +13 -0
  247. data/vendor-src/libleptris/benchmarks/results/leptris_dom_output.txt +24 -0
  248. data/vendor-src/libleptris/benchmarks/results/leptris_modify.json +36 -0
  249. data/vendor-src/libleptris/benchmarks/results/leptris_modify_optimized.json +36 -0
  250. data/vendor-src/libleptris/benchmarks/results/leptris_modify_session1.json +36 -0
  251. data/vendor-src/libleptris/benchmarks/results/leptris_modify_session2.json +36 -0
  252. data/vendor-src/libleptris/benchmarks/results/leptris_serialize.json +34 -0
  253. data/vendor-src/libleptris/benchmarks/results/leptris_xpath_output.txt +24 -0
  254. data/vendor-src/libleptris/benchmarks/results/libxml2_dom_output.txt +24 -0
  255. data/vendor-src/libleptris/benchmarks/results/libxml2_xpath_output.txt +24 -0
  256. data/vendor-src/libleptris/benchmarks/results/phase16_session2.json +21 -0
  257. data/vendor-src/libleptris/benchmarks/results/phase17.5_session1.json +30 -0
  258. data/vendor-src/libleptris/benchmarks/results/phase17_session1.json +30 -0
  259. data/vendor-src/libleptris/benchmarks/results/pugixml_dom_output.txt +51 -0
  260. data/vendor-src/libleptris/benchmarks/results/xpath_axes_leptris.json +318 -0
  261. data/vendor-src/libleptris/benchmarks/results/xpath_axes_libxml2.json +318 -0
  262. data/vendor-src/libleptris/benchmarks/results/xpath_functions_leptris.json +222 -0
  263. data/vendor-src/libleptris/benchmarks/results/xpath_functions_libxml2.json +222 -0
  264. data/vendor-src/libleptris/benchmarks/sax/bench_iterparse.c +115 -0
  265. data/vendor-src/libleptris/benchmarks/sax/bench_leptris.c +124 -0
  266. data/vendor-src/libleptris/benchmarks/sax/bench_libxml2.c +115 -0
  267. data/vendor-src/libleptris/benchmarks/serialization/bench_leptris_serialize.c +198 -0
  268. data/vendor-src/libleptris/benchmarks/src/benchmark_base.h +175 -0
  269. data/vendor-src/libleptris/benchmarks/twins/mutation_leptris.c +37 -0
  270. data/vendor-src/libleptris/benchmarks/twins/mutation_pugixml.cpp +28 -0
  271. data/vendor-src/libleptris/benchmarks/twins/parse_leptris.c +35 -0
  272. data/vendor-src/libleptris/benchmarks/twins/parse_pugixml.cpp +35 -0
  273. data/vendor-src/libleptris/benchmarks/utils.c +171 -0
  274. data/vendor-src/libleptris/benchmarks/utils.h +70 -0
  275. data/vendor-src/libleptris/benchmarks/workflows/bench_dom_modify.c +325 -0
  276. data/vendor-src/libleptris/benchmarks/workflows/bench_end_to_end.c +529 -0
  277. data/vendor-src/libleptris/benchmarks/xpath/bench_axes.c +411 -0
  278. data/vendor-src/libleptris/benchmarks/xpath/bench_axes_libxml2.c +108 -0
  279. data/vendor-src/libleptris/benchmarks/xpath/bench_diagnostic.c +431 -0
  280. data/vendor-src/libleptris/benchmarks/xpath/bench_functions.c +271 -0
  281. data/vendor-src/libleptris/benchmarks/xpath/bench_functions_libxml2.c +123 -0
  282. data/vendor-src/libleptris/benchmarks/xpath/bench_leptris.c +78 -0
  283. data/vendor-src/libleptris/benchmarks/xpath/bench_libxml2.c +98 -0
  284. data/vendor-src/libleptris/benchmarks/xpath/bench_pugixml.cpp +117 -0
  285. data/vendor-src/libleptris/benchmarks/xpath/bench_scalar_eval.c +86 -0
  286. data/vendor-src/libleptris/benchmarks/xpath/bench_scalar_eval_libxml2.c +70 -0
  287. data/vendor-src/libleptris/benchmarks/xpath/bench_xslt_transform.c +48 -0
  288. data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch.c +52 -0
  289. data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch_heavy.c +82 -0
  290. data/vendor-src/libleptris/benchmarks/xslt/bench_dispatch_pred.c +34 -0
  291. data/vendor-src/libleptris/benchmarks/xslt/bench_subtree_copy.c +55 -0
  292. data/vendor-src/libleptris/benchmarks/xslt/bench_valueof.c +46 -0
  293. data/vendor-src/libleptris/benchmarks/xslt/heavy_lxml.py +48 -0
  294. data/vendor-src/libleptris/benchmarks/xslt/scorecard_lxml.py +169 -0
  295. data/vendor-src/libleptris/bindings/ruby/leptris.gemspec +22 -0
  296. data/vendor-src/libleptris/bindings/ruby/lib/leptris/document.rb +60 -0
  297. data/vendor-src/libleptris/bindings/ruby/lib/leptris/element.rb +86 -0
  298. data/vendor-src/libleptris/bindings/ruby/lib/leptris/error.rb +6 -0
  299. data/vendor-src/libleptris/bindings/ruby/lib/leptris/node.rb +73 -0
  300. data/vendor-src/libleptris/bindings/ruby/lib/leptris/sax.rb +189 -0
  301. data/vendor-src/libleptris/bindings/ruby/lib/leptris/xpath.rb +44 -0
  302. data/vendor-src/libleptris/bindings/ruby/lib/leptris.rb +137 -0
  303. data/vendor-src/libleptris/bindings/ruby/spec/leptris_spec.rb +113 -0
  304. data/vendor-src/libleptris/bindings/ruby/spec/sax_spec.rb +141 -0
  305. data/vendor-src/libleptris/bindings/ruby/spec/spec_helper.rb +7 -0
  306. data/vendor-src/libleptris/bindings/ruby/test_full.rb +21 -0
  307. data/vendor-src/libleptris/bindings/rust/Cargo.lock +7 -0
  308. data/vendor-src/libleptris/bindings/rust/Cargo.toml +13 -0
  309. data/vendor-src/libleptris/bindings/rust/README.md +61 -0
  310. data/vendor-src/libleptris/bindings/rust/build.rs +74 -0
  311. data/vendor-src/libleptris/bindings/rust/src/ffi.rs +204 -0
  312. data/vendor-src/libleptris/bindings/rust/src/lib.rs +580 -0
  313. data/vendor-src/libleptris/bindings/rust/tests/integration.rs +156 -0
  314. data/vendor-src/libleptris/cli/ARCHITECTURE_REVIEW.md +514 -0
  315. data/vendor-src/libleptris/cli/CLI_ARCHITECTURE.md +851 -0
  316. data/vendor-src/libleptris/cli/CMakeLists.txt +46 -0
  317. data/vendor-src/libleptris/cli/cli.c +115 -0
  318. data/vendor-src/libleptris/cli/cli.h +232 -0
  319. data/vendor-src/libleptris/cli/commands/diff.c +208 -0
  320. data/vendor-src/libleptris/cli/commands/format.c +379 -0
  321. data/vendor-src/libleptris/cli/commands/parse.c +343 -0
  322. data/vendor-src/libleptris/cli/commands/validate.c +284 -0
  323. data/vendor-src/libleptris/cli/commands/version.c +49 -0
  324. data/vendor-src/libleptris/cli/commands/xpath.c +428 -0
  325. data/vendor-src/libleptris/cli/commands/xquery.c +188 -0
  326. data/vendor-src/libleptris/cli/completion/leptris.bash +86 -0
  327. data/vendor-src/libleptris/cli/completion/leptris.zsh +74 -0
  328. data/vendor-src/libleptris/cli/error.c +394 -0
  329. data/vendor-src/libleptris/cli/error.h +360 -0
  330. data/vendor-src/libleptris/cli/leptris +0 -0
  331. data/vendor-src/libleptris/cli/main.c +127 -0
  332. data/vendor-src/libleptris/cli/man/leptris-format.1.adoc +226 -0
  333. data/vendor-src/libleptris/cli/man/leptris-parse.1.adoc +213 -0
  334. data/vendor-src/libleptris/cli/man/leptris-xpath.1.adoc +479 -0
  335. data/vendor-src/libleptris/cli/man/leptris.1.adoc +192 -0
  336. data/vendor-src/libleptris/cli/options.c +451 -0
  337. data/vendor-src/libleptris/cli/options.h +378 -0
  338. data/vendor-src/libleptris/cli/output.c +841 -0
  339. data/vendor-src/libleptris/cli/output.h +361 -0
  340. data/vendor-src/libleptris/cmake/FindUtf8proc.cmake +56 -0
  341. data/vendor-src/libleptris/cmake/leptris-config.cmake.in +14 -0
  342. data/vendor-src/libleptris/cmake/leptris.pc.in +11 -0
  343. data/vendor-src/libleptris/cmake/modules/AdocMan.cmake +132 -0
  344. data/vendor-src/libleptris/docs/ARCHITECTURE_REVIEW.md +280 -0
  345. data/vendor-src/libleptris/docs/Doxyfile +47 -0
  346. data/vendor-src/libleptris/docs/FFI.md +165 -0
  347. data/vendor-src/libleptris/docs/README.md +47 -0
  348. data/vendor-src/libleptris/docs/ROADMAP-SAXON-PARITY.md +194 -0
  349. data/vendor-src/libleptris/docs/guide/building.md +199 -0
  350. data/vendor-src/libleptris/docs/guide/getting-started.md +134 -0
  351. data/vendor-src/libleptris/docs/guide/parsing.md +315 -0
  352. data/vendor-src/libleptris/docs/guide/xpath-queries.md +444 -0
  353. data/vendor-src/libleptris/examples/c/CMakeLists.txt +58 -0
  354. data/vendor-src/libleptris/examples/c/README.md +345 -0
  355. data/vendor-src/libleptris/examples/c/basic_example.c +80 -0
  356. data/vendor-src/libleptris/examples/c/dom_traversal_example.c +58 -0
  357. data/vendor-src/libleptris/examples/c/error_handling_example.c +121 -0
  358. data/vendor-src/libleptris/examples/c/namespace_example.c +49 -0
  359. data/vendor-src/libleptris/examples/c/xpath_example.c +74 -0
  360. data/vendor-src/libleptris/ports/leptris/portfile.cmake +41 -0
  361. data/vendor-src/libleptris/ports/leptris/usage +28 -0
  362. data/vendor-src/libleptris/scripts/check_dll_exports.py +54 -0
  363. data/vendor-src/libleptris/scripts/check_export_surface.py +84 -0
  364. data/vendor-src/libleptris/scripts/check_ffi_mirrors.py +163 -0
  365. data/vendor-src/libleptris/scripts/check_formatting.sh +30 -0
  366. data/vendor-src/libleptris/scripts/check_shared_exports.sh +120 -0
  367. data/vendor-src/libleptris/scripts/check_trailing_whitespace.sh +18 -0
  368. data/vendor-src/libleptris/scripts/gen-api-docs.sh +31 -0
  369. data/vendor-src/libleptris/scripts/run_static_analysis.sh +16 -0
  370. data/vendor-src/libleptris/scripts/validate.sh +199 -0
  371. data/vendor-src/libleptris/scripts/xslt_triage.sh +72 -0
  372. data/vendor-src/libleptris/src/CMakeLists.txt +597 -0
  373. data/vendor-src/libleptris/src/include/leptris/descriptor.h +178 -0
  374. data/vendor-src/libleptris/src/include/leptris/dom/document.h +213 -0
  375. data/vendor-src/libleptris/src/include/leptris/dom/element.h +435 -0
  376. data/vendor-src/libleptris/src/include/leptris/dom/serialize.h +133 -0
  377. data/vendor-src/libleptris/src/include/leptris/dtd.h +178 -0
  378. data/vendor-src/libleptris/src/include/leptris/error.h +97 -0
  379. data/vendor-src/libleptris/src/include/leptris/sax/sax.h +584 -0
  380. data/vendor-src/libleptris/src/include/leptris/types.h +386 -0
  381. data/vendor-src/libleptris/src/include/leptris/xpath/xpath.h +250 -0
  382. data/vendor-src/libleptris/src/include/leptris/xquery/xquery.h +80 -0
  383. data/vendor-src/libleptris/src/include/leptris.h +3701 -0
  384. data/vendor-src/libleptris/src/leptris/chartype.h +124 -0
  385. data/vendor-src/libleptris/src/leptris/common/chartype.c +90 -0
  386. data/vendor-src/libleptris/src/leptris/common/chartype.h +44 -0
  387. data/vendor-src/libleptris/src/leptris/common/cpu.c +40 -0
  388. data/vendor-src/libleptris/src/leptris/common/cpu.h +63 -0
  389. data/vendor-src/libleptris/src/leptris/common/entities.c +329 -0
  390. data/vendor-src/libleptris/src/leptris/common/entities.h +79 -0
  391. data/vendor-src/libleptris/src/leptris/common/format_number.c +273 -0
  392. data/vendor-src/libleptris/src/leptris/common/format_number.h +29 -0
  393. data/vendor-src/libleptris/src/leptris/common/port.h +171 -0
  394. data/vendor-src/libleptris/src/leptris/common/simd_text.c +237 -0
  395. data/vendor-src/libleptris/src/leptris/common/simd_text.h +104 -0
  396. data/vendor-src/libleptris/src/leptris/common/simd_text_avx2.c +105 -0
  397. data/vendor-src/libleptris/src/leptris/common/simd_text_neon.c +280 -0
  398. data/vendor-src/libleptris/src/leptris/common/string_view.c +204 -0
  399. data/vendor-src/libleptris/src/leptris/common/string_view.h +68 -0
  400. data/vendor-src/libleptris/src/leptris/common/types_internal.h +31 -0
  401. data/vendor-src/libleptris/src/leptris/core.c +201 -0
  402. data/vendor-src/libleptris/src/leptris/descriptor/plan.c +527 -0
  403. data/vendor-src/libleptris/src/leptris/diff/diff.c +491 -0
  404. data/vendor-src/libleptris/src/leptris/dom/cdata.c +47 -0
  405. data/vendor-src/libleptris/src/leptris/dom/cdata.h +73 -0
  406. data/vendor-src/libleptris/src/leptris/dom/comment.c +48 -0
  407. data/vendor-src/libleptris/src/leptris/dom/comment.h +74 -0
  408. data/vendor-src/libleptris/src/leptris/dom/compact.c +397 -0
  409. data/vendor-src/libleptris/src/leptris/dom/compact.h +307 -0
  410. data/vendor-src/libleptris/src/leptris/dom/diag.c +58 -0
  411. data/vendor-src/libleptris/src/leptris/dom/diag.h +75 -0
  412. data/vendor-src/libleptris/src/leptris/dom/digest.c +255 -0
  413. data/vendor-src/libleptris/src/leptris/dom/doctype.c +137 -0
  414. data/vendor-src/libleptris/src/leptris/dom/doctype.h +52 -0
  415. data/vendor-src/libleptris/src/leptris/dom/document_node.c +13 -0
  416. data/vendor-src/libleptris/src/leptris/dom/document_node.h +21 -0
  417. data/vendor-src/libleptris/src/leptris/dom/edges.h +60 -0
  418. data/vendor-src/libleptris/src/leptris/dom/element.c +1114 -0
  419. data/vendor-src/libleptris/src/leptris/dom/element.h +1109 -0
  420. data/vendor-src/libleptris/src/leptris/dom/element_index.c +444 -0
  421. data/vendor-src/libleptris/src/leptris/dom/element_index.h +135 -0
  422. data/vendor-src/libleptris/src/leptris/dom/element_modify.c +2185 -0
  423. data/vendor-src/libleptris/src/leptris/dom/element_query.c +1468 -0
  424. data/vendor-src/libleptris/src/leptris/dom/entity_ref.c +57 -0
  425. data/vendor-src/libleptris/src/leptris/dom/entity_ref.h +70 -0
  426. data/vendor-src/libleptris/src/leptris/dom/node.c +420 -0
  427. data/vendor-src/libleptris/src/leptris/dom/node.h +170 -0
  428. data/vendor-src/libleptris/src/leptris/dom/node_public.c +937 -0
  429. data/vendor-src/libleptris/src/leptris/dom/node_vtable.c +138 -0
  430. data/vendor-src/libleptris/src/leptris/dom/pi.c +70 -0
  431. data/vendor-src/libleptris/src/leptris/dom/pi.h +80 -0
  432. data/vendor-src/libleptris/src/leptris/dom/root_doc_map.c +310 -0
  433. data/vendor-src/libleptris/src/leptris/dom/root_doc_map.h +30 -0
  434. data/vendor-src/libleptris/src/leptris/dom/text.c +157 -0
  435. data/vendor-src/libleptris/src/leptris/dom/text.h +119 -0
  436. data/vendor-src/libleptris/src/leptris/dtd/content_check.c +300 -0
  437. data/vendor-src/libleptris/src/leptris/dtd/model.c +533 -0
  438. data/vendor-src/libleptris/src/leptris/dtd/model.h +354 -0
  439. data/vendor-src/libleptris/src/leptris/dtd/parser.c +827 -0
  440. data/vendor-src/libleptris/src/leptris/dtd/resolver.c +354 -0
  441. data/vendor-src/libleptris/src/leptris/dtd/validator.c +668 -0
  442. data/vendor-src/libleptris/src/leptris/encoding/encoders.c +346 -0
  443. data/vendor-src/libleptris/src/leptris/encoding/encoders.h +61 -0
  444. data/vendor-src/libleptris/src/leptris/encoding/encoding.c +451 -0
  445. data/vendor-src/libleptris/src/leptris/encoding/encoding.h +118 -0
  446. data/vendor-src/libleptris/src/leptris/encoding/unicode.c +317 -0
  447. data/vendor-src/libleptris/src/leptris/encoding/unicode.h +64 -0
  448. data/vendor-src/libleptris/src/leptris/encoding/utf16.c +204 -0
  449. data/vendor-src/libleptris/src/leptris/encoding/utf16.h +78 -0
  450. data/vendor-src/libleptris/src/leptris/encoding/wrapper.c +243 -0
  451. data/vendor-src/libleptris/src/leptris/error.c +134 -0
  452. data/vendor-src/libleptris/src/leptris/flat/direct_parse.c +1935 -0
  453. data/vendor-src/libleptris/src/leptris/flat/direct_parse.h +41 -0
  454. data/vendor-src/libleptris/src/leptris/html/html_parse.c +8040 -0
  455. data/vendor-src/libleptris/src/leptris/leptris.c +1264 -0
  456. data/vendor-src/libleptris/src/leptris/leptris_internal.h +910 -0
  457. data/vendor-src/libleptris/src/leptris/leptris_memory.c +179 -0
  458. data/vendor-src/libleptris/src/leptris/leptris_memory.h +180 -0
  459. data/vendor-src/libleptris/src/leptris/leptris_parse.h +195 -0
  460. data/vendor-src/libleptris/src/leptris/memory/arena.c +243 -0
  461. data/vendor-src/libleptris/src/leptris/memory/arena.h +93 -0
  462. data/vendor-src/libleptris/src/leptris/memory/pool.c +1055 -0
  463. data/vendor-src/libleptris/src/leptris/memory/pool.h +426 -0
  464. data/vendor-src/libleptris/src/leptris/rng/parse.c +814 -0
  465. data/vendor-src/libleptris/src/leptris/rng/rng_internal.h +112 -0
  466. data/vendor-src/libleptris/src/leptris/rng/rng_public.c +159 -0
  467. data/vendor-src/libleptris/src/leptris/rng/rng_regex.c +453 -0
  468. data/vendor-src/libleptris/src/leptris/rng/validate.c +1923 -0
  469. data/vendor-src/libleptris/src/leptris/sax/iterparse.c +435 -0
  470. data/vendor-src/libleptris/src/leptris/sax/parser.c +105 -0
  471. data/vendor-src/libleptris/src/leptris/sax/pull.c +489 -0
  472. data/vendor-src/libleptris/src/leptris/sax/recorder.c +252 -0
  473. data/vendor-src/libleptris/src/leptris/sax/sax_internal.h +163 -0
  474. data/vendor-src/libleptris/src/leptris/sax/streaming.c +1469 -0
  475. data/vendor-src/libleptris/src/leptris/sch/schematron.c +1588 -0
  476. data/vendor-src/libleptris/src/leptris/serialize/c14n.c +1143 -0
  477. data/vendor-src/libleptris/src/leptris/serialize/serialize.c +2333 -0
  478. data/vendor-src/libleptris/src/leptris/serialize/serialize.h +188 -0
  479. data/vendor-src/libleptris/src/leptris/simd_helpers.h +447 -0
  480. data/vendor-src/libleptris/src/leptris/unicode/unicode.c +237 -0
  481. data/vendor-src/libleptris/src/leptris/unicode/unicode.h +113 -0
  482. data/vendor-src/libleptris/src/leptris/xinclude/xinclude.c +794 -0
  483. data/vendor-src/libleptris/src/leptris/xpath/bytecode.h +229 -0
  484. data/vendor-src/libleptris/src/leptris/xpath/compiler.c +1478 -0
  485. data/vendor-src/libleptris/src/leptris/xpath/evaluator.c +1099 -0
  486. data/vendor-src/libleptris/src/leptris/xpath/evaluator.h +189 -0
  487. data/vendor-src/libleptris/src/leptris/xpath/evaluator_axes.c +787 -0
  488. data/vendor-src/libleptris/src/leptris/xpath/evaluator_internal.h +112 -0
  489. data/vendor-src/libleptris/src/leptris/xpath/evaluator_operators.c +2138 -0
  490. data/vendor-src/libleptris/src/leptris/xpath/evaluator_path.c +1312 -0
  491. data/vendor-src/libleptris/src/leptris/xpath/evaluator_types.c +294 -0
  492. data/vendor-src/libleptris/src/leptris/xpath/functions.c +2544 -0
  493. data/vendor-src/libleptris/src/leptris/xpath/functions.h +161 -0
  494. data/vendor-src/libleptris/src/leptris/xpath/functions_exslt.c +545 -0
  495. data/vendor-src/libleptris/src/leptris/xpath/functions_ext31.c +4316 -0
  496. data/vendor-src/libleptris/src/leptris/xpath/lexer.c +636 -0
  497. data/vendor-src/libleptris/src/leptris/xpath/lexer.h +25 -0
  498. data/vendor-src/libleptris/src/leptris/xpath/parser.c +2992 -0
  499. data/vendor-src/libleptris/src/leptris/xpath/parser.h +28 -0
  500. data/vendor-src/libleptris/src/leptris/xpath/vm.c +2903 -0
  501. data/vendor-src/libleptris/src/leptris/xpath/xpath_ast_cache.c +319 -0
  502. data/vendor-src/libleptris/src/leptris/xpath/xpath_compiled.c +263 -0
  503. data/vendor-src/libleptris/src/leptris/xpath/xpath_internal.h +134 -0
  504. data/vendor-src/libleptris/src/leptris/xpath/xpath_public.c +1139 -0
  505. data/vendor-src/libleptris/src/leptris/xpath/xpath_variables.c +410 -0
  506. data/vendor-src/libleptris/src/leptris/xpath/xpath_variables.h +230 -0
  507. data/vendor-src/libleptris/src/leptris/xquery/xquery.c +2641 -0
  508. data/vendor-src/libleptris/src/leptris/xslt/xslt_exec.c +4887 -0
  509. data/vendor-src/libleptris/src/leptris/xslt/xslt_functions.c +1612 -0
  510. data/vendor-src/libleptris/src/leptris/xslt/xslt_internal.h +862 -0
  511. data/vendor-src/libleptris/src/leptris/xslt/xslt_parse.c +2418 -0
  512. data/vendor-src/libleptris/src/leptris/xslt/xslt_pattern.c +441 -0
  513. data/vendor-src/libleptris/src/leptris/xslt/xslt_public.c +710 -0
  514. data/vendor-src/libleptris/src/leptris.symvers +16 -0
  515. data/vendor-src/libleptris/src/man/libleptris.5.adoc +961 -0
  516. data/vendor-src/libleptris/test/CMakeLists.txt +234 -0
  517. data/vendor-src/libleptris/test/README.md +59 -0
  518. data/vendor-src/libleptris/test/abi/test_descriptor.cpp +441 -0
  519. data/vendor-src/libleptris/test/abi/test_doctype_api.cpp +51 -0
  520. data/vendor-src/libleptris/test/abi/test_dom_deep_copy.cpp +110 -0
  521. data/vendor-src/libleptris/test/abi/test_dom_mutation_bugs.cpp +210 -0
  522. data/vendor-src/libleptris/test/abi/test_header_hygiene.cpp +269 -0
  523. data/vendor-src/libleptris/test/abi/test_namespace_mutation_and_create.cpp +198 -0
  524. data/vendor-src/libleptris/test/abi/test_node_get_xpath.cpp +128 -0
  525. data/vendor-src/libleptris/test/abi/test_nokogiri_api.cpp +392 -0
  526. data/vendor-src/libleptris/test/abi/test_parse_fragment.cpp +114 -0
  527. data/vendor-src/libleptris/test/abi/test_previous_sibling_and_c14n_ex.cpp +299 -0
  528. data/vendor-src/libleptris/test/abi/test_public_surface.cpp +463 -0
  529. data/vendor-src/libleptris/test/abi/test_serialize_abi.cpp +67 -0
  530. data/vendor-src/libleptris/test/abi/test_v0_5_14_bugs.cpp +299 -0
  531. data/vendor-src/libleptris/test/abi/test_xpath_custom_fns.cpp +106 -0
  532. data/vendor-src/libleptris/test/cli/test_cli.cpp +493 -0
  533. data/vendor-src/libleptris/test/common/test_simd_spans.cpp +88 -0
  534. data/vendor-src/libleptris/test/common/test_simd_text.cpp +142 -0
  535. data/vendor-src/libleptris/test/concurrency/test_concurrency.cpp +218 -0
  536. data/vendor-src/libleptris/test/diff/test_diff.cpp +244 -0
  537. data/vendor-src/libleptris/test/dom/test_compact.cpp +339 -0
  538. data/vendor-src/libleptris/test/dom/test_digest.cpp +111 -0
  539. data/vendor-src/libleptris/test/dom/test_document_children.cpp +270 -0
  540. data/vendor-src/libleptris/test/dom/test_dom.cpp +2310 -0
  541. data/vendor-src/libleptris/test/dom/test_map_lifecycle.cpp +111 -0
  542. data/vendor-src/libleptris/test/dom/test_node_surface_parity.cpp +268 -0
  543. data/vendor-src/libleptris/test/dom/test_text_borrowed.cpp +126 -0
  544. data/vendor-src/libleptris/test/dom/test_vtable.cpp +108 -0
  545. data/vendor-src/libleptris/test/dtd/test_dtd_validate.cpp +1227 -0
  546. data/vendor-src/libleptris/test/dtd/test_w3c_conformance.cpp +212 -0
  547. data/vendor-src/libleptris/test/fixtures/basic.xml +13 -0
  548. data/vendor-src/libleptris/test/fixtures/cdata.xml +5 -0
  549. data/vendor-src/libleptris/test/fixtures/malformed.xml +2 -0
  550. data/vendor-src/libleptris/test/fixtures/namespaces.xml +11 -0
  551. data/vendor-src/libleptris/test/fixtures/utf16_decl.xml +5 -0
  552. data/vendor-src/libleptris/test/fuzz/fuzz_parse.c +40 -0
  553. data/vendor-src/libleptris/test/html/html5lib-redlist.txt +1366 -0
  554. data/vendor-src/libleptris/test/html/html5lib-tests/LICENSE +21 -0
  555. data/vendor-src/libleptris/test/html/html5lib-tests/README.md +11 -0
  556. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/adoption01.dat +354 -0
  557. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/adoption02.dat +39 -0
  558. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/blocks.dat +695 -0
  559. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/comments01.dat +217 -0
  560. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/doctype01.dat +474 -0
  561. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/domjs-unsafe.dat +0 -0
  562. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/entities01.dat +943 -0
  563. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/entities02.dat +309 -0
  564. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/foreign-fragment.dat +645 -0
  565. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/html5test-com.dat +301 -0
  566. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/inbody01.dat +54 -0
  567. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/isindex.dat +49 -0
  568. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/main-element.dat +46 -0
  569. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/math.dat +104 -0
  570. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/menuitem-element.dat +240 -0
  571. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/namespace-sensitivity.dat +22 -0
  572. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/noscript01.dat +237 -0
  573. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/pending-spec-changes-plain-text-unsafe.dat +0 -0
  574. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/pending-spec-changes.dat +46 -0
  575. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/plain-text-unsafe.dat +0 -0
  576. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/ruby.dat +302 -0
  577. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/scriptdata01.dat +372 -0
  578. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/search-element.dat +46 -0
  579. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/svg.dat +104 -0
  580. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tables01.dat +308 -0
  581. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/template.dat +1673 -0
  582. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests1.dat +1956 -0
  583. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests10.dat +849 -0
  584. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests11.dat +523 -0
  585. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests12.dat +62 -0
  586. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests14.dat +75 -0
  587. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests15.dat +216 -0
  588. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests16.dat +2602 -0
  589. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests17.dat +179 -0
  590. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests18.dat +558 -0
  591. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests19.dat +1398 -0
  592. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests2.dat +821 -0
  593. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests20.dat +842 -0
  594. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests21.dat +306 -0
  595. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests22.dat +190 -0
  596. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests23.dat +168 -0
  597. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests24.dat +79 -0
  598. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests25.dat +288 -0
  599. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests26.dat +453 -0
  600. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests3.dat +305 -0
  601. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests4.dat +58 -0
  602. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests5.dat +210 -0
  603. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests6.dat +663 -0
  604. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests7.dat +417 -0
  605. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests8.dat +165 -0
  606. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests9.dat +472 -0
  607. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tests_innerHTML_1.dat +843 -0
  608. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/tricky01.dat +336 -0
  609. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/webkit01.dat +785 -0
  610. data/vendor-src/libleptris/test/html/html5lib-tests/tree-construction/webkit02.dat +554 -0
  611. data/vendor-src/libleptris/test/html/html5lib_cases.h.in +6 -0
  612. data/vendor-src/libleptris/test/html/nokogiri-parity-redlist.txt +1183 -0
  613. data/vendor-src/libleptris/test/html/nokogiri-tree-tests.dat +18107 -0
  614. data/vendor-src/libleptris/test/html/test_html.cpp +2191 -0
  615. data/vendor-src/libleptris/test/html/test_html5lib.cpp +831 -0
  616. data/vendor-src/libleptris/test/memory/test_arena.cpp +252 -0
  617. data/vendor-src/libleptris/test/memory/test_oom_injection.cpp +170 -0
  618. data/vendor-src/libleptris/test/memory/test_pool.cpp +331 -0
  619. data/vendor-src/libleptris/test/memory/test_pool_arena.cpp +180 -0
  620. data/vendor-src/libleptris/test/parser/test_encoding.cpp +282 -0
  621. data/vendor-src/libleptris/test/parser/test_large_documents.cpp +346 -0
  622. data/vendor-src/libleptris/test/parser/test_parser.cpp +565 -0
  623. data/vendor-src/libleptris/test/parser/test_simd_count.cpp +70 -0
  624. data/vendor-src/libleptris/test/perf/test_perf.cpp +362 -0
  625. data/vendor-src/libleptris/test/perf/test_stress_high_doc_count.cpp +67 -0
  626. data/vendor-src/libleptris/test/rng/include-cases/bad-construct.rng +7 -0
  627. data/vendor-src/libleptris/test/rng/include-cases/bad-override.rng +6 -0
  628. data/vendor-src/libleptris/test/rng/include-cases/bad-start-override.rng +5 -0
  629. data/vendor-src/libleptris/test/rng/include-cases/ext-lib.rng +3 -0
  630. data/vendor-src/libleptris/test/rng/include-cases/ext-main.rng +7 -0
  631. data/vendor-src/libleptris/test/rng/include-cases/lib.rng +5 -0
  632. data/vendor-src/libleptris/test/rng/include-cases/lib2.rng +6 -0
  633. data/vendor-src/libleptris/test/rng/include-cases/main.rng +4 -0
  634. data/vendor-src/libleptris/test/rng/include-cases/no-href.rng +4 -0
  635. data/vendor-src/libleptris/test/rng/include-cases/override.rng +8 -0
  636. data/vendor-src/libleptris/test/rng/include-cases/self-include.rng +4 -0
  637. data/vendor-src/libleptris/test/rng/include-cases/start-override.rng +5 -0
  638. data/vendor-src/libleptris/test/rng/jing-cases/000.bad.xml +1 -0
  639. data/vendor-src/libleptris/test/rng/jing-cases/000.ok.xml +1 -0
  640. data/vendor-src/libleptris/test/rng/jing-cases/000.rng +1 -0
  641. data/vendor-src/libleptris/test/rng/jing-cases/001.bad.xml +1 -0
  642. data/vendor-src/libleptris/test/rng/jing-cases/001.ok.xml +1 -0
  643. data/vendor-src/libleptris/test/rng/jing-cases/001.rng +1 -0
  644. data/vendor-src/libleptris/test/rng/jing-cases/002.bad.xml +1 -0
  645. data/vendor-src/libleptris/test/rng/jing-cases/002.ok.xml +1 -0
  646. data/vendor-src/libleptris/test/rng/jing-cases/002.rng +1 -0
  647. data/vendor-src/libleptris/test/rng/jing-cases/003.bad.xml +1 -0
  648. data/vendor-src/libleptris/test/rng/jing-cases/003.ok.xml +1 -0
  649. data/vendor-src/libleptris/test/rng/jing-cases/003.rng +1 -0
  650. data/vendor-src/libleptris/test/rng/jing-cases/004.bad.xml +1 -0
  651. data/vendor-src/libleptris/test/rng/jing-cases/004.ok.xml +1 -0
  652. data/vendor-src/libleptris/test/rng/jing-cases/004.rng +1 -0
  653. data/vendor-src/libleptris/test/rng/jing-cases/005.bad.xml +1 -0
  654. data/vendor-src/libleptris/test/rng/jing-cases/005.ok.xml +1 -0
  655. data/vendor-src/libleptris/test/rng/jing-cases/005.rng +1 -0
  656. data/vendor-src/libleptris/test/rng/jing-cases/006.bad.xml +1 -0
  657. data/vendor-src/libleptris/test/rng/jing-cases/006.ok.xml +1 -0
  658. data/vendor-src/libleptris/test/rng/jing-cases/006.rng +1 -0
  659. data/vendor-src/libleptris/test/rng/jing-cases/007.bad.xml +1 -0
  660. data/vendor-src/libleptris/test/rng/jing-cases/007.ok.xml +1 -0
  661. data/vendor-src/libleptris/test/rng/jing-cases/007.rng +1 -0
  662. data/vendor-src/libleptris/test/rng/jing-cases/008.bad.xml +1 -0
  663. data/vendor-src/libleptris/test/rng/jing-cases/008.ok.xml +1 -0
  664. data/vendor-src/libleptris/test/rng/jing-cases/008.rng +1 -0
  665. data/vendor-src/libleptris/test/rng/jing-cases/009.bad.xml +1 -0
  666. data/vendor-src/libleptris/test/rng/jing-cases/009.ok.xml +1 -0
  667. data/vendor-src/libleptris/test/rng/jing-cases/009.rng +1 -0
  668. data/vendor-src/libleptris/test/rng/jing-cases/010.bad.xml +1 -0
  669. data/vendor-src/libleptris/test/rng/jing-cases/010.ok.xml +1 -0
  670. data/vendor-src/libleptris/test/rng/jing-cases/010.rng +1 -0
  671. data/vendor-src/libleptris/test/rng/jing-cases/011.bad.xml +1 -0
  672. data/vendor-src/libleptris/test/rng/jing-cases/011.ok.xml +1 -0
  673. data/vendor-src/libleptris/test/rng/jing-cases/011.rng +1 -0
  674. data/vendor-src/libleptris/test/rng/jing-cases/012.bad.xml +1 -0
  675. data/vendor-src/libleptris/test/rng/jing-cases/012.ok.xml +1 -0
  676. data/vendor-src/libleptris/test/rng/jing-cases/012.rng +1 -0
  677. data/vendor-src/libleptris/test/rng/jing-cases/013.bad.xml +1 -0
  678. data/vendor-src/libleptris/test/rng/jing-cases/013.ok.xml +1 -0
  679. data/vendor-src/libleptris/test/rng/jing-cases/013.rng +1 -0
  680. data/vendor-src/libleptris/test/rng/jing-cases/014.bad.xml +1 -0
  681. data/vendor-src/libleptris/test/rng/jing-cases/014.ok.xml +1 -0
  682. data/vendor-src/libleptris/test/rng/jing-cases/014.rng +1 -0
  683. data/vendor-src/libleptris/test/rng/jing-cases/015.bad.xml +1 -0
  684. data/vendor-src/libleptris/test/rng/jing-cases/015.ok.xml +1 -0
  685. data/vendor-src/libleptris/test/rng/jing-cases/015.rng +1 -0
  686. data/vendor-src/libleptris/test/rng/jing-cases/016.bad.xml +1 -0
  687. data/vendor-src/libleptris/test/rng/jing-cases/016.ok.xml +1 -0
  688. data/vendor-src/libleptris/test/rng/jing-cases/016.rng +1 -0
  689. data/vendor-src/libleptris/test/rng/jing-cases/017.bad.xml +1 -0
  690. data/vendor-src/libleptris/test/rng/jing-cases/017.ok.xml +1 -0
  691. data/vendor-src/libleptris/test/rng/jing-cases/017.rng +1 -0
  692. data/vendor-src/libleptris/test/rng/jing-cases/018.bad.xml +1 -0
  693. data/vendor-src/libleptris/test/rng/jing-cases/018.ok.xml +1 -0
  694. data/vendor-src/libleptris/test/rng/jing-cases/018.rng +1 -0
  695. data/vendor-src/libleptris/test/rng/jing-cases/019.bad.xml +1 -0
  696. data/vendor-src/libleptris/test/rng/jing-cases/019.ok.xml +1 -0
  697. data/vendor-src/libleptris/test/rng/jing-cases/019.rng +7 -0
  698. data/vendor-src/libleptris/test/rng/jing-cases/020-book.rng +4 -0
  699. data/vendor-src/libleptris/test/rng/jing-cases/020.bad.xml +1 -0
  700. data/vendor-src/libleptris/test/rng/jing-cases/020.ok.xml +1 -0
  701. data/vendor-src/libleptris/test/rng/jing-cases/020.rng +3 -0
  702. data/vendor-src/libleptris/test/rng/jing-cases/README.md +32 -0
  703. data/vendor-src/libleptris/test/rng/jing-cases/jing-ref.json +212 -0
  704. data/vendor-src/libleptris/test/rng/jing-cases/meta.json +1 -0
  705. data/vendor-src/libleptris/test/rng/test_rng.cpp +1365 -0
  706. data/vendor-src/libleptris/test/rng/test_rng_corpus.cpp +133 -0
  707. data/vendor-src/libleptris/test/rng/test_rng_corpus_msg.cpp +233 -0
  708. data/vendor-src/libleptris/test/sax/test_iterparse.cpp +203 -0
  709. data/vendor-src/libleptris/test/sax/test_pull.cpp +214 -0
  710. data/vendor-src/libleptris/test/sax/test_pull_batch.cpp +201 -0
  711. data/vendor-src/libleptris/test/sax/test_recorder.cpp +265 -0
  712. data/vendor-src/libleptris/test/sax/test_sax.cpp +665 -0
  713. data/vendor-src/libleptris/test/sax/test_streaming.cpp +434 -0
  714. data/vendor-src/libleptris/test/sch/conformance-cases/README.md +15 -0
  715. data/vendor-src/libleptris/test/sch/conformance-cases/extends-baseuri-fixup-01.xml +28 -0
  716. data/vendor-src/libleptris/test/sch/conformance-cases/extends-recursive-01.xml +27 -0
  717. data/vendor-src/libleptris/test/sch/conformance-cases/include-baseuri-fixup-01.xml +24 -0
  718. data/vendor-src/libleptris/test/sch/conformance-cases/include-recursive-01.xml +24 -0
  719. data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-01.xml +20 -0
  720. data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-02.xml +20 -0
  721. data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-03.xml +20 -0
  722. data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-04.xml +23 -0
  723. data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-05.xml +20 -0
  724. data/vendor-src/libleptris/test/sch/conformance-cases/let-name-collision-error-06.xml +25 -0
  725. data/vendor-src/libleptris/test/sch/conformance-cases/let-pattern-global-01.xml +24 -0
  726. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-01.xml +18 -0
  727. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-02.xml +18 -0
  728. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-03.xml +18 -0
  729. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-04.xml +19 -0
  730. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-05.xml +20 -0
  731. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-06.xml +20 -0
  732. data/vendor-src/libleptris/test/sch/conformance-cases/let-reference-undefined-07.xml +18 -0
  733. data/vendor-src/libleptris/test/sch/conformance-cases/let-rule-global-01.xml +20 -0
  734. data/vendor-src/libleptris/test/sch/conformance-cases/let-rule-global-02.xml +23 -0
  735. data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-pattern-01.xml +25 -0
  736. data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-phase-01.xml +23 -0
  737. data/vendor-src/libleptris/test/sch/conformance-cases/let-scope-rule-01.xml +23 -0
  738. data/vendor-src/libleptris/test/sch/conformance-cases/let-value-element-content-01.xml +33 -0
  739. data/vendor-src/libleptris/test/sch/conformance-cases/pattern-abstract-01.xml +22 -0
  740. data/vendor-src/libleptris/test/sch/conformance-cases/pattern-subordinate-document-01.xml +21 -0
  741. data/vendor-src/libleptris/test/sch/conformance-cases/pattern-subordinate-document-02.xml +21 -0
  742. data/vendor-src/libleptris/test/sch/conformance-cases/rule-abstract-01.xml +21 -0
  743. data/vendor-src/libleptris/test/sch/conformance-cases/rule-abstract-02.xml +23 -0
  744. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-attribute-01.xml +18 -0
  745. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-comment-01.xml +20 -0
  746. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-element-01.xml +18 -0
  747. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-pi-01.xml +20 -0
  748. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-root-01.xml +18 -0
  749. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-text-01.xml +18 -0
  750. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-01.xml +22 -0
  751. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-02.xml +25 -0
  752. data/vendor-src/libleptris/test/sch/conformance-cases/rule-context-variable-03.xml +22 -0
  753. data/vendor-src/libleptris/test/sch/conformance-cases/rule-order-01.xml +21 -0
  754. data/vendor-src/libleptris/test/sch/conformance-cases/schema-default-phase-01.xml +26 -0
  755. data/vendor-src/libleptris/test/sch/conformance-cases/schema-default-phase-02.xml +25 -0
  756. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-diagnostic-01.xml +28 -0
  757. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-diagnostic-02.xml +25 -0
  758. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-name-nopath-01.xml +23 -0
  759. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-name-path-01.xml +23 -0
  760. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-property-01.xml +28 -0
  761. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-property-copy-of.xml +26 -0
  762. data/vendor-src/libleptris/test/sch/conformance-cases/svrl-value-of-01.xml +23 -0
  763. data/vendor-src/libleptris/test/sch/conformance-cases/xslt-key-01.xml +19 -0
  764. data/vendor-src/libleptris/test/sch/conformance-cases/xslt-key-element-content-01.xml +21 -0
  765. data/vendor-src/libleptris/test/sch/test_schematron.cpp +337 -0
  766. data/vendor-src/libleptris/test/sch/test_schematron_corpus.cpp +421 -0
  767. data/vendor-src/libleptris/test/serializer/test_c14n.cpp +539 -0
  768. data/vendor-src/libleptris/test/serializer/test_serialize.cpp +890 -0
  769. data/vendor-src/libleptris/test/smoke/test_smoke.cpp +41 -0
  770. data/vendor-src/libleptris/test/xinclude/test_xinclude.cpp +903 -0
  771. data/vendor-src/libleptris/test/xpath/test_bytecode_vm.cpp +755 -0
  772. data/vendor-src/libleptris/test/xpath/test_compiled.cpp +171 -0
  773. data/vendor-src/libleptris/test/xpath/test_exslt.cpp +141 -0
  774. data/vendor-src/libleptris/test/xpath/test_xpath.cpp +2433 -0
  775. data/vendor-src/libleptris/test/xpath/test_xpath_conformance.cpp +570 -0
  776. data/vendor-src/libleptris/test/xpath/test_xslt.cpp +4245 -0
  777. data/vendor-src/libleptris/test/xquery/books.xml +1 -0
  778. data/vendor-src/libleptris/test/xquery/qt3/README.md +28 -0
  779. data/vendor-src/libleptris/test/xquery/qt3/fn/concat.xml +878 -0
  780. data/vendor-src/libleptris/test/xquery/qt3/fn/contains.xml +795 -0
  781. data/vendor-src/libleptris/test/xquery/qt3/fn/ends-with.xml +556 -0
  782. data/vendor-src/libleptris/test/xquery/qt3/fn/starts-with.xml +644 -0
  783. data/vendor-src/libleptris/test/xquery/qt3/fn/substring/concepts.xml +1 -0
  784. data/vendor-src/libleptris/test/xquery/qt3/fn/substring.xml +449 -0
  785. data/vendor-src/libleptris/test/xquery/test_qt3.cpp +324 -0
  786. data/vendor-src/libleptris/test/xquery/test_xquery.cpp +768 -0
  787. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/ATTRIBUTION.md +12 -0
  788. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.out +4 -0
  789. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.xml +7 -0
  790. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/array.xsl +26 -0
  791. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.out +6 -0
  792. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.xml +7 -0
  793. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-1-.xsl +21 -0
  794. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.out +2 -0
  795. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.xml +3 -0
  796. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-10-.xsl +10 -0
  797. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.out +2 -0
  798. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.xml +1 -0
  799. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-100.xsl +9 -0
  800. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.out +2 -0
  801. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.xml +1 -0
  802. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-101.xsl +8 -0
  803. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102-inc.xsl +21 -0
  804. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.out +3 -0
  805. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.xml +1 -0
  806. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-102.xsl +10 -0
  807. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.out +2 -0
  808. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.xml +1 -0
  809. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-103.xsl +13 -0
  810. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.out +2 -0
  811. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.xml +1 -0
  812. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-104.xsl +10 -0
  813. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.out +2 -0
  814. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.xml +1 -0
  815. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-105.xsl +8 -0
  816. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.out +2 -0
  817. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.xml +2 -0
  818. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-106.xsl +12 -0
  819. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.out +8 -0
  820. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.xml +7 -0
  821. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-107.xsl +11 -0
  822. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.out +25 -0
  823. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.xml +4 -0
  824. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-108.xsl +21 -0
  825. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.out +3 -0
  826. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.xml +4 -0
  827. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-109.xsl +7 -0
  828. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.out +1 -0
  829. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.xml +4 -0
  830. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-11-.xsl +12 -0
  831. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.ent +1 -0
  832. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.out +1 -0
  833. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.xml +9 -0
  834. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-110.xsl +20 -0
  835. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.out +6 -0
  836. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.xml +17 -0
  837. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-111.xsl +45 -0
  838. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.out +2 -0
  839. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.xml +1 -0
  840. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-112.xsl +22 -0
  841. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.out +4 -0
  842. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.xml +7 -0
  843. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-113.xsl +15 -0
  844. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.out +3 -0
  845. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.xml +7 -0
  846. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-114.xsl +16 -0
  847. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.out +2 -0
  848. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.xml +1 -0
  849. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-115.xsl +19 -0
  850. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.out +2 -0
  851. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.xml +1 -0
  852. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-116.xsl +22 -0
  853. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.out +5 -0
  854. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.xml +10 -0
  855. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-117.xsl +59 -0
  856. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.out +3 -0
  857. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.xml +6 -0
  858. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-118.xsl +14 -0
  859. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.out +10 -0
  860. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.xml +12 -0
  861. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-119.xsl +12 -0
  862. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.out +2 -0
  863. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.xml +9 -0
  864. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-12-.xsl +16 -0
  865. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.out +8 -0
  866. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.xml +15 -0
  867. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-120.xsl +27 -0
  868. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.out +1 -0
  869. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.xml +1 -0
  870. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-121.xsl +8 -0
  871. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.out +2 -0
  872. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.xml +11 -0
  873. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-122.xsl +17 -0
  874. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.out +2 -0
  875. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.xml +2 -0
  876. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-123.xsl +14 -0
  877. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.out +2 -0
  878. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.xml +6 -0
  879. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-124.xsl +14 -0
  880. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.out +351 -0
  881. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.xml +118 -0
  882. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-125.xsl +99 -0
  883. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.out +9 -0
  884. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.xml +1 -0
  885. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-126.xsl +17 -0
  886. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.out +1 -0
  887. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.xml +1 -0
  888. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-127.xsl +18 -0
  889. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.out +5 -0
  890. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.xml +26 -0
  891. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-128.xsl +26 -0
  892. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.out +6 -0
  893. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.xml +6 -0
  894. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-129.xsl +10 -0
  895. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.out +2 -0
  896. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.xml +1 -0
  897. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-13-.xsl +10 -0
  898. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp1.imp +25 -0
  899. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp2.imp +14 -0
  900. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp3.imp +16 -0
  901. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130-imp4.imp +22 -0
  902. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.doc +7 -0
  903. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.out +1 -0
  904. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.xml +4 -0
  905. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-130.xsl +22 -0
  906. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131-imp.imp +19 -0
  907. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.out +2 -0
  908. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.xml +3 -0
  909. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-131.xsl +13 -0
  910. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.out +6 -0
  911. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.xml +6 -0
  912. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-132.xsl +13 -0
  913. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.out +6 -0
  914. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.xml +7 -0
  915. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-133.xsl +32 -0
  916. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.out +2 -0
  917. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.xml +5 -0
  918. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-134.xsl +12 -0
  919. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.out +2 -0
  920. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.xml +5 -0
  921. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-135.xsl +10 -0
  922. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.out +4 -0
  923. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.xml +4 -0
  924. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-136.xsl +8 -0
  925. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.imp +12 -0
  926. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.out +2 -0
  927. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.xml +1 -0
  928. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-137.xsl +8 -0
  929. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.out +23 -0
  930. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.xml +15 -0
  931. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-138.xsl +28 -0
  932. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.out +4 -0
  933. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.xml +9 -0
  934. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-139.xsl +14 -0
  935. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.out +4 -0
  936. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.xml +7 -0
  937. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-14-.xsl +23 -0
  938. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.out +4 -0
  939. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.xml +6 -0
  940. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-140.xsl +32 -0
  941. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.out +46 -0
  942. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.xml +9 -0
  943. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-141.xsl +25 -0
  944. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.out +35 -0
  945. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.xml +65 -0
  946. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-142.xsl +85 -0
  947. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.out +2 -0
  948. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.xml +1 -0
  949. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-143.xsl +10 -0
  950. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.out +2 -0
  951. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.xml +1 -0
  952. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-144.xsl +10 -0
  953. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.err +5 -0
  954. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.xml +10 -0
  955. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-145.xsl +10 -0
  956. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-1.imp +11 -0
  957. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-2.imp +11 -0
  958. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-3.imp +57 -0
  959. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-4.imp +15 -0
  960. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-5.imp +27 -0
  961. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147-6.imp +31 -0
  962. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.out +17 -0
  963. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.xml +21 -0
  964. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-147.xsl +29 -0
  965. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.out +2 -0
  966. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.xml +1 -0
  967. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-148.xsl +13 -0
  968. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.out +2 -0
  969. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.xml +1 -0
  970. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-149.xsl +11 -0
  971. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.out +5 -0
  972. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.xml +5 -0
  973. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-15-.xsl +15 -0
  974. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.out +2 -0
  975. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.xml +1 -0
  976. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-150.xsl +9 -0
  977. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-151.xml +1 -0
  978. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-151.xsl +15 -0
  979. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.out +12 -0
  980. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.xml +1 -0
  981. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-152.xsl +30 -0
  982. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.doc +4 -0
  983. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.out +2 -0
  984. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.xml +9 -0
  985. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-153.xsl +19 -0
  986. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-154.xml +1 -0
  987. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-154.xsl +4 -0
  988. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.out +3 -0
  989. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.xml +5 -0
  990. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-155.xsl +10 -0
  991. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.err +2 -0
  992. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.imp1.imp +16 -0
  993. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.imp2.imp +10 -0
  994. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.xml +1 -0
  995. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-156.xsl +12 -0
  996. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.err +3 -0
  997. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.out +9 -0
  998. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.xml +6 -0
  999. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-157.xsl +22 -0
  1000. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.doc +3 -0
  1001. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.out +4 -0
  1002. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.xml +2 -0
  1003. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-158.xsl +19 -0
  1004. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.out +8 -0
  1005. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.xml +1 -0
  1006. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-159.xsl +17 -0
  1007. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.out +14 -0
  1008. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.xml +17 -0
  1009. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-16-.xsl +13 -0
  1010. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.out +7 -0
  1011. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.xml +8 -0
  1012. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-160.xsl +14 -0
  1013. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.out +6 -0
  1014. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.xml +5 -0
  1015. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-161.xsl +18 -0
  1016. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.out +2 -0
  1017. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.xml +5 -0
  1018. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-163.xsl +6 -0
  1019. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.out +4 -0
  1020. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.xml +4 -0
  1021. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-164.xsl +13 -0
  1022. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.err +6 -0
  1023. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.xml +10 -0
  1024. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-165.xsl +9 -0
  1025. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.out +15256 -0
  1026. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.xml +15255 -0
  1027. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-166.xsl +131 -0
  1028. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.out +1 -0
  1029. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.xml +1 -0
  1030. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-167.xsl +20 -0
  1031. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.out +2 -0
  1032. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.xml +9 -0
  1033. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-168.xsl +9 -0
  1034. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.imp +5 -0
  1035. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.out +2 -0
  1036. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.xml +1 -0
  1037. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-169.xsl +11 -0
  1038. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.out +2 -0
  1039. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.xml +1 -0
  1040. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-17-.xsl +7 -0
  1041. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.out +4 -0
  1042. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.xml +3 -0
  1043. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-170.xsl +6 -0
  1044. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.out +2 -0
  1045. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.xml +4 -0
  1046. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-171.xsl +7 -0
  1047. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.out +6 -0
  1048. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.xml +6 -0
  1049. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-172.xsl +22 -0
  1050. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.out +1 -0
  1051. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.xml +1 -0
  1052. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-173.xsl +11 -0
  1053. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.err +1 -0
  1054. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.xml +1 -0
  1055. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-174.xsl +18 -0
  1056. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.err +2 -0
  1057. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.out +8 -0
  1058. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.xml +1 -0
  1059. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-175.xsl +33 -0
  1060. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.out +2 -0
  1061. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.xml +1 -0
  1062. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-176.xsl +11 -0
  1063. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.out +2 -0
  1064. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.xml +1 -0
  1065. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-177.xsl +7 -0
  1066. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.out +2 -0
  1067. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.xml +1 -0
  1068. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-178.xsl +18 -0
  1069. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.out +9 -0
  1070. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.xml +1 -0
  1071. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-179.xsl +24 -0
  1072. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.out +2 -0
  1073. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.xml +3 -0
  1074. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-18-.xsl +17 -0
  1075. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.err +4 -0
  1076. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.xml +2 -0
  1077. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-180.xsl +8 -0
  1078. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.out +5 -0
  1079. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.xml +4 -0
  1080. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-181.xsl +13 -0
  1081. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.out +2 -0
  1082. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.xml +4 -0
  1083. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-182.xsl +21 -0
  1084. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.out +2 -0
  1085. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.xml +5 -0
  1086. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-183.xsl +9 -0
  1087. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.err +6 -0
  1088. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.xml +1 -0
  1089. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-184.xsl +8 -0
  1090. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.out +5 -0
  1091. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.xml +4 -0
  1092. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-186.xsl +7 -0
  1093. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.err +6 -0
  1094. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.out +14 -0
  1095. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.xml +1 -0
  1096. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-187.xsl +42 -0
  1097. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188-imp.xsl +8 -0
  1098. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.out +4 -0
  1099. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.xml +1 -0
  1100. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-188.xsl +20 -0
  1101. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.out +5 -0
  1102. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.xml +1 -0
  1103. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-189.xsl +25 -0
  1104. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.out +2 -0
  1105. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.xml +3 -0
  1106. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-19-.xsl +17 -0
  1107. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190-imp.xsl +10 -0
  1108. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.out +4 -0
  1109. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.xml +1 -0
  1110. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-190.xsl +16 -0
  1111. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191-imp.xsl +8 -0
  1112. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.err +2 -0
  1113. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.xml +1 -0
  1114. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-191.xsl +9 -0
  1115. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.out +1 -0
  1116. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.xml +1 -0
  1117. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-192.xsl +33 -0
  1118. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.out +2 -0
  1119. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.xml +1 -0
  1120. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-193.xsl +11 -0
  1121. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.err +9 -0
  1122. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.xml +1 -0
  1123. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-194.xsl +8 -0
  1124. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.out +8 -0
  1125. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.xml +9 -0
  1126. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-195.xsl +19 -0
  1127. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.out +7 -0
  1128. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.xml +9 -0
  1129. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-196.xsl +19 -0
  1130. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.out +6 -0
  1131. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.xml +6 -0
  1132. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-197.xsl +16 -0
  1133. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.out +2 -0
  1134. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.xml +2 -0
  1135. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-198.xsl +17 -0
  1136. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.out +6 -0
  1137. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.xml +6 -0
  1138. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-199.xsl +18 -0
  1139. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.out +8 -0
  1140. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.xml +12 -0
  1141. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-2-.xsl +16 -0
  1142. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.out +4 -0
  1143. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.xml +7 -0
  1144. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-20-.xsl +22 -0
  1145. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.out +2 -0
  1146. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.xml +1 -0
  1147. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-200.xsl +5 -0
  1148. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.err +6 -0
  1149. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.xml +1 -0
  1150. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-201.xsl +16 -0
  1151. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.err +2 -0
  1152. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.xml +1 -0
  1153. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-202.xsl +5 -0
  1154. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.err +1 -0
  1155. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.xml +1 -0
  1156. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-203.xsl +5 -0
  1157. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.err +2 -0
  1158. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.xml +1 -0
  1159. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-204.xsl +6 -0
  1160. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.out +2 -0
  1161. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.xml +1 -0
  1162. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-205.xsl +10 -0
  1163. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.out +2 -0
  1164. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.xml +1 -0
  1165. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-206.xsl +9 -0
  1166. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.out +2 -0
  1167. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.xml +1 -0
  1168. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-207.xsl +61 -0
  1169. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.err +6 -0
  1170. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.xml +8 -0
  1171. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-208.xsl +8 -0
  1172. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.out +2 -0
  1173. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.xml +1 -0
  1174. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-209.xsl +21 -0
  1175. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.out +2 -0
  1176. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.xml +8 -0
  1177. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-21-.xsl +7 -0
  1178. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.out +2 -0
  1179. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.xml +1 -0
  1180. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-210.xsl +20 -0
  1181. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.out +2 -0
  1182. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.xml +1 -0
  1183. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-211.xsl +26 -0
  1184. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.out +1 -0
  1185. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.xml +1 -0
  1186. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-212.xsl +25 -0
  1187. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.out +1 -0
  1188. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.xml +1 -0
  1189. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-213.xsl +26 -0
  1190. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.out +6 -0
  1191. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.xml +6 -0
  1192. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-214.xsl +25 -0
  1193. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.err +5 -0
  1194. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.xml +1 -0
  1195. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-215.xsl +6 -0
  1196. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.out +2 -0
  1197. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.xml +1 -0
  1198. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-216.xsl +11 -0
  1199. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.out +2 -0
  1200. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.xml +1 -0
  1201. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-217.xsl +24 -0
  1202. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.out +2 -0
  1203. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.xml +1 -0
  1204. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-218.xsl +8 -0
  1205. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.out +68 -0
  1206. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.xml +22 -0
  1207. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-219.xsl +17 -0
  1208. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.out +12 -0
  1209. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.xml +18 -0
  1210. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-22-.xsl +19 -0
  1211. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.out +2 -0
  1212. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.xml +1 -0
  1213. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-220.xsl +15 -0
  1214. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.out +2 -0
  1215. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.xml +9 -0
  1216. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-221.xsl +15 -0
  1217. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.out +2 -0
  1218. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.xml +1 -0
  1219. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-222.xsl +6 -0
  1220. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223-imp.xsl +12 -0
  1221. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223-inc.xsl +12 -0
  1222. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.out +1 -0
  1223. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.xml +1 -0
  1224. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-223.xsl +17 -0
  1225. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.out +9 -0
  1226. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.xml +8 -0
  1227. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-224.xsl +28 -0
  1228. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.out +2 -0
  1229. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.xml +1 -0
  1230. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-225.xsl +32 -0
  1231. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.out +15 -0
  1232. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.xml +21 -0
  1233. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-23-.xsl +20 -0
  1234. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.out +27 -0
  1235. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.xml +2419 -0
  1236. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-24-.xsl +22 -0
  1237. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.out +3 -0
  1238. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.xml +1 -0
  1239. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-25-.xsl +10 -0
  1240. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.out +2 -0
  1241. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.xml +1 -0
  1242. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-26-.xsl +9 -0
  1243. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.out +2 -0
  1244. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.xml +1 -0
  1245. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-27-.xsl +14 -0
  1246. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.out +1 -0
  1247. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.xml +1 -0
  1248. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-28-.xsl +9 -0
  1249. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.ent +7 -0
  1250. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.out +10 -0
  1251. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.xml +5 -0
  1252. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-29-.xsl +16 -0
  1253. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.out +2 -0
  1254. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.xml +1 -0
  1255. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-3-.xsl +13 -0
  1256. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.out +2 -0
  1257. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.xml +1 -0
  1258. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-30-.xsl +7 -0
  1259. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.out +3 -0
  1260. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.xml +4 -0
  1261. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-31-.xsl +10 -0
  1262. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.out +2 -0
  1263. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.xml +1 -0
  1264. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-32-.xsl +17 -0
  1265. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.out +16 -0
  1266. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.xml +14 -0
  1267. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-33-.xsl +29 -0
  1268. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.out +2 -0
  1269. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.xml +1 -0
  1270. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-35-.xsl +10 -0
  1271. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.out +4 -0
  1272. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.xml +5 -0
  1273. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-.xsl +8 -0
  1274. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-36-inc.xsl +16 -0
  1275. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.out +4 -0
  1276. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.xml +5 -0
  1277. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-.xsl +8 -0
  1278. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-37-inc.xsl +15 -0
  1279. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.out +2 -0
  1280. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.xml +17 -0
  1281. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-38-.xsl +17 -0
  1282. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.out +3 -0
  1283. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.xml +3 -0
  1284. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-39-.xsl +34 -0
  1285. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.out +6 -0
  1286. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.xml +38 -0
  1287. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-4-.xsl +12 -0
  1288. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.out +2 -0
  1289. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.xml +1 -0
  1290. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-40-.xsl +16 -0
  1291. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.out +2 -0
  1292. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.xml +1 -0
  1293. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-41-.xsl +19 -0
  1294. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.out +2 -0
  1295. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.xml +1 -0
  1296. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-42-.xsl +16 -0
  1297. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.out +2 -0
  1298. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.xml +1 -0
  1299. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-43-.xsl +19 -0
  1300. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.out +2 -0
  1301. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.xml +1 -0
  1302. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-44-.xsl +19 -0
  1303. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.out +2 -0
  1304. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.xml +1 -0
  1305. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-45-.xsl +27 -0
  1306. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.out +2 -0
  1307. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.xml +1 -0
  1308. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-46-.xsl +16 -0
  1309. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.out +2 -0
  1310. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.xml +1 -0
  1311. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-47-.xsl +18 -0
  1312. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.out +2 -0
  1313. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.xml +1 -0
  1314. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-48-.xsl +24 -0
  1315. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.out +2 -0
  1316. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.xml +1 -0
  1317. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-49-.xsl +15 -0
  1318. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.out +954 -0
  1319. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.xml +475 -0
  1320. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-5-.xsl +158 -0
  1321. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.out +7 -0
  1322. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.xml +3 -0
  1323. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-50-.xsl +14 -0
  1324. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.out +3 -0
  1325. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.xml +12 -0
  1326. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-52.xsl +16 -0
  1327. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.out +1 -0
  1328. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.xml +6 -0
  1329. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-53.xsl +11 -0
  1330. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.out +2 -0
  1331. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.xml +2 -0
  1332. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-54.xsl +22 -0
  1333. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.out +2 -0
  1334. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.xml +3 -0
  1335. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-55.xsl +9 -0
  1336. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.out +3 -0
  1337. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.xml +1 -0
  1338. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-56.xsl +28 -0
  1339. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.out +2 -0
  1340. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.xml +8 -0
  1341. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-57.xsl +21 -0
  1342. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-58.xsl +274 -0
  1343. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.out +2 -0
  1344. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.xml +1 -0
  1345. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-59.xsl +9 -0
  1346. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.out +4 -0
  1347. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.xml +6 -0
  1348. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-6-.xsl +32 -0
  1349. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.err +2 -0
  1350. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.out +2 -0
  1351. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.xml +1 -0
  1352. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-60.xsl +15 -0
  1353. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.out +10 -0
  1354. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.xml +1 -0
  1355. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-61.xsl +14 -0
  1356. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62-inc.xsl +4 -0
  1357. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.out +2 -0
  1358. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.xml +1 -0
  1359. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-62.xsl +8 -0
  1360. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.out +22 -0
  1361. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.xml +13 -0
  1362. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-63.xsl +13 -0
  1363. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.out +2 -0
  1364. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.xml +1 -0
  1365. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-64.xsl +8 -0
  1366. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.ent +7 -0
  1367. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.out +8 -0
  1368. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.xml +5 -0
  1369. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-65.xsl +26 -0
  1370. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.out +2 -0
  1371. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.xml +8 -0
  1372. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-66.xsl +12 -0
  1373. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.out +1 -0
  1374. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.xml +1 -0
  1375. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-68.xsl +8 -0
  1376. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.out +2 -0
  1377. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.xml +2 -0
  1378. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-69.xsl +12 -0
  1379. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.out +2 -0
  1380. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.xml +3 -0
  1381. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-7-.xsl +11 -0
  1382. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.out +9 -0
  1383. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.xml +10 -0
  1384. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-70.xsl +13 -0
  1385. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.out +2 -0
  1386. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.xml +1 -0
  1387. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-71.xsl +17 -0
  1388. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.out +6 -0
  1389. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.xml +3 -0
  1390. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-72.xsl +31 -0
  1391. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.out +3 -0
  1392. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.xml +5 -0
  1393. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-73.xsl +17 -0
  1394. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.out +2 -0
  1395. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.xml +3 -0
  1396. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-74.xsl +12 -0
  1397. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.out +6 -0
  1398. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.xml +1 -0
  1399. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-75.xsl +9 -0
  1400. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.out +4 -0
  1401. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.xml +4 -0
  1402. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-76.xsl +16 -0
  1403. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.out +5 -0
  1404. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.xml +4 -0
  1405. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-77.xsl +18 -0
  1406. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.out +3 -0
  1407. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.xml +8 -0
  1408. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-78.xsl +17 -0
  1409. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.out +5 -0
  1410. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.xml +4 -0
  1411. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-79.xsl +4 -0
  1412. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.out +3 -0
  1413. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.xml +5 -0
  1414. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-8-.xsl +13 -0
  1415. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.out +2 -0
  1416. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.xml +6 -0
  1417. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-80.xsl +29 -0
  1418. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.out +4 -0
  1419. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.xml +12 -0
  1420. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-81.xsl +18 -0
  1421. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.out +5 -0
  1422. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.xml +4 -0
  1423. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-82.xsl +12 -0
  1424. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.out +1 -0
  1425. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.xml +1 -0
  1426. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-83.xsl +14 -0
  1427. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.out +15 -0
  1428. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.xml +22 -0
  1429. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-84.xsl +14 -0
  1430. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.out +6 -0
  1431. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.xml +7 -0
  1432. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-86.xsl +7 -0
  1433. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.out +5 -0
  1434. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.xml +6 -0
  1435. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-87.xsl +16 -0
  1436. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.out +2 -0
  1437. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.xml +1 -0
  1438. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-88.xsl +6 -0
  1439. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.out +12 -0
  1440. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.xml +13 -0
  1441. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-89.xsl +105 -0
  1442. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.out +2 -0
  1443. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.xml +3 -0
  1444. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-9-.xsl +10 -0
  1445. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.out +13 -0
  1446. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.xml +15 -0
  1447. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-90.xsl +35 -0
  1448. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.out +3 -0
  1449. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.xml +4 -0
  1450. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-91.xsl +8 -0
  1451. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.out +15 -0
  1452. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.xml +19 -0
  1453. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-92.xsl +19 -0
  1454. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93-inc.xsl +12 -0
  1455. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.out +3 -0
  1456. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.xml +1 -0
  1457. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-93.xsl +7 -0
  1458. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.out +2 -0
  1459. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.xml +9 -0
  1460. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-94.xsl +35 -0
  1461. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.out +4 -0
  1462. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.xml +5 -0
  1463. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-95.xsl +22 -0
  1464. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.out +5 -0
  1465. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.xml +5 -0
  1466. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-96.xsl +10 -0
  1467. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.out +9 -0
  1468. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.xml +16 -0
  1469. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-97.xsl +32 -0
  1470. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.out +6 -0
  1471. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.xml +10 -0
  1472. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-98.xsl +31 -0
  1473. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.out +2 -0
  1474. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.xml +1 -0
  1475. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/bug-99.xsl +16 -0
  1476. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.out +2 -0
  1477. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.xml +23 -0
  1478. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/character.xsl +16 -0
  1479. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.out +9 -0
  1480. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.xml +1 -0
  1481. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/date_add.xsl +16 -0
  1482. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.dtd +7 -0
  1483. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.out +16 -0
  1484. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.xml +17 -0
  1485. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/doc.xsl +62 -0
  1486. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/inner.xsl +12 -0
  1487. data/vendor-src/libleptris/test/xslt/libxslt_suite_general/items.xml +34 -0
  1488. data/vendor-src/libleptris/test/xslt/open_cases.txt +0 -0
  1489. data/vendor-src/libleptris/test/xslt/test_libxslt_suite.cpp +398 -0
  1490. data/vendor-src/libleptris/vcpkg.json +29 -0
  1491. data/vendor-src/utf8proc/CMakeLists.txt +133 -0
  1492. data/vendor-src/utf8proc/Doxyfile +2765 -0
  1493. data/vendor-src/utf8proc/LICENSE.md +93 -0
  1494. data/vendor-src/utf8proc/MANIFEST +9 -0
  1495. data/vendor-src/utf8proc/Makefile +203 -0
  1496. data/vendor-src/utf8proc/NEWS.md +479 -0
  1497. data/vendor-src/utf8proc/README.md +143 -0
  1498. data/vendor-src/utf8proc/appveyor.yml +46 -0
  1499. data/vendor-src/utf8proc/bench/Makefile +40 -0
  1500. data/vendor-src/utf8proc/bench/bench.c +56 -0
  1501. data/vendor-src/utf8proc/bench/icu.c +61 -0
  1502. data/vendor-src/utf8proc/bench/unistring.c +60 -0
  1503. data/vendor-src/utf8proc/bench/util.c +39 -0
  1504. data/vendor-src/utf8proc/bench/util.h +22 -0
  1505. data/vendor-src/utf8proc/cmake/utf8proc-config.cmake.in +5 -0
  1506. data/vendor-src/utf8proc/data/Makefile +62 -0
  1507. data/vendor-src/utf8proc/data/Manifest.toml +16 -0
  1508. data/vendor-src/utf8proc/data/Project.toml +2 -0
  1509. data/vendor-src/utf8proc/data/data_generator.jl +498 -0
  1510. data/vendor-src/utf8proc/libutf8proc.pc.cmakein +10 -0
  1511. data/vendor-src/utf8proc/libutf8proc.pc.in +10 -0
  1512. data/vendor-src/utf8proc/lump.md +27 -0
  1513. data/vendor-src/utf8proc/test/app/CMakeLists.txt +6 -0
  1514. data/vendor-src/utf8proc/test/app/app.c +9 -0
  1515. data/vendor-src/utf8proc/test/case.c +76 -0
  1516. data/vendor-src/utf8proc/test/charwidth.c +91 -0
  1517. data/vendor-src/utf8proc/test/custom.c +28 -0
  1518. data/vendor-src/utf8proc/test/fuzz_main.c +54 -0
  1519. data/vendor-src/utf8proc/test/fuzzer.c +97 -0
  1520. data/vendor-src/utf8proc/test/graphemetest.c +136 -0
  1521. data/vendor-src/utf8proc/test/iscase.c +63 -0
  1522. data/vendor-src/utf8proc/test/iterate.c +168 -0
  1523. data/vendor-src/utf8proc/test/maxdecomposition.c +22 -0
  1524. data/vendor-src/utf8proc/test/misc.c +51 -0
  1525. data/vendor-src/utf8proc/test/normtest.c +64 -0
  1526. data/vendor-src/utf8proc/test/ossfuzz.sh +13 -0
  1527. data/vendor-src/utf8proc/test/printproperty.c +68 -0
  1528. data/vendor-src/utf8proc/test/tests.c +60 -0
  1529. data/vendor-src/utf8proc/test/tests.h +27 -0
  1530. data/vendor-src/utf8proc/test/valid.c +41 -0
  1531. data/vendor-src/utf8proc/utf8proc.c +834 -0
  1532. data/vendor-src/utf8proc/utf8proc.h +794 -0
  1533. data/vendor-src/utf8proc/utf8proc_data.c +17141 -0
  1534. data/vendor-src/utf8proc/utils.cmake +20 -0
  1535. 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 &lt;b&gt; (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>&lt;b&gt;</t></r>")), "<b>");
174
+ EXPECT_EQ(body(run(
175
+ "<xsl:template match='/'>"
176
+ "<xsl:value-of select='/r/t'/>"
177
+ "</xsl:template>", "<r><t>&lt;b&gt;</t></r>")), "&lt;b&gt;");
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'>&lt;hr/&gt;</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='. &gt; 10'>B</xsl:when>"
427
+ "<xsl:when test='. &gt; 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='. &gt; $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 &lt; 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]]&gt;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]]&gt;</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: &apos; 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=\"&quot;'&quot;\"/></x>"
752
+ "</xsl:template>", "<r/>")), "<x><input value=\"&quot;'&quot;\"></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 &lt; 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 &lt; 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', '&#10;', '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 &amp; 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'>&lt;![CDATA[</xsl:text>"
2150
+ "<xsl:value-of select='$v' disable-output-escaping='yes'/>"
2151
+ "<xsl:text disable-output-escaping='yes'>]]&gt;</xsl:text>"
2152
+ "</xsl:template>",
2153
+ "<r><t>a&amp;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) &gt; 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='. = &quot;b&quot;'>"
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&amp;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&amp;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&amp;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&amp;c'), "
3154
+ "iri-to-uri('a b'), escape-html-uri('&lt;a&gt;')\"/>]"
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 &amp;lt;a&amp;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('{&quot;b&quot;: &quot;beta&quot;, &quot;n&quot;: 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('{&quot;b&quot;: &quot;beta&quot;, &quot;n&quot;: 2}')),"
3666
+ " 'b')\"/>|<xsl:value-of select=\"map:get(xml-to-json("
3667
+ "json-to-xml('{&quot;b&quot;: &quot;beta&quot;, &quot;n&quot;: 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('{&quot;b&quot;: "
3682
+ "&quot;beta&quot;, &quot;n&quot;: 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
+ "'{&quot;a&quot;: 1, &quot;b&quot;: &quot;beta&quot;}'),"
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
+ "'{&quot;a&quot;: 1, &quot;b&quot;: 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='&#8594;' string='-&gt;'/>"
3963
+ "</xsl:character-map>"
3964
+ "<xsl:character-map name='cm2'>"
3965
+ "<xsl:output-character character='&#955;' string='lambda'/>"
3966
+ "</xsl:character-map>"
3967
+ "<xsl:template match='/'>"
3968
+ "<o a='x&#8594;y'>&#955;</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 &lt;/&gt; around it re-escape on output). */
4111
+ EXPECT_EQ(body(run(
4112
+ "<xsl:template match='/r/t'>"
4113
+ "&lt;<xsl:value-of select='.'/>&gt;"
4114
+ "</xsl:template>",
4115
+ "<r><t>hi</t></r>")),
4116
+ "&lt;hi&gt;");
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
+ }