nokogiri 1.1.1-java

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.

Files changed (142) hide show
  1. data/History.ja.txt +99 -0
  2. data/History.txt +99 -0
  3. data/Manifest.txt +141 -0
  4. data/README.ja.txt +100 -0
  5. data/README.txt +109 -0
  6. data/Rakefile +354 -0
  7. data/ext/nokogiri/extconf.rb +93 -0
  8. data/ext/nokogiri/html_document.c +86 -0
  9. data/ext/nokogiri/html_document.h +10 -0
  10. data/ext/nokogiri/html_sax_parser.c +36 -0
  11. data/ext/nokogiri/html_sax_parser.h +11 -0
  12. data/ext/nokogiri/native.c +41 -0
  13. data/ext/nokogiri/native.h +50 -0
  14. data/ext/nokogiri/xml_cdata.c +44 -0
  15. data/ext/nokogiri/xml_cdata.h +9 -0
  16. data/ext/nokogiri/xml_comment.c +42 -0
  17. data/ext/nokogiri/xml_comment.h +9 -0
  18. data/ext/nokogiri/xml_document.c +206 -0
  19. data/ext/nokogiri/xml_document.h +10 -0
  20. data/ext/nokogiri/xml_dtd.c +121 -0
  21. data/ext/nokogiri/xml_dtd.h +8 -0
  22. data/ext/nokogiri/xml_io.c +17 -0
  23. data/ext/nokogiri/xml_io.h +9 -0
  24. data/ext/nokogiri/xml_node.c +727 -0
  25. data/ext/nokogiri/xml_node.h +13 -0
  26. data/ext/nokogiri/xml_node_set.c +118 -0
  27. data/ext/nokogiri/xml_node_set.h +9 -0
  28. data/ext/nokogiri/xml_reader.c +465 -0
  29. data/ext/nokogiri/xml_reader.h +10 -0
  30. data/ext/nokogiri/xml_sax_parser.c +201 -0
  31. data/ext/nokogiri/xml_sax_parser.h +10 -0
  32. data/ext/nokogiri/xml_syntax_error.c +199 -0
  33. data/ext/nokogiri/xml_syntax_error.h +11 -0
  34. data/ext/nokogiri/xml_text.c +40 -0
  35. data/ext/nokogiri/xml_text.h +9 -0
  36. data/ext/nokogiri/xml_xpath.c +53 -0
  37. data/ext/nokogiri/xml_xpath.h +11 -0
  38. data/ext/nokogiri/xml_xpath_context.c +214 -0
  39. data/ext/nokogiri/xml_xpath_context.h +9 -0
  40. data/ext/nokogiri/xslt_stylesheet.c +123 -0
  41. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  42. data/lib/action-nokogiri.rb +30 -0
  43. data/lib/nokogiri.rb +72 -0
  44. data/lib/nokogiri/css.rb +25 -0
  45. data/lib/nokogiri/css/generated_parser.rb +721 -0
  46. data/lib/nokogiri/css/generated_tokenizer.rb +159 -0
  47. data/lib/nokogiri/css/node.rb +97 -0
  48. data/lib/nokogiri/css/parser.rb +64 -0
  49. data/lib/nokogiri/css/parser.y +216 -0
  50. data/lib/nokogiri/css/syntax_error.rb +6 -0
  51. data/lib/nokogiri/css/tokenizer.rb +9 -0
  52. data/lib/nokogiri/css/tokenizer.rex +63 -0
  53. data/lib/nokogiri/css/xpath_visitor.rb +168 -0
  54. data/lib/nokogiri/decorators.rb +2 -0
  55. data/lib/nokogiri/decorators/hpricot.rb +3 -0
  56. data/lib/nokogiri/decorators/hpricot/node.rb +56 -0
  57. data/lib/nokogiri/decorators/hpricot/node_set.rb +54 -0
  58. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +28 -0
  59. data/lib/nokogiri/decorators/slop.rb +31 -0
  60. data/lib/nokogiri/hpricot.rb +51 -0
  61. data/lib/nokogiri/html.rb +105 -0
  62. data/lib/nokogiri/html/builder.rb +9 -0
  63. data/lib/nokogiri/html/document.rb +9 -0
  64. data/lib/nokogiri/html/sax/parser.rb +21 -0
  65. data/lib/nokogiri/version.rb +3 -0
  66. data/lib/nokogiri/xml.rb +83 -0
  67. data/lib/nokogiri/xml/after_handler.rb +18 -0
  68. data/lib/nokogiri/xml/attr.rb +10 -0
  69. data/lib/nokogiri/xml/before_handler.rb +33 -0
  70. data/lib/nokogiri/xml/builder.rb +84 -0
  71. data/lib/nokogiri/xml/cdata.rb +9 -0
  72. data/lib/nokogiri/xml/comment.rb +6 -0
  73. data/lib/nokogiri/xml/document.rb +55 -0
  74. data/lib/nokogiri/xml/dtd.rb +6 -0
  75. data/lib/nokogiri/xml/element.rb +6 -0
  76. data/lib/nokogiri/xml/entity_declaration.rb +9 -0
  77. data/lib/nokogiri/xml/node.rb +333 -0
  78. data/lib/nokogiri/xml/node_set.rb +197 -0
  79. data/lib/nokogiri/xml/notation.rb +6 -0
  80. data/lib/nokogiri/xml/reader.rb +20 -0
  81. data/lib/nokogiri/xml/sax.rb +9 -0
  82. data/lib/nokogiri/xml/sax/document.rb +59 -0
  83. data/lib/nokogiri/xml/sax/parser.rb +37 -0
  84. data/lib/nokogiri/xml/syntax_error.rb +21 -0
  85. data/lib/nokogiri/xml/text.rb +6 -0
  86. data/lib/nokogiri/xml/xpath.rb +10 -0
  87. data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
  88. data/lib/nokogiri/xml/xpath_context.rb +14 -0
  89. data/lib/nokogiri/xslt.rb +28 -0
  90. data/lib/nokogiri/xslt/stylesheet.rb +6 -0
  91. data/test/css/test_nthiness.rb +159 -0
  92. data/test/css/test_parser.rb +237 -0
  93. data/test/css/test_tokenizer.rb +162 -0
  94. data/test/css/test_xpath_visitor.rb +64 -0
  95. data/test/files/dont_hurt_em_why.xml +422 -0
  96. data/test/files/exslt.xml +8 -0
  97. data/test/files/exslt.xslt +35 -0
  98. data/test/files/staff.xml +59 -0
  99. data/test/files/staff.xslt +32 -0
  100. data/test/files/tlm.html +850 -0
  101. data/test/helper.rb +78 -0
  102. data/test/hpricot/files/basic.xhtml +17 -0
  103. data/test/hpricot/files/boingboing.html +2266 -0
  104. data/test/hpricot/files/cy0.html +3653 -0
  105. data/test/hpricot/files/immob.html +400 -0
  106. data/test/hpricot/files/pace_application.html +1320 -0
  107. data/test/hpricot/files/tenderlove.html +16 -0
  108. data/test/hpricot/files/uswebgen.html +220 -0
  109. data/test/hpricot/files/utf8.html +1054 -0
  110. data/test/hpricot/files/week9.html +1723 -0
  111. data/test/hpricot/files/why.xml +19 -0
  112. data/test/hpricot/load_files.rb +11 -0
  113. data/test/hpricot/test_alter.rb +67 -0
  114. data/test/hpricot/test_builder.rb +27 -0
  115. data/test/hpricot/test_parser.rb +426 -0
  116. data/test/hpricot/test_paths.rb +15 -0
  117. data/test/hpricot/test_preserved.rb +77 -0
  118. data/test/hpricot/test_xml.rb +30 -0
  119. data/test/html/sax/test_parser.rb +27 -0
  120. data/test/html/test_builder.rb +89 -0
  121. data/test/html/test_document.rb +150 -0
  122. data/test/html/test_node.rb +21 -0
  123. data/test/test_convert_xpath.rb +185 -0
  124. data/test/test_css_cache.rb +57 -0
  125. data/test/test_gc.rb +15 -0
  126. data/test/test_memory_leak.rb +38 -0
  127. data/test/test_nokogiri.rb +97 -0
  128. data/test/test_reader.rb +222 -0
  129. data/test/test_xslt_transforms.rb +93 -0
  130. data/test/xml/sax/test_parser.rb +95 -0
  131. data/test/xml/test_attr.rb +15 -0
  132. data/test/xml/test_builder.rb +16 -0
  133. data/test/xml/test_cdata.rb +18 -0
  134. data/test/xml/test_comment.rb +16 -0
  135. data/test/xml/test_document.rb +195 -0
  136. data/test/xml/test_dtd.rb +43 -0
  137. data/test/xml/test_node.rb +394 -0
  138. data/test/xml/test_node_set.rb +143 -0
  139. data/test/xml/test_text.rb +13 -0
  140. data/test/xml/test_xpath.rb +105 -0
  141. data/vendor/hoe.rb +1020 -0
  142. metadata +233 -0
