nokogiri 1.2.3 → 1.3.0

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 (200) hide show
  1. data/.autotest +14 -2
  2. data/CHANGELOG.ja.rdoc +38 -0
  3. data/CHANGELOG.rdoc +43 -0
  4. data/Manifest.txt +80 -5
  5. data/README.ja.rdoc +12 -11
  6. data/README.rdoc +4 -2
  7. data/Rakefile +103 -173
  8. data/bin/nokogiri +47 -0
  9. data/ext/nokogiri/extconf.rb +19 -13
  10. data/ext/nokogiri/html_document.c +39 -3
  11. data/ext/nokogiri/html_document.h +1 -1
  12. data/ext/nokogiri/html_element_description.c +272 -0
  13. data/ext/nokogiri/html_element_description.h +10 -0
  14. data/ext/nokogiri/html_entity_lookup.h +1 -1
  15. data/ext/nokogiri/html_sax_parser.h +1 -1
  16. data/ext/nokogiri/{native.c → nokogiri.c} +11 -3
  17. data/ext/nokogiri/{native.h → nokogiri.h} +18 -4
  18. data/ext/nokogiri/xml_attr.c +14 -5
  19. data/ext/nokogiri/xml_attr.h +1 -1
  20. data/ext/nokogiri/xml_cdata.c +15 -6
  21. data/ext/nokogiri/xml_cdata.h +1 -1
  22. data/ext/nokogiri/xml_comment.c +13 -4
  23. data/ext/nokogiri/xml_comment.h +1 -1
  24. data/ext/nokogiri/xml_document.c +50 -41
  25. data/ext/nokogiri/xml_document.h +1 -1
  26. data/ext/nokogiri/xml_document_fragment.c +12 -4
  27. data/ext/nokogiri/xml_document_fragment.h +1 -1
  28. data/ext/nokogiri/xml_dtd.c +1 -1
  29. data/ext/nokogiri/xml_dtd.h +1 -1
  30. data/ext/nokogiri/xml_entity_reference.c +13 -4
  31. data/ext/nokogiri/xml_entity_reference.h +1 -1
  32. data/ext/nokogiri/xml_io.h +1 -1
  33. data/ext/nokogiri/xml_namespace.c +69 -0
  34. data/ext/nokogiri/xml_namespace.h +12 -0
  35. data/ext/nokogiri/xml_node.c +232 -124
  36. data/ext/nokogiri/xml_node.h +3 -4
  37. data/ext/nokogiri/xml_node_set.c +206 -19
  38. data/ext/nokogiri/xml_node_set.h +1 -1
  39. data/ext/nokogiri/xml_processing_instruction.c +14 -4
  40. data/ext/nokogiri/xml_processing_instruction.h +1 -1
  41. data/ext/nokogiri/xml_reader.c +87 -7
  42. data/ext/nokogiri/xml_reader.h +1 -1
  43. data/ext/nokogiri/xml_relax_ng.c +106 -0
  44. data/ext/nokogiri/xml_relax_ng.h +9 -0
  45. data/ext/nokogiri/xml_sax_parser.c +122 -2
  46. data/ext/nokogiri/xml_sax_parser.h +1 -1
  47. data/ext/nokogiri/xml_sax_push_parser.c +1 -0
  48. data/ext/nokogiri/xml_sax_push_parser.h +1 -1
  49. data/ext/nokogiri/xml_schema.c +107 -0
  50. data/ext/nokogiri/xml_schema.h +9 -0
  51. data/ext/nokogiri/xml_syntax_error.h +1 -1
  52. data/ext/nokogiri/xml_text.c +10 -3
  53. data/ext/nokogiri/xml_text.h +1 -1
  54. data/ext/nokogiri/xml_xpath.h +1 -1
  55. data/ext/nokogiri/xml_xpath_context.h +1 -1
  56. data/ext/nokogiri/xslt_stylesheet.c +29 -16
  57. data/ext/nokogiri/xslt_stylesheet.h +1 -1
  58. data/lib/action-nokogiri.rb +7 -1
  59. data/lib/nokogiri.rb +21 -5
  60. data/lib/nokogiri/css/generated_parser.rb +49 -14
  61. data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
  62. data/lib/nokogiri/css/node.rb +13 -3
  63. data/lib/nokogiri/css/parser.rb +8 -0
  64. data/lib/nokogiri/css/parser.y +7 -7
  65. data/lib/nokogiri/css/tokenizer.rb +2 -0
  66. data/lib/nokogiri/css/xpath_visitor.rb +10 -6
  67. data/lib/nokogiri/decorators/hpricot/node.rb +1 -1
  68. data/lib/nokogiri/decorators/hpricot/node_set.rb +2 -2
  69. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +2 -0
  70. data/lib/nokogiri/decorators/slop.rb +3 -1
  71. data/lib/nokogiri/ffi/html/document.rb +37 -0
  72. data/lib/nokogiri/ffi/html/element_description.rb +85 -0
  73. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  74. data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
  75. data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
  76. data/lib/nokogiri/ffi/libxml.rb +314 -0
  77. data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
  78. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  79. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  80. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  81. data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
  82. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  83. data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
  84. data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
  85. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  86. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  87. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  88. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  89. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  90. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  91. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
  92. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  93. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  94. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  95. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
  96. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  97. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  98. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  99. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  100. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  101. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  102. data/lib/nokogiri/ffi/xml/document.rb +107 -0
  103. data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
  104. data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
  105. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  106. data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
  107. data/lib/nokogiri/ffi/xml/node.rb +380 -0
  108. data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
  109. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  110. data/lib/nokogiri/ffi/xml/reader.rb +217 -0
  111. data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
  112. data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
  113. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
  114. data/lib/nokogiri/ffi/xml/schema.rb +55 -0
  115. data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
  116. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  117. data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
  118. data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
  119. data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
  120. data/lib/nokogiri/hpricot.rb +14 -3
  121. data/lib/nokogiri/html.rb +11 -46
  122. data/lib/nokogiri/html/builder.rb +27 -1
  123. data/lib/nokogiri/html/document.rb +62 -6
  124. data/lib/nokogiri/html/document_fragment.rb +15 -0
  125. data/lib/nokogiri/html/element_description.rb +23 -0
  126. data/lib/nokogiri/html/entity_lookup.rb +2 -0
  127. data/lib/nokogiri/html/sax/parser.rb +27 -1
  128. data/lib/nokogiri/version.rb +26 -1
  129. data/lib/nokogiri/version_warning.rb +11 -0
  130. data/lib/nokogiri/xml.rb +25 -51
  131. data/lib/nokogiri/xml/builder.rb +166 -10
  132. data/lib/nokogiri/xml/cdata.rb +3 -1
  133. data/lib/nokogiri/xml/document.rb +39 -6
  134. data/lib/nokogiri/xml/document_fragment.rb +41 -1
  135. data/lib/nokogiri/xml/dtd.rb +3 -1
  136. data/lib/nokogiri/xml/entity_declaration.rb +3 -1
  137. data/lib/nokogiri/xml/fragment_handler.rb +24 -3
  138. data/lib/nokogiri/xml/namespace.rb +7 -0
  139. data/lib/nokogiri/xml/node.rb +314 -65
  140. data/lib/nokogiri/xml/node/save_options.rb +12 -2
  141. data/lib/nokogiri/xml/node_set.rb +58 -8
  142. data/lib/nokogiri/xml/parse_options.rb +80 -0
  143. data/lib/nokogiri/xml/processing_instruction.rb +2 -0
  144. data/lib/nokogiri/xml/reader.rb +42 -3
  145. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  146. data/lib/nokogiri/xml/sax.rb +0 -7
  147. data/lib/nokogiri/xml/sax/document.rb +84 -0
  148. data/lib/nokogiri/xml/sax/parser.rb +38 -2
  149. data/lib/nokogiri/xml/sax/push_parser.rb +12 -0
  150. data/lib/nokogiri/xml/schema.rb +65 -0
  151. data/lib/nokogiri/xml/syntax_error.rb +11 -0
  152. data/lib/nokogiri/xml/xpath.rb +1 -1
  153. data/lib/nokogiri/xml/xpath_context.rb +2 -0
  154. data/lib/nokogiri/xslt.rb +21 -1
  155. data/lib/nokogiri/xslt/stylesheet.rb +19 -0
  156. data/lib/xsd/xmlparser/nokogiri.rb +12 -2
  157. data/tasks/test.rb +42 -19
  158. data/test/css/test_parser.rb +29 -0
  159. data/test/ffi/test_document.rb +35 -0
  160. data/test/files/address_book.rlx +12 -0
  161. data/test/files/address_book.xml +10 -0
  162. data/test/files/po.xml +32 -0
  163. data/test/files/po.xsd +66 -0
  164. data/test/helper.rb +38 -8
  165. data/test/html/sax/test_parser.rb +12 -0
  166. data/test/html/test_builder.rb +25 -2
  167. data/test/html/test_document.rb +91 -20
  168. data/test/html/test_document_fragment.rb +97 -0
  169. data/test/html/test_element_description.rb +95 -0
  170. data/test/html/test_node.rb +66 -3
  171. data/test/test_convert_xpath.rb +1 -1
  172. data/test/test_memory_leak.rb +57 -18
  173. data/test/test_nokogiri.rb +24 -2
  174. data/test/test_reader.rb +77 -0
  175. data/test/test_xslt_transforms.rb +120 -82
  176. data/test/xml/node/test_subclass.rb +44 -0
  177. data/test/xml/sax/test_parser.rb +9 -0
  178. data/test/xml/sax/test_push_parser.rb +24 -0
  179. data/test/xml/test_attr.rb +7 -0
  180. data/test/xml/test_builder.rb +48 -0
  181. data/test/xml/test_cdata.rb +19 -0
  182. data/test/xml/test_comment.rb +6 -0
  183. data/test/xml/test_document.rb +101 -2
  184. data/test/xml/test_document_fragment.rb +55 -3
  185. data/test/xml/test_entity_reference.rb +4 -0
  186. data/test/xml/test_namespace.rb +43 -0
  187. data/test/xml/test_node.rb +255 -8
  188. data/test/xml/test_node_attributes.rb +34 -0
  189. data/test/xml/test_node_encoding.rb +9 -2
  190. data/test/xml/test_node_set.rb +197 -1
  191. data/test/xml/test_parse_options.rb +52 -0
  192. data/test/xml/test_processing_instruction.rb +5 -0
  193. data/test/xml/test_relax_ng.rb +60 -0
  194. data/test/xml/test_schema.rb +65 -0
  195. data/test/xml/test_text.rb +5 -0
  196. data/test/xml/test_unparented_node.rb +3 -3
  197. metadata +128 -12
  198. data/lib/nokogiri/xml/comment.rb +0 -6
  199. data/lib/nokogiri/xml/element.rb +0 -6
  200. data/lib/nokogiri/xml/text.rb +0 -6
