nokogiri-xml-range 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.document +3 -0
- data/.gitignore +2 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +3 -0
- data/README.md +155 -0
- data/Rakefile +35 -0
- data/lib/nokogiri/xml/range.rb +583 -0
- data/lib/nokogiri/xml/range/refinement.rb +124 -0
- data/lib/nokogiri/xml/range/version.rb +8 -0
- data/lib/nokogiri/xml/replacable.rb +39 -0
- data/nokogiri-xml-range.gemspec +31 -0
- data/test/helper.rb +19 -0
- data/test/test_nokogiri-xml-range-refinement.rb +65 -0
- data/test/test_nokogiri-xml-range.rb +316 -0
- data/test/test_nokogiri-xml-replacable.rb +21 -0
- metadata +206 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
module Nokogiri::XML
|
2
|
+
class Range
|
3
|
+
module Refinement
|
4
|
+
refine Node do
|
5
|
+
def ancestors_to(node)
|
6
|
+
nodes = NodeSet.new(document)
|
7
|
+
current = self
|
8
|
+
root = document.root
|
9
|
+
nodes << current
|
10
|
+
until current == node or current == root
|
11
|
+
current = current.parent
|
12
|
+
nodes << current
|
13
|
+
end
|
14
|
+
return unless current == node
|
15
|
+
nodes
|
16
|
+
end
|
17
|
+
|
18
|
+
def length
|
19
|
+
case type
|
20
|
+
when Node::DOCUMENT_TYPE_NODE
|
21
|
+
0
|
22
|
+
when Node::TEXT_NODE, Node::CDATA_SECTION_NODE, Node::PI_NODE, Node::COMMENT_NODE
|
23
|
+
content.encode('UTF-16LE').bytesize / 2
|
24
|
+
else
|
25
|
+
children.length
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def following_node
|
30
|
+
child || next_sibling
|
31
|
+
end
|
32
|
+
|
33
|
+
def preceding_node
|
34
|
+
previous_sibling || parent
|
35
|
+
end
|
36
|
+
|
37
|
+
def inclusive_ancestors
|
38
|
+
[self] + ancestors
|
39
|
+
end
|
40
|
+
|
41
|
+
def inclusive_ancestor?(node)
|
42
|
+
inclusive_ancestors.include? node
|
43
|
+
end
|
44
|
+
|
45
|
+
def host_including_inclusive_ancestor?(node)
|
46
|
+
return true if inclusive_ancestor? node
|
47
|
+
root_node = ancestors.last
|
48
|
+
root_node.fragment? and
|
49
|
+
root_node.host.host_including_inclusive_ancestor?(node)
|
50
|
+
end
|
51
|
+
|
52
|
+
def replace_all_with(node)
|
53
|
+
document.adopt node if node
|
54
|
+
children.each &:remove
|
55
|
+
if node
|
56
|
+
add_child node
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def replacable?
|
61
|
+
kind_of? Nokogiri::XML::Replacable
|
62
|
+
end
|
63
|
+
|
64
|
+
def validate_pre_insertion(parent, child)
|
65
|
+
unless [Node::DOCUMENT_TYPE_NODE, Node::DOCUMENT_FRAG_NODE, Node::ELEMENT_NODE].include? parent.type
|
66
|
+
raise HierarchyRequestError
|
67
|
+
end
|
68
|
+
raise HierarchyRequestError if parent.host_including_inclusive_ancestor? self
|
69
|
+
raise NotFoundError if child and child.parent != parent
|
70
|
+
unless [Node::DOCUMENT_FRAG_NODE, Node::DOCUMENT_TYPE_NODE, Node::ELEMENT_NODE, Node::TEXT_NODE, Node::PI_NODE, Node::COMMENT_NODE].include? type
|
71
|
+
raise HierarchyRequestError
|
72
|
+
end
|
73
|
+
raise HierarchyRequestError if text? && parent.document?
|
74
|
+
raise HierarchyRequestError if type == Node::DOCUMENT_TYPE_NODE and !parent.document?
|
75
|
+
return unless parent.document?
|
76
|
+
case type
|
77
|
+
when Node::DOCUMENT_FRAG_NODE
|
78
|
+
child_element_count = 0
|
79
|
+
children.each do |node|
|
80
|
+
raise HierarchyRequestError if node.text?
|
81
|
+
child_element_count += 1 if node.element?
|
82
|
+
raise HierarchyRequestError if child_element_count > 1
|
83
|
+
end
|
84
|
+
if child_element_count == 1
|
85
|
+
raise HierarchyRequestError if parent.children.any?(&:element?)
|
86
|
+
return unless child
|
87
|
+
raise HierarchyRequestError if child.type = Node::DOCUMENT_TYPE_NODE
|
88
|
+
raise HierarchyRequestError if child.following_node.type == Node::DOCUMENT_TYPE_NODE
|
89
|
+
end
|
90
|
+
when Node::ELEMENT_NODE
|
91
|
+
raise HierarchyRequestError if parent.children.any?(&:element?)
|
92
|
+
return unless child
|
93
|
+
raise HierarchyRequestError if child.type == Node::DOCUMENT_TYPE_NODE
|
94
|
+
raise HierarchyRequestError if child.following_node.type == Node::DOCUMENT_TYPE_NODE
|
95
|
+
when Node::DOCUMENT_TYPE_NODE
|
96
|
+
raise HierarchyRequestError if parent.children.any? {|node|
|
97
|
+
node.type == Node::DOCUMENT_TYPE_NODE
|
98
|
+
}
|
99
|
+
return unless child
|
100
|
+
raise HierarchyRequestError if child.preceding_node.element?
|
101
|
+
raise HierarchyRequestError if parent.children.any?(&:element?)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
refine Document do
|
107
|
+
def adopt(node)
|
108
|
+
old_document = node.document
|
109
|
+
unless node.document == self
|
110
|
+
root << node
|
111
|
+
node.remove
|
112
|
+
end
|
113
|
+
if block_given?
|
114
|
+
yield node, old_document
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
refine DocumentFragment do
|
120
|
+
attr_accessor :host
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
using Nokogiri::XML::Range::Refinement
|
2
|
+
|
3
|
+
module Nokogiri::XML
|
4
|
+
module Replacable
|
5
|
+
def replace_data(offset, count, data)
|
6
|
+
len = length
|
7
|
+
raise IndexSizeError, 'offset is greater than node length' if offset > len
|
8
|
+
|
9
|
+
count = len - offset if offset + count > len
|
10
|
+
encoding = content.encoding
|
11
|
+
utf16_content = content.encode('UTF-16LE')
|
12
|
+
utf16_data = data.encode('UTF-16LE')
|
13
|
+
result = utf16_content.byteslice(0, offset * 2) + utf16_data + utf16_content.byteslice(offset * 2, utf16_content.bytesize)
|
14
|
+
delete_offset = offset + utf16_data.bytesize / 2
|
15
|
+
result = result.byteslice(0, delete_offset * 2) + result.byteslice((delete_offset + count) * 2, result.bytesize)
|
16
|
+
|
17
|
+
self.content = result.encode(encoding)
|
18
|
+
end
|
19
|
+
|
20
|
+
def substring_data(offset, count)
|
21
|
+
len = length
|
22
|
+
raise IndexSizeError, 'offset is greater than node length' if offset > len
|
23
|
+
|
24
|
+
encoding = content.encoding
|
25
|
+
utf16_content = content.encode('UTF-16LE')
|
26
|
+
|
27
|
+
byte_length = [utf16_content.bytesize - offset * 2, count * 2].min
|
28
|
+
utf16_content.byteslice(offset * 2, byte_length).encode(encoding)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class CharacterData
|
33
|
+
include Replacable
|
34
|
+
end
|
35
|
+
|
36
|
+
class ProcessingInstruction
|
37
|
+
include Replacable
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.expand_path('../lib/nokogiri/xml/range/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "nokogiri-xml-range"
|
7
|
+
gem.version = Nokogiri::XML::Range::VERSION
|
8
|
+
gem.summary = %q{DOM Range implementation on Nokogiri}
|
9
|
+
gem.description = %q{Nokogiri DOM Range Implementatin based on DOM Standard specification.}
|
10
|
+
gem.license = "LGPL"
|
11
|
+
gem.authors = ["KITAITI Makoto"]
|
12
|
+
gem.email = "KitaitiMakoto@gmail.com"
|
13
|
+
gem.homepage = "https://rubygems.org/gems/nokogiri-xml-range"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.add_runtime_dependency 'nokogiri'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'test-unit', '~> 3'
|
23
|
+
gem.add_development_dependency 'test-unit-notify'
|
24
|
+
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
25
|
+
gem.add_development_dependency 'yard', '~> 0.8'
|
26
|
+
gem.add_development_dependency 'rake'
|
27
|
+
gem.add_development_dependency 'bundler'
|
28
|
+
gem.add_development_dependency 'pry'
|
29
|
+
gem.add_development_dependency 'simplecov'
|
30
|
+
gem.add_development_dependency 'coveralls'
|
31
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'coveralls'
|
3
|
+
Coveralls.wear!
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
Coveralls::SimpleCov::Formatter
|
7
|
+
]
|
8
|
+
SimpleCov.start do
|
9
|
+
add_filter '/test/'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'pp'
|
13
|
+
require 'rubygems'
|
14
|
+
require 'test/unit'
|
15
|
+
require 'test/unit/notify'
|
16
|
+
require 'pry'
|
17
|
+
|
18
|
+
class Test::Unit::TestCase
|
19
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'nokogiri/xml/range/refinement'
|
4
|
+
require 'nokogiri/xml/replacable'
|
5
|
+
|
6
|
+
class TestNokogiriXMLRangeRefinement < Test::Unit::TestCase
|
7
|
+
using Nokogiri::XML::Range::Refinement
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@doc = Nokogiri.XML(<<EOD)
|
11
|
+
<root>
|
12
|
+
<parent>
|
13
|
+
<child>child 1</child>
|
14
|
+
<child>child 2</child>
|
15
|
+
</parent>
|
16
|
+
</root>
|
17
|
+
EOD
|
18
|
+
@root = @doc.root
|
19
|
+
@parent = @root.search('parent').first
|
20
|
+
@child1 = @parent.search('child')[0]
|
21
|
+
@child2 = @parent.search('child')[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
data({
|
25
|
+
'root' => [:root, 3],
|
26
|
+
'parent' => [:parent, 5],
|
27
|
+
'child1' => [:child1, 1],
|
28
|
+
})
|
29
|
+
def test_element_length(data)
|
30
|
+
node_name, length = data
|
31
|
+
node = instance_variable_get("@#{node_name}")
|
32
|
+
assert_equal length, node.length
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_text_length
|
36
|
+
assert_equal 7, @child1.children[0].length
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_inclusive_ancestor?
|
40
|
+
[@root, @parent, @child1].each do |node|
|
41
|
+
assert_true @child1.inclusive_ancestor? node
|
42
|
+
end
|
43
|
+
assert_false @child1.inclusive_ancestor? @child2
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_host_including_inclusive_ancestor?
|
47
|
+
fragment = Nokogiri::XML::DocumentFragment.new(@doc)
|
48
|
+
fragment.host = @parent
|
49
|
+
child = Nokogiri::XML::Element.new('child', @doc)
|
50
|
+
fragment << child
|
51
|
+
assert_true child.host_including_inclusive_ancestor? @root
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_adopt
|
55
|
+
@doc.adopt @child1
|
56
|
+
assert_equal @doc, @child1.document
|
57
|
+
|
58
|
+
another_doc = Nokogiri.XML('<root><child/></root>')
|
59
|
+
elem = another_doc.search('root').first
|
60
|
+
@doc.adopt elem
|
61
|
+
assert_equal @doc, elem.document
|
62
|
+
assert_equal @doc, elem.child.document
|
63
|
+
assert_equal Nokogiri.XML('').to_s, another_doc.to_s
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,316 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'helper'
|
3
|
+
require 'nokogiri/xml/range'
|
4
|
+
|
5
|
+
class TestNokogiriXMLRange < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@doc = Nokogiri.XML(<<EOX)
|
8
|
+
<root>
|
9
|
+
<parent>
|
10
|
+
<child>child 1</child>
|
11
|
+
<child>child 2</child>
|
12
|
+
</parent>
|
13
|
+
</root>
|
14
|
+
EOX
|
15
|
+
@root = @doc.search('root')[0]
|
16
|
+
@parent = @doc.search('parent')[0]
|
17
|
+
@child1 = @doc.search('child')[0]
|
18
|
+
@child2 = @doc.search('child')[1]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_version
|
22
|
+
version = Nokogiri::XML::Range.const_get('VERSION')
|
23
|
+
|
24
|
+
assert !version.empty?, 'should have a VERSION constant'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_compare_points
|
28
|
+
assert_equal -1, Nokogiri::XML::Range.compare_points(@child1, 0, @child1, 1)
|
29
|
+
assert_equal 1, Nokogiri::XML::Range.compare_points(@child2, 0, @child1, 0)
|
30
|
+
assert_equal 0, Nokogiri::XML::Range.compare_points(@child1, 1, @child1, 1)
|
31
|
+
assert_equal -1, Nokogiri::XML::Range.compare_points(@doc.root, 0, @child1, 0)
|
32
|
+
assert_equal 1, Nokogiri::XML::Range.compare_points(@doc.root, 2, @child1, 1)
|
33
|
+
assert_equal -1, Nokogiri::XML::Range.compare_points(@child1, 0, @child2, 3)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_contain_node?
|
37
|
+
assert_true Nokogiri::XML::Range.new(@doc.root, 0, @child2, 0).contain_node?(@child1)
|
38
|
+
assert_false Nokogiri::XML::Range.new(@doc.root, 0, @child1, 1).contain_node?(@child2)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_partially_contain_node?
|
42
|
+
assert_false Nokogiri::XML::Range.new(@root, 0, @child1, 0).partially_contain_node?(@child2)
|
43
|
+
assert_false Nokogiri::XML::Range.new(@child1, 0, @child2, 0).partially_contain_node?(@root)
|
44
|
+
assert_false Nokogiri::XML::Range.new(@child1, 0, @child1, 1).partially_contain_node?(@child2)
|
45
|
+
assert_true Nokogiri::XML::Range.new(@child1.children[0], 0, @child2, 0).partially_contain_node?(@child1)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_common_ancestor_container
|
49
|
+
assert_equal @parent, Nokogiri::XML::Range.new(@child1, 0, @child2.children[0], 0).common_ancestor_container
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_set_boundary_point
|
53
|
+
range1 = Nokogiri::XML::Range.new(@child1, 0, @child2, 0)
|
54
|
+
range2 = range1.dup
|
55
|
+
|
56
|
+
range1.set_start @parent, 1
|
57
|
+
assert_equal [@parent, 1], range1.start_point
|
58
|
+
|
59
|
+
range2.set_end @parent, 1
|
60
|
+
assert_equal [@parent, 1], range2.end_point
|
61
|
+
assert_equal [@parent, 1], range2.start_point
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_set_start_before
|
65
|
+
range = Nokogiri::XML::Range.new(@child2, 0, @child2, 1)
|
66
|
+
range.set_start_before(@child1)
|
67
|
+
|
68
|
+
assert_equal [@parent, 1], range.start_point
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_set_start_after
|
72
|
+
range = Nokogiri::XML::Range.new(@child2, 0, @child2, 1)
|
73
|
+
range.set_start_after(@child1)
|
74
|
+
|
75
|
+
assert_equal [@parent, 2], range.start_point
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_set_end_before
|
79
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @child2, 1)
|
80
|
+
range.set_end_before(@parent)
|
81
|
+
|
82
|
+
assert_equal [@root, 1], range.end_point
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_set_end_after
|
86
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @child2, 1)
|
87
|
+
range.set_end_after(@parent)
|
88
|
+
|
89
|
+
assert_equal [@root, 2], range.end_point
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_collapse
|
93
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @child2, 1)
|
94
|
+
range.collapse!
|
95
|
+
|
96
|
+
assert_equal [@child2, 1], range.start_point
|
97
|
+
assert_equal [@child2, 1], range.end_point
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_select_node
|
101
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @child2, 1)
|
102
|
+
range.select_node(@parent)
|
103
|
+
|
104
|
+
assert_equal [@root, 1], range.start_point
|
105
|
+
assert_equal [@root, 2], range.end_point
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_select_node_contents
|
109
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @child2, 1)
|
110
|
+
range.select_node_contents @child2
|
111
|
+
|
112
|
+
assert_equal [@child2, 0], range.start_point
|
113
|
+
assert_equal [@child2, 1], range.end_point
|
114
|
+
end
|
115
|
+
|
116
|
+
data(
|
117
|
+
{
|
118
|
+
'START_TO_START' => [-1, Nokogiri::XML::Range::START_TO_START],
|
119
|
+
'START_TO_END' => [1, Nokogiri::XML::Range::START_TO_END],
|
120
|
+
'END_TO_END' => [1, Nokogiri::XML::Range::END_TO_END],
|
121
|
+
'END_TO_START' => [-1, Nokogiri::XML::Range::END_TO_START]
|
122
|
+
}
|
123
|
+
)
|
124
|
+
def test_compare_boundary_points(data)
|
125
|
+
comparison, how = data
|
126
|
+
|
127
|
+
range1 = Nokogiri::XML::Range.new(@parent, 0, @child2, 1)
|
128
|
+
range2 = Nokogiri::XML::Range.new(@child1, 0, @parent, 3)
|
129
|
+
|
130
|
+
assert_equal comparison, range1.compare_boundary_points(how, range2)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_delete_contents_child_elements
|
134
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @parent, 4)
|
135
|
+
range.delete_contents
|
136
|
+
|
137
|
+
assert_equal Nokogiri.XML(<<EXPECTED).to_s, @doc.to_s
|
138
|
+
<root>
|
139
|
+
<parent>
|
140
|
+
<child/>
|
141
|
+
</parent>
|
142
|
+
</root>
|
143
|
+
EXPECTED
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_delete_contents_text
|
147
|
+
range = Nokogiri::XML::Range.new(@child1.children[0], 1, @child1.children[0], 5)
|
148
|
+
range.delete_contents
|
149
|
+
|
150
|
+
assert_equal Nokogiri.XML(<<EXPECTED).to_s, @doc.to_s
|
151
|
+
<root>
|
152
|
+
<parent>
|
153
|
+
<child>c 1</child>
|
154
|
+
<child>child 2</child>
|
155
|
+
</parent>
|
156
|
+
</root>
|
157
|
+
EXPECTED
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_extract_contents_child_elements
|
161
|
+
range = Nokogiri::XML::Range.new(@child1, 0, @parent, 4)
|
162
|
+
range.extract_contents
|
163
|
+
|
164
|
+
assert_equal Nokogiri.XML(<<EXPECTED).to_s, @doc.to_s
|
165
|
+
<root>
|
166
|
+
<parent>
|
167
|
+
<child/>
|
168
|
+
</parent>
|
169
|
+
</root>
|
170
|
+
EXPECTED
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_extract_contents_text
|
174
|
+
range = Nokogiri::XML::Range.new(@child1.children[0], 1, @child1.children[0], 5)
|
175
|
+
range.extract_contents
|
176
|
+
|
177
|
+
assert_equal Nokogiri.XML(<<EXPECTED).to_s, @doc.to_s
|
178
|
+
<root>
|
179
|
+
<parent>
|
180
|
+
<child>c 1</child>
|
181
|
+
<child>child 2</child>
|
182
|
+
</parent>
|
183
|
+
</root>
|
184
|
+
EXPECTED
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_extract_contents_from_elements
|
188
|
+
range = Nokogiri::XML::Range.new(@child1.child, 1, @child2.child, 5)
|
189
|
+
extracted = range.extract_contents
|
190
|
+
|
191
|
+
assert_equal Nokogiri.XML(<<REMAINED).to_s, @doc.to_s
|
192
|
+
<root>
|
193
|
+
<parent>
|
194
|
+
<child>c</child><child> 2</child>
|
195
|
+
</parent>
|
196
|
+
</root>
|
197
|
+
REMAINED
|
198
|
+
assert_equal <<EXTRACTED.chomp, extracted.to_s.chomp
|
199
|
+
<child>hild 1</child>
|
200
|
+
<child>child</child>
|
201
|
+
EXTRACTED
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_extract_contents_from_text
|
205
|
+
range = Nokogiri::XML::Range.new(@child1.child, 1, @child1.child, 5)
|
206
|
+
extracted = range.extract_contents
|
207
|
+
|
208
|
+
assert_equal Nokogiri.XML(<<REMAINED).to_s, @doc.to_s
|
209
|
+
<root>
|
210
|
+
<parent>
|
211
|
+
<child>c 1</child>
|
212
|
+
<child>child 2</child>
|
213
|
+
</parent>
|
214
|
+
</root>
|
215
|
+
REMAINED
|
216
|
+
assert_equal 'hild', extracted.to_s
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_clone_contents_from_elements
|
220
|
+
range = Nokogiri::XML::Range.new(@child1.child, 1, @child2.child, 5)
|
221
|
+
cloned = range.clone_contents
|
222
|
+
|
223
|
+
assert_equal <<CLONED.chomp, cloned.to_s.chomp
|
224
|
+
<child>hild 1</child>
|
225
|
+
<child>child</child>
|
226
|
+
CLONED
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_clone_contents_from_text
|
230
|
+
range = Nokogiri::XML::Range.new(@child1.child, 1, @child1.child, 5)
|
231
|
+
cloned = range.clone_contents
|
232
|
+
|
233
|
+
assert_equal 'hild', cloned.to_s
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_insert_node_to_element
|
237
|
+
range = Nokogiri::XML::Range.new(@parent, 1, @parent, 3)
|
238
|
+
grand_child = Nokogiri::XML::Element.new('grand-child', @doc)
|
239
|
+
range.insert_node grand_child
|
240
|
+
|
241
|
+
assert_equal Nokogiri.XML(<<EOX).to_s, @doc.to_s
|
242
|
+
<root>
|
243
|
+
<parent>
|
244
|
+
<grand-child/><child>child 1</child>
|
245
|
+
<child>child 2</child>
|
246
|
+
</parent>
|
247
|
+
</root>
|
248
|
+
EOX
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_insert_node_to_text
|
252
|
+
range = Nokogiri::XML::Range.new(@child1.child, 5, @child1.child, 8)
|
253
|
+
text = Nokogiri::XML::Text.new('inserted', @doc)
|
254
|
+
range.insert_node text
|
255
|
+
|
256
|
+
assert_equal Nokogiri.XML(<<EOX).to_s, @doc.to_s
|
257
|
+
<root>
|
258
|
+
<parent>
|
259
|
+
<child>childinserted 1</child>
|
260
|
+
<child>child 2</child>
|
261
|
+
</parent>
|
262
|
+
</root>
|
263
|
+
EOX
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_surround_contents
|
267
|
+
range = Nokogiri::XML::Range.new(@child1.child, 6, @child1.child, 7)
|
268
|
+
number = Nokogiri::XML::Element.new('number', @doc)
|
269
|
+
range.surround_contents number
|
270
|
+
|
271
|
+
assert_equal Nokogiri.XML(<<EOX).to_s, @doc.to_s
|
272
|
+
<root>
|
273
|
+
<parent>
|
274
|
+
<child>child <number>1</number></child>
|
275
|
+
<child>child 2</child>
|
276
|
+
</parent>
|
277
|
+
</root>
|
278
|
+
EOX
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_point_in_range?
|
282
|
+
range = Nokogiri::XML::Range.new(@child1.child, 2, @parent, 4)
|
283
|
+
|
284
|
+
assert_true range.point_in_range? @child2, 0
|
285
|
+
assert_true range.point_in_range? @child1.child, 3
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_compare_point
|
289
|
+
range = Nokogiri::XML::Range.new(@child1.child, 2, @parent, 4)
|
290
|
+
|
291
|
+
assert_equal -1, range.compare_point(@parent, 0)
|
292
|
+
assert_equal 0, range.compare_point(@child2, 0)
|
293
|
+
assert_equal 1, range.compare_point(@root, 2)
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_intersect_node?
|
297
|
+
range = Nokogiri::XML::Range.new(@child1.child, 2, @parent, 4)
|
298
|
+
|
299
|
+
assert_true range.intersect_node? @child1.child
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_to_s
|
303
|
+
assert_equal 'hild', Nokogiri::XML::Range.new(@child1.child, 1, @child1.child, 5).to_s
|
304
|
+
assert_equal <<EOS.chomp, Nokogiri::XML::Range.new(@root, 0, @root, 2).to_s
|
305
|
+
|
306
|
+
|
307
|
+
child 1
|
308
|
+
child 2
|
309
|
+
|
310
|
+
EOS
|
311
|
+
assert_equal <<EOS.chomp, Nokogiri::XML::Range.new(@parent, 1, @child2.child, 5).to_s
|
312
|
+
child 1
|
313
|
+
child
|
314
|
+
EOS
|
315
|
+
end
|
316
|
+
end
|