PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/test/rexml/test_sax.rb

https://gitlab.com/klauer/ruby
Ruby | 278 lines | 228 code | 31 blank | 19 comment | 1 complexity | 67be54d6716832df4e7e4d951a563979 MD5 | raw file
  1. require "rexml_test_utils"
  2. require 'rexml/sax2listener'
  3. require 'rexml/parsers/sax2parser'
  4. class SAX2Tester < Test::Unit::TestCase
  5. include REXMLTestUtils
  6. include REXML
  7. def test_characters
  8. d = Document.new( "<A>@blah@</A>" )
  9. txt = d.root.text
  10. p = Parsers::SAX2Parser.new "<A>@blah@</A>"
  11. p.listen(:characters) {|x| assert_equal txt, x}
  12. p.listen(:characters, ["A"]) {|x| assert_equal txt,x}
  13. p.parse
  14. end
  15. def test_entity_replacement
  16. source = '<!DOCTYPE foo [
  17. <!ENTITY la "1234">
  18. <!ENTITY lala "--&la;--">
  19. <!ENTITY lalal "&la;&la;">
  20. ]><a><la>&la;</la><lala>&lala;</lala></a>'
  21. sax = Parsers::SAX2Parser.new( source )
  22. results = []
  23. sax.listen(:characters) {|x| results << x }
  24. sax.parse
  25. assert_equal 2, results.size
  26. assert_equal '1234', results[0]
  27. assert_equal '--1234--', results[1]
  28. end
  29. def test_sax2
  30. f = File.new(fixture_path("documentation.xml"))
  31. parser = Parsers::SAX2Parser.new( f )
  32. # Listen to all events on the following elements
  33. count = 0
  34. blok = proc { |uri,localname,qname,attributes|
  35. assert %w{ bugs todo }.include?(localname),
  36. "Mismatched name; we got '#{qname}'\nArgs were:\n\tURI: #{uri}\n\tLOCALNAME: #{localname}\n\tQNAME: #{qname}\n\tATTRIBUTES: #{attributes.inspect}\n\tSELF=#{blok}"
  37. count += 1
  38. }
  39. start_document = 0
  40. end_document = 0
  41. parser.listen( :start_document ) { start_document += 1 }
  42. parser.listen( :end_document ) { end_document += 1 }
  43. parser.listen( :start_element, %w{ changelog bugs todo }, &blok )
  44. # Listen to all events on the following elements. Synonymous with
  45. # listen( :start_element, %w{ ... } )
  46. parser.listen( %w{ changelog bugs todo }, &blok )
  47. # Listen for all start element events
  48. parser.listen( :start_element ) { |uri,localname,qname,attributes|
  49. }
  50. listener = MySAX2Listener.new
  51. # Listen for all events
  52. parser.listen( listener )
  53. # Listen for all events on the given elements. Does not include children
  54. # events. Regular expressions work as well!
  55. parser.listen( %w{ /change/ bugs todo }, listener )
  56. # Test the deafening method
  57. blok = proc { |uri,localname,qname,attributes|
  58. assert_fail "This listener should have been deafened!"
  59. }
  60. parser.listen( %w{ changelog }, &blok )
  61. parser.deafen( &blok )
  62. tc = 0
  63. parser.listen( :characters, %w{version} ) {|text|
  64. assert(text=~/@ANT_VERSION@/, "version was '#{text}'")
  65. tc += 1
  66. }
  67. begin
  68. parser.parse
  69. rescue => exception
  70. if exception.kind_of? Test::Unit::AssertionFailedError
  71. raise exception
  72. end
  73. puts $!
  74. puts exception.backtrace
  75. end
  76. assert_equal 2, count
  77. assert_equal 1, tc
  78. assert_equal 1, start_document
  79. assert_equal 1, end_document
  80. end
  81. # used by test_simple_doctype_listener
  82. # submitted by Jeff Barczewski
  83. class SimpleDoctypeListener
  84. include REXML::SAX2Listener
  85. attr_reader :name, :pub_sys, :long_name, :uri
  86. def initialize
  87. @name = @pub_sys = @long_name = @uri = nil
  88. end
  89. def doctype(name, pub_sys, long_name, uri)
  90. @name = name
  91. @pub_sys = pub_sys
  92. @long_name = long_name
  93. @uri = uri
  94. end
  95. end
  96. # test simple non-entity doctype in sax listener
  97. # submitted by Jeff Barczewski
  98. def test_simple_doctype_listener
  99. xml = <<-END
  100. <?xml version="1.0"?>
  101. <!DOCTYPE greeting PUBLIC "Hello Greeting DTD" "http://foo/hello.dtd">
  102. <greeting>Hello, world!</greeting>
  103. END
  104. parser = Parsers::SAX2Parser.new(xml)
  105. dtl = SimpleDoctypeListener.new
  106. parser.listen(dtl)
  107. tname = nil
  108. tpub_sys = nil
  109. tlong_name = nil
  110. turi = nil
  111. parser.listen(:doctype) do |name, pub_sys, long_name, uri|
  112. tname = name
  113. tpub_sys = pub_sys
  114. tlong_name = long_name
  115. turi = uri
  116. end
  117. parser.parse
  118. assert_equal 'greeting', tname, 'simple doctype block listener failed - incorrect name'
  119. assert_equal 'PUBLIC', tpub_sys, 'simple doctype block listener failed - incorrect pub_sys'
  120. assert_equal 'Hello Greeting DTD', tlong_name, 'simple doctype block listener failed - incorrect long_name'
  121. assert_equal 'http://foo/hello.dtd', turi, 'simple doctype block listener failed - incorrect uri'
  122. assert_equal 'greeting', dtl.name, 'simple doctype listener failed - incorrect name'
  123. assert_equal 'PUBLIC', dtl.pub_sys, 'simple doctype listener failed - incorrect pub_sys'
  124. assert_equal 'Hello Greeting DTD', dtl.long_name, 'simple doctype listener failed - incorrect long_name'
  125. assert_equal 'http://foo/hello.dtd', dtl.uri, 'simple doctype listener failed - incorrect uri'
  126. end
  127. # test doctype with missing name, should throw ParseException
  128. # submitted by Jeff Barczewseki
  129. def test_doctype_with_mising_name_throws_exception
  130. xml = <<-END
  131. <?xml version="1.0"?>
  132. <!DOCTYPE >
  133. <greeting>Hello, world!</greeting>
  134. END
  135. parser = Parsers::SAX2Parser.new(xml)
  136. assert_raise(REXML::ParseException, 'doctype missing name did not throw ParseException') do
  137. parser.parse
  138. end
  139. end
  140. class KouListener
  141. include REXML::SAX2Listener
  142. attr_accessor :sdoc, :edoc
  143. attr_reader :selem, :decl, :pi
  144. def initialize
  145. @sdoc = @edoc = @selem = false
  146. @decl = 0
  147. @pi = 0
  148. end
  149. def start_document
  150. @sdoc = true
  151. end
  152. def end_document
  153. @edoc = true
  154. end
  155. def xmldecl( *arg )
  156. @decl += 1
  157. end
  158. def processing_instruction( *arg )
  159. @pi += 1
  160. end
  161. def start_element( *arg )
  162. @selem = true
  163. end
  164. end
  165. # Submitted by Kou
  166. def test_begin_end_document
  167. parser = Parsers::SAX2Parser.new("<a/>")
  168. kl = KouListener.new
  169. parser.listen(kl)
  170. sd = false
  171. ed = false
  172. parser.listen(:start_document) { sd = true }
  173. parser.listen(:end_document) { ed = true }
  174. parser.parse
  175. assert( sd, ':start_document block failed' )
  176. assert( ed, ':end_document block failed' )
  177. assert( kl.sdoc, ':start_document listener failed' )
  178. assert( kl.edoc, ':end_document listener failed' )
  179. end
  180. # Submitted by Kou
  181. def test_listen_before_start
  182. # FIXME: the following comment should be a test for validity. (The xml declaration
  183. # is invalid).
  184. #parser = Parsers::SAX2Parser.new( "<?xml ?><?pi?><a><?pi?></a>")
  185. parser = Parsers::SAX2Parser.new( "<?xml version='1.0'?><?pi?><a><?pi?></a>")
  186. k1 = KouListener.new
  187. parser.listen( k1 )
  188. xmldecl = false
  189. pi = 0
  190. parser.listen( :xmldecl ) { xmldecl = true }
  191. parser.listen( :processing_instruction ) { pi += 1 }
  192. parser.parse
  193. assert( xmldecl, ':xmldecl failed' )
  194. assert_equal( 2, pi, ':processing_instruction failed' )
  195. assert( k1.decl, 'Listener for xmldecl failed' )
  196. assert_equal( 2, k1.pi, 'Listener for processing instruction failed' )
  197. end
  198. def test_socket
  199. require 'socket'
  200. server = TCPServer.new('127.0.0.1', 0)
  201. socket = TCPSocket.new('127.0.0.1', server.addr[1])
  202. ok = false
  203. session = server.accept
  204. session << '<foo>'
  205. parser = REXML::Parsers::SAX2Parser.new(socket)
  206. Fiber.new do
  207. parser.listen(:start_element) do
  208. ok = true
  209. Fiber.yield
  210. end
  211. parser.parse
  212. end.resume
  213. assert(ok)
  214. end
  215. def test_char_ref_sax2()
  216. parser = REXML::Parsers::SAX2Parser.new('<ABC>&#252;</ABC>')
  217. result = nil
  218. parser.listen(:characters) {|text| result = text.unpack('U*')}
  219. parser.parse()
  220. assert_equal(1, result.size)
  221. assert_equal(252, result[0])
  222. end
  223. def test_char_ref_dom()
  224. doc = REXML::Document.new('<ABC>&#252;</ABC>')
  225. result = doc.root.text.unpack('U*')
  226. assert_equal(1, result.size)
  227. assert_equal(252, result[0])
  228. end
  229. class Ticket68
  230. include REXML::SAX2Listener
  231. end
  232. def test_ticket_68
  233. parser = REXML::Parsers::SAX2Parser.new(File.new(fixture_path('ticket_68.xml')))
  234. parser.listen( Ticket68.new )
  235. begin
  236. parser.parse
  237. rescue
  238. p parser.source.position
  239. p parser.source.current_line
  240. puts $!.backtrace.join("\n")
  241. flunk $!.message
  242. end
  243. end
  244. end
  245. class MySAX2Listener
  246. include REXML::SAX2Listener
  247. end