@@ -3,22 +3,74 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
3
3
  module Nokogiri
4
4
  module XML
5
5
  class TestDocumentFragment < Nokogiri::TestCase
6
- def test_new
6
+ def setup
7
+ super
7
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
9
+ end
10
+
11
+ def test_new
8
12
  fragment = Nokogiri::XML::DocumentFragment.new(@xml)
9
13
  end
10
14
 
11
15
  def test_fragment_should_have_document
12
- @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
13
16
  fragment = Nokogiri::XML::DocumentFragment.new(@xml)
14
17
  assert_equal @xml, fragment.document
15
18
  end
16
19
 
17
20
  def test_name
18
- @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
19
21
  fragment = Nokogiri::XML::DocumentFragment.new(@xml)
20
22
  assert_equal '#document-fragment', fragment.name
21
23
  end
24
+
25
+ def test_static_method
26
+ fragment = Nokogiri::XML::DocumentFragment.parse("<div>a</div>")
27
+ assert_instance_of Nokogiri::XML::DocumentFragment, fragment
28
+ end
29
+
30
+ def test_many_fragments
31
+ 100.times { Nokogiri::XML::DocumentFragment.new(@xml) }
32
+ end
33
+
34
+ def test_subclass
35
+ klass = Class.new(Nokogiri::XML::DocumentFragment)
36
+ fragment = klass.new(@xml, "<div>a</div>")
37
+ assert_instance_of klass, fragment
38
+ end
39
+
40
+ def test_xml_fragment
41
+ fragment = Nokogiri::XML.fragment("<div>a</div>")
42
+ assert_equal "<div>a</div>", fragment.to_s
43
+ end
44
+
45
+ def test_xml_fragment_has_multiple_toplevel_children
46
+ # TODO: this is lame. xml fragment() should support multiple top-level children
47
+ doc = "<div>b</div><div>e</div>"
48
+ fragment = Nokogiri::XML::Document.new.fragment(doc)
49
+ assert_equal "<div>b</div>", fragment.to_s
50
+ end
51
+
52
+ def test_xml_fragment_has_outer_text
53
+ # this test is descriptive, not prescriptive.
54
+ doc = "a<div>b</div>"
55
+ fragment = Nokogiri::XML::Document.new.fragment(doc)
56
+ assert_equal "", fragment.to_s
57
+
58
+ doc = "<div>b</div>c"
59
+ fragment = Nokogiri::XML::Document.new.fragment(doc)
60
+ assert_equal "<div>b</div>", fragment.to_s
61
+ end
62
+
63
+ def test_xml_fragment_case_sensitivity
64
+ doc = "<crazyDiv>b</crazyDiv>"
65
+ fragment = Nokogiri::XML::Document.new.fragment(doc)
66
+ assert_equal "<crazyDiv>b</crazyDiv>", fragment.to_s
67
+ end
68
+
69
+ def test_xml_fragment_with_leading_whitespace
70
+ doc = " <div>b</div> "
71
+ fragment = Nokogiri::XML::Document.new.fragment(doc)
72
+ assert_equal "<div>b</div>", fragment.to_s
73
+ end
22
74
  end
