1# frozen_string_literal: false 2require_relative 'rexml_test_utils' 3 4require "rexml/document" 5require "rexml/xpath" 6 7# Harness to test REXML's capabilities against the test suite from Jaxen 8# ryan.a.cox@gmail.com 9 10module REXMLTests 11 class JaxenTester < Test::Unit::TestCase 12 include REXMLTestUtils 13 include REXML 14 15 def test_axis ; process_test_case("axis") ; end 16 def test_basic ; process_test_case("basic") ; end 17 def test_basicupdate ; process_test_case("basicupdate") ; end 18 def test_contents ; process_test_case("contents") ; end 19 def test_defaultNamespace ; process_test_case("defaultNamespace") ; end 20 def test_fibo ; process_test_case("fibo") ; end 21 def test_id ; process_test_case("id") ; end 22 def test_jaxen24 ; process_test_case("jaxen24") ; end 23 def test_lang ; process_test_case("lang") ; end 24 # document() function for XSLT isn't supported 25 def _test_message ; process_test_case("message") ; end 26 def test_moreover ; process_test_case("moreover") ; end 27 def test_much_ado ; process_test_case("much_ado") ; end 28 def test_namespaces ; process_test_case("namespaces") ; end 29 def test_nitf ; process_test_case("nitf") ; end 30 # Exception should be considered 31 def _test_numbers ; process_test_case("numbers") ; end 32 def test_pi ; process_test_case("pi") ; end 33 def test_pi2 ; process_test_case("pi2") ; end 34 def test_simple ; process_test_case("simple") ; end 35 # TODO: namespace node is needed 36 def _test_testNamespaces ; process_test_case("testNamespaces") ; end 37 # document() function for XSLT isn't supported 38 def _test_text ; process_test_case("text") ; end 39 def test_underscore ; process_test_case("underscore") ; end 40 def _test_web ; process_test_case("web") ; end 41 def test_web2 ; process_test_case("web2") ; end 42 43 private 44 def process_test_case(name) 45 xml_path = "#{name}.xml" 46 doc = File.open(fixture_path(xml_path)) do |file| 47 Document.new(file) 48 end 49 test_doc = File.open(fixture_path("test/tests.xml")) do |file| 50 Document.new(file) 51 end 52 XPath.each(test_doc, 53 "/tests/document[@url='xml/#{xml_path}']/context") do |context| 54 process_context(doc, context) 55 end 56 end 57 58 # processes a tests/document/context node 59 def process_context(doc, context) 60 test_context = XPath.match(doc, context.attributes["select"]) 61 namespaces = context.namespaces 62 namespaces.delete("var") 63 namespaces = nil if namespaces.empty? 64 variables = {} 65 var_namespace = "http://jaxen.org/test-harness/var" 66 XPath.each(context, 67 "@*[namespace-uri() = '#{var_namespace}']") do |attribute| 68 variables[attribute.name] = attribute.value 69 end 70 XPath.each(context, "valueOf") do |value| 71 process_value_of(test_context, variables, namespaces, value) 72 end 73 XPath.each(context, 74 "test[not(@exception) or (@exception != 'true')]") do |test| 75 process_nominal_test(test_context, variables, namespaces, test) 76 end 77 XPath.each(context, 78 "test[@exception = 'true']") do |test| 79 process_exceptional_test(test_context, variables, namespaces, test) 80 end 81 end 82 83 # processes a tests/document/context/valueOf or tests/document/context/test/valueOf node 84 def process_value_of(context, variables, namespaces, value_of) 85 expected = value_of.text 86 xpath = value_of.attributes["select"] 87 matched = XPath.match(context, xpath, namespaces, variables, strict: true) 88 89 message = user_message(context, xpath, matched) 90 assert_equal(expected || "", 91 REXML::Functions.string(matched), 92 message) 93 end 94 95 # processes a tests/document/context/test node ( where @exception is false or doesn't exist ) 96 def process_nominal_test(context, variables, namespaces, test) 97 xpath = test.attributes["select"] 98 matched = XPath.match(context, xpath, namespaces, variables, strict: true) 99 # might be a test with no count attribute, but nested valueOf elements 100 expected = test.attributes["count"] 101 if expected 102 assert_equal(Integer(expected, 10), 103 matched.size, 104 user_message(context, xpath, matched)) 105 end 106 107 XPath.each(test, "valueOf") do |value_of| 108 process_value_of(matched, variables, namespaces, value_of) 109 end 110 end 111 112 # processes a tests/document/context/test node ( where @exception is true ) 113 def process_exceptional_test(context, variables, namespaces, test) 114 xpath = test.attributes["select"] 115 assert_raise(REXML::ParseException) do 116 XPath.match(context, xpath, namespaces, variables, strict: true) 117 end 118 end 119 120 def user_message(context, xpath, matched) 121 message = "" 122 context.each_with_index do |node, i| 123 message << "Node#{i}:\n" 124 message << "#{node}\n" 125 end 126 message << "XPath: <#{xpath}>\n" 127 message << "Matched <#{matched}>" 128 message 129 end 130 end 131end 132