require 'xml' require 'test/unit' require 'stringio' class TestParser < Test::Unit::TestCase def setup XML::Error.set_handler(&XML::Error::QUIET_HANDLER) @xp = XML::Parser.new end def teardown @xp = nil GC.start GC.start GC.start end # ----- Sources ------ def test_file file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) @xp.file = file assert_equal(file, @xp.file) assert_equal(file, @xp.input.file) doc = @xp.parse assert_instance_of(XML::Document, doc) assert_instance_of(XML::Parser::Context, @xp.context) GC.start GC.start GC.start end def test_file_class file = File.expand_path(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) xp = XML::Parser.file(file) assert_instance_of(XML::Parser, xp) assert_equal(file, xp.file) assert_equal(file, xp.input.file) end def test_string str = 'onetwo' @xp.string = str assert_equal(str, @xp.string) assert_equal(str, @xp.input.string) doc = @xp.parse assert_instance_of(XML::Document, doc) assert_instance_of(XML::Parser::Context, @xp.context) end def test_string_empty assert_raise(XML::Error) do @xp.string = '' @xp.parse end assert_raise(TypeError) do @xp.string = nil end end def test_string_class str = 'onetwo' xp = XML::Parser.string(str) assert_instance_of(XML::Parser, xp) assert_equal(str, xp.string) assert_equal(str, xp.input.string) end def test_io File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io| @xp.io = io assert_equal(io, @xp.io) assert_equal(io, @xp.input.io) doc = @xp.parse assert_instance_of(XML::Document, doc) assert_instance_of(XML::Parser::Context, @xp.context) end end def test_io_class File.open(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) do |io| xp = XML::Parser.io(io) assert_instance_of(XML::Parser, xp) assert_equal(io, xp.io) assert_equal(io, xp.input.io) end end def test_string_io data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml')) string_io = StringIO.new(data) assert_raises(TypeError) do @xp.io = string_io end end def test_fd_gc # Test opening # of documents up to the file limit for the OS. # Ideally it should run until libxml emits a warning, # thereby knowing we've done a GC sweep. For the time being, # re-open the same doc `limit descriptors` times. # If we make it to the end, then we've succeeded, # otherwise an exception will be thrown. XML::Error.set_handler {|error|} max_fd = if RUBY_PLATFORM.match(/mswin32/i) 500 else (`ulimit -n`.chomp.to_i) + 1 end file = File.join(File.dirname(__FILE__), 'model/rubynet.xml') max_fd.times do XML::Parser.file(file).parse end XML::Error.reset_handler {|error|} end # ----- Errors ------ def test_error error = assert_raise(XML::Error) do XML::Parser.string('').parse end assert_not_nil(error) assert_kind_of(XML::Error, error) assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", error.message) assert_equal(XML::Error::PARSER, error.domain) assert_equal(XML::Error::TAG_NAME_MISMATCH, error.code) assert_equal(XML::Error::FATAL, error.level) assert_nil(error.file) assert_equal(1, error.line) assert_equal('foo', error.str1) assert_equal('foz', error.str2) assert_nil(error.str3) assert_equal(1, error.int1) assert_equal(20, error.int2) assert_nil(error.node) end def test_bad_xml @xp.string = 'onetwo' error = assert_raise(XML::Error) do assert_not_nil(@xp.parse) end assert_not_nil(error) assert_kind_of(XML::Error, error) assert_equal("Fatal error: Extra content at the end of the document at :1.", error.message) assert_equal(XML::Error::PARSER, error.domain) assert_equal(XML::Error::DOCUMENT_END, error.code) assert_equal(XML::Error::FATAL, error.level) assert_nil(error.file) assert_equal(1, error.line) assert_nil(error.str1) assert_nil(error.str2) assert_nil(error.str3) assert_equal(0, error.int1) assert_equal(20, error.int2) assert_nil(error.node) end def test_double_parse parser = XML::Parser.string("something") doc = parser.parse assert_raise(RuntimeError) do parser.parse end end end