require "test/unit/testcase"

require "rexml/document"
require "rexml/validation/relaxng"

class RNGValidation < Test::Unit::TestCase
  include REXML

  def test_validate
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <element name="B">
    <element name="C">
      <attribute name="X"/>
      <zeroOrMore>
        <element name="E">
          <empty/>
        </element>
      </zeroOrMore>
    </element>
    <element name="D">
      <empty/>
    </element>
  </element>
</element>
    }
    validator = REXML::Validation::RelaxNG.new( rng )
    source = %q{<A><B><C X="x"><E/><E/></C><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    assert_nothing_raised { parser.parse }
    
    source = %q{<A><B><D/><C X="x"/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }
  end


  def test_sequence
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <element name="B">
    <element name="C">
      <empty/>
    </element>
    <element name="D">
      <empty/>
    </element>
  </element>
</element>
    }
    source = %q{<A><B><C/><C/><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A><B><D/><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A><C/><D/></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A><B><C/><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_nothing_raised { parser.parse }
  end


  def test_choice
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <element name="B">
    <choice>
      <element name="C">
        <empty/>
      </element>
      <element name="D">
        <empty/>
      </element>
    </choice>
  </element>
</element>
    }
    source = %q{<A><B><C/><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A><B><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( REXML::Validation::RelaxNG.new( rng ) )
    assert_nothing_raised { parser.parse }
  end

  def test_optional
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <element name="B">
    <optional>
      <element name="C">
        <empty/>
      </element>
    </optional>
  </element>
</element>
    }
    validator = REXML::Validation::RelaxNG.new( rng )
    source = %q{<A><B/></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A><B><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    validator.reset
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    validator.reset
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }
  end

  def test_zero_or_more
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <element name="B">
    <zeroOrMore>
      <element name="C">
        <empty/>
      </element>
    </zeroOrMore>
  </element>
</element>
    }
    validator = REXML::Validation::RelaxNG.new( rng )
    source = %q{<A><B/></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><C/><C/><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }
  end

  def test_one_or_more
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <element name="B">
    <oneOrMore>
      <element name="C">
        <empty/>
      </element>
    </oneOrMore>
  </element>
</element>
    }
    validator = REXML::Validation::RelaxNG.new( rng )
    source = %q{<A><B/></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A><B><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><C/><C/><C/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_nothing_raised { parser.parse }

    source = %q{<A><B><D/></B></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }
  end

  def test_attribute
    rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
  <attribute name="X"/>
  <attribute name="Y"/>
</element>
    }
    validator = REXML::Validation::RelaxNG.new( rng )
    source = %q{<A><B/></A>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A/>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A X=""/>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_raises( REXML::Validation::ValidationException, 
                  "Expected a validation error" ) { parser.parse }

    source = %q{<A X="1" Y="1"/>}
    parser = REXML::Parsers::TreeParser.new( source )
    parser.add_listener( validator.reset )
    assert_nothing_raised { parser.parse }
  end

  def test_empty
    flunk( "NOT IMPLEMENTED" )
  end
end