23
75
  end
24
76
  end
@@ -12,6 +12,10 @@ module Nokogiri
12
12
  assert ref = EntityReference.new(@xml, 'ent4')
13
13
  assert_instance_of EntityReference, ref
14
14
  end
15
+
16
+ def test_many_references
17
+ 100.times { EntityReference.new(@xml, 'foo') }
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestNamespace < Nokogiri::TestCase
6
+ def setup
7
+ @xml = Nokogiri::XML <<-eoxml
8
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
9
+ <awesome/>
10
+ </root>
11
+ eoxml
12
+ end
13
+
14
+ def test_namespace_node_prefix
15
+ namespaces = @xml.root.namespace_definitions
16
+ assert_equal [nil, 'foo'], namespaces.map { |x| x.prefix }
17
+ end
18
+
19
+ def test_namespace_node_href
20
+ namespaces = @xml.root.namespace_definitions
21
+ assert_equal [
22
+ 'http://tenderlovemaking.com/',
23
+ 'bar'
24
+ ], namespaces.map { |x| x.href }
25
+ end
26
+
27
+ def test_equality
28
+ namespaces = @xml.root.namespace_definitions
29
+ assert_equal namespaces, @xml.root.namespace_definitions
30
+ end
31
+
32
+ def test_add_definition
33
+ @xml.root.add_namespace_definition('baz', 'bar')
34
+ assert_equal 3, @xml.root.namespace_definitions.length
35
+ end
36
+
37
+ def test_add_definition_return
38
+ ns = @xml.root.add_namespace_definition('baz', 'bar')
39
+ assert_equal 'baz', ns.prefix
40
+ end
41
+ end
42
+ end
43
+ end
@@ -7,7 +7,89 @@ module Nokogiri
7
7
  class TestNode < Nokogiri::TestCase
