# encoding: UTF-8 require './test_helper' require 'stringio' require 'test/unit' class TestReader < Test::Unit::TestCase XML_FILE = File.join(File.dirname(__FILE__), 'model/atom.xml') def verify_simple(reader) node_types = [] # Read each node 26.times do assert(reader.read) node_types << reader.node_type end # There are no more nodes assert(!reader.read) # Check what was read expected = [XML::Reader::TYPE_PROCESSING_INSTRUCTION, XML::Reader::TYPE_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_COMMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_ELEMENT, XML::Reader::TYPE_CDATA, XML::Reader::TYPE_END_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_ELEMENT, XML::Reader::TYPE_TEXT, XML::Reader::TYPE_END_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_END_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_END_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_END_ELEMENT, XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, XML::Reader::TYPE_END_ELEMENT] assert_equal(expected, node_types) end def test_document reader = XML::Reader.document(XML::Document.file(XML_FILE)) verify_simple(reader) end def test_file reader = XML::Reader.file(XML_FILE) verify_simple(reader) end def test_invalid_file assert_raise(XML::Error) do XML::Reader.file('/does/not/exist') end end def test_string reader = XML::Reader.string(File.read(XML_FILE)) verify_simple(reader) end def test_io File.open(XML_FILE, 'rb') do |io| reader = XML::Reader.io(io) verify_simple(reader) end end def test_io_gc # Test that the reader keeps a reference # to the io object file = File.open(XML_FILE, 'rb') reader = XML::Reader.io(file) file = nil GC.start assert(reader.read) end def test_string_io data = File.read(XML_FILE) string_io = StringIO.new(data) reader = XML::Reader.io(string_io) verify_simple(reader) end def test_error reader = XML::Reader.string('") assert(parser.read) assert_equal('foo', parser.name) assert_equal('1', parser['x']) assert_equal('1', parser[0]) assert_equal('2', parser['y']) assert_equal('2', parser[1]) assert_equal(nil, parser['z']) assert_equal(nil, parser[2]) end def test_move_to_attribute_depreciation previous_stderr, $stderr = $stderr, StringIO.new reader = XML::Reader.string("") assert(reader.read) assert(reader.move_to_attribute 1) assert($stderr.string =~ /deprecated/) ensure $stderr = previous_stderr end def test_move_attr reader = XML::Reader.string('') assert(reader.read) # assert(reader.read) # assert(reader.move_to_attribute_no(1)) assert_equal(reader.value, 'def') assert(reader.move_to_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace')) assert_equal(reader.value, 'abc') assert(reader.move_to_attribute('bar')) assert_equal(reader.value, 'jkl') # 1 in case of success, -1 in case of error, 0 if not found assert_equal(reader.move_to_attribute_no(12), 0) assert_equal(reader.move_to_attribute('baz'), 0) assert_equal(reader.move_to_attribute_ns('baz', 'http://ruby/namespace'), 0) end def test_get_attr reader = XML::Reader.string('') assert(reader.read) # assert(reader.read) # assert_equal(reader.get_attribute_no(1), 'def') assert_equal(reader.get_attribute_ns('id', 'http://www.w3.org/XML/1998/namespace'), 'abc') assert_equal(reader.get_attribute('bar'), 'jkl') assert_equal(reader.get_attribute_no(12), nil) assert_equal(reader.get_attribute('baz'), nil) assert_equal(reader.get_attribute_ns('baz', 'http://ruby/namespace'), nil) end def test_value parser = XML::Reader.string("123") assert(parser.read) assert_equal('foo', parser.name) assert_equal(nil, parser.value) 3.times do |i| assert(parser.read) assert_equal(XML::Reader::TYPE_ELEMENT, parser.node_type) assert_equal('bar', parser.name) assert(parser.read) assert_equal(XML::Reader::TYPE_TEXT, parser.node_type) assert_equal((i + 1).to_s, parser.value) assert(parser.read) assert_equal(XML::Reader::TYPE_END_ELEMENT, parser.node_type) end end def test_expand reader = XML::Reader.file(XML_FILE) reader.read.to_s reader.read # Read a node node = reader.expand assert_equal('feed', node.name) assert_equal(::Encoding::UTF_8, node.name.encoding) if defined?(::Encoding) end def test_expand_doc reader = XML::Reader.file(XML_FILE) reader.read.to_s reader.read # Read a node node = reader.expand # Try to access the document assert_not_nil(node.doc) end def test_expand_find reader = XML::Reader.file(XML_FILE) reader.read.to_s reader.read # Read first node which node = reader.expand assert_equal('feed', node.name) # Search for entries entries = node.find('atom:entry', 'atom:http://www.w3.org/2005/Atom') assert_equal(1, entries.length) end def test_expand_invalid reader = XML::Reader.file(XML_FILE) # Expand a node before one has been read error = assert_raise(RuntimeError) do reader.expand end assert_equal("The reader does not have a document. Did you forget to call read?", error.to_s) end def test_expand_invalid_access reader = XML::Reader.file(XML_FILE) # Read a node reader.read reader.read # Expand the node node = reader.expand assert_equal('feed', node.name) # Read another node, this makes the last node invalid reader.next # The previous node is now invalid error = assert_raise(RuntimeError) do assert_equal('feed', node.name) end assert_equal("This node has already been freed.", error.to_s) end def test_mode reader = XML::Reader.string('') assert_equal(XML::Reader::MODE_INITIAL, reader.read_state) reader.read assert_equal(XML::Reader::MODE_EOF, reader.read_state) end def test_bytes_consumed reader = XML::Reader.file(XML_FILE) reader.read assert_equal(416, reader.byte_consumed) end def test_node XML.default_line_numbers = true reader = XML::Reader.file(XML_FILE) # first try to get a node assert_nil(reader.node) reader.read assert_instance_of(XML::Node, reader.node) end def test_base_uri # UTF8: # ö - c3 b6 in hex, \303\266 in octal # ü - c3 bc in hex, \303\274 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = XML::Reader.string(xml, :base_uri => "http://libxml.rubyforge.org") reader.read assert_equal(reader.base_uri, "http://libxml.rubyforge.org") assert_equal(::Encoding::UTF_8, reader.base_uri.encoding) if defined?(::Encoding) end def test_options xml = <<-EOS ]> &foo; EOS # Parse normally reader = XML::Reader.string(xml) reader.read # foo reader.read # test reader.read # text reader.read # cdata reader.read # cdata-section assert_equal(XML::Node::CDATA_SECTION_NODE, reader.node_type) # Convert cdata section to text reader = XML::Reader.string(xml, :options => XML::Parser::Options::NOCDATA) reader.read # foo reader.read # test reader.read # text reader.read # cdata reader.read # cdata-section assert_equal(XML::Node::TEXT_NODE, reader.node_type) end def test_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = XML::Reader.string(xml, :encoding => XML::Encoding::ISO_8859_1) reader.read if defined?(Encoding) assert_equal(Encoding::ISO8859_1, reader.read_outer_xml.encoding) assert_equal(Encoding::ISO8859_1, reader.read_inner_xml.encoding) assert_equal(Encoding::ISO8859_1, reader.read_string.encoding) assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), reader.read_outer_xml) assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), reader.read_inner_xml) assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n".force_encoding(Encoding::ISO8859_1), reader.read_string) else assert_equal("\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n", reader.read_outer_xml) end end def test_invalid_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = XML::Reader.string(xml) error = assert_raise(XML::Error) do node = reader.read end assert_equal("Fatal error: Input is not proper UTF-8, indicate encoding !\nBytes: 0xF6 0x74 0x6C 0x65 at :2.", error.to_s) end def test_file_encoding reader = XML::Reader.file(XML_FILE) reader.read assert_equal(XML::Encoding::UTF_8, reader.encoding) assert_equal(Encoding::UTF_8, reader.value.encoding) if defined?(Encoding) end def test_string_encoding # ISO_8859_1: # ö - f6 in hex, \366 in octal # ü - fc in hex, \374 in octal xml = "\n An American heavy metal band formed in Los Angeles, California in 1981.\n British heavy metal band formed in 1975.\n" reader = XML::Reader.string(xml, :encoding => XML::Encoding::ISO_8859_1) reader.read # Encoding is always null for strings, very annoying! assert_equal(reader.encoding, XML::Encoding::NONE) end end