nokogiri 1.6.2.rc1-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.autotest +26 -0
- data/.editorconfig +17 -0
- data/.gemtest +0 -0
- data/.travis.yml +25 -0
- data/CHANGELOG.ja.rdoc +857 -0
- data/CHANGELOG.rdoc +880 -0
- data/C_CODING_STYLE.rdoc +33 -0
- data/Gemfile +21 -0
- data/Manifest.txt +371 -0
- data/README.ja.rdoc +112 -0
- data/README.rdoc +180 -0
- data/ROADMAP.md +89 -0
- data/Rakefile +351 -0
- data/STANDARD_RESPONSES.md +47 -0
- data/Y_U_NO_GEMSPEC.md +155 -0
- data/bin/nokogiri +78 -0
- data/build_all +130 -0
- data/dependencies.yml +4 -0
- data/ext/nokogiri/depend +358 -0
- data/ext/nokogiri/extconf.rb +453 -0
- data/ext/nokogiri/html_document.c +170 -0
- data/ext/nokogiri/html_document.h +10 -0
- data/ext/nokogiri/html_element_description.c +279 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +32 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser_context.c +116 -0
- data/ext/nokogiri/html_sax_parser_context.h +11 -0
- data/ext/nokogiri/html_sax_push_parser.c +87 -0
- data/ext/nokogiri/html_sax_push_parser.h +9 -0
- data/ext/nokogiri/nokogiri.c +148 -0
- data/ext/nokogiri/nokogiri.h +164 -0
- data/ext/nokogiri/xml_attr.c +94 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_attribute_decl.c +70 -0
- data/ext/nokogiri/xml_attribute_decl.h +9 -0
- data/ext/nokogiri/xml_cdata.c +56 -0
- data/ext/nokogiri/xml_cdata.h +9 -0
- data/ext/nokogiri/xml_comment.c +54 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +577 -0
- data/ext/nokogiri/xml_document.h +23 -0
- data/ext/nokogiri/xml_document_fragment.c +48 -0
- data/ext/nokogiri/xml_document_fragment.h +10 -0
- data/ext/nokogiri/xml_dtd.c +202 -0
- data/ext/nokogiri/xml_dtd.h +10 -0
- data/ext/nokogiri/xml_element_content.c +123 -0
- data/ext/nokogiri/xml_element_content.h +10 -0
- data/ext/nokogiri/xml_element_decl.c +69 -0
- data/ext/nokogiri/xml_element_decl.h +9 -0
- data/ext/nokogiri/xml_encoding_handler.c +79 -0
- data/ext/nokogiri/xml_encoding_handler.h +8 -0
- data/ext/nokogiri/xml_entity_decl.c +110 -0
- data/ext/nokogiri/xml_entity_decl.h +10 -0
- data/ext/nokogiri/xml_entity_reference.c +52 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +56 -0
- data/ext/nokogiri/xml_io.h +11 -0
- data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
- data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
- data/ext/nokogiri/xml_namespace.c +78 -0
- data/ext/nokogiri/xml_namespace.h +13 -0
- data/ext/nokogiri/xml_node.c +1541 -0
- data/ext/nokogiri/xml_node.h +13 -0
- data/ext/nokogiri/xml_node_set.c +467 -0
- data/ext/nokogiri/xml_node_set.h +14 -0
- data/ext/nokogiri/xml_processing_instruction.c +56 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +681 -0
- data/ext/nokogiri/xml_reader.h +10 -0
- data/ext/nokogiri/xml_relax_ng.c +161 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +312 -0
- data/ext/nokogiri/xml_sax_parser.h +39 -0
- data/ext/nokogiri/xml_sax_parser_context.c +262 -0
- data/ext/nokogiri/xml_sax_parser_context.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +115 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +205 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +63 -0
- data/ext/nokogiri/xml_syntax_error.h +13 -0
- data/ext/nokogiri/xml_text.c +52 -0
- data/ext/nokogiri/xml_text.h +9 -0
- data/ext/nokogiri/xml_xpath_context.c +307 -0
- data/ext/nokogiri/xml_xpath_context.h +10 -0
- data/ext/nokogiri/xslt_stylesheet.c +270 -0
- data/ext/nokogiri/xslt_stylesheet.h +14 -0
- data/lib/nokogiri.rb +137 -0
- data/lib/nokogiri/2.0/nokogiri.so +0 -0
- data/lib/nokogiri/2.1/nokogiri.so +0 -0
- data/lib/nokogiri/css.rb +27 -0
- data/lib/nokogiri/css/node.rb +52 -0
- data/lib/nokogiri/css/parser.rb +715 -0
- data/lib/nokogiri/css/parser.y +249 -0
- data/lib/nokogiri/css/parser_extras.rb +91 -0
- data/lib/nokogiri/css/syntax_error.rb +7 -0
- data/lib/nokogiri/css/tokenizer.rb +152 -0
- data/lib/nokogiri/css/tokenizer.rex +55 -0
- data/lib/nokogiri/css/xpath_visitor.rb +219 -0
- data/lib/nokogiri/decorators/slop.rb +35 -0
- data/lib/nokogiri/html.rb +37 -0
- data/lib/nokogiri/html/builder.rb +35 -0
- data/lib/nokogiri/html/document.rb +333 -0
- data/lib/nokogiri/html/document_fragment.rb +41 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/element_description_defaults.rb +671 -0
- data/lib/nokogiri/html/entity_lookup.rb +13 -0
- data/lib/nokogiri/html/sax/parser.rb +52 -0
- data/lib/nokogiri/html/sax/parser_context.rb +16 -0
- data/lib/nokogiri/html/sax/push_parser.rb +16 -0
- data/lib/nokogiri/syntax_error.rb +4 -0
- data/lib/nokogiri/version.rb +106 -0
- data/lib/nokogiri/xml.rb +73 -0
- data/lib/nokogiri/xml/attr.rb +14 -0
- data/lib/nokogiri/xml/attribute_decl.rb +18 -0
- data/lib/nokogiri/xml/builder.rb +443 -0
- data/lib/nokogiri/xml/cdata.rb +11 -0
- data/lib/nokogiri/xml/character_data.rb +7 -0
- data/lib/nokogiri/xml/document.rb +279 -0
- data/lib/nokogiri/xml/document_fragment.rb +112 -0
- data/lib/nokogiri/xml/dtd.rb +32 -0
- data/lib/nokogiri/xml/element_content.rb +36 -0
- data/lib/nokogiri/xml/element_decl.rb +13 -0
- data/lib/nokogiri/xml/entity_decl.rb +19 -0
- data/lib/nokogiri/xml/namespace.rb +13 -0
- data/lib/nokogiri/xml/node.rb +982 -0
- data/lib/nokogiri/xml/node/save_options.rb +61 -0
- data/lib/nokogiri/xml/node_set.rb +355 -0
- data/lib/nokogiri/xml/notation.rb +6 -0
- data/lib/nokogiri/xml/parse_options.rb +98 -0
- data/lib/nokogiri/xml/pp.rb +2 -0
- data/lib/nokogiri/xml/pp/character_data.rb +18 -0
- data/lib/nokogiri/xml/pp/node.rb +56 -0
- data/lib/nokogiri/xml/processing_instruction.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +112 -0
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax.rb +4 -0
- data/lib/nokogiri/xml/sax/document.rb +171 -0
- data/lib/nokogiri/xml/sax/parser.rb +123 -0
- data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
- data/lib/nokogiri/xml/schema.rb +63 -0
- data/lib/nokogiri/xml/syntax_error.rb +47 -0
- data/lib/nokogiri/xml/text.rb +9 -0
- data/lib/nokogiri/xml/xpath.rb +10 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
- data/lib/nokogiri/xml/xpath_context.rb +16 -0
- data/lib/nokogiri/xslt.rb +56 -0
- data/lib/nokogiri/xslt/stylesheet.rb +25 -0
- data/lib/xsd/xmlparser/nokogiri.rb +102 -0
- data/suppressions/README.txt +1 -0
- data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
- data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
- data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
- data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
- data/tasks/nokogiri.org.rb +24 -0
- data/tasks/test.rb +95 -0
- data/test/css/test_nthiness.rb +222 -0
- data/test/css/test_parser.rb +358 -0
- data/test/css/test_tokenizer.rb +198 -0
- data/test/css/test_xpath_visitor.rb +96 -0
- data/test/decorators/test_slop.rb +16 -0
- data/test/files/2ch.html +108 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/atom.xml +344 -0
- data/test/files/bar/bar.xsd +4 -0
- data/test/files/bogus.xml +0 -0
- data/test/files/dont_hurt_em_why.xml +422 -0
- data/test/files/encoding.html +82 -0
- data/test/files/encoding.xhtml +84 -0
- data/test/files/exslt.xml +8 -0
- data/test/files/exslt.xslt +35 -0
- data/test/files/foo/foo.xsd +4 -0
- data/test/files/metacharset.html +10 -0
- data/test/files/noencoding.html +47 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/files/saml/saml20assertion_schema.xsd +283 -0
- data/test/files/saml/saml20protocol_schema.xsd +302 -0
- data/test/files/saml/xenc_schema.xsd +146 -0
- data/test/files/saml/xmldsig_schema.xsd +318 -0
- data/test/files/shift_jis.html +10 -0
- data/test/files/shift_jis.xml +5 -0
- data/test/files/shift_jis_no_charset.html +9 -0
- data/test/files/snuggles.xml +3 -0
- data/test/files/staff.dtd +10 -0
- data/test/files/staff.xml +59 -0
- data/test/files/staff.xslt +32 -0
- data/test/files/test_document_url/bar.xml +2 -0
- data/test/files/test_document_url/document.dtd +4 -0
- data/test/files/test_document_url/document.xml +6 -0
- data/test/files/tlm.html +850 -0
- data/test/files/to_be_xincluded.xml +2 -0
- data/test/files/valid_bar.xml +2 -0
- data/test/files/xinclude.xml +4 -0
- data/test/helper.rb +164 -0
- data/test/html/sax/test_parser.rb +141 -0
- data/test/html/sax/test_parser_context.rb +46 -0
- data/test/html/test_builder.rb +164 -0
- data/test/html/test_document.rb +619 -0
- data/test/html/test_document_encoding.rb +148 -0
- data/test/html/test_document_fragment.rb +261 -0
- data/test/html/test_element_description.rb +105 -0
- data/test/html/test_named_characters.rb +14 -0
- data/test/html/test_node.rb +196 -0
- data/test/html/test_node_encoding.rb +27 -0
- data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +14 -0
- data/test/namespaces/test_namespaces_in_builder_doc.rb +75 -0
- data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
- data/test/namespaces/test_namespaces_in_created_doc.rb +75 -0
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +66 -0
- data/test/test_convert_xpath.rb +135 -0
- data/test/test_css_cache.rb +45 -0
- data/test/test_encoding_handler.rb +46 -0
- data/test/test_memory_leak.rb +156 -0
- data/test/test_nokogiri.rb +138 -0
- data/test/test_reader.rb +558 -0
- data/test/test_soap4r_sax.rb +52 -0
- data/test/test_xslt_transforms.rb +279 -0
- data/test/xml/node/test_save_options.rb +28 -0
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +382 -0
- data/test/xml/sax/test_parser_context.rb +115 -0
- data/test/xml/sax/test_push_parser.rb +157 -0
- data/test/xml/test_attr.rb +64 -0
- data/test/xml/test_attribute_decl.rb +86 -0
- data/test/xml/test_builder.rb +315 -0
- data/test/xml/test_c14n.rb +161 -0
- data/test/xml/test_cdata.rb +48 -0
- data/test/xml/test_comment.rb +29 -0
- data/test/xml/test_document.rb +934 -0
- data/test/xml/test_document_encoding.rb +28 -0
- data/test/xml/test_document_fragment.rb +228 -0
- data/test/xml/test_dtd.rb +187 -0
- data/test/xml/test_dtd_encoding.rb +33 -0
- data/test/xml/test_element_content.rb +56 -0
- data/test/xml/test_element_decl.rb +73 -0
- data/test/xml/test_entity_decl.rb +122 -0
- data/test/xml/test_entity_reference.rb +245 -0
- data/test/xml/test_namespace.rb +95 -0
- data/test/xml/test_node.rb +1155 -0
- data/test/xml/test_node_attributes.rb +113 -0
- data/test/xml/test_node_encoding.rb +107 -0
- data/test/xml/test_node_inheritance.rb +32 -0
- data/test/xml/test_node_reparenting.rb +374 -0
- data/test/xml/test_node_set.rb +755 -0
- data/test/xml/test_parse_options.rb +64 -0
- data/test/xml/test_processing_instruction.rb +30 -0
- data/test/xml/test_reader_encoding.rb +142 -0
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +129 -0
- data/test/xml/test_syntax_error.rb +12 -0
- data/test/xml/test_text.rb +45 -0
- data/test/xml/test_unparented_node.rb +422 -0
- data/test/xml/test_xinclude.rb +83 -0
- data/test/xml/test_xpath.rb +376 -0
- data/test/xslt/test_custom_functions.rb +133 -0
- data/test/xslt/test_exception_handling.rb +37 -0
- data/test_all +81 -0
- metadata +601 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
class TestNodeAttributes < Nokogiri::TestCase
|
6
|
+
def test_attribute_with_ns
|
7
|
+
doc = Nokogiri::XML <<-eoxml
|
8
|
+
<root xmlns:tlm='http://tenderlovemaking.com/'>
|
9
|
+
<node tlm:foo='bar' foo='baz' />
|
10
|
+
</root>
|
11
|
+
eoxml
|
12
|
+
|
13
|
+
node = doc.at('node')
|
14
|
+
|
15
|
+
assert_equal 'bar',
|
16
|
+
node.attribute_with_ns('foo', 'http://tenderlovemaking.com/').value
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_prefixed_attributes
|
20
|
+
doc = Nokogiri::XML "<root xml:lang='en-GB' />"
|
21
|
+
|
22
|
+
node = doc.root
|
23
|
+
|
24
|
+
assert_equal 'en-GB', node['xml:lang']
|
25
|
+
assert_equal 'en-GB', node.attributes['lang'].value
|
26
|
+
assert_equal nil, node['lang']
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_set_prefixed_attributes
|
30
|
+
doc = Nokogiri::XML %Q{<root xmlns:foo="x"/>}
|
31
|
+
|
32
|
+
node = doc.root
|
33
|
+
|
34
|
+
node['xml:lang'] = 'en-GB'
|
35
|
+
node['foo:bar'] = 'bazz'
|
36
|
+
|
37
|
+
assert_equal 'en-GB', node['xml:lang']
|
38
|
+
assert_equal 'en-GB', node.attributes['lang'].value
|
39
|
+
assert_equal nil, node['lang']
|
40
|
+
assert_equal 'http://www.w3.org/XML/1998/namespace', node.attributes['lang'].namespace.href
|
41
|
+
|
42
|
+
assert_equal 'bazz', node['foo:bar']
|
43
|
+
assert_equal 'bazz', node.attributes['bar'].value
|
44
|
+
assert_equal nil, node['bar']
|
45
|
+
assert_equal 'x', node.attributes['bar'].namespace.href
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_append_child_namespace_definitions_prefixed_attributes
|
49
|
+
doc = Nokogiri::XML "<root/>"
|
50
|
+
node = doc.root
|
51
|
+
|
52
|
+
node['xml:lang'] = 'en-GB'
|
53
|
+
|
54
|
+
assert_equal [], node.namespace_definitions.map(&:prefix)
|
55
|
+
|
56
|
+
child_node = Nokogiri::XML::Node.new 'foo', doc
|
57
|
+
node << child_node
|
58
|
+
|
59
|
+
assert_equal [], node.namespace_definitions.map(&:prefix)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_append_child_element_with_prefixed_attributes
|
63
|
+
doc = Nokogiri::XML "<root/>"
|
64
|
+
node = doc.root
|
65
|
+
|
66
|
+
assert_equal [], node.namespace_definitions.map(&:prefix)
|
67
|
+
|
68
|
+
|
69
|
+
# assert_nothing_raised do
|
70
|
+
child_node = Nokogiri::XML::Node.new 'foo', doc
|
71
|
+
child_node['xml:lang'] = 'en-GB'
|
72
|
+
|
73
|
+
node << child_node
|
74
|
+
# end
|
75
|
+
|
76
|
+
assert_equal [], child_node.namespace_definitions.map(&:prefix)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_namespace_key?
|
80
|
+
doc = Nokogiri::XML <<-eoxml
|
81
|
+
<root xmlns:tlm='http://tenderlovemaking.com/'>
|
82
|
+
<node tlm:foo='bar' foo='baz' />
|
83
|
+
</root>
|
84
|
+
eoxml
|
85
|
+
|
86
|
+
node = doc.at('node')
|
87
|
+
|
88
|
+
assert node.namespaced_key?('foo', 'http://tenderlovemaking.com/')
|
89
|
+
assert node.namespaced_key?('foo', nil)
|
90
|
+
assert !node.namespaced_key?('foo', 'foo')
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_set_attribute_frees_nodes # testing a segv
|
94
|
+
skip("JRuby doesn't do GC.") if Nokogiri.jruby?
|
95
|
+
document = Nokogiri::XML.parse("<foo></foo>")
|
96
|
+
|
97
|
+
node = document.root
|
98
|
+
node['visible'] = 'foo'
|
99
|
+
attribute = node.attribute('visible')
|
100
|
+
text = Nokogiri::XML::Text.new 'bar', document
|
101
|
+
attribute.add_child(text)
|
102
|
+
|
103
|
+
begin
|
104
|
+
gc_previous = GC.stress
|
105
|
+
GC.stress = true
|
106
|
+
node['visible'] = 'attr'
|
107
|
+
ensure
|
108
|
+
GC.stress = gc_previous
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
if RUBY_VERSION =~ /^1\.9/
|
6
|
+
class TestNodeEncoding < Nokogiri::TestCase
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
@html = Nokogiri::HTML(File.read(HTML_FILE), HTML_FILE)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_get_attribute
|
13
|
+
node = @html.css('a').first
|
14
|
+
assert_equal @html.encoding, node['href'].encoding.name
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_text_encoding_is_utf_8
|
18
|
+
@html = Nokogiri::HTML(File.open(NICH_FILE))
|
19
|
+
assert_equal 'UTF-8', @html.text.encoding.name
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_serialize_encoding_html
|
23
|
+
@html = Nokogiri::HTML(File.open(NICH_FILE))
|
24
|
+
assert_equal @html.encoding.downcase,
|
25
|
+
@html.serialize.encoding.name.downcase
|
26
|
+
|
27
|
+
@doc = Nokogiri::HTML(@html.serialize)
|
28
|
+
assert_equal @html.serialize, @doc.serialize
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_serialize_encoding_xml
|
32
|
+
@xml = Nokogiri::XML(File.open(SHIFT_JIS_XML))
|
33
|
+
assert_equal @xml.encoding.downcase,
|
34
|
+
@xml.serialize.encoding.name.downcase
|
35
|
+
|
36
|
+
@doc = Nokogiri::XML(@xml.serialize)
|
37
|
+
assert_equal @xml.serialize, @doc.serialize
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_encode_special_chars
|
41
|
+
foo = @html.css('a').first.encode_special_chars('foo')
|
42
|
+
assert_equal @html.encoding, foo.encoding.name
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_content
|
46
|
+
node = @html.css('a').first
|
47
|
+
assert_equal @html.encoding, node.content.encoding.name
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_name
|
51
|
+
node = @html.css('a').first
|
52
|
+
assert_equal @html.encoding, node.name.encoding.name
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_path
|
56
|
+
node = @html.css('a').first
|
57
|
+
assert_equal @html.encoding, node.path.encoding.name
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_namespace
|
61
|
+
xml = <<-eoxml
|
62
|
+
<root>
|
63
|
+
<car xmlns:part="http://general-motors.com/">
|
64
|
+
<part:tire>Michelin Model XGV</part:tire>
|
65
|
+
</car>
|
66
|
+
<bicycle xmlns:part="http://schwinn.com/">
|
67
|
+
<part:tire>I'm a bicycle tire!</part:tire>
|
68
|
+
</bicycle>
|
69
|
+
</root>
|
70
|
+
eoxml
|
71
|
+
doc = Nokogiri::XML(xml, nil, 'UTF-8')
|
72
|
+
assert_equal 'UTF-8', doc.encoding
|
73
|
+
n = doc.xpath('//part:tire', { 'part' => 'http://schwinn.com/' }).first
|
74
|
+
assert n
|
75
|
+
assert_equal doc.encoding, n.namespace.href.encoding.name
|
76
|
+
assert_equal doc.encoding, n.namespace.prefix.encoding.name
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_namespace_as_hash
|
80
|
+
xml = <<-eoxml
|
81
|
+
<root>
|
82
|
+
<car xmlns:part="http://general-motors.com/">
|
83
|
+
<part:tire>Michelin Model XGV</part:tire>
|
84
|
+
</car>
|
85
|
+
<bicycle xmlns:part="http://schwinn.com/">
|
86
|
+
<part:tire>I'm a bicycle tire!</part:tire>
|
87
|
+
</bicycle>
|
88
|
+
</root>
|
89
|
+
eoxml
|
90
|
+
doc = Nokogiri::XML(xml, nil, 'UTF-8')
|
91
|
+
assert_equal 'UTF-8', doc.encoding
|
92
|
+
assert n = doc.xpath('//car').first
|
93
|
+
|
94
|
+
n.namespace_definitions.each do |nd|
|
95
|
+
assert_equal doc.encoding, nd.href.encoding.name
|
96
|
+
assert_equal doc.encoding, nd.prefix.encoding.name
|
97
|
+
end
|
98
|
+
|
99
|
+
n.namespaces.each do |k,v|
|
100
|
+
assert_equal doc.encoding, k.encoding.name
|
101
|
+
assert_equal doc.encoding, v.encoding.name
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# issue#560
|
2
|
+
|
3
|
+
require 'helper'
|
4
|
+
|
5
|
+
module Nokogiri
|
6
|
+
module XML
|
7
|
+
class TestNodeInheritance < Nokogiri::TestCase
|
8
|
+
MyNode = Class.new Nokogiri::XML::Node
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
@node = MyNode.new 'foo', Nokogiri::XML::Document.new
|
12
|
+
@node['foo'] = 'bar'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_node_name
|
16
|
+
assert @node.name == 'foo'
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_node_writing_an_attribute_accessing_via_attributes
|
20
|
+
assert @node.attributes['foo']
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_node_writing_an_attribute_accessing_via_key
|
24
|
+
assert @node.key? 'foo'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_node_writing_an_attribute_accessing_via_brackets
|
28
|
+
assert @node['foo'] == 'bar'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
class TestNodeReparenting < Nokogiri::TestCase
|
6
|
+
|
7
|
+
describe "standard node reparenting behavior" do
|
8
|
+
# describe "namespace handling during reparenting" do
|
9
|
+
# describe "given a Node" do
|
10
|
+
# describe "with a Namespace" do
|
11
|
+
# it "keeps the Namespace"
|
12
|
+
# end
|
13
|
+
# describe "given a parent Node with a default and a non-default Namespace" do
|
14
|
+
# describe "passed an Node without a namespace" do
|
15
|
+
# it "inserts an Node that inherits the default Namespace"
|
16
|
+
# end
|
17
|
+
# describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
|
18
|
+
# it "inserts a Node that inherits the matching parent Namespace"
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# describe "given a markup string" do
|
23
|
+
# describe "parsed relative to the document" do
|
24
|
+
# describe "with a Namespace" do
|
25
|
+
# it "keeps the Namespace"
|
26
|
+
# end
|
27
|
+
# describe "given a parent Node with a default and a non-default Namespace" do
|
28
|
+
# describe "passed an Node without a namespace" do
|
29
|
+
# it "inserts an Node that inherits the default Namespace"
|
30
|
+
# end
|
31
|
+
# describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
|
32
|
+
# it "inserts a Node that inherits the matching parent Namespace"
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
# describe "parsed relative to a specific node" do
|
37
|
+
# describe "with a Namespace" do
|
38
|
+
# it "keeps the Namespace"
|
39
|
+
# end
|
40
|
+
# describe "given a parent Node with a default and a non-default Namespace" do
|
41
|
+
# describe "passed an Node without a namespace" do
|
42
|
+
# it "inserts an Node that inherits the default Namespace"
|
43
|
+
# end
|
44
|
+
# describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
|
45
|
+
# it "inserts a Node that inherits the matching parent Namespace"
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
|
52
|
+
{
|
53
|
+
:add_child => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
|
54
|
+
:<< => {:target => "/root/a1", :returns_self => true, :children_tags => %w[text b1 b2]},
|
55
|
+
|
56
|
+
:replace => {:target => "/root/a1/node()", :returns_self => false, :children_tags => %w[b1 b2]},
|
57
|
+
:swap => {:target => "/root/a1/node()", :returns_self => true, :children_tags => %w[b1 b2]},
|
58
|
+
|
59
|
+
:children= => {:target => "/root/a1", :returns_self => false, :children_tags => %w[b1 b2]},
|
60
|
+
:inner_html= => {:target => "/root/a1", :returns_self => true, :children_tags => %w[b1 b2]},
|
61
|
+
|
62
|
+
:add_previous_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
|
63
|
+
:previous= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
|
64
|
+
:before => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[b1 b2 text]},
|
65
|
+
|
66
|
+
:add_next_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
|
67
|
+
:next= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
|
68
|
+
:after => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[text b1 b2]}
|
69
|
+
}.each do |method, params|
|
70
|
+
|
71
|
+
before do
|
72
|
+
@doc = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third <bx />node</a3></root>"
|
73
|
+
@doc2 = @doc.dup
|
74
|
+
@fragment_string = "<b1>foo</b1><b2>bar</b2>"
|
75
|
+
@fragment = Nokogiri::XML::DocumentFragment.parse @fragment_string
|
76
|
+
@node_set = Nokogiri::XML("<root><b1>foo</b1><b2>bar</b2></root>").xpath("/root/node()")
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "##{method}" do
|
80
|
+
describe "passed a Node" do
|
81
|
+
[:current, :another].each do |which|
|
82
|
+
describe "passed a Node in the #{which} document" do
|
83
|
+
before do
|
84
|
+
@other_doc = which == :current ? @doc : @doc2
|
85
|
+
@other_node = @other_doc.at_xpath("/root/a2")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "unlinks the Node from its previous position" do
|
89
|
+
@doc.at_xpath(params[:target]).send(method, @other_node)
|
90
|
+
@other_doc.at_xpath("/root/a2").must_be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "inserts the Node in the proper position" do
|
94
|
+
@doc.at_xpath(params[:target]).send(method, @other_node)
|
95
|
+
@doc.at_xpath("/root/a1/a2").wont_be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns the expected value" do
|
99
|
+
sendee = @doc.at_xpath(params[:target])
|
100
|
+
result = sendee.send(method, @other_node)
|
101
|
+
if params[:returns_self]
|
102
|
+
result.must_equal sendee
|
103
|
+
else
|
104
|
+
result.must_equal @other_node
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
describe "passed a markup string" do
|
111
|
+
it "inserts the fragment roots in the proper position" do
|
112
|
+
@doc.at_xpath(params[:target]).send(method, @fragment_string)
|
113
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns the expected value" do
|
117
|
+
sendee = @doc.at_xpath(params[:target])
|
118
|
+
result = sendee.send(method, @fragment_string)
|
119
|
+
if params[:returns_self]
|
120
|
+
result.must_equal sendee
|
121
|
+
else
|
122
|
+
result.must_be_kind_of Nokogiri::XML::NodeSet
|
123
|
+
result.to_html.must_equal @fragment_string
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
describe "passed a fragment" do
|
128
|
+
it "inserts the fragment roots in the proper position" do
|
129
|
+
@doc.at_xpath(params[:target]).send(method, @fragment)
|
130
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
describe "passed a document" do
|
134
|
+
it "raises an exception" do
|
135
|
+
proc { @doc.at_xpath("/root/a1").send(method, @doc2) }.must_raise(ArgumentError)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
describe "passed a non-Node" do
|
139
|
+
it "raises an exception" do
|
140
|
+
proc { @doc.at_xpath("/root/a1").send(method, 42) }.must_raise(ArgumentError)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
describe "passed a NodeSet" do
|
144
|
+
it "inserts each member of the NodeSet in the proper order" do
|
145
|
+
@doc.at_xpath(params[:target]).send(method, @node_set)
|
146
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "text node merging" do
|
153
|
+
describe "#add_child" do
|
154
|
+
it "merges the Text node with adjacent Text nodes" do
|
155
|
+
@doc.at_xpath("/root/a1").add_child Nokogiri::XML::Text.new('hello', @doc)
|
156
|
+
@doc.at_xpath("/root/a1/text()").content.must_equal "First nodehello"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "#replace" do
|
161
|
+
it "merges the Text node with adjacent Text nodes" do
|
162
|
+
@doc.at_xpath("/root/a3/bx").replace Nokogiri::XML::Text.new('hello', @doc)
|
163
|
+
@doc.at_xpath("/root/a3/text()").content.must_equal "Third hellonode"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "ad hoc node reparenting behavior" do
|
170
|
+
describe "#<<" do
|
171
|
+
it "allows chaining" do
|
172
|
+
doc = Nokogiri::XML::Document.new
|
173
|
+
root = Nokogiri::XML::Element.new('root', doc)
|
174
|
+
doc.root = root
|
175
|
+
|
176
|
+
child1 = Nokogiri::XML::Element.new('child1', doc)
|
177
|
+
child2 = Nokogiri::XML::Element.new('child2', doc)
|
178
|
+
|
179
|
+
doc.root << child1 << child2
|
180
|
+
|
181
|
+
assert_equal [child1, child2], doc.root.children.to_a
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "#add_child" do
|
186
|
+
describe "given a new node with a namespace" do
|
187
|
+
it "keeps the namespace" do
|
188
|
+
doc = Nokogiri::XML::Document.new
|
189
|
+
item = Nokogiri::XML::Element.new('item', doc)
|
190
|
+
doc.root = item
|
191
|
+
|
192
|
+
entry = Nokogiri::XML::Element.new('entry', doc)
|
193
|
+
entry.add_namespace('tlm', 'http://tenderlovemaking.com')
|
194
|
+
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
195
|
+
item.add_child(entry)
|
196
|
+
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "given a parent node with a default namespace" do
|
201
|
+
before do
|
202
|
+
@doc = Nokogiri::XML(<<-eoxml)
|
203
|
+
<root xmlns="http://tenderlovemaking.com/">
|
204
|
+
<first>
|
205
|
+
</first>
|
206
|
+
</root>
|
207
|
+
eoxml
|
208
|
+
end
|
209
|
+
|
210
|
+
it "inserts a node that inherits the default namespace" do
|
211
|
+
assert node = @doc.at('//xmlns:first')
|
212
|
+
child = Nokogiri::XML::Node.new('second', @doc)
|
213
|
+
node.add_child(child)
|
214
|
+
assert @doc.at('//xmlns:second')
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "given a parent node with a non-default namespace" do
|
219
|
+
before do
|
220
|
+
@doc = Nokogiri::XML(<<-eoxml)
|
221
|
+
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="http://flavorjon.es/">
|
222
|
+
<first>
|
223
|
+
</first>
|
224
|
+
</root>
|
225
|
+
eoxml
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "and a child node with a namespace matching the parent's non-default namespace" do
|
229
|
+
it "inserts a node that inherits the matching parent namespace" do
|
230
|
+
assert node = @doc.at('//xmlns:first')
|
231
|
+
child = Nokogiri::XML::Node.new('second', @doc)
|
232
|
+
|
233
|
+
ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
|
234
|
+
child.namespace = ns
|
235
|
+
|
236
|
+
node.add_child(child)
|
237
|
+
assert @doc.at('//foo:second', "foo" => "http://flavorjon.es/")
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "#add_previous_sibling" do
|
244
|
+
it "should not merge text nodes during the operation" do
|
245
|
+
xml = Nokogiri::XML %Q(<root>text node</root>)
|
246
|
+
replacee = xml.root.children.first
|
247
|
+
replacee.add_previous_sibling "foo <p></p> bar"
|
248
|
+
assert_equal "foo <p></p> bartext node", xml.root.children.to_html
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should remove the child node after the operation' do
|
252
|
+
fragment = Nokogiri::HTML::DocumentFragment.parse("a<a>b</a>")
|
253
|
+
node = fragment.children.last
|
254
|
+
node.add_previous_sibling node.children
|
255
|
+
assert_empty node.children, "should have no childrens"
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "with a text node before" do
|
259
|
+
it "should not defensively dup the 'before' text node" do
|
260
|
+
xml = Nokogiri::XML %Q(<root>before<p></p>after</root>)
|
261
|
+
pivot = xml.at_css("p")
|
262
|
+
before = xml.root.children.first
|
263
|
+
after = xml.root.children.last
|
264
|
+
pivot.add_previous_sibling("x")
|
265
|
+
|
266
|
+
assert_equal "after", after.content
|
267
|
+
assert !after.parent.nil?, "unrelated node should not be affected"
|
268
|
+
|
269
|
+
assert_equal "before", before.content
|
270
|
+
assert !before.parent.nil?, "no need to reparent"
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "#add_next_sibling" do
|
276
|
+
it "should not merge text nodes during the operation" do
|
277
|
+
xml = Nokogiri::XML %Q(<root>text node</root>)
|
278
|
+
replacee = xml.root.children.first
|
279
|
+
replacee.add_next_sibling "foo <p></p> bar"
|
280
|
+
assert_equal "text nodefoo <p></p> bar", xml.root.children.to_html
|
281
|
+
end
|
282
|
+
|
283
|
+
describe "with a text node after" do
|
284
|
+
it "should not defensively dup the 'after' text node" do
|
285
|
+
xml = Nokogiri::XML %Q(<root>before<p></p>after</root>)
|
286
|
+
pivot = xml.at_css("p")
|
287
|
+
before = xml.root.children.first
|
288
|
+
after = xml.root.children.last
|
289
|
+
pivot.add_next_sibling("x")
|
290
|
+
|
291
|
+
assert_equal "before", before.content
|
292
|
+
assert !before.parent.nil?, "unrelated node should not be affected"
|
293
|
+
|
294
|
+
assert_equal "after", after.content
|
295
|
+
assert !after.parent.nil?
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
describe "#replace" do
|
301
|
+
describe "a text node with a text node" do
|
302
|
+
it "should not merge text nodes during the operation" do
|
303
|
+
xml = Nokogiri::XML %Q(<root>text node</root>)
|
304
|
+
replacee = xml.root.children.first
|
305
|
+
replacee.replace "new text node"
|
306
|
+
assert_equal "new text node", xml.root.children.first.content
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "when a document has a default namespace" do
|
311
|
+
before do
|
312
|
+
@fruits = Nokogiri::XML(<<-eoxml)
|
313
|
+
<fruit xmlns="http://fruits.org">
|
314
|
+
<apple />
|
315
|
+
</fruit>
|
316
|
+
eoxml
|
317
|
+
end
|
318
|
+
|
319
|
+
it "inserts a node with default namespaces" do
|
320
|
+
apple = @fruits.css('apple').first
|
321
|
+
|
322
|
+
orange = Nokogiri::XML::Node.new('orange', @fruits)
|
323
|
+
apple.replace(orange)
|
324
|
+
|
325
|
+
assert_equal orange, @fruits.css('orange').first
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe "unlinking a node and then reparenting it" do
|
331
|
+
it "not blow up" do
|
332
|
+
# see http://github.com/sparklemotion/nokogiri/issues#issue/22
|
333
|
+
10.times do
|
334
|
+
begin
|
335
|
+
doc = Nokogiri::XML <<-EOHTML
|
336
|
+
<root>
|
337
|
+
<a>
|
338
|
+
<b/>
|
339
|
+
<c/>
|
340
|
+
</a>
|
341
|
+
</root>
|
342
|
+
EOHTML
|
343
|
+
|
344
|
+
assert root = doc.at("root")
|
345
|
+
assert a = root.at("a")
|
346
|
+
assert b = a.at("b")
|
347
|
+
assert c = a.at("c")
|
348
|
+
a.add_next_sibling(b.unlink)
|
349
|
+
c.unlink
|
350
|
+
end
|
351
|
+
GC.start
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "replace-merging text nodes" do
|
357
|
+
[
|
358
|
+
['<root>a<br/></root>', 'afoo'],
|
359
|
+
['<root>a<br/>b</root>', 'afoob'],
|
360
|
+
['<root><br/>b</root>', 'foob']
|
361
|
+
].each do |xml, result|
|
362
|
+
it "doesn't blow up on #{xml}" do
|
363
|
+
doc = Nokogiri::XML.parse(xml)
|
364
|
+
saved_nodes = doc.root.children
|
365
|
+
doc.at_xpath("/root/br").replace(Nokogiri::XML::Text.new('foo', doc))
|
366
|
+
saved_nodes.each { |child| child.inspect } # try to cause a crash
|
367
|
+
assert_equal result, doc.at_xpath("/root/text()").inner_text
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|