8
8
  def setup
9
9
  super
10
- @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
10
+ @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
11
+ end
12
+
13
+ def test_namespace_nodes
14
+ xml = Nokogiri::XML <<-eoxml
15
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
16
+ <awesome/>
17
+ </root>
18
+ eoxml
19
+ awesome = xml.root
20
+ namespaces = awesome.namespace_definitions
21
+ assert_equal 2, namespaces.length
22
+ end
23
+
24
+ def test_no_definitions
25
+ xml = Nokogiri::XML <<-eoxml
26
+ <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
27
+ <awesome/>
28
+ </root>
29
+ eoxml
30
+ awesome = xml.at('//xmlns:awesome')
31
+ namespaces = awesome.namespace_definitions
32
+ assert_equal 0, namespaces.length
33
+ end
34
+
35
+ def test_subclass_dup
36
+ subclass = Class.new(Nokogiri::XML::Node)
37
+ node = subclass.new('foo', @xml).dup
38
+ assert_instance_of subclass, node
39
+ end
40
+
41
+ def test_namespace_goes_to_children
42
+ fruits = Nokogiri::XML(<<-eoxml)
43
+ <Fruit xmlns='www.fruits.org'>
44
+ </Fruit>
45
+ eoxml
46
+ apple = Nokogiri::XML::Node.new('Apple', fruits)
47
+ orange = Nokogiri::XML::Node.new('Orange', fruits)
48
+ apple << orange
49
+ fruits.root << apple
50
+ assert fruits.at('//fruit:Orange',{'fruit'=>'www.fruits.org'})
51
+ assert fruits.at('//fruit:Apple',{'fruit'=>'www.fruits.org'})
52
+ end
53
+
54
+ def test_description
55
+ assert_nil @xml.at('employee').description
56
+ end
57
+
58
+ def test_add_namespace_add_child
59
+ doc = Nokogiri::XML::Document.new
60
+ item = Nokogiri::XML::Element.new('item', doc)
61
+ doc.root = item
62
+
63
+ entry = Nokogiri::XML::Element.new('entry', doc)
64
+ entry.add_namespace('tlm', 'http://tenderlovemaking.com')
65
+ assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
66
+ item.add_child(entry)
67
+ assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
68
+ end
69
+
70
+ def test_spaceship
71
+ nodes = @xml.xpath('//employee')
72
+ assert_equal(-1, (nodes.first <=> nodes.last))
73
+ list = [nodes.first, nodes.last].sort
74
+ assert_equal nodes.first, list.first
75
+ assert_equal nodes.last, list.last
76
+ end
77
+
78
+ def test_incorrect_spaceship
79
+ nodes = @xml.xpath('//employee')
80
+ assert_nil(nodes.first <=> 'asdf')
81
+ end
82
+
83
+ def test_document_compare
84
+ nodes = @xml.xpath('//employee')
85
+ assert_equal(-1, (nodes.first <=> @xml))
86
+ end
87
+
88
+ def test_different_document_compare
89
+ nodes = @xml.xpath('//employee')
90
+ doc = Nokogiri::XML('<a><b/></a>')
91
+ b = doc.at('b')
92
+ assert_nil(nodes.first <=> b)
11
93
  end
