nokogiri 1.4.1-x86-mswin32 → 1.4.2.1-x86-mswin32
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.
- data/CHANGELOG.ja.rdoc +45 -0
- data/CHANGELOG.rdoc +53 -1
- data/Manifest.txt +3 -3
- data/README.ja.rdoc +1 -1
- data/README.rdoc +11 -5
- data/Rakefile +13 -79
- data/ext/nokogiri/extconf.rb +25 -74
- data/ext/nokogiri/html_document.c +17 -8
- data/ext/nokogiri/html_element_description.c +20 -16
- data/ext/nokogiri/html_entity_lookup.c +2 -2
- data/ext/nokogiri/html_sax_parser_context.c +10 -8
- data/ext/nokogiri/nokogiri.c +0 -1
- data/ext/nokogiri/nokogiri.h +33 -28
- data/ext/nokogiri/xml_attr.c +7 -5
- data/ext/nokogiri/xml_attribute_decl.c +5 -2
- data/ext/nokogiri/xml_cdata.c +4 -2
- data/ext/nokogiri/xml_comment.c +4 -2
- data/ext/nokogiri/xml_document.c +93 -15
- data/ext/nokogiri/xml_document.h +0 -1
- data/ext/nokogiri/xml_document_fragment.c +4 -2
- data/ext/nokogiri/xml_dtd.c +18 -8
- data/ext/nokogiri/xml_element_content.c +2 -2
- data/ext/nokogiri/xml_entity_decl.c +15 -2
- data/ext/nokogiri/xml_entity_reference.c +4 -2
- data/ext/nokogiri/xml_io.c +1 -1
- data/ext/nokogiri/xml_namespace.c +5 -3
- data/ext/nokogiri/xml_node.c +353 -114
- data/ext/nokogiri/xml_node_set.c +35 -22
- data/ext/nokogiri/xml_node_set.h +1 -1
- data/ext/nokogiri/xml_processing_instruction.c +4 -2
- data/ext/nokogiri/xml_reader.c +119 -47
- data/ext/nokogiri/xml_relax_ng.c +21 -12
- data/ext/nokogiri/xml_sax_parser.c +6 -3
- data/ext/nokogiri/xml_sax_parser.h +13 -17
- data/ext/nokogiri/xml_sax_parser_context.c +8 -6
- data/ext/nokogiri/xml_sax_push_parser.c +7 -6
- data/ext/nokogiri/xml_schema.c +62 -13
- data/ext/nokogiri/xml_syntax_error.c +18 -12
- data/ext/nokogiri/xml_syntax_error.h +1 -1
- data/ext/nokogiri/xml_text.c +4 -2
- data/ext/nokogiri/xml_xpath_context.c +60 -23
- data/ext/nokogiri/xslt_stylesheet.c +14 -3
- data/lib/nokogiri.rb +17 -0
- data/lib/nokogiri/1.8/nokogiri.so +0 -0
- data/lib/nokogiri/1.9/nokogiri.so +0 -0
- data/lib/nokogiri/css/generated_parser.rb +72 -62
- data/lib/nokogiri/css/generated_tokenizer.rb +23 -23
- data/lib/nokogiri/css/parser.y +3 -1
- data/lib/nokogiri/css/tokenizer.rex +3 -3
- data/lib/nokogiri/css/xpath_visitor.rb +8 -3
- data/lib/nokogiri/ffi/html/sax/parser_context.rb +3 -3
- data/lib/nokogiri/ffi/libxml.rb +16 -2
- data/lib/nokogiri/ffi/structs/common_node.rb +15 -3
- data/lib/nokogiri/ffi/structs/xml_document.rb +13 -4
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +3 -2
- data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
- data/lib/nokogiri/ffi/xml/document.rb +27 -0
- data/lib/nokogiri/ffi/xml/entity_decl.rb +9 -0
- data/lib/nokogiri/ffi/xml/node.rb +142 -61
- data/lib/nokogiri/ffi/xml/node_set.rb +15 -12
- data/lib/nokogiri/ffi/xml/reader.rb +5 -0
- data/lib/nokogiri/ffi/xml/schema.rb +17 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +4 -4
- data/lib/nokogiri/ffi/xml/xpath.rb +0 -10
- data/lib/nokogiri/ffi/xml/xpath_context.rb +22 -9
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +3 -0
- data/lib/nokogiri/html/document.rb +5 -3
- data/lib/nokogiri/html/document_fragment.rb +28 -7
- data/lib/nokogiri/version.rb +6 -2
- data/lib/nokogiri/version_warning.rb +6 -3
- data/lib/nokogiri/xml.rb +1 -1
- data/lib/nokogiri/xml/builder.rb +35 -22
- data/lib/nokogiri/xml/document.rb +44 -12
- data/lib/nokogiri/xml/document_fragment.rb +16 -12
- data/lib/nokogiri/xml/entity_decl.rb +4 -0
- data/lib/nokogiri/xml/node.rb +152 -95
- data/lib/nokogiri/xml/node_set.rb +2 -1
- data/lib/nokogiri/xml/sax/push_parser.rb +1 -1
- data/lib/nokogiri/xml/schema.rb +1 -5
- data/lib/nokogiri/xml/syntax_error.rb +4 -0
- data/lib/nokogiri/xml/text.rb +9 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
- data/tasks/cross_compile.rb +158 -0
- data/tasks/test.rb +0 -6
- data/test/css/test_xpath_visitor.rb +9 -0
- data/test/helper.rb +49 -11
- data/test/html/sax/test_parser.rb +11 -1
- data/test/html/test_document.rb +8 -0
- data/test/html/test_document_fragment.rb +14 -2
- data/test/html/test_element_description.rb +5 -1
- data/test/html/test_node.rb +5 -66
- data/test/test_reader.rb +28 -0
- data/test/test_xslt_transforms.rb +14 -0
- data/test/xml/test_builder.rb +43 -0
- data/test/xml/test_cdata.rb +12 -0
- data/test/xml/test_document.rb +74 -39
- data/test/xml/test_document_fragment.rb +36 -0
- data/test/xml/test_entity_decl.rb +37 -0
- data/test/xml/test_node.rb +192 -65
- data/test/xml/test_node_reparenting.rb +253 -236
- data/test/xml/test_node_set.rb +67 -0
- data/test/xml/test_text.rb +8 -0
- data/test/xml/test_xpath.rb +32 -0
- metadata +151 -79
- data/ext/nokogiri/iconv.dll +0 -0
- data/ext/nokogiri/libexslt.dll +0 -0
- data/ext/nokogiri/libxml2.dll +0 -0
- data/ext/nokogiri/libxslt.dll +0 -0
- data/ext/nokogiri/xml_xpath.c +0 -53
- data/ext/nokogiri/xml_xpath.h +0 -11
- data/ext/nokogiri/zlib1.dll +0 -0
- data/lib/nokogiri/xml/fragment_handler.rb +0 -79
@@ -4,258 +4,275 @@ module Nokogiri
|
|
4
4
|
module XML
|
5
5
|
class TestNodeReparenting < Nokogiri::TestCase
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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 => :reparented, :children_tags => %w[text b1 b2]},
|
54
|
+
:<< => {:target => "/root/a1", :returns => :reparented, :children_tags => %w[text b1 b2]},
|
55
|
+
|
56
|
+
:replace => {:target => "/root/a1/node()", :returns => :reparented, :children_tags => %w[b1 b2]},
|
57
|
+
:swap => {:target => "/root/a1/node()", :returns => :self, :children_tags => %w[b1 b2]},
|
58
|
+
|
59
|
+
:inner_html= => {:target => "/root/a1", :returns => :self, :children_tags => %w[b1 b2]},
|
60
|
+
|
61
|
+
:add_previous_sibling => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[b1 b2 text]},
|
62
|
+
:previous= => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[b1 b2 text]},
|
63
|
+
:before => {:target => "/root/a1/text()", :returns => :self, :children_tags => %w[b1 b2 text]},
|
64
|
+
|
65
|
+
:add_next_sibling => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[text b1 b2]},
|
66
|
+
:next= => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[text b1 b2]},
|
67
|
+
:after => {:target => "/root/a1/text()", :returns => :self, :children_tags => %w[text b1 b2]}
|
68
|
+
}.each do |method, params|
|
69
|
+
|
70
|
+
before do
|
71
|
+
@doc = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third <bx />node</a3></root>"
|
72
|
+
@doc2 = @doc.dup
|
73
|
+
@fragment_string = "<b1>foo</b1><b2>bar</b2>"
|
74
|
+
@fragment = Nokogiri::XML::DocumentFragment.parse @fragment_string
|
75
|
+
@node_set = Nokogiri::XML("<root><b1>foo</b1><b2>bar</b2></root>").xpath("/root/node()")
|
76
|
+
end
|
42
77
|
|
43
|
-
|
44
|
-
|
45
|
-
|
78
|
+
describe "##{method}" do
|
79
|
+
describe "passed a Node" do
|
80
|
+
[:current, :another].each do |which|
|
81
|
+
describe "passed a Node in the #{which} document" do
|
82
|
+
before do
|
83
|
+
@other_doc = which == :current ? @doc : @doc2
|
84
|
+
@other_node = @other_doc.at_xpath("/root/a2")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "unlinks the Node from its previous position" do
|
88
|
+
@doc.at_xpath(params[:target]).send(method, @other_node)
|
89
|
+
@other_doc.at_xpath("/root/a2").must_be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it "inserts the Node in the proper position" do
|
93
|
+
@doc.at_xpath(params[:target]).send(method, @other_node)
|
94
|
+
@doc.at_xpath("/root/a1/a2").wont_be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "returns the expected value" do
|
98
|
+
if params[:returns] == :self
|
99
|
+
sendee = @doc.at_xpath(params[:target])
|
100
|
+
sendee.send(method, @other_node).must_equal sendee
|
101
|
+
else
|
102
|
+
@doc.at_xpath(params[:target]).send(method, @other_node).must_equal @other_node
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
describe "passed a markup string" do
|
109
|
+
it "inserts the fragment roots in the proper position" do
|
110
|
+
@doc.at_xpath(params[:target]).send(method, @fragment_string)
|
111
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
describe "passed a fragment" do
|
115
|
+
it "inserts the fragment roots in the proper position" do
|
116
|
+
@doc.at_xpath(params[:target]).send(method, @fragment)
|
117
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
describe "passed a document" do
|
121
|
+
it "raises an exception" do
|
122
|
+
proc { @doc.at_xpath("/root/a1").send(method, @doc2) }.must_raise(ArgumentError)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
describe "passed a non-Node" do
|
126
|
+
it "raises an exception" do
|
127
|
+
proc { @doc.at_xpath("/root/a1").send(method, 42) }.must_raise(ArgumentError)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
describe "passed a NodeSet" do
|
131
|
+
it "inserts each member of the NodeSet in the proper order" do
|
132
|
+
@doc.at_xpath(params[:target]).send(method, @node_set)
|
133
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
46
137
|
|
47
|
-
|
48
|
-
|
138
|
+
describe "text node merging" do
|
139
|
+
describe "#add_child" do
|
140
|
+
it "merges the Text node with adjacent Text nodes" do
|
141
|
+
@doc.at_xpath("/root/a1").add_child Nokogiri::XML::Text.new('hello', @doc)
|
142
|
+
@doc.at_xpath("/root/a1/text()").content.must_equal "First nodehello"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
describe "#replace" do
|
146
|
+
it "merges the Text node with adjacent Text nodes" do
|
147
|
+
@doc.at_xpath("/root/a3/bx").replace Nokogiri::XML::Text.new('hello', @doc)
|
148
|
+
@doc.at_xpath("/root/a3/text()").content.must_equal "Third hellonode"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
49
152
|
end
|
50
|
-
|
51
|
-
assert_equal 0, d2.search('item').size
|
52
|
-
assert_equal 4, d1.search('item').size
|
53
153
|
end
|
54
154
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
def test_add_child_node_following_sequential_text_nodes_should_have_right_path
|
68
|
-
node = @xml.root.children.first
|
69
|
-
node.add_child(Nokogiri::XML::Text.new('text', @xml))
|
70
|
-
|
71
|
-
item = node.add_child(Nokogiri::XML::Element.new('item', @xml))
|
72
|
-
|
73
|
-
assert_equal '/root/a1/item', item.path
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_add_child_node_with_namespace_should_keep_namespace
|
77
|
-
doc = Nokogiri::XML::Document.new
|
78
|
-
item = Nokogiri::XML::Element.new('item', doc)
|
79
|
-
doc.root = item
|
80
|
-
|
81
|
-
entry = Nokogiri::XML::Element.new('entry', doc)
|
82
|
-
entry.add_namespace('tlm', 'http://tenderlovemaking.com')
|
83
|
-
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
84
|
-
item.add_child(entry)
|
85
|
-
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_add_child_node_should_inherit_namespace
|
89
|
-
doc = Nokogiri::XML(<<-eoxml)
|
90
|
-
<root xmlns="http://tenderlovemaking.com/">
|
91
|
-
<first>
|
92
|
-
</first>
|
93
|
-
</root>
|
94
|
-
eoxml
|
95
|
-
assert node = doc.at('//xmlns:first')
|
96
|
-
child = Nokogiri::XML::Node.new('second', doc)
|
97
|
-
node.add_child(child)
|
98
|
-
assert doc.at('//xmlns:second')
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_add_child_node_should_not_inherit_namespace_if_it_has_one
|
102
|
-
doc = Nokogiri::XML(<<-eoxml)
|
103
|
-
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="http://flavorjon.es/">
|
104
|
-
<first>
|
105
|
-
</first>
|
106
|
-
</root>
|
107
|
-
eoxml
|
108
|
-
assert node = doc.at('//xmlns:first')
|
109
|
-
child = Nokogiri::XML::Node.new('second', doc)
|
110
|
-
|
111
|
-
ns = doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
|
112
|
-
child.namespace = ns
|
113
|
-
|
114
|
-
node.add_child(child)
|
115
|
-
assert doc.at('//foo:second', "foo" => "http://flavorjon.es/")
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_replace_node_should_remove_previous_node_and_insert_new_node
|
119
|
-
second_node = @xml.root.children[1]
|
120
|
-
|
121
|
-
new_node = Nokogiri::XML::Node.new('foo', @xml)
|
122
|
-
second_node.replace(new_node)
|
123
|
-
|
124
|
-
assert_equal @xml.root.children[1], new_node
|
125
|
-
assert_nil second_node.parent
|
126
|
-
end
|
127
|
-
|
128
|
-
def test_replace_fragment_should_replace_node_with_fragment_roots
|
129
|
-
node = @xml.root.children[1]
|
130
|
-
fragment = Nokogiri::XML.fragment("<b1>foo</b1><b2>bar</b2>")
|
131
|
-
fc1 = fragment.children[0]
|
132
|
-
fc2 = fragment.children[1]
|
133
|
-
|
134
|
-
node.replace fragment
|
135
|
-
|
136
|
-
assert_equal 4, @xml.root.children.length
|
137
|
-
assert_equal fc1, @xml.root.children[1]
|
138
|
-
assert_equal fc2, @xml.root.children[2]
|
139
|
-
end
|
140
|
-
|
141
|
-
def test_replace_with_default_namespaces
|
142
|
-
fruits = Nokogiri::XML(<<-eoxml)
|
143
|
-
<fruit xmlns="http://fruits.org">
|
144
|
-
<apple />
|
145
|
-
</fruit>
|
146
|
-
eoxml
|
147
|
-
|
148
|
-
apple = fruits.css('apple').first
|
149
|
-
|
150
|
-
orange = Nokogiri::XML::Node.new('orange', fruits)
|
151
|
-
apple.replace(orange)
|
152
|
-
|
153
|
-
assert_equal orange, fruits.css('orange').first
|
154
|
-
end
|
155
|
-
|
156
|
-
def test_illegal_replace_of_node_with_doc
|
157
|
-
new_node = Nokogiri::XML.parse('<foo>bar</foo>')
|
158
|
-
old_node = @xml.at_css('a1')
|
159
|
-
assert_raises(ArgumentError){ old_node.replace new_node }
|
160
|
-
end
|
161
|
-
|
162
|
-
def test_replace_with_node_from_different_docs
|
163
|
-
xml1 = "<test> <caption>Original caption</caption> </test>"
|
164
|
-
xml2 = "<test> <caption>Replacement caption</caption> </test>"
|
165
|
-
doc1 = Nokogiri::XML(xml1)
|
166
|
-
doc2 = Nokogiri::XML(xml2)
|
167
|
-
caption1 = doc1.xpath("//caption")[0]
|
168
|
-
caption2 = doc2.xpath("//caption")[0]
|
169
|
-
caption1.replace(caption2) # this segfaulted under 1.4.0 and earlier
|
170
|
-
assert_equal "Replacement caption", doc1.css("caption").inner_text
|
171
|
-
end
|
172
|
-
|
173
|
-
def test_add_next_sibling_should_insert_after
|
174
|
-
node = Nokogiri::XML::Node.new('x', @xml)
|
175
|
-
@xml.root.children[1].add_next_sibling node
|
176
|
-
assert_equal ["a1", "a2", "x", "a3"], @xml.root.children.collect {|n| n.name}
|
177
|
-
end
|
178
|
-
|
179
|
-
def test_next_equals_should_insert_after
|
180
|
-
node = Nokogiri::XML::Node.new('x', @xml)
|
181
|
-
@xml.root.children[1].next = node
|
182
|
-
assert_equal ["a1", "a2", "x", "a3"], @xml.root.children.collect {|n| n.name}
|
183
|
-
end
|
184
|
-
|
185
|
-
def test_add_next_sibling_fragment_should_insert_fragment_roots_after
|
186
|
-
fragment = Nokogiri::XML.fragment("<b1>foo</b1><b2>bar</b2>")
|
187
|
-
@xml.root.children[1].add_next_sibling fragment
|
188
|
-
assert_equal ["a1", "a2", "b1", "b2", "a3"], @xml.root.children.collect {|n| n.name}
|
189
|
-
end
|
190
|
-
|
191
|
-
def test_add_next_sibling_text_node_should_merge_with_adjacent_text_nodes
|
192
|
-
node = @xml.root.children.first
|
193
|
-
text = node.children.first
|
194
|
-
new_text = Nokogiri::XML::Text.new('text', @xml)
|
195
|
-
|
196
|
-
text.add_next_sibling new_text
|
197
|
-
|
198
|
-
assert_equal "First nodetext", node.children.first.content
|
199
|
-
assert_equal "First nodetext", text.content
|
200
|
-
assert_equal "First nodetext", new_text.content
|
201
|
-
end
|
155
|
+
describe "ad hoc node reparenting behavior" do
|
156
|
+
before do
|
157
|
+
@xml = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third node</a3></root>"
|
158
|
+
@html = Nokogiri::HTML(<<-eohtml)
|
159
|
+
<html>
|
160
|
+
<head></head>
|
161
|
+
<body>
|
162
|
+
<div class='baz'><a href="foo" class="bar">first</a></div>
|
163
|
+
</body>
|
164
|
+
</html>
|
165
|
+
eohtml
|
166
|
+
end
|
202
167
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
168
|
+
describe "#add_child" do
|
169
|
+
describe "given a new node with a namespace" do
|
170
|
+
it "keeps the namespace" do
|
171
|
+
doc = Nokogiri::XML::Document.new
|
172
|
+
item = Nokogiri::XML::Element.new('item', doc)
|
173
|
+
doc.root = item
|
174
|
+
|
175
|
+
entry = Nokogiri::XML::Element.new('entry', doc)
|
176
|
+
entry.add_namespace('tlm', 'http://tenderlovemaking.com')
|
177
|
+
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
178
|
+
item.add_child(entry)
|
179
|
+
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
180
|
+
end
|
181
|
+
end
|
208
182
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
183
|
+
describe "given a parent node with a default namespace" do
|
184
|
+
before do
|
185
|
+
@doc = Nokogiri::XML(<<-eoxml)
|
186
|
+
<root xmlns="http://tenderlovemaking.com/">
|
187
|
+
<first>
|
188
|
+
</first>
|
189
|
+
</root>
|
190
|
+
eoxml
|
191
|
+
end
|
192
|
+
|
193
|
+
it "inserts a node that inherits the default namespace" do
|
194
|
+
assert node = @doc.at('//xmlns:first')
|
195
|
+
child = Nokogiri::XML::Node.new('second', @doc)
|
196
|
+
node.add_child(child)
|
197
|
+
assert @doc.at('//xmlns:second')
|
198
|
+
end
|
199
|
+
end
|
214
200
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
201
|
+
describe "given a parent node with a non-default namespace" do
|
202
|
+
before do
|
203
|
+
@doc = Nokogiri::XML(<<-eoxml)
|
204
|
+
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="http://flavorjon.es/">
|
205
|
+
<first>
|
206
|
+
</first>
|
207
|
+
</root>
|
208
|
+
eoxml
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "and a child node with a namespace matching the parent's non-default namespace" do
|
212
|
+
it "inserts a node that inherits the matching parent namespace" do
|
213
|
+
assert node = @doc.at('//xmlns:first')
|
214
|
+
child = Nokogiri::XML::Node.new('second', @doc)
|
215
|
+
|
216
|
+
ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
|
217
|
+
child.namespace = ns
|
218
|
+
|
219
|
+
node.add_child(child)
|
220
|
+
assert @doc.at('//foo:second', "foo" => "http://flavorjon.es/")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
220
225
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
226
|
+
describe "#replace" do
|
227
|
+
describe "when a document has a default namespace" do
|
228
|
+
before do
|
229
|
+
@fruits = Nokogiri::XML(<<-eoxml)
|
230
|
+
<fruit xmlns="http://fruits.org">
|
231
|
+
<apple />
|
232
|
+
</fruit>
|
233
|
+
eoxml
|
234
|
+
end
|
225
235
|
|
226
|
-
|
236
|
+
it "inserts a node with default namespaces" do
|
237
|
+
apple = @fruits.css('apple').first
|
227
238
|
|
228
|
-
|
229
|
-
|
230
|
-
assert_equal "textFirst node", new_text.content
|
231
|
-
end
|
239
|
+
orange = Nokogiri::XML::Node.new('orange', @fruits)
|
240
|
+
apple.replace(orange)
|
232
241
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
STDOUT.flush
|
238
|
-
begin
|
239
|
-
doc = Nokogiri::XML <<-EOHTML
|
240
|
-
<root>
|
241
|
-
<a>
|
242
|
-
<b/>
|
243
|
-
<c/>
|
244
|
-
</a>
|
245
|
-
</root>
|
246
|
-
EOHTML
|
242
|
+
assert_equal orange, @fruits.css('orange').first
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
247
246
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
247
|
+
describe "unlinking a node and then reparenting it" do
|
248
|
+
it "not blow up" do
|
249
|
+
# see http://github.com/tenderlove/nokogiri/issues#issue/22
|
250
|
+
10.times do
|
251
|
+
STDOUT.putc "."
|
252
|
+
STDOUT.flush
|
253
|
+
begin
|
254
|
+
doc = Nokogiri::XML <<-EOHTML
|
255
|
+
<root>
|
256
|
+
<a>
|
257
|
+
<b/>
|
258
|
+
<c/>
|
259
|
+
</a>
|
260
|
+
</root>
|
261
|
+
EOHTML
|
262
|
+
|
263
|
+
root = doc.at("root")
|
264
|
+
a = root.at("a")
|
265
|
+
b = a.at("b")
|
266
|
+
c = a.at("c")
|
267
|
+
a.add_next_sibling(b.unlink)
|
268
|
+
c.unlink
|
269
|
+
end
|
270
|
+
GC.start
|
271
|
+
end
|
254
272
|
end
|
255
|
-
GC.start
|
256
273
|
end
|
257
|
-
end
|
258
274
|
|
275
|
+
end
|
259
276
|
end
|
260
277
|
end
|
261
278
|
end
|