@@ -0,0 +1,95 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ module SAX
6
+ class TestParser < Nokogiri::SAX::TestCase
7
+ def setup
8
+ @parser = XML::SAX::Parser.new(Doc.new)
9
+ end
10
+
11
+ def test_parse
12
+ File.open(XML_FILE, 'rb') { |f|
13
+ @parser.parse(f)
14
+ }
15
+ @parser.parse(File.read(XML_FILE))
16
+ assert(@parser.document.cdata_blocks.length > 0)
17
+ end
18
+
19
+ def test_parse_io
20
+ File.open(XML_FILE, 'rb') { |f|
21
+ @parser.parse_io(f)
22
+ }
23
+ assert(@parser.document.cdata_blocks.length > 0)
24
+ end
25
+
26
+ def test_parse_file
27
+ @parser.parse_file(XML_FILE)
28
+ assert_raises(Errno::ENOENT) {
29
+ @parser.parse_file('')
30
+ }
31
+ assert_raises(Errno::EISDIR) {
32
+ @parser.parse_file(File.expand_path(File.dirname(__FILE__)))
33
+ }
34
+ end
35
+
36
+ def test_ctag
37
+ @parser.parse_memory(<<-eoxml)
38
+ <p id="asdfasdf">
39
+ <![CDATA[ This is a comment ]]>
40
+ Paragraph 1
41
+ </p>
42
+ eoxml
43
+ assert_equal [' This is a comment '], @parser.document.cdata_blocks
44
+ end
45
+
46
+ def test_comment
47
+ @parser.parse_memory(<<-eoxml)
48
+ <p id="asdfasdf">
49
+ <!-- This is a comment -->
50
+ Paragraph 1
51
+ </p>
52
+ eoxml
53
+ assert_equal [' This is a comment '], @parser.document.comments
54
+ end
55
+
56
+ def test_characters
57
+ @parser.parse_memory(<<-eoxml)
58
+ <p id="asdfasdf">Paragraph 1</p>
59
+ eoxml
60
+ assert_equal ['Paragraph 1'], @parser.document.data
61
+ end
62
+
63
+ def test_end_document
64
+ @parser.parse_memory(<<-eoxml)
65
+ <p id="asdfasdf">Paragraph 1</p>
66
+ eoxml
67
+ assert @parser.document.end_document_called
68
+ end
69
+
70
+ def test_end_element
71
+ @parser.parse_memory(<<-eoxml)
72
+ <p id="asdfasdf">Paragraph 1</p>
73
+ eoxml
74
+ assert_equal [["p"]],
75
+ @parser.document.end_elements
76
+ end
77
+
78
+ def test_start_element_attrs
79
+ @parser.parse_memory(<<-eoxml)
80
+ <p id="asdfasdf">Paragraph 1</p>
81
+ eoxml
82
+ assert_equal [["p", ["id", "asdfasdf"]]],
83
+ @parser.document.start_elements
84
+ end
85
+
86
+ def test_parse_document
87
+ @parser.parse_memory(<<-eoxml)
88
+ <p>Paragraph 1</p>
89
+ <p>Paragraph 2</p>
90
+ eoxml
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestAttr < Nokogiri::TestCase
6
+ def test_unlink
7
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
+ address = xml.xpath('/staff/employee/address').first
9
+ assert_equal 'Yes', address['domestic']
10
+ address.attribute_nodes.first.unlink
11
+ assert_nil address['domestic']
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestBuilder < Nokogiri::TestCase
6
+ def test_cdata
7
+ builder = Nokogiri::XML::Builder.new do
8
+ root {
9
+ cdata "hello world"
10
+ }
11
+ end
12
+ assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>", builder.to_xml.gsub(/\n/, ''))
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestCDATA < Nokogiri::TestCase
6
+ def setup
7
+ @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
+ end
9
+
10
+ def test_cdata_node
11
+ name = @xml.xpath('//employee[2]/name').first
12
+ assert cdata = name.children[1]
13
+ assert cdata.cdata?
14
+ assert_equal 'cdata-section', cdata.name
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestComment < Nokogiri::TestCase
6
+ def setup
7
+ @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
+ end
9
+
10
+ def test_new
11
+ comment = Nokogiri::XML::Comment.new(@xml, 'hello world')
12
+ assert_equal('<!--hello world-->', comment.to_s)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,195 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestDocument < Nokogiri::TestCase
6
+ def setup
7
+ @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
+ end
9
+
10
+ def test_XML_function
11
+ xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
12
+ assert xml.xml?
13
+ end
14
+
15
+ def test_document_parent
16
+ xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
17
+ assert_raises(NoMethodError) {
18
+ xml.parent
19
+ }
20
+ end
21
+
22
+ def test_document_name
23
+ xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
24
+ assert_equal 'document', xml.name
25
+ end
26
+
27
+ def test_parse_can_take_io
28
+ xml = nil
29
+ File.open(XML_FILE, 'rb') { |f|
30
+ xml = Nokogiri::XML(f)
31
+ }
32
+ assert xml.xml?
33
+ set = xml.search('//employee')
34
+ assert set.length > 0
35
+ end
36
+
37
+ def test_search_on_empty_documents
38
+ doc = Nokogiri::XML::Document.new
39
+ ns = doc.search('//foo')
40
+ assert_equal 0, ns.length
41
+ end
42
+
43
+ def test_bad_xpath_raises_syntax_error
44
+ assert_raises(XML::XPath::SyntaxError) {
45
+ @xml.xpath('\\')
46
+ }
47
+ end
48
+
49
+ def test_new_document_collect_namespaces
50
+ doc = Nokogiri::XML::Document.new
51
+ assert_equal({}, doc.collect_namespaces)
52
+ end
53
+
54
+ def test_find_with_namespace
55
+ doc = Nokogiri::XML.parse(<<-eoxml)
56
+ <x xmlns:tenderlove='http://tenderlovemaking.com/'>
57
+ <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
58
+ </x>
59
+ eoxml
60
+
61
+ ctx = Nokogiri::XML::XPathContext.new(doc)
62
+ ctx.register_ns 'tenderlove', 'http://tenderlovemaking.com/'
63
+ set = ctx.evaluate('//tenderlove:foo').node_set
64
+ assert_equal 1, set.length
65
+ assert_equal 'foo', set.first.name
66
+
67
+ # It looks like only the URI is important:
68
+ ctx = Nokogiri::XML::XPathContext.new(doc)
69
+ ctx.register_ns 'america', 'http://tenderlovemaking.com/'
70
+ set = ctx.evaluate('//america:foo').node_set
71
+ assert_equal 1, set.length
72
+ assert_equal 'foo', set.first.name
73
+
74
+ # Its so important that a missing slash will cause it to return nothing
75
+ ctx = Nokogiri::XML::XPathContext.new(doc)
76
+ ctx.register_ns 'america', 'http://tenderlovemaking.com'
77
+ set = ctx.evaluate('//america:foo').node_set
78
+ assert_equal 0, set.length
79
+ end
80
+
81
+ def test_xml?
82
+ assert @xml.xml?
83
+ end
84
+
85
+ def test_document
86
+ assert @xml.document
87
+ end
88
+
89
+ def test_singleton_methods
90
+ assert node_set = @xml.search('//name')
91
+ assert node_set.length > 0
92
+ node = node_set.first
93
+ def node.test
94
+ 'test'
95
+ end
96
+ assert node_set = @xml.search('//name')
97
+ assert_equal 'test', node_set.first.test
98
+ end
99
+
100
+ def test_multiple_search
101
+ assert node_set = @xml.search('//employee', '//name')
102
+ employees = @xml.search('//employee')
103
+ names = @xml.search('//name')
104
+ assert_equal(employees.length + names.length, node_set.length)
105
+ end
106
+
107
+ def test_node_set_index
108
+ assert node_set = @xml.search('//employee')
109
+
110
+ assert_equal(5, node_set.length)
111
+ assert node_set[4]
112
+ assert_nil node_set[5]
113
+ end
114
+
115
+ def test_search
116
+ assert node_set = @xml.search('//employee')
117
+
118
+ assert_equal(5, node_set.length)
119
+
120
+ node_set.each do |node|
121
+ assert_equal('employee', node.name)
122
+ end
123
+ end
124
+
125
+ def test_dump
126
+ assert @xml.serialize
127
+ assert @xml.to_xml
128
+ end
129
+
130
+ def test_subset_is_decorated
131
+ x = Module.new do
132
+ def awesome!
133
+ end
134
+ end
135
+ util_decorate(@xml, x)
136
+
137
+ assert @xml.respond_to?(:awesome!)
138
+ assert node_set = @xml.search('//staff')
139
+ assert node_set.respond_to?(:awesome!)
140
+ assert subset = node_set.search('.//employee')
141
+ assert subset.respond_to?(:awesome!)
142
+ assert sub_subset = node_set.search('.//name')
143
+ assert sub_subset.respond_to?(:awesome!)
144
+ end
145
+
146
+ def test_decorator_is_applied
147
+ x = Module.new do
148
+ def awesome!
149
+ end
150
+ end
151
+ util_decorate(@xml, x)
152
+
153
+ assert @xml.respond_to?(:awesome!)
154
+ assert node_set = @xml.search('//employee')
155
+ assert node_set.respond_to?(:awesome!)
156
+ node_set.each do |node|
157
+ assert node.respond_to?(:awesome!), node.class
158
+ end
159
+ assert @xml.root.respond_to?(:awesome!)
160
+ end
161
+
162
+ def test_new
163
+ doc = nil
164
+ assert_nothing_raised {
165
+ doc = Nokogiri::XML::Document.new
166
+ }
167
+ assert doc
168
+ assert doc.xml?
169
+ assert_nil doc.root
170
+ end
171
+
172
+ def test_set_root
173
+ doc = nil
174
+ assert_nothing_raised {
175
+ doc = Nokogiri::XML::Document.new
176
+ }
177
+ assert doc
178
+ assert doc.xml?
179
+ assert_nil doc.root
180
+ node = Nokogiri::XML::Node.new("b", doc) { |n|
181
+ n.content = 'hello world'
182
+ }
183
+ assert_equal('hello world', node.content)
184
+ doc.root = node
185
+ assert_equal(node, doc.root)
186
+ end
187
+
188
+ def util_decorate(document, x)
189
+ document.decorators(XML::Node) << x
190
+ document.decorators(XML::NodeSet) << x
191
+ document.decorate!
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module HTML
5
+ class TestDTD < Nokogiri::TestCase
6
+ def setup
7
+ @xml = Nokogiri::XML.parse(File.read(XML_FILE))
8
+ assert @dtd = @xml.internal_subset
9
+ end
10
+
11
+ def test_external_subsets
12
+ assert subset = @xml.internal_subset
13
+ assert_equal 'staff', subset.name
14
+ end
15
+
16
+ def test_entities
17
+ assert entities = @dtd.entities
18
+ assert_equal %w[ ent1 ent2 ent3 ent4 ent5 ].sort, entities.keys.sort
19
+ end
20
+
21
+ def test_attributes
22
+ assert attributes = @dtd.attributes
23
+ assert_equal %w[ width ], attributes.keys
24
+ assert_equal 'width', attributes['width'].name
25
+ end
26
+
27
+ def test_elements
28
+ assert elements = @dtd.elements
29
+ assert_equal %w[ br ], elements.keys
30
+ assert_equal 'br', elements['br'].name
31
+ end
32
+
33
+ def test_notations
34
+ assert notations = @dtd.notations
35
+ assert_equal %w[ notation1 notation2 ].sort, notations.keys.sort
36
+ assert notation1 = notations['notation1']
37
+ assert_equal 'notation1', notation1.name
38
+ assert_equal 'notation1File', notation1.public_id
39
+ assert_nil notation1.system_id
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,394 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestNode < Nokogiri::TestCase
6
+ def test_ancestors
7
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
+ address = xml.xpath('//address').first
9
+ assert_equal 3, address.ancestors.length
10
+ assert_equal ['employee', 'staff', nil],
11
+ address.ancestors.map { |x| x.name }
12
+ end
13
+
14
+ def test_read_only?
15
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
16
+ assert entity_decl = xml.internal_subset.children.find { |x|
17
+ x.type == Node::ENTITY_DECL
18
+ }
19
+ assert entity_decl.read_only?
20
+ end
21
+
22
+ def test_remove_attribute
23
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
24
+ address = xml.xpath('/staff/employee/address').first
25
+ assert_equal 'Yes', address['domestic']
26
+ address.remove_attribute 'domestic'
27
+ assert_nil address['domestic']
28
+ end
29
+
30
+ def test_delete
31
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
32
+ address = xml.xpath('/staff/employee/address').first
33
+ assert_equal 'Yes', address['domestic']
34
+ address.delete 'domestic'
35
+ assert_nil address['domestic']
36
+ end
37
+
38
+ def test_angry_add_child
39
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
40
+ child = xml.css('employee').first
41
+
42
+ assert new_child = child.children.first
43
+
44
+ last = child.children.last
45
+
46
+ # Magic! Don't try this at home folks
47
+ child.add_child(new_child)
48
+ assert_equal new_child, child.children.last
49
+ assert_equal last, child.children.last
50
+ end
51
+
52
+ def test_add_child
53
+ xml = Nokogiri::XML(<<-eoxml)
54
+ <root>
55
+ <a>Hello world</a>
56
+ </root>
57
+ eoxml
58
+ text_node = Nokogiri::XML::Text.new('hello', xml)
59
+ assert_equal Nokogiri::XML::Node::TEXT_NODE, text_node.type
60
+ xml.root.add_child text_node
61
+ assert_match 'hello', xml.to_s
62
+ end
63
+
64
+ def test_chevron_works_as_add_child
65
+ xml = Nokogiri::XML(<<-eoxml)
66
+ <root>
67
+ <a>Hello world</a>
68
+ </root>
69
+ eoxml
70
+ text_node = Nokogiri::XML::Text.new('hello', xml)
71
+ xml.root << text_node
72
+ assert_match 'hello', xml.to_s
73
+ end
74
+
75
+ def test_add_previous_sibling
76
+ xml = Nokogiri::XML(<<-eoxml)
77
+ <root>
78
+ <a>Hello world</a>
79
+ </root>
80
+ eoxml
81
+ b_node = Nokogiri::XML::Node.new('a', xml)
82
+ assert_equal Nokogiri::XML::Node::ELEMENT_NODE, b_node.type
83
+ b_node.content = 'first'
84
+ a_node = xml.xpath('//a').first
85
+ a_node.add_previous_sibling(b_node)
86
+ assert_equal('first', xml.xpath('//a').first.text)
87
+ end
88
+
89
+ def test_add_previous_sibling_merge
90
+ xml = Nokogiri::XML(<<-eoxml)
91
+ <root>
92
+ <a>Hello world</a>
93
+ </root>
94
+ eoxml
95
+
96
+ assert a_tag = xml.css('a').first
97
+
98
+ left_space = a_tag.previous
99
+ right_space = a_tag.next
100
+ assert left_space.text?
101
+ assert right_space.text?
102
+
103
+ left_space.add_previous_sibling(right_space)
104
+ assert_equal left_space, right_space
105
+ end
106
+
107
+ def test_add_next_sibling_merge
108
+ xml = Nokogiri::XML(<<-eoxml)
109
+ <root>
110
+ <a>Hello world</a>
111
+ </root>
112
+ eoxml
113
+
114
+ assert a_tag = xml.css('a').first
115
+
116
+ left_space = a_tag.previous
117
+ right_space = a_tag.next
118
+ assert left_space.text?
119
+ assert right_space.text?
120
+
121
+ right_space.add_next_sibling(left_space)
122
+ assert_equal left_space, right_space
123
+ end
124
+
125
+ def test_find_by_css_with_tilde_eql
126
+ xml = Nokogiri::XML.parse(<<-eoxml)
127
+ <root>
128
+ <a>Hello world</a>
129
+ <a class='foo bar'>Bar</a>
130
+ <a class='bar foo'>Bar</a>
131
+ <a class='bar'>Bar</a>
132
+ <a class='baz bar foo'>Bar</a>
133
+ <a class='bazbarfoo'>Awesome</a>
134
+ <a class='bazbar'>Awesome</a>
135
+ </root>
136
+ eoxml
137
+ set = xml.css('a[@class~="bar"]')
138
+ assert_equal 4, set.length
139
+ assert_equal ['Bar'], set.map { |node| node.content }.uniq
140
+ end
141
+
142
+ def test_unlink
143
+ xml = Nokogiri::XML.parse(<<-eoxml)
144
+ <root>
145
+ <a class='foo bar'>Bar</a>
146
+ <a class='bar foo'>Bar</a>
147
+ <a class='bar'>Bar</a>
148
+ <a>Hello world</a>
149
+ <a class='baz bar foo'>Bar</a>
150
+ <a class='bazbarfoo'>Awesome</a>
151
+ <a class='bazbar'>Awesome</a>
152
+ </root>
153
+ eoxml
154
+ node = xml.xpath('//a')[3]
155
+ assert_equal('Hello world', node.text)
156
+ assert_match(/Hello world/, xml.to_s)
157
+ assert node.parent
158
+ assert node.document
159
+ assert node.previous_sibling
160
+ assert node.next_sibling
161
+ node.unlink
162
+ assert !node.parent
163
+ # assert !node.document # ugh. libxml doesn't clear node->doc pointer, due to xmlDict implementation.
164
+ assert !node.previous_sibling
165
+ assert !node.next_sibling
166
+ assert_no_match(/Hello world/, xml.to_s)
167
+ end
168
+
169
+ def test_dup_shallow
170
+ html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
171
+ found = html.search('//div/a').first
172
+ dup = found.dup(0)
173
+ assert dup
174
+ assert_equal '', dup.content
175
+ end
176
+
177
+ def test_dup
178
+ html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
179
+ found = html.search('//div/a').first
180
+ dup = found.dup
181
+ assert dup
182
+ assert_equal found.content, dup.content
183
+ end
184
+
185
+ def test_search_can_handle_xpath_and_css
186
+ html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
187
+ found = html.search('//div/a', 'div > p')
188
+ length = html.xpath('//div/a').length +
189
+ html.css('div > p').length
190
+ assert_equal length, found.length
191
+ end
192
+
193
+ def test_find_by_xpath
194
+ html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
195
+ found = html.xpath('//div/a')
196
+ assert_equal 3, found.length
197
+ end
198
+
199
+ def test_find_by_css
200
+ html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
201
+ found = html.css('div > a')
202
+ assert_equal 3, found.length
203
+ end
204
+
205
+ def test_next_sibling
206
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
207
+ assert node = xml.root
208
+ assert sibling = node.child.next_sibling
209
+ assert_equal('employee', sibling.name)
210
+ end
211
+
212
+ def test_previous_sibling
213
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
214
+ assert node = xml.root
215
+ assert sibling = node.child.next_sibling
216
+ assert_equal('employee', sibling.name)
217
+ assert_equal(sibling.previous_sibling, node.child)
218
+ end
219
+
220
+ def test_name=
221
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
222
+ assert node = xml.root
223
+ node.name = 'awesome'
224
+ assert_equal('awesome', node.name)
225
+ end
226
+
227
+ def test_child
228
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
229
+ assert node = xml.root
230
+ assert child = node.child
231
+ assert_equal('text', child.name)
232
+ end
233
+
234
+ def test_key?
235
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
236
+ assert node = xml.search('//address').first
237
+ assert(!node.key?('asdfasdf'))
238
+ end
239
+
240
+ def test_set_property
241
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
242
+ assert node = xml.search('//address').first
243
+ node['foo'] = 'bar'
244
+ assert_equal('bar', node['foo'])
245
+ end
246
+
247
+ def test_attributes
248
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
249
+ assert node = xml.search('//address').first
250
+ assert_nil(node['asdfasdfasdf'])
251
+ assert_equal('Yes', node['domestic'])
252
+
253
+ assert node = xml.search('//address')[2]
254
+ attr = node.attributes
255
+ assert_equal 2, attr.size
256
+ assert_equal 'Yes', attr['domestic'].value
257
+ assert_equal 'Yes', attr['domestic'].to_s
258
+ assert_equal 'No', attr['street'].value
259
+ end
260
+
261
+ def test_path
262
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
263
+ assert set = xml.search('//employee')
264
+ assert node = set.first
265
+ assert_equal('/staff/employee[1]', node.path)
266
+ end
267
+
268
+ def test_search_by_symbol
269
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
270
+ assert set = xml.search(:employee)
271
+ assert 5, set.length
272
+
273
+ assert node = xml.at(:employee)
274
+ assert node.text =~ /EMP0001/
275
+ end
276
+
277
+ def test_new_node
278
+ xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
279
+ node = Nokogiri::XML::Node.new('form', xml)
280
+ assert_equal('form', node.name)
281
+ assert(node.document)
282
+ end
283
+
284
+ def test_content
285
+ xml = Nokogiri::XML.parse(File.read(XML_FILE))
286
+ node = Nokogiri::XML::Node.new('form', xml)
287
+ assert_equal('', node.content)
288
+
289
+ node.content = 'hello world!'
290
+ assert_equal('hello world!', node.content)
291
+ end
292
+
293
+ def test_whitespace_nodes
294
+ doc = Nokogiri::XML.parse("<root><b>Foo</b>\n<i>Bar</i> <p>Bazz</p></root>")
295
+ children = doc.at('//root').children.collect{|j| j.to_s}
296
+ assert_equal "\n", children[1]
297
+ assert_equal " ", children[3]
298
+ end
299
+
300
+ def test_replace
301
+ xml = Nokogiri::XML.parse(File.read(XML_FILE))
302
+ set = xml.search('//employee')
303
+ assert 5, set.length
304
+ assert 0, xml.search('//form').length
305
+
306
+ first = set[0]
307
+ second = set[1]
308
+
309
+ node = Nokogiri::XML::Node.new('form', xml)
310
+ first.replace(node)
311
+
312
+ assert set = xml.search('//employee')
313
+ assert_equal 4, set.length
314
+ assert 1, xml.search('//form').length
315
+
316
+ assert_equal set[0].to_xml, second.to_xml
317
+ assert_equal set[0].to_xml(5), second.to_xml(5)
318
+ assert_not_equal set[0].to_xml, set[0].to_xml(5)
319
+ end
320
+
321
+ def test_illegal_replace_of_node_with_doc
322
+ xml = Nokogiri::XML.parse(File.read(XML_FILE))
323
+ new_node = Nokogiri::XML.parse('<foo>bar</foo>')
324
+ old_node = xml.at('//employee')
325
+ assert_raises(ArgumentError){ old_node.replace new_node }
326
+ end
327
+
328
+ def test_namespace_as_hash
329
+ xml = Nokogiri::XML.parse(<<-eoxml)
330
+ <root>
331
+ <car xmlns:part="http://general-motors.com/">
332
+ <part:tire>Michelin Model XGV</part:tire>
333
+ </car>
334
+ <bicycle xmlns:part="http://schwinn.com/">
335
+ <part:tire>I'm a bicycle tire!</part:tire>
336
+ </bicycle>
337
+ </root>
338
+ eoxml
339
+
340
+ tires = xml.xpath('//bike:tire', {'bike' => 'http://schwinn.com/'})
341
+ assert_equal 1, tires.length
342
+ end
343
+
344
+ def test_namespaces
345
+ xml = Nokogiri::XML.parse(<<-EOF)
346
+ <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
347
+ <y xmlns:c='http://bazz.com/'>
348
+ <a:div>hello a</a:div>
349
+ <b:div>hello b</b:div>
350
+ <c:div>hello c</c:div>
351
+ </y>
352
+ </x>
353
+ EOF
354
+ assert namespaces = xml.root.namespaces
355
+ assert namespaces.key?('xmlns:a')
356
+ assert_equal 'http://foo.com/', namespaces['xmlns:a']
357
+ assert namespaces.key?('xmlns:b')
358
+ assert_equal 'http://bar.com/', namespaces['xmlns:b']
359
+ assert ! namespaces.key?('xmlns:c')
360
+
361
+ assert namespaces = xml.namespaces
362
+ assert namespaces.key?('xmlns:a')
363
+ assert_equal 'http://foo.com/', namespaces['xmlns:a']
364
+ assert namespaces.key?('xmlns:b')
365
+ assert_equal 'http://bar.com/', namespaces['xmlns:b']
366
+ assert namespaces.key?('xmlns:c')
367
+ assert_equal 'http://bazz.com/', namespaces['xmlns:c']
368
+
369
+ assert_equal "hello a", xml.search("//a:div", xml.namespaces).first.inner_text
370
+ assert_equal "hello b", xml.search("//b:div", xml.namespaces).first.inner_text
371
+ assert_equal "hello c", xml.search("//c:div", xml.namespaces).first.inner_text
372
+ end
373
+
374
+ def test_namespace
375
+ xml = Nokogiri::XML.parse(<<-EOF)
376
+ <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
377
+ <y xmlns:c='http://bazz.com/'>
378
+ <a:div>hello a</a:div>
379
+ <b:div>hello b</b:div>
380
+ <c:div>hello c</c:div>
381
+ <div>hello moon</div>
382
+ </y>
383
+ </x>
384
+ EOF
385
+ set = xml.search("//y/*")
386
+ assert_equal "a", set[0].namespace
387
+ assert_equal "b", set[1].namespace
388
+ assert_equal "c", set[2].namespace
389
+ assert_equal nil, set[3].namespace
390
+ end
391
+
392
+ end
393
+ end
394
+ end