12
94
 
13
95
  def test_duplicate_node_removes_namespace
@@ -22,7 +104,16 @@ module Nokogiri
22
104
  assert_equal 2, fruits.xpath('//xmlns:Apple').length
23
105
  assert_equal 1, fruits.to_xml.scan('www.fruits.org').length
24
106
  end
25
-
107
+
108
+ [:clone, :dup].each do |symbol|
109
+ define_method "test_#{symbol}" do
110
+ node = @xml.at('//employee')
111
+ other = node.send(symbol)
112
+ assert_equal "employee", other.name
113
+ assert_nil other.parent
114
+ end
115
+ end
116
+
26
117
  def test_node_added_to_root_should_get_namespace
27
118
  fruits = Nokogiri::XML(<<-eoxml)
28
119
  <Fruit xmlns='http://www.fruits.org'>
@@ -40,6 +131,12 @@ module Nokogiri
40
131
  assert_equal '/root/item', item.path
41
132
  end
42
133
 
134
+ def test_new_node_can_have_ancestors
135
+ xml = Nokogiri::XML('<root>text</root>')
136
+ item = Nokogiri::XML::Element.new('item', xml)
137
+ assert_equal 0, item.ancestors.length
138
+ end
139
+
43
140
  def test_children
44
141
  doc = Nokogiri::XML(<<-eoxml)
