nokogiri 1.8.5 → 1.9.1
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 +4 -4
- data/README.md +0 -1
- data/ext/nokogiri/extconf.rb +10 -6
- data/ext/nokogiri/xml_attr.c +26 -21
- data/ext/nokogiri/xml_document.c +4 -1
- data/ext/nokogiri/xml_namespace.c +3 -3
- data/ext/nokogiri/xml_namespace.h +1 -2
- data/ext/nokogiri/xml_node.c +55 -15
- data/lib/nokogiri/css/parser.rb +61 -61
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml/document_fragment.rb +11 -0
- data/lib/nokogiri/xml/node.rb +12 -0
- data/lib/nokogiri/xml/node_set.rb +4 -8
- metadata +17 -153
- data/.autotest +0 -22
- data/.cross_rubies +0 -8
- data/.editorconfig +0 -17
- data/.gemtest +0 -0
- data/.travis.yml +0 -63
- data/CHANGELOG.md +0 -1368
- data/CONTRIBUTING.md +0 -42
- data/C_CODING_STYLE.rdoc +0 -33
- data/Gemfile +0 -23
- data/Gemfile-libxml-ruby +0 -3
- data/Manifest.txt +0 -370
- data/ROADMAP.md +0 -111
- data/Rakefile +0 -348
- data/SECURITY.md +0 -19
- data/STANDARD_RESPONSES.md +0 -47
- data/Y_U_NO_GEMSPEC.md +0 -155
- data/appveyor.yml +0 -29
- data/build_all +0 -44
- data/patches/sort-patches-by-date +0 -25
- data/suppressions/README.txt +0 -1
- data/suppressions/nokogiri_ruby-2.supp +0 -10
- data/tasks/test.rb +0 -100
- data/test/css/test_nthiness.rb +0 -226
- data/test/css/test_parser.rb +0 -386
- data/test/css/test_tokenizer.rb +0 -215
- data/test/css/test_xpath_visitor.rb +0 -96
- data/test/decorators/test_slop.rb +0 -23
- data/test/files/2ch.html +0 -108
- data/test/files/GH_1042.html +0 -18
- data/test/files/address_book.rlx +0 -12
- data/test/files/address_book.xml +0 -10
- data/test/files/atom.xml +0 -344
- data/test/files/bar/bar.xsd +0 -4
- data/test/files/bogus.xml +0 -0
- data/test/files/dont_hurt_em_why.xml +0 -422
- data/test/files/encoding.html +0 -82
- data/test/files/encoding.xhtml +0 -84
- data/test/files/exslt.xml +0 -8
- data/test/files/exslt.xslt +0 -35
- data/test/files/foo/foo.xsd +0 -4
- data/test/files/metacharset.html +0 -10
- data/test/files/namespace_pressure_test.xml +0 -1684
- data/test/files/noencoding.html +0 -47
- data/test/files/po.xml +0 -32
- data/test/files/po.xsd +0 -66
- data/test/files/saml/saml20assertion_schema.xsd +0 -283
- data/test/files/saml/saml20protocol_schema.xsd +0 -302
- data/test/files/saml/xenc_schema.xsd +0 -146
- data/test/files/saml/xmldsig_schema.xsd +0 -318
- data/test/files/shift_jis.html +0 -10
- data/test/files/shift_jis.xml +0 -5
- data/test/files/shift_jis_no_charset.html +0 -9
- data/test/files/slow-xpath.xml +0 -25509
- data/test/files/snuggles.xml +0 -3
- data/test/files/staff.dtd +0 -10
- data/test/files/staff.xml +0 -59
- data/test/files/staff.xslt +0 -32
- data/test/files/test_document_url/bar.xml +0 -2
- data/test/files/test_document_url/document.dtd +0 -4
- data/test/files/test_document_url/document.xml +0 -6
- data/test/files/tlm.html +0 -851
- data/test/files/to_be_xincluded.xml +0 -2
- data/test/files/valid_bar.xml +0 -2
- data/test/files/xinclude.xml +0 -4
- data/test/helper.rb +0 -271
- data/test/html/sax/test_parser.rb +0 -168
- data/test/html/sax/test_parser_context.rb +0 -46
- data/test/html/sax/test_parser_text.rb +0 -163
- data/test/html/sax/test_push_parser.rb +0 -87
- data/test/html/test_attributes.rb +0 -85
- data/test/html/test_builder.rb +0 -164
- data/test/html/test_document.rb +0 -712
- data/test/html/test_document_encoding.rb +0 -143
- data/test/html/test_document_fragment.rb +0 -310
- data/test/html/test_element_description.rb +0 -105
- data/test/html/test_named_characters.rb +0 -14
- data/test/html/test_node.rb +0 -212
- data/test/html/test_node_encoding.rb +0 -91
- data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
- data/test/namespaces/test_namespaces_aliased_default.rb +0 -24
- data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_cloned_doc.rb +0 -31
- data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -80
- data/test/namespaces/test_namespaces_preservation.rb +0 -31
- data/test/test_convert_xpath.rb +0 -135
- data/test/test_css_cache.rb +0 -47
- data/test/test_encoding_handler.rb +0 -48
- data/test/test_memory_leak.rb +0 -156
- data/test/test_nokogiri.rb +0 -138
- data/test/test_soap4r_sax.rb +0 -52
- data/test/test_xslt_transforms.rb +0 -314
- data/test/xml/node/test_save_options.rb +0 -28
- data/test/xml/node/test_subclass.rb +0 -44
- data/test/xml/sax/test_parser.rb +0 -402
- data/test/xml/sax/test_parser_context.rb +0 -115
- data/test/xml/sax/test_parser_text.rb +0 -202
- data/test/xml/sax/test_push_parser.rb +0 -265
- data/test/xml/test_attr.rb +0 -74
- data/test/xml/test_attribute_decl.rb +0 -86
- data/test/xml/test_builder.rb +0 -341
- data/test/xml/test_c14n.rb +0 -180
- data/test/xml/test_cdata.rb +0 -54
- data/test/xml/test_comment.rb +0 -40
- data/test/xml/test_document.rb +0 -982
- data/test/xml/test_document_encoding.rb +0 -31
- data/test/xml/test_document_fragment.rb +0 -298
- data/test/xml/test_dtd.rb +0 -187
- data/test/xml/test_dtd_encoding.rb +0 -31
- data/test/xml/test_element_content.rb +0 -56
- data/test/xml/test_element_decl.rb +0 -73
- data/test/xml/test_entity_decl.rb +0 -122
- data/test/xml/test_entity_reference.rb +0 -262
- data/test/xml/test_namespace.rb +0 -96
- data/test/xml/test_node.rb +0 -1325
- data/test/xml/test_node_attributes.rb +0 -115
- data/test/xml/test_node_encoding.rb +0 -75
- data/test/xml/test_node_inheritance.rb +0 -32
- data/test/xml/test_node_reparenting.rb +0 -592
- data/test/xml/test_node_set.rb +0 -809
- data/test/xml/test_parse_options.rb +0 -64
- data/test/xml/test_processing_instruction.rb +0 -30
- data/test/xml/test_reader.rb +0 -620
- data/test/xml/test_reader_encoding.rb +0 -134
- data/test/xml/test_relax_ng.rb +0 -60
- data/test/xml/test_schema.rb +0 -142
- data/test/xml/test_syntax_error.rb +0 -36
- data/test/xml/test_text.rb +0 -60
- data/test/xml/test_unparented_node.rb +0 -483
- data/test/xml/test_xinclude.rb +0 -83
- data/test/xml/test_xpath.rb +0 -470
- data/test/xslt/test_custom_functions.rb +0 -133
- data/test/xslt/test_exception_handling.rb +0 -37
@@ -1,592 +0,0 @@
|
|
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
|
-
before do
|
54
|
-
@doc = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third <bx />node</a3></root>"
|
55
|
-
@doc2 = @doc.dup
|
56
|
-
@fragment_string = "<b1>foo</b1><b2>bar</b2>"
|
57
|
-
@fragment = Nokogiri::XML::DocumentFragment.parse @fragment_string
|
58
|
-
@node_set = Nokogiri::XML("<root><b1>foo</b1><b2>bar</b2></root>").xpath("/root/node()")
|
59
|
-
end
|
60
|
-
|
61
|
-
{
|
62
|
-
:add_child => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
|
63
|
-
:<< => {:target => "/root/a1", :returns_self => true, :children_tags => %w[text b1 b2]},
|
64
|
-
|
65
|
-
:replace => {:target => "/root/a1/node()", :returns_self => false, :children_tags => %w[b1 b2]},
|
66
|
-
:swap => {:target => "/root/a1/node()", :returns_self => true, :children_tags => %w[b1 b2]},
|
67
|
-
|
68
|
-
:children= => {:target => "/root/a1", :returns_self => false, :children_tags => %w[b1 b2]},
|
69
|
-
:inner_html= => {:target => "/root/a1", :returns_self => true, :children_tags => %w[b1 b2]},
|
70
|
-
|
71
|
-
:add_previous_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
|
72
|
-
:previous= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
|
73
|
-
:before => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[b1 b2 text]},
|
74
|
-
|
75
|
-
:add_next_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
|
76
|
-
:next= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
|
77
|
-
:after => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[text b1 b2]}
|
78
|
-
}.each do |method, params|
|
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 the new document is empty" do
|
201
|
-
it "adds the node to the new document" do
|
202
|
-
doc1 = Nokogiri::XML.parse("<value>3</value>")
|
203
|
-
doc2 = Nokogiri::XML::Document.new
|
204
|
-
node = doc1.at_xpath("//value")
|
205
|
-
node.remove
|
206
|
-
doc2.add_child(node)
|
207
|
-
assert_match /<value>3<\/value>/, doc2.to_xml
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
describe "given a parent node with a default namespace" do
|
212
|
-
before do
|
213
|
-
@doc = Nokogiri::XML(<<-eoxml)
|
214
|
-
<root xmlns="http://tenderlovemaking.com/">
|
215
|
-
<first>
|
216
|
-
</first>
|
217
|
-
</root>
|
218
|
-
eoxml
|
219
|
-
end
|
220
|
-
|
221
|
-
it "inserts a node that inherits the default namespace" do
|
222
|
-
assert node = @doc.at('//xmlns:first')
|
223
|
-
child = Nokogiri::XML::Node.new('second', @doc)
|
224
|
-
node.add_child(child)
|
225
|
-
assert @doc.at('//xmlns:second')
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
describe "given a parent node with a default and non-default namespace" do
|
230
|
-
before do
|
231
|
-
@doc = Nokogiri::XML(<<-eoxml)
|
232
|
-
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="http://flavorjon.es/">
|
233
|
-
<first>
|
234
|
-
</first>
|
235
|
-
</root>
|
236
|
-
eoxml
|
237
|
-
assert @node = @doc.at('//xmlns:first')
|
238
|
-
@child = Nokogiri::XML::Node.new('second', @doc)
|
239
|
-
end
|
240
|
-
|
241
|
-
describe "and a child with a namespace matching the parent's default namespace" do
|
242
|
-
describe "and as the default prefix" do
|
243
|
-
before do
|
244
|
-
@ns = @child.add_namespace(nil, 'http://tenderlovemaking.com/')
|
245
|
-
@child.namespace = @ns
|
246
|
-
end
|
247
|
-
|
248
|
-
it "inserts a node that inherits the parent's default namespace" do
|
249
|
-
@node.add_child(@child)
|
250
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://tenderlovemaking.com/")
|
251
|
-
assert reparented.namespace_definitions.empty?
|
252
|
-
assert_equal @ns, reparented.namespace
|
253
|
-
assert_equal(
|
254
|
-
{
|
255
|
-
"xmlns" => "http://tenderlovemaking.com/",
|
256
|
-
"xmlns:foo" => "http://flavorjon.es/",
|
257
|
-
},
|
258
|
-
reparented.namespaces)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
describe "but with a different prefix" do
|
263
|
-
before do
|
264
|
-
@ns = @child.add_namespace("baz", 'http://tenderlovemaking.com/')
|
265
|
-
@child.namespace = @ns
|
266
|
-
end
|
267
|
-
|
268
|
-
it "inserts a node that uses its own namespace" do
|
269
|
-
@node.add_child(@child)
|
270
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://tenderlovemaking.com/")
|
271
|
-
assert reparented.namespace_definitions.include?(@ns)
|
272
|
-
assert_equal @ns, reparented.namespace
|
273
|
-
assert_equal(
|
274
|
-
{
|
275
|
-
"xmlns" => "http://tenderlovemaking.com/",
|
276
|
-
"xmlns:foo" => "http://flavorjon.es/",
|
277
|
-
"xmlns:baz" => "http://tenderlovemaking.com/",
|
278
|
-
},
|
279
|
-
reparented.namespaces)
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
describe "and a child with a namespace matching the parent's non-default namespace" do
|
285
|
-
describe "set by #namespace=" do
|
286
|
-
before do
|
287
|
-
@ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
|
288
|
-
@child.namespace = @ns
|
289
|
-
end
|
290
|
-
|
291
|
-
it "inserts a node that inherits the matching parent namespace" do
|
292
|
-
@node.add_child(@child)
|
293
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/")
|
294
|
-
assert reparented.namespace_definitions.empty?
|
295
|
-
assert_equal @ns, reparented.namespace
|
296
|
-
assert_equal(
|
297
|
-
{
|
298
|
-
"xmlns" => "http://tenderlovemaking.com/",
|
299
|
-
"xmlns:foo" => "http://flavorjon.es/",
|
300
|
-
},
|
301
|
-
reparented.namespaces)
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
describe "with the same prefix" do
|
306
|
-
before do
|
307
|
-
@ns = @child.add_namespace("foo", 'http://flavorjon.es/')
|
308
|
-
@child.namespace = @ns
|
309
|
-
end
|
310
|
-
|
311
|
-
it "inserts a node that uses the parent's namespace" do
|
312
|
-
@node.add_child(@child)
|
313
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/")
|
314
|
-
assert reparented.namespace_definitions.empty?
|
315
|
-
assert_equal @ns, reparented.namespace
|
316
|
-
assert_equal(
|
317
|
-
{
|
318
|
-
"xmlns" => "http://tenderlovemaking.com/",
|
319
|
-
"xmlns:foo" => "http://flavorjon.es/",
|
320
|
-
},
|
321
|
-
reparented.namespaces)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
describe "as the default prefix" do
|
326
|
-
before do
|
327
|
-
@ns = @child.add_namespace(nil, 'http://flavorjon.es/')
|
328
|
-
@child.namespace = @ns
|
329
|
-
end
|
330
|
-
|
331
|
-
it "inserts a node that keeps its namespace" do
|
332
|
-
@node.add_child(@child)
|
333
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/")
|
334
|
-
assert reparented.namespace_definitions.include?(@ns)
|
335
|
-
assert_equal @ns, reparented.namespace
|
336
|
-
assert_equal(
|
337
|
-
{
|
338
|
-
"xmlns" => "http://flavorjon.es/",
|
339
|
-
"xmlns:foo" => "http://flavorjon.es/",
|
340
|
-
},
|
341
|
-
reparented.namespaces)
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
describe "but with a different prefix" do
|
346
|
-
before do
|
347
|
-
@ns = @child.add_namespace('baz', 'http://flavorjon.es/')
|
348
|
-
@child.namespace = @ns
|
349
|
-
end
|
350
|
-
|
351
|
-
it "inserts a node that keeps its namespace" do
|
352
|
-
@node.add_child(@child)
|
353
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://flavorjon.es/")
|
354
|
-
assert reparented.namespace_definitions.include?(@ns)
|
355
|
-
assert_equal @ns, reparented.namespace
|
356
|
-
assert_equal(
|
357
|
-
{
|
358
|
-
"xmlns" =>"http://tenderlovemaking.com/",
|
359
|
-
"xmlns:foo" =>"http://flavorjon.es/",
|
360
|
-
"xmlns:baz" =>"http://flavorjon.es/",
|
361
|
-
},
|
362
|
-
reparented.namespaces)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
describe "and a child node with a default namespace not matching the parent's default namespace and a namespace matching a parent namespace but with a different prefix" do
|
368
|
-
before do
|
369
|
-
@ns = @child.add_namespace(nil, 'http://example.org/')
|
370
|
-
@child.namespace = @ns
|
371
|
-
@ns2 = @child.add_namespace('baz', 'http://tenderlovemaking.com/')
|
372
|
-
end
|
373
|
-
|
374
|
-
it "inserts a node that keeps its namespace" do
|
375
|
-
@node.add_child(@child)
|
376
|
-
assert reparented = @doc.at('//bar:second', "bar" => "http://example.org/")
|
377
|
-
assert reparented.namespace_definitions.include?(@ns)
|
378
|
-
assert reparented.namespace_definitions.include?(@ns2)
|
379
|
-
assert_equal @ns, reparented.namespace
|
380
|
-
assert_equal(
|
381
|
-
{
|
382
|
-
"xmlns" => "http://example.org/",
|
383
|
-
"xmlns:foo" => "http://flavorjon.es/",
|
384
|
-
"xmlns:baz" => "http://tenderlovemaking.com/",
|
385
|
-
},
|
386
|
-
reparented.namespaces)
|
387
|
-
end
|
388
|
-
end
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
describe "#add_previous_sibling" do
|
393
|
-
it "should not merge text nodes during the operation" do
|
394
|
-
xml = Nokogiri::XML %Q(<root>text node</root>)
|
395
|
-
replacee = xml.root.children.first
|
396
|
-
replacee.add_previous_sibling "foo <p></p> bar"
|
397
|
-
assert_equal "foo <p></p> bartext node", xml.root.children.to_html
|
398
|
-
end
|
399
|
-
|
400
|
-
it 'should remove the child node after the operation' do
|
401
|
-
fragment = Nokogiri::HTML::DocumentFragment.parse("a<a>b</a>")
|
402
|
-
node = fragment.children.last
|
403
|
-
node.add_previous_sibling node.children
|
404
|
-
assert_empty node.children, "should have no childrens"
|
405
|
-
end
|
406
|
-
|
407
|
-
describe "with a text node before" do
|
408
|
-
it "should not defensively dup the 'before' text node" do
|
409
|
-
xml = Nokogiri::XML %Q(<root>before<p></p>after</root>)
|
410
|
-
pivot = xml.at_css("p")
|
411
|
-
before = xml.root.children.first
|
412
|
-
after = xml.root.children.last
|
413
|
-
pivot.add_previous_sibling("x")
|
414
|
-
|
415
|
-
assert_equal "after", after.content
|
416
|
-
assert !after.parent.nil?, "unrelated node should not be affected"
|
417
|
-
|
418
|
-
assert_equal "before", before.content
|
419
|
-
assert !before.parent.nil?, "no need to reparent"
|
420
|
-
end
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
describe "#add_next_sibling" do
|
425
|
-
it "should not merge text nodes during the operation" do
|
426
|
-
xml = Nokogiri::XML %Q(<root>text node</root>)
|
427
|
-
replacee = xml.root.children.first
|
428
|
-
replacee.add_next_sibling "foo <p></p> bar"
|
429
|
-
assert_equal "text nodefoo <p></p> bar", xml.root.children.to_html
|
430
|
-
end
|
431
|
-
|
432
|
-
it 'should append a text node before an existing non text node' do
|
433
|
-
xml = Nokogiri::XML %Q(<root><p>foo</p><p>bar</p></root>)
|
434
|
-
p = xml.at_css 'p'
|
435
|
-
p.add_next_sibling 'a'
|
436
|
-
assert_equal '<root><p>foo</p>a<p>bar</p></root>', xml.root.to_s
|
437
|
-
end
|
438
|
-
|
439
|
-
it 'should append a text node before an existing text node' do
|
440
|
-
xml = Nokogiri::XML %Q(<root><p>foo</p>after</root>)
|
441
|
-
p = xml.at_css 'p'
|
442
|
-
p.add_next_sibling 'x'
|
443
|
-
assert_equal '<root><p>foo</p>xafter</root>', xml.root.to_s
|
444
|
-
end
|
445
|
-
|
446
|
-
describe "with a text node after" do
|
447
|
-
it "should not defensively dup the 'after' text node" do
|
448
|
-
xml = Nokogiri::XML %Q(<root>before<p></p>after</root>)
|
449
|
-
pivot = xml.at_css("p")
|
450
|
-
before = xml.root.children.first
|
451
|
-
after = xml.root.children.last
|
452
|
-
pivot.add_next_sibling("x")
|
453
|
-
|
454
|
-
assert_equal "before", before.content
|
455
|
-
assert !before.parent.nil?, "unrelated node should not be affected"
|
456
|
-
|
457
|
-
assert_equal "after", after.content
|
458
|
-
assert !after.parent.nil?
|
459
|
-
end
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
describe "#replace" do
|
464
|
-
describe "a text node with a text node" do
|
465
|
-
it "should not merge text nodes during the operation" do
|
466
|
-
xml = Nokogiri::XML %Q(<root>text node</root>)
|
467
|
-
replacee = xml.root.children.first
|
468
|
-
replacee.replace "new text node"
|
469
|
-
assert_equal "new text node", xml.root.children.first.content
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
it "can replace with a comment node" do
|
474
|
-
doc = Nokogiri::XML %Q{<parent><child>text}
|
475
|
-
replacee = doc.at_css("child")
|
476
|
-
replacer = doc.create_comment("<b>text</b>")
|
477
|
-
replacee.replace replacer
|
478
|
-
assert_equal 1, doc.root.children.length
|
479
|
-
assert_equal replacer, doc.root.children.first
|
480
|
-
end
|
481
|
-
|
482
|
-
it "can replace with a CDATA node" do
|
483
|
-
doc = Nokogiri::XML %Q{<parent><child>text}
|
484
|
-
replacee = doc.at_css("child")
|
485
|
-
replacer = doc.create_cdata("<b>text</b>")
|
486
|
-
replacee.replace replacer
|
487
|
-
assert_equal 1, doc.root.children.length
|
488
|
-
assert_equal replacer, doc.root.children.first
|
489
|
-
end
|
490
|
-
|
491
|
-
describe "when a document has a default namespace" do
|
492
|
-
before do
|
493
|
-
@fruits = Nokogiri::XML(<<-eoxml)
|
494
|
-
<fruit xmlns="http://fruits.org">
|
495
|
-
<apple />
|
496
|
-
</fruit>
|
497
|
-
eoxml
|
498
|
-
end
|
499
|
-
|
500
|
-
it "inserts a node with default namespaces" do
|
501
|
-
apple = @fruits.css('apple').first
|
502
|
-
|
503
|
-
orange = Nokogiri::XML::Node.new('orange', @fruits)
|
504
|
-
apple.replace(orange)
|
505
|
-
|
506
|
-
assert_equal orange, @fruits.css('orange').first
|
507
|
-
end
|
508
|
-
end
|
509
|
-
end
|
510
|
-
|
511
|
-
describe "unlinking a node and then reparenting it" do
|
512
|
-
it "not blow up" do
|
513
|
-
# see http://github.com/sparklemotion/nokogiri/issues#issue/22
|
514
|
-
10.times do
|
515
|
-
begin
|
516
|
-
doc = Nokogiri::XML <<-EOHTML
|
517
|
-
<root>
|
518
|
-
<a>
|
519
|
-
<b/>
|
520
|
-
<c/>
|
521
|
-
</a>
|
522
|
-
</root>
|
523
|
-
EOHTML
|
524
|
-
|
525
|
-
assert root = doc.at("root")
|
526
|
-
assert a = root.at("a")
|
527
|
-
assert b = a.at("b")
|
528
|
-
assert c = a.at("c")
|
529
|
-
a.add_next_sibling(b.unlink)
|
530
|
-
c.unlink
|
531
|
-
end
|
532
|
-
GC.start
|
533
|
-
end
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
|
-
describe "replace-merging text nodes" do
|
538
|
-
[
|
539
|
-
['<root>a<br/></root>', 'afoo'],
|
540
|
-
['<root>a<br/>b</root>', 'afoob'],
|
541
|
-
['<root><br/>b</root>', 'foob']
|
542
|
-
].each do |xml, result|
|
543
|
-
it "doesn't blow up on #{xml}" do
|
544
|
-
doc = Nokogiri::XML.parse(xml)
|
545
|
-
saved_nodes = doc.root.children
|
546
|
-
doc.at_xpath("/root/br").replace(Nokogiri::XML::Text.new('foo', doc))
|
547
|
-
saved_nodes.each { |child| child.inspect } # try to cause a crash
|
548
|
-
assert_equal result, doc.at_xpath("/root/text()").inner_text
|
549
|
-
end
|
550
|
-
end
|
551
|
-
end
|
552
|
-
|
553
|
-
describe "reparenting into another document" do
|
554
|
-
it "correctly sets default namespace of a reparented node" do
|
555
|
-
# issue described in #391
|
556
|
-
# thanks to Nick Canzoneri @nickcanz for this test case!
|
557
|
-
source_doc = Nokogiri::XML <<-EOX
|
558
|
-
<?xml version="1.0" encoding="utf-8"?>
|
559
|
-
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
560
|
-
<Product>
|
561
|
-
<Package />
|
562
|
-
<Directory Id="TARGETDIR" Name="SourceDir">
|
563
|
-
<Component>
|
564
|
-
<File />
|
565
|
-
</Component>
|
566
|
-
</Directory>
|
567
|
-
</Product>
|
568
|
-
</Wix>
|
569
|
-
EOX
|
570
|
-
|
571
|
-
dest_doc = Nokogiri::XML <<-EOX
|
572
|
-
<?xml version="1.0" encoding="utf-8"?>
|
573
|
-
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
|
574
|
-
<Fragment Id='MSIComponents'>
|
575
|
-
<DirectoryRef Id='InstallDir'>
|
576
|
-
</DirectoryRef>
|
577
|
-
</Fragment>
|
578
|
-
</Wix>
|
579
|
-
EOX
|
580
|
-
|
581
|
-
stuff = source_doc.at_css("Directory[Id='TARGETDIR']")
|
582
|
-
insert_point = dest_doc.at_css("DirectoryRef[Id='InstallDir']")
|
583
|
-
insert_point.children = stuff.children()
|
584
|
-
|
585
|
-
assert_no_match(/default:/, insert_point.children.to_xml)
|
586
|
-
assert_match(/<Component>/, insert_point.children.to_xml)
|
587
|
-
end
|
588
|
-
end
|
589
|
-
end
|
590
|
-
end
|
591
|
-
end
|
592
|
-
end
|