require "runit/testcase"
require "runit/cui/testrunner"

require "rexml/document"
require "rexml/parseexception"

class ContribTester < RUNIT::TestCase
	include REXML

XML_STRING_01 = <<DELIMITER
<?xml version="1.0" encoding="UTF-8"?>
<biblio>
  <entry type="Book">
    <author>Thomas, David; Hunt, Andrew</author>
    <language>english</language>
    <publisher>Addison-Wesley</publisher>
    <title>Programming Ruby. The Pragmatic Programmer's Guide</title>
    <year>2000</year>
  </entry>
  <entry type="Book">
    <author>Blammo, Blah</author>
    <language>english</language>
    <publisher>Hubbabubba</publisher>
    <title>Foozboozer's Life</title>
    <type>Book</type>
    <year>2002</year>
  </entry>
</biblio>
DELIMITER

XML_STRING_02 = <<DELIMITER
<biblio>
  <entry type="Book">
    <language>english</language>
    <publisher>Addison-Wesley</publisher>
    <title>Programming Ruby. The Pragmatic Programmer's Guide</title>
    <type>Book</type>
    <year>2000</year>
  </entry>
  <entry type="Book">
    <author>Blammo, Blah</author>
    <language>english</language>
    <publisher>Hubbabubba</publisher>
    <title>Foozboozer's Life</title>
    <type>Book</type>
    <year>2002</year>
  </entry>
</biblio>
DELIMITER

	# Tobias Reif <tobiasreif@pinkjuice.com>
	def test_bad_doctype_Tobias
		source = <<-EOF
		 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
				"http://www.w3.org/TR/SVG/DTD/svg10.dtd"
			 [
			 <!-- <!ENTITY % fast-slow "0 0  .5 1">-->
			 <!--<!ENTITY % slow-fast ".5 0  1 1">-->
			 <!ENTITY hover_ani
				'<animateTransform attributeName="transform"
				 type="scale" restart="whenNotActive" values="1;0.96"
				 dur="0.5s" calcMode="spline" keySplines="0 0  .5 1"
				 fill="freeze" begin="mouseover"/>
				 <animateTransform  attributeName="transform"
				 type="scale" restart="whenNotActive" values="0.96;1"
				 dur="0.5s" calcMode="spline" keySplines=".5 0  1 1"
				 fill="freeze" begin="mouseover+0.5s"/>'
			 >
			 ]
		 >
		EOF
		doc = REXML::Document.new source
		out = ""
		doc.write(out)
		assert out[/>'>/] != nil, "Couldn't find >'>" # '
		assert out[/]>/] != nil, "Couldn't find ]>"
	end

	# Peter Verhage
	def test_namespace_Peter
		source = <<-EOF
		<?xml version="1.0"?>
		<config:myprog-config xmlns:config="http://someurl/program/version">
		<!-- main options -->
			<config:main>
				<config:parameter name="name"  value="value"/>
			</config:main>
		</config:myprog-config>
		EOF
		doc = REXML::Document.new source
		assert_equal "myprog-config", doc.root.name
		count = 0
		REXML::XPath.each(doc, "x:myprog-config/x:main/x:parameter", 
			{"x","http://someurl/program/version"}) { |element|
				assert_equal "name", element.attributes["name"]
			count += 1;
		}
		assert_equal 1, count
		assert_equal "myprog-config", doc.elements["config:myprog-config"].name
	end

	# Tobias Reif <tobiasreif@pinkjuice.com>
	def test_complex_xpath_Tobias
		source = <<-EOF
		<root>
			<foo>
				<bar style="baz"/>
				<blah style="baz"/>
				<blam style="baz"/>
			</foo>
			<wax>
				<fudge>
					<noodle/>
				</fudge>
			</wax>
		</root>
		EOF
		complex_path = "*[* "+
			"and not(*/node()) "+
			"and not(*[not(@style)]) "+
			"and not(*/@style != */@style)]"
		doc = REXML::Document.new source
		results = REXML::XPath.match( doc.root, complex_path )
		assert_not_nil results
		assert_equal 1, results.size
		assert_equal "foo", results[0].name
	end

	# "Chris Morris" <chrismo@charter.net>
	def test_extra_newline_on_read_Chris
		text = 'test text'
		e = REXML::Element.new('Test')
		e.add_text(text)
		out = ''
		e.write(out)

		doc = REXML::Document.new(out)
		outtext = doc.root.text

		assert_equal(text, outtext)
	end

	# Tobias Reif <tobiasreif@pinkjuice.com>
	def test_other_xpath_Tobias
		schema = <<-DELIM
		<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
			elementFormDefault="qualified">
			<xs:element name="rect">
				<xs:complexType>
					<xs:attribute name="width" type="xs:byte" use="required"/>
					<xs:attribute name="height" type="xs:byte" use="required"/>
				</xs:complexType>
			</xs:element>
			<xs:element name="svg">
				<xs:complexType>
					<xs:sequence>
						<xs:element ref="rect"/>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:schema>
		DELIM

		doc = REXML::Document.new schema

		result = REXML::XPath.first(doc.root, 'xs:element[descendant::xs:element[@ref]]')
		assert_not_nil result
		assert_equal "svg", result.attributes['name']
		result = REXML::XPath.first(doc, 'element[descendant::element[@ref]]')
		assert_nil result
	end

  #this first test succeeds, to check if stuff is set up correctly
  def test_xpath_01_TobiasReif
    doc = Document.new XML_STRING_01.dup
    desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
    xpath = '//author'
    result = XPath.first(doc, xpath)
    assert_equal desired_result.to_s, result.to_s
  end
  
  def test_xpath_whitespace_TobiasReif
    # same as oabove, with whitespace in XPath
    doc = Document.new XML_STRING_01.dup
    desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
    xpath = "\/\/author\n \n"
    result = XPath.first(doc, xpath)
    failure_message = "\n[[[TR: AFAIK, whitespace should be allowed]]]\n"
    assert_equal desired_result.to_s, result.to_s, failure_message
  end
  
  def test_xpath_02_TobiasReif
    doc = Document.new XML_STRING_01.dup
    desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
    # Could that quirky
    #  Programmer',&quot;'&quot;,'s
    # be handled automatically, somehow?
    # Or is there a simpler way? (the below XPath should match the author element above,
    # AFAIK; I tested it inside an XSLT)
    xpath = "/biblio/entry[
    title=concat('Programming Ruby. The Pragmatic Programmer',&quot;'&quot;,'s Guide')
    and
    year='2000'
    ]/author"
    result = XPath.first(doc, xpath)
    failure_message = "\nHow to handle the apos inside the string inside the XPath?\n"
    assert_equal desired_result.to_s, result.to_s, failure_message
  end
  
  def test_xpath_03_TobiasReif
    doc = Document.new XML_STRING_02.dup
    desired_result_string =
"<entry type='Book'>
    <language>english</language>
    <publisher>Addison-Wesley</publisher>
    <title>Programming Ruby. The Pragmatic Programmer&apos;s Guide</title>
    <type>Book</type>
    <year>2000</year>
  </entry>"
    desired_result_tree = Document.new desired_result_string
    xpath = "/biblio/entry[not(author)]"
    result = XPath.first(doc, xpath)
    assert_equal desired_result_string, result.to_s
  end

  def test_umlaut
		koln_iso = 'Köln'
		koln_utf = 'KÃ¶ln'
    source_iso = "<?xml version='1.0' encoding='ISO-8859-1'?><test>#{koln_iso}</test>"
    source_utf = "<?xml version='1.0' encoding='UTF-8'?><test>#{koln_utf}</test>"
		doc = REXML::Document.new(source_iso)
		assert_equal 'ISO-8859-1', doc.xml_decl.encoding
		assert_equal koln_utf, doc.root.text
		out = '' ; doc.write out
		assert_equal source_iso, out 
		doc.xml_decl.encoding = 'UTF-8'
		out = '' ; doc.write out
		assert_equal source_utf, out
  end
end