45
142
  <root>#{'<a/>' * 9 }</root>
@@ -60,6 +157,114 @@ module Nokogiri
60
157
  assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
61
158
  end
62
159
 
160
+ def test_add_default_ns
161
+ node = @xml.at('address')
162
+ node.add_namespace(nil, 'http://tenderlovemaking.com')
163
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
164
+ end
165
+
166
+ def test_add_multiple_namespaces
167
+ node = @xml.at('address')
168
+
169
+ node.add_namespace(nil, 'http://tenderlovemaking.com')
170
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
171
+
172
+ node.add_namespace('foo', 'http://tenderlovemaking.com')
173
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
174
+ end
175
+
176
+ def test_default_namespace=
177
+ node = @xml.at('address')
178
+ node.default_namespace = 'http://tenderlovemaking.com'
179
+ assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
180
+ end
181
+
182
+ def test_namespace=
183
+ node = @xml.at('address')
184
+ assert_nil node.namespace
185
+ definition = node.add_namespace_definition 'bar', 'http://tlm.com/'
186
+
187
+ node.namespace = definition
188
+
189
+ assert_equal definition, node.namespace
190
+
191
+ assert_equal node, @xml.at('//foo:address', {
192
+ 'foo' => 'http://tlm.com/'
193
+ })
194
+ end
195
+
196
+ def test_add_namespace_with_nil_associates_node
197
+ node = @xml.at('address')
198
+ assert_nil node.namespace
199
+ definition = node.add_namespace_definition nil, 'http://tlm.com/'
200
+ assert_equal definition, node.namespace
201
+ end
202
+
203
+ def test_add_namespace_does_not_associate_node
204
+ node = @xml.at('address')
205
+ assert_nil node.namespace
206
+ definition = node.add_namespace_definition 'foo', 'http://tlm.com/'
207
+ assert_nil node.namespace
208
+ end
209
+
210
+ def test_set_namespace_from_different_doc
211
+ node = @xml.at('address')
212
+ doc = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
213
+ decl = doc.root.add_namespace_definition 'foo', 'bar'
214
+
215
+ assert_raises(ArgumentError) do
216
+ node.namespace = decl
217
+ end
218
+ end
219
+
220
+ def test_set_namespace_must_only_take_a_namespace
221
+ node = @xml.at('address')
222
+ assert_raises(TypeError) do
223
+ node.namespace = node
224
+ end
225
+ end
226
+
227
+ def test_at
228
+ node = @xml.at('address')
229
+ assert_equal node, @xml.xpath('//address').first
230
+ end
231
+
232
+ def test_percent
233
+ node = @xml % ('address')
234
+ assert_equal node, @xml.xpath('//address').first
235
+ end
236
+
237
+ def test_accept
238
+ visitor = Class.new {
239
+ attr_accessor :visited
240
+ def accept target
241
+ target.accept(self)
242
+ end
243
+
244
+ def visit node
245
+ node.children.each { |c| c.accept(self) }
246
+ @visited = true
247
+ end
248
+ }.new
249
+ visitor.accept(@xml.root)
250
+ assert visitor.visited
251
+ end
252
+
253
+ def test_replace_with_default_namespaces
254
+ fruits = Nokogiri::XML(<<-eoxml)
255
+ <fruit xmlns="http://fruits.org">
256
+ <apple />
257
+ </fruit>
258
+ eoxml
259
+
260
+ apple = fruits.css('apple').first
261
+
262
+ orange = Nokogiri::XML::Node.new('orange', fruits)
263
+ apple.replace(orange)
264
+
265
+ assert_equal orange, fruits.css('orange').first
266
+ end
267
+
63
268
  def test_add_child_should_inherit_namespace
