require 'rexml/document'
require 'rexml/streamlistener'
require 'runit/testcase'
require "runit/cui/testrunner"

begin
	require 'xmlparser'
	class MyXMLParser
		class Listener < XML::Parser
			# Dummy handler to get XML::Parser::XML_DECL event.
			def xmlDecl; end
		end

		def parse( stringOrReadable )
			text = ""
			Listener.new.parse( stringOrReadable ) do | type, name, data |
				case type
				when XML::Parser::CDATA
		text << data
				end
			end
			text
		end
	end
rescue LoadError
	puts "XMLParser not available"
end

begin
	require 'nqxml/tokenizer'
	class MyNQXMLLightWeightListener
		def parse( stringOrReadable )
			text = ""
			isText = false
			tokenizer = NQXML::Tokenizer.new( stringOrReadable )
			tokenizer.each do | entity |
				case entity
				when NQXML::Tag
		if !entity.isTagEnd
			isText = true
		else
			isText = false
		end
				when NQXML::Text
		if isText
			text << entity.text
			isText = false
		end
				end
			end
			text
		end
	end
rescue LoadError
	puts "NQXML not available"
end

class MyREXMLListener
  include REXML::StreamListener

  def initialize
    @text = nil
  end

  def parse( stringOrReadable )
    @text = ""
    REXML::Document.parse_stream( stringOrReadable, self )
    @text
  end

  def text( text )
    @text << text
  end
end

class BaseTester < RUNIT::TestCase
	def test_empty
		return unless defined? @listener
		# Empty.
		t1 = <<__EOS__
<string></string>
__EOS__
		assert_equal( "", @listener.parse( t1 ), 
			"Empty" )
	end

	def test_space
		return unless defined? @listener
		# Space.
		t2 = <<__EOS__
<string>    </string>
__EOS__
		assert_equal( "    ", @listener.parse( t2 ),
			"Space" )
	end

	def test_whitespace
		return unless defined? @listener
		# Whitespaces.
		t3 = <<__EOS__
<string>RE\n \t \n \t XML</string>
__EOS__
		assert_equal( "RE\n \t \n \t XML", @listener.parse( t3 ),
			"Whitespaces" )
	end

	def test_leading_trailing_whitespace
		return unless defined? @listener
		# Leading and trailing whitespaces.
		t4 = <<__EOS__
<string>    REXML    </string>
__EOS__
		assert_equal( "    REXML    ", @listener.parse( t4 ),
			"Leading and trailing whitespaces" )
	end

	def test_entity_reference
		return unless defined? @listener
		# Entity reference.
		t5 = <<__EOS__
<string>&lt;&gt;&amp;lt;&amp;gt;</string>
__EOS__
		assert_equal( "<>&lt;&gt;", @listener.parse( t5 ),
			"Entity reference" )
	end

	def test_character_reference
		return unless defined? @listener
		# Character reference.
		t6 = <<__EOS__
<string>&#xd;</string>
__EOS__
		assert_equal( "\r", @listener.parse( t6 ),
			"Character reference." )
	end

	def test_cr
		return unless defined? @listener
		# CR.
		t7 = <<__EOS__
<string> \r\n \r \n </string>
__EOS__
		assert_equal( " \n \n \n ", @listener.parse( t7 ),
			"CR" )
	end
end

class REXMLTester < BaseTester
	def setup
		@listener = MyREXMLListener.new
	end

	def test_character_reference_2
		t6 = <<__EOS__
<string>&#xd;</string>
__EOS__
		assert_equal( t6.strip, REXML::Document.new(t6).to_s )
	end
end

class NQXMLTester < BaseTester
	def setup
		@listener = MyNQXMLLightWeightListener.new
	end
end

class XMLParserTester < BaseTester
	def setup
		@listener = MyXMLParser.new
	end
end

if __FILE__ == $0
	case ARGV[0]
	when 'NQXML'
		RUNIT::CUI::TestRunner.run( NQXMLTester.suite )
	when 'XMLParser'
		RUNIT::CUI::TestRunner.run( XMLParserTester.suite )
	else
		RUNIT::CUI::TestRunner.run( REXMLTester.suite )
	end
end
