| 1 | # coding: binary |
|---|
| 2 | require 'test/unit/testcase' |
|---|
| 3 | require 'rexml/document' |
|---|
| 4 | require 'rexml/streamlistener' |
|---|
| 5 | |
|---|
| 6 | class BaseTester < Test::Unit::TestCase |
|---|
| 7 | def test_empty |
|---|
| 8 | return unless defined? @listener |
|---|
| 9 | # Empty. |
|---|
| 10 | t1 = %Q{<string></string>} |
|---|
| 11 | assert_equal( "", @listener.parse( t1 ), |
|---|
| 12 | "Empty" ) |
|---|
| 13 | end |
|---|
| 14 | |
|---|
| 15 | def test_space |
|---|
| 16 | return unless defined? @listener |
|---|
| 17 | # Space. |
|---|
| 18 | t2 = %Q{<string> </string>} |
|---|
| 19 | assert_equal( " ", @listener.parse( t2 ), |
|---|
| 20 | "Space" ) |
|---|
| 21 | end |
|---|
| 22 | |
|---|
| 23 | def test_whitespace |
|---|
| 24 | return unless defined? @listener |
|---|
| 25 | # Whitespaces. |
|---|
| 26 | t3 = %Q{<string>RE\n \t \n \t XML</string>} |
|---|
| 27 | assert_equal( "RE\n \t \n \t XML", @listener.parse( t3 ), |
|---|
| 28 | "Whitespaces" ) |
|---|
| 29 | end |
|---|
| 30 | |
|---|
| 31 | def test_leading_trailing_whitespace |
|---|
| 32 | return unless defined? @listener |
|---|
| 33 | # Leading and trailing whitespaces. |
|---|
| 34 | t4 = %Q{<string> REXML </string>} |
|---|
| 35 | assert_equal( " REXML ", @listener.parse( t4 ), |
|---|
| 36 | "Leading and trailing whitespaces" ) |
|---|
| 37 | end |
|---|
| 38 | |
|---|
| 39 | def test_entity_reference |
|---|
| 40 | return unless defined? @listener |
|---|
| 41 | # Entity reference. |
|---|
| 42 | t5 = %Q{<string><>&lt;&gt;</string>} |
|---|
| 43 | assert_equal( "<><>", @listener.parse( t5 ), |
|---|
| 44 | "Entity reference" ) |
|---|
| 45 | end |
|---|
| 46 | |
|---|
| 47 | def test_character_reference |
|---|
| 48 | return unless defined? @listener |
|---|
| 49 | # Character reference. |
|---|
| 50 | t6 = %Q{<string>
</string>} |
|---|
| 51 | assert_equal( "\r", @listener.parse( t6 ), |
|---|
| 52 | "Character reference." ) |
|---|
| 53 | end |
|---|
| 54 | |
|---|
| 55 | def test_cr |
|---|
| 56 | return unless defined? @listener |
|---|
| 57 | # CR. |
|---|
| 58 | t7 = %Q{<string> \r\n \r \n </string>} |
|---|
| 59 | assert_equal( " \n \n \n ".unpack("C*").inspect, |
|---|
| 60 | @listener.parse( t7 ).unpack("C*").inspect, "CR" ) |
|---|
| 61 | end |
|---|
| 62 | |
|---|
| 63 | # The accent bug, and the code that exibits the bug, was contributed by |
|---|
| 64 | # Guilhem Vellut |
|---|
| 65 | class AccentListener |
|---|
| 66 | def tag_start(name,attributes) |
|---|
| 67 | #p name |
|---|
| 68 | #p attributes |
|---|
| 69 | end |
|---|
| 70 | def tag_end(name) |
|---|
| 71 | #p "/"+name |
|---|
| 72 | end |
|---|
| 73 | def xmldecl(a,b,c) |
|---|
| 74 | #puts "#{a} #{b} #{c}" |
|---|
| 75 | end |
|---|
| 76 | def text(tx) |
|---|
| 77 | #p tx |
|---|
| 78 | end |
|---|
| 79 | end |
|---|
| 80 | |
|---|
| 81 | def test_accents |
|---|
| 82 | source = '<?xml version="1.0" encoding="ISO-8859-1"?> |
|---|
| 83 | <g> |
|---|
| 84 | <f a="é" /> |
|---|
| 85 | </g>' |
|---|
| 86 | doc = REXML::Document.new( source ) |
|---|
| 87 | a = doc.elements['/g/f'].attribute('a') |
|---|
| 88 | if a.value.respond_to? :force_encoding |
|---|
| 89 | a.value.force_encoding('binary') |
|---|
| 90 | end |
|---|
| 91 | assert_equal( 'é', a.value) |
|---|
| 92 | doc = REXML::Document.parse_stream( |
|---|
| 93 | File::new("test/data/stream_accents.xml"), |
|---|
| 94 | AccentListener::new |
|---|
| 95 | ) |
|---|
| 96 | end |
|---|
| 97 | end |
|---|
| 98 | |
|---|
| 99 | ######################################################### |
|---|
| 100 | # Other parsers commented out because they cause failures |
|---|
| 101 | # in the unit tests, which aren't REXMLs problems |
|---|
| 102 | # ####################################################### |
|---|
| 103 | =begin |
|---|
| 104 | begin |
|---|
| 105 | require 'xmlparser' |
|---|
| 106 | class MyXMLParser |
|---|
| 107 | class Listener < XML::Parser |
|---|
| 108 | # Dummy handler to get XML::Parser::XML_DECL event. |
|---|
| 109 | def xmlDecl; end |
|---|
| 110 | end |
|---|
| 111 | |
|---|
| 112 | def parse( stringOrReadable ) |
|---|
| 113 | text = "" |
|---|
| 114 | Listener.new.parse( stringOrReadable ) do | type, name, data | |
|---|
| 115 | case type |
|---|
| 116 | when XML::Parser::CDATA |
|---|
| 117 | text << data |
|---|
| 118 | end |
|---|
| 119 | end |
|---|
| 120 | text |
|---|
| 121 | end |
|---|
| 122 | end |
|---|
| 123 | |
|---|
| 124 | class XMLParserTester < BaseTester |
|---|
| 125 | def setup |
|---|
| 126 | @listener = MyXMLParser.new |
|---|
| 127 | end |
|---|
| 128 | end |
|---|
| 129 | rescue LoadError |
|---|
| 130 | #puts "XMLParser not available" |
|---|
| 131 | end |
|---|
| 132 | |
|---|
| 133 | begin |
|---|
| 134 | require 'nqxml/tokenizer' |
|---|
| 135 | class MyNQXMLLightWeightListener |
|---|
| 136 | def parse( stringOrReadable ) |
|---|
| 137 | text = "" |
|---|
| 138 | isText = false |
|---|
| 139 | tokenizer = NQXML::Tokenizer.new( stringOrReadable ) |
|---|
| 140 | tokenizer.each do | entity | |
|---|
| 141 | case entity |
|---|
| 142 | when NQXML::Tag |
|---|
| 143 | if !entity.isTagEnd |
|---|
| 144 | isText = true |
|---|
| 145 | else |
|---|
| 146 | isText = false |
|---|
| 147 | end |
|---|
| 148 | when NQXML::Text |
|---|
| 149 | if isText |
|---|
| 150 | text << entity.text |
|---|
| 151 | isText = false |
|---|
| 152 | end |
|---|
| 153 | end |
|---|
| 154 | end |
|---|
| 155 | text |
|---|
| 156 | end |
|---|
| 157 | end |
|---|
| 158 | |
|---|
| 159 | class NQXMLTester < BaseTester |
|---|
| 160 | def setup |
|---|
| 161 | @listener = MyNQXMLLightWeightListener.new |
|---|
| 162 | end |
|---|
| 163 | end |
|---|
| 164 | rescue LoadError |
|---|
| 165 | #puts "NQXML not available" |
|---|
| 166 | end |
|---|
| 167 | =end |
|---|
| 168 | |
|---|
| 169 | class MyREXMLListener |
|---|
| 170 | include REXML::StreamListener |
|---|
| 171 | |
|---|
| 172 | def initialize |
|---|
| 173 | @text = nil |
|---|
| 174 | end |
|---|
| 175 | |
|---|
| 176 | def parse( stringOrReadable ) |
|---|
| 177 | @text = "" |
|---|
| 178 | REXML::Document.parse_stream( stringOrReadable, self ) |
|---|
| 179 | @text |
|---|
| 180 | end |
|---|
| 181 | |
|---|
| 182 | def text( text ) |
|---|
| 183 | @text << text |
|---|
| 184 | end |
|---|
| 185 | end |
|---|
| 186 | |
|---|
| 187 | class REXMLTester < BaseTester |
|---|
| 188 | def setup |
|---|
| 189 | @listener = MyREXMLListener.new |
|---|
| 190 | end |
|---|
| 191 | |
|---|
| 192 | def test_character_reference_2 |
|---|
| 193 | t6 = %Q{<string>
</string>} |
|---|
| 194 | assert_equal( t6.strip, REXML::Document.new(t6).to_s ) |
|---|
| 195 | end |
|---|
| 196 | end |
|---|
| 197 | |
|---|
| 198 | if __FILE__ == $0 |
|---|
| 199 | case ARGV[0] |
|---|
| 200 | when 'NQXML' |
|---|
| 201 | RUNIT::CUI::TestRunner.run( NQXMLTester.suite ) |
|---|
| 202 | when 'XMLParser' |
|---|
| 203 | RUNIT::CUI::TestRunner.run( XMLParserTester.suite ) |
|---|
| 204 | else |
|---|
| 205 | RUNIT::CUI::TestRunner.run( REXMLTester.suite ) |
|---|
| 206 | end |
|---|
| 207 | end |
|---|