64
269
  doc = Nokogiri::XML(<<-eoxml)
65
270
  <root xmlns="http://tenderlovemaking.com/">
@@ -152,6 +357,7 @@ module Nokogiri
152
357
  def test_new
153
358
  assert node = Nokogiri::XML::Node.new('input', @xml)
154
359
  assert_equal 1, node.node_type
360
+ assert_instance_of Nokogiri::XML::Node, node
155
361
  end
156
362
 
157
363
  def test_to_str
@@ -452,12 +658,12 @@ module Nokogiri
452
658
  def test_node_equality
453
659
  doc1 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
454
660
  doc2 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
455
-
661
+
456
662
  address1_1 = doc1.xpath('//address').first
457
663
  address1_2 = doc1.xpath('//address').first
458
-
664
+
459
665
  address2 = doc2.xpath('//address').first
460
-
666
+
461
667
  assert_not_equal address1_1, address2 # two references to very, very similar nodes
462
668
  assert_equal address1_1, address1_2 # two references to the exact same node
463
669
  end
@@ -536,12 +742,25 @@ EOF
536
742
  </x>
537
743
  EOF
538
744
  set = xml.search("//y/*")
539
- assert_equal "a", set[0].namespace
540
- assert_equal "b", set[1].namespace
541
- assert_equal "c", set[2].namespace
745
+ assert_equal "a", set[0].namespace.prefix
746
+ assert_equal "b", set[1].namespace.prefix
747
+ assert_equal "c", set[2].namespace.prefix
542
748
  assert_equal nil, set[3].namespace
543
749
  end
544
750
 
751
+ def test_namespace_without_an_href_on_html_node
752
+ # because microsoft word's HTML formatting does this. ick.
753
+ xml = Nokogiri::HTML.parse <<-EOF
754
+ <div><o:p>foo</o:p></div>
755
+ EOF
756
+
757
+ assert_not_nil(node = xml.at('p'))
758
+
759
+ assert_equal 1, node.namespaces.keys.size
760
+ assert node.namespaces.has_key?('xmlns:o')
761
+ assert_equal nil, node.namespaces['xmlns:o']
762
+ end
763
+
545
764
  def test_line
546
765
  xml = Nokogiri::XML(<<-eoxml)
547
766
  <root>
@@ -556,6 +775,34 @@ EOF
556
775
  assert_equal 2, node.line
557
776
  end
558
777
 
778
+ def test_unlink_then_reparent
779
+ # see http://github.com/tenderlove/nokogiri/issues#issue/22
780
+ 10.times do
781
+ STDOUT.putc "."
782
+ STDOUT.flush
783
+ begin
784
+ doc = Nokogiri::XML <<-EOHTML
785
+ <root>
786
+ <a>
787
+ <b/>
788
+ <c/>
789
+ </a>
790
+ </root>
791
+ EOHTML
792
+
793
+ root = doc.at("root")
794
+ a = root.at("a")
795
+ b = a.at("b")
796
+ c = a.at("c")
797
+ a.add_next_sibling(b.unlink)
798
+ c.unlink
799
+ end
800
+
801
+ GC.start
802
+ end
803
+
804
+ end
805
+
559
806
  end
560
807
  end
561
808
  end