summaryrefslogtreecommitdiff
path: root/test/rexml/parse
diff options
context:
space:
mode:
Diffstat (limited to 'test/rexml/parse')
-rw-r--r--test/rexml/parse/test_document_type_declaration.rb193
-rw-r--r--test/rexml/parse/test_element.rb26
-rw-r--r--test/rexml/parse/test_notation_declaration.rb181
-rw-r--r--test/rexml/parse/test_processing_instruction.rb19
4 files changed, 412 insertions, 7 deletions
diff --git a/test/rexml/parse/test_document_type_declaration.rb b/test/rexml/parse/test_document_type_declaration.rb
index 80f70888fb..55713909e7 100644
--- a/test/rexml/parse/test_document_type_declaration.rb
+++ b/test/rexml/parse/test_document_type_declaration.rb
@@ -5,17 +5,187 @@ require "rexml/document"
module REXMLTests
class TestParseDocumentTypeDeclaration < Test::Unit::TestCase
private
- def xml(internal_subset)
- <<-XML
-<!DOCTYPE r SYSTEM "urn:x-rexml:test" [
-#{internal_subset}
-]>
+ def parse(doctype)
+ REXML::Document.new(<<-XML).doctype
+#{doctype}
<r/>
XML
end
- def parse(internal_subset)
- REXML::Document.new(xml(internal_subset)).doctype
+ class TestName < self
+ def test_valid
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r>
+ DOCTYPE
+ assert_equal("r", doctype.name)
+ end
+
+ def test_garbage_plus_before_name_at_line_start
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE +
+r SYSTEM "urn:x-rexml:test" [
+]>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: invalid name
+Line: 5
+Position: 51
+Last 80 unconsumed characters:
++ r SYSTEM "urn:x-rexml:test" [ ]> <r/>
+ DETAIL
+ end
+ end
+
+ class TestExternalID < self
+ class TestSystem < self
+ def test_left_bracket_in_system_literal
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "urn:x-rexml:[test" [
+]>
+ DOCTYPE
+ assert_equal([
+ "r",
+ "SYSTEM",
+ nil,
+ "urn:x-rexml:[test",
+ ],
+ [
+ doctype.name,
+ doctype.external_id,
+ doctype.public,
+ doctype.system,
+ ])
+ end
+
+ def test_greater_than_in_system_literal
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "urn:x-rexml:>test" [
+]>
+ DOCTYPE
+ assert_equal([
+ "r",
+ "SYSTEM",
+ nil,
+ "urn:x-rexml:>test",
+ ],
+ [
+ doctype.name,
+ doctype.external_id,
+ doctype.public,
+ doctype.system,
+ ])
+ end
+
+ def test_no_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: system literal is missing
+Line: 3
+Position: 26
+Last 80 unconsumed characters:
+ SYSTEM> <r/>
+ DETAIL
+ end
+
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM 'r.dtd'x'>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: garbage after external ID
+Line: 3
+Position: 36
+Last 80 unconsumed characters:
+x'> <r/>
+ DETAIL
+ end
+
+ def test_single_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM 'r".dtd'>
+ DOCTYPE
+ assert_equal("r\".dtd", doctype.system)
+ end
+
+ def test_double_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "r'.dtd">
+ DOCTYPE
+ assert_equal("r'.dtd", doctype.system)
+ end
+ end
+
+ class TestPublic < self
+ class TestPublicIDLiteral < self
+ def test_content_double_quote
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC 'double quote " is invalid' "r.dtd">
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: invalid public ID literal
+Line: 3
+Position: 62
+Last 80 unconsumed characters:
+ PUBLIC 'double quote " is invalid' "r.dtd"> <r/>
+ DETAIL
+ end
+
+ def test_single_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC 'public-id-literal' "r.dtd">
+ DOCTYPE
+ assert_equal("public-id-literal", doctype.public)
+ end
+
+ def test_double_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC "public'-id-literal" "r.dtd">
+ DOCTYPE
+ assert_equal("public'-id-literal", doctype.public)
+ end
+ end
+
+ class TestSystemLiteral < self
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC 'public-id-literal' 'system-literal'x'>
+ DOCTYPE
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed DOCTYPE: garbage after external ID
+Line: 3
+Position: 65
+Last 80 unconsumed characters:
+x'> <r/>
+ DETAIL
+ end
+
+ def test_single_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC "public-id-literal" 'system"-literal'>
+ DOCTYPE
+ assert_equal("system\"-literal", doctype.system)
+ end
+
+ def test_double_quote
+ doctype = parse(<<-DOCTYPE)
+<!DOCTYPE r PUBLIC "public-id-literal" "system'-literal">
+ DOCTYPE
+ assert_equal("system'-literal", doctype.system)
+ end
+ end
+ end
end
class TestMixed < self
@@ -45,6 +215,15 @@ module REXMLTests
assert_equal([REXML::NotationDecl, REXML::AttlistDecl],
doctype.children.collect(&:class))
end
+
+ private
+ def parse(internal_subset)
+ super(<<-DOCTYPE)
+<!DOCTYPE r SYSTEM "urn:x-rexml:test" [
+#{internal_subset}
+]>
+ DOCTYPE
+ end
end
end
end
diff --git a/test/rexml/parse/test_element.rb b/test/rexml/parse/test_element.rb
index aad915fe7b..7206fe595a 100644
--- a/test/rexml/parse/test_element.rb
+++ b/test/rexml/parse/test_element.rb
@@ -33,6 +33,32 @@ Last 80 unconsumed characters:
DETAIL
end
+
+ def test_garbage_less_than_before_root_element_at_line_start
+ exception = assert_raise(REXML::ParseException) do
+ parse("<\n<x/>")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+malformed XML: missing tag start
+Line: 2
+Position: 6
+Last 80 unconsumed characters:
+< <x/>
+ DETAIL
+ end
+
+ def test_garbage_less_than_slash_before_end_tag_at_line_start
+ exception = assert_raise(REXML::ParseException) do
+ parse("<x></\n</x>")
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Missing end tag for 'x'
+Line: 2
+Position: 10
+Last 80 unconsumed characters:
+</ </x>
+ DETAIL
+ end
end
end
end
diff --git a/test/rexml/parse/test_notation_declaration.rb b/test/rexml/parse/test_notation_declaration.rb
index 0d29f0d81f..19a0536d0a 100644
--- a/test/rexml/parse/test_notation_declaration.rb
+++ b/test/rexml/parse/test_notation_declaration.rb
@@ -23,10 +23,100 @@ module REXMLTests
doctype = parse("<!NOTATION name PUBLIC 'urn:public-id'>")
assert_equal("name", doctype.notation("name").name)
end
+
+ def test_no_name
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: name is missing
+Line: 5
+Position: 72
+Last 80 unconsumed characters:
+ <!NOTATION> ]> <r/>
+ DETAIL
+ end
+
+ def test_invalid_name
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION '>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid name
+Line: 5
+Position: 74
+Last 80 unconsumed characters:
+'> ]> <r/>
+ DETAIL
+ end
+
+ def test_no_id_type
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid ID type
+Line: 5
+Position: 77
+Last 80 unconsumed characters:
+> ]> <r/>
+ DETAIL
+ end
+
+ def test_invalid_id_type
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name INVALID>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid ID type
+Line: 5
+Position: 85
+Last 80 unconsumed characters:
+ INVALID> ]> <r/>
+ DETAIL
+ end
end
class TestExternalID < self
class TestSystem < self
+ def test_no_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name SYSTEM>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: system literal is missing
+Line: 5
+Position: 84
+Last 80 unconsumed characters:
+ SYSTEM> ]> <r/>
+ DETAIL
+ end
+
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name SYSTEM 'system-literal'x'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: garbage before end >
+Line: 5
+Position: 103
+Last 80 unconsumed characters:
+x'> ]> <r/>
+ DETAIL
+ end
+
def test_single_quote
doctype = parse(<<-INTERNAL_SUBSET)
<!NOTATION name SYSTEM 'system-literal'>
@@ -44,6 +134,21 @@ module REXMLTests
class TestPublic < self
class TestPublicIDLiteral < self
+ def test_content_double_quote
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'double quote " is invalid' "system-literal">
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid public ID literal
+Line: 5
+Position: 129
+Last 80 unconsumed characters:
+ PUBLIC 'double quote " is invalid' "system-literal"> ]> <r/>
+ DETAIL
+ end
+
def test_single_quote
doctype = parse(<<-INTERNAL_SUBSET)
<!NOTATION name PUBLIC 'public-id-literal' "system-literal">
@@ -60,6 +165,21 @@ module REXMLTests
end
class TestSystemLiteral < self
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'public-id-literal' 'system-literal'x'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: garbage before end >
+Line: 5
+Position: 123
+Last 80 unconsumed characters:
+x'> ]> <r/>
+ DETAIL
+ end
+
def test_single_quote
doctype = parse(<<-INTERNAL_SUBSET)
<!NOTATION name PUBLIC "public-id-literal" 'system-literal'>
@@ -96,5 +216,66 @@ module REXMLTests
end
end
end
+
+ class TestPublicID < self
+ def test_no_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: public ID literal is missing
+Line: 5
+Position: 84
+Last 80 unconsumed characters:
+ PUBLIC> ]> <r/>
+ DETAIL
+ end
+
+ def test_literal_content_double_quote
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'double quote " is invalid in PubidLiteral'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: invalid public ID literal
+Line: 5
+Position: 128
+Last 80 unconsumed characters:
+ PUBLIC 'double quote \" is invalid in PubidLiteral'> ]> <r/>
+ DETAIL
+ end
+
+ def test_garbage_after_literal
+ exception = assert_raise(REXML::ParseException) do
+ parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'public-id-literal'x'>
+ INTERNAL_SUBSET
+ end
+ assert_equal(<<-DETAIL.chomp, exception.to_s)
+Malformed notation declaration: garbage before end >
+Line: 5
+Position: 106
+Last 80 unconsumed characters:
+x'> ]> <r/>
+ DETAIL
+ end
+
+ def test_literal_single_quote
+ doctype = parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC 'public-id-literal'>
+ INTERNAL_SUBSET
+ assert_equal("public-id-literal", doctype.notation("name").public)
+ end
+
+ def test_literal_double_quote
+ doctype = parse(<<-INTERNAL_SUBSET)
+<!NOTATION name PUBLIC "public-id-literal">
+ INTERNAL_SUBSET
+ assert_equal("public-id-literal", doctype.notation("name").public)
+ end
+ end
end
end
diff --git a/test/rexml/parse/test_processing_instruction.rb b/test/rexml/parse/test_processing_instruction.rb
index a23513fc6e..f0c0c24e67 100644
--- a/test/rexml/parse/test_processing_instruction.rb
+++ b/test/rexml/parse/test_processing_instruction.rb
@@ -20,6 +20,25 @@ Last 80 unconsumed characters:
<??>
DETAIL
end
+
+ def test_garbage_text
+ # TODO: This should be parse error.
+ # Create test/parse/test_document.rb or something and move this to it.
+ doc = parse(<<-XML)
+x<?x y
+<!--?><?x -->?>
+<r/>
+ XML
+ pi = doc.children[1]
+ assert_equal([
+ "x",
+ "y\n<!--",
+ ],
+ [
+ pi.target,
+ pi.content,
+ ])
+ end
end
end
end