nokogiri 1.4.3.1-java → 1.5.0-java

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.
Files changed (231) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.ja.rdoc +113 -0
  3. data/CHANGELOG.rdoc +113 -1
  4. data/Manifest.txt +72 -68
  5. data/README.ja.rdoc +4 -4
  6. data/README.rdoc +31 -7
  7. data/Rakefile +110 -132
  8. data/bin/nokogiri +7 -3
  9. data/ext/java/nokogiri/EncodingHandler.java +124 -0
  10. data/ext/java/nokogiri/HtmlDocument.java +119 -0
  11. data/ext/java/nokogiri/HtmlElementDescription.java +145 -0
  12. data/ext/java/nokogiri/HtmlEntityLookup.java +79 -0
  13. data/ext/java/nokogiri/HtmlSaxParserContext.java +259 -0
  14. data/ext/java/nokogiri/NokogiriService.java +590 -0
  15. data/ext/java/nokogiri/XmlAttr.java +180 -0
  16. data/ext/java/nokogiri/XmlAttributeDecl.java +130 -0
  17. data/ext/java/nokogiri/XmlCdata.java +84 -0
  18. data/ext/java/nokogiri/XmlComment.java +86 -0
  19. data/ext/java/nokogiri/XmlDocument.java +519 -0
  20. data/ext/java/nokogiri/XmlDocumentFragment.java +223 -0
  21. data/ext/java/nokogiri/XmlDtd.java +469 -0
  22. data/ext/java/nokogiri/XmlElement.java +195 -0
  23. data/ext/java/nokogiri/XmlElementContent.java +382 -0
  24. data/ext/java/nokogiri/XmlElementDecl.java +152 -0
  25. data/ext/java/nokogiri/XmlEntityDecl.java +162 -0
  26. data/ext/java/nokogiri/XmlEntityReference.java +97 -0
  27. data/ext/java/nokogiri/XmlNamespace.java +183 -0
  28. data/ext/java/nokogiri/XmlNode.java +1378 -0
  29. data/ext/java/nokogiri/XmlNodeSet.java +267 -0
  30. data/ext/java/nokogiri/XmlProcessingInstruction.java +99 -0
  31. data/ext/java/nokogiri/XmlReader.java +408 -0
  32. data/ext/java/nokogiri/XmlRelaxng.java +144 -0
  33. data/ext/java/nokogiri/XmlSaxParserContext.java +367 -0
  34. data/ext/java/nokogiri/XmlSaxPushParser.java +184 -0
  35. data/ext/java/nokogiri/XmlSchema.java +324 -0
  36. data/ext/java/nokogiri/XmlSyntaxError.java +119 -0
  37. data/ext/java/nokogiri/XmlText.java +119 -0
  38. data/ext/java/nokogiri/XmlXpathContext.java +199 -0
  39. data/ext/java/nokogiri/XsltStylesheet.java +197 -0
  40. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +204 -0
  41. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +73 -0
  42. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +86 -0
  43. data/ext/java/nokogiri/internals/NokogiriHandler.java +327 -0
  44. data/ext/java/nokogiri/internals/NokogiriHelpers.java +639 -0
  45. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +167 -0
  46. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +130 -0
  47. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +74 -0
  48. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +121 -0
  49. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +79 -0
  50. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +141 -0
  51. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +73 -0
  52. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +67 -0
  53. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +86 -0
  54. data/ext/java/nokogiri/internals/ParserContext.java +276 -0
  55. data/ext/java/nokogiri/internals/PushInputStream.java +411 -0
  56. data/ext/java/nokogiri/internals/ReaderNode.java +531 -0
  57. data/ext/java/nokogiri/internals/SaveContextVisitor.java +567 -0
  58. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +76 -0
  59. data/ext/java/nokogiri/internals/XmlDeclHandler.java +42 -0
  60. data/ext/java/nokogiri/internals/XmlDomParser.java +76 -0
  61. data/ext/java/nokogiri/internals/XmlDomParserContext.java +244 -0
  62. data/ext/java/nokogiri/internals/XmlSaxParser.java +65 -0
  63. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +72 -0
  64. data/ext/nokogiri/depend +358 -32
  65. data/ext/nokogiri/extconf.rb +10 -6
  66. data/ext/nokogiri/nokogiri.c +23 -3
  67. data/ext/nokogiri/nokogiri.h +7 -2
  68. data/ext/nokogiri/xml_document.c +9 -0
  69. data/ext/nokogiri/xml_dtd.c +2 -2
  70. data/ext/nokogiri/xml_io.c +32 -7
  71. data/ext/nokogiri/xml_node.c +45 -25
  72. data/ext/nokogiri/xml_node_set.c +1 -1
  73. data/ext/nokogiri/xml_relax_ng.c +0 -7
  74. data/ext/nokogiri/xml_sax_parser.c +14 -7
  75. data/ext/nokogiri/xml_sax_parser_context.c +40 -0
  76. data/ext/nokogiri/xml_xpath_context.c +33 -2
  77. data/ext/nokogiri/xslt_stylesheet.c +128 -6
  78. data/lib/isorelax.jar +0 -0
  79. data/lib/jing.jar +0 -0
  80. data/lib/nekodtd.jar +0 -0
  81. data/lib/nekohtml.jar +0 -0
  82. data/lib/nokogiri/css/parser.rb +665 -70
  83. data/lib/nokogiri/css/parser.y +3 -1
  84. data/lib/nokogiri/css/parser_extras.rb +91 -0
  85. data/lib/nokogiri/css/tokenizer.rb +148 -3
  86. data/lib/nokogiri/css/tokenizer.rex +1 -1
  87. data/lib/nokogiri/css/xpath_visitor.rb +15 -7
  88. data/lib/nokogiri/css.rb +5 -3
  89. data/lib/nokogiri/decorators/slop.rb +5 -3
  90. data/lib/nokogiri/html/document.rb +142 -19
  91. data/lib/nokogiri/html/document_fragment.rb +19 -17
  92. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  93. data/lib/nokogiri/html/sax/parser.rb +6 -2
  94. data/lib/nokogiri/html.rb +1 -0
  95. data/lib/nokogiri/nokogiri.jar +0 -0
  96. data/lib/nokogiri/version.rb +76 -26
  97. data/lib/nokogiri/xml/attribute_decl.rb +1 -1
  98. data/lib/nokogiri/xml/builder.rb +7 -0
  99. data/lib/nokogiri/xml/document.rb +43 -2
  100. data/lib/nokogiri/xml/document_fragment.rb +16 -2
  101. data/lib/nokogiri/xml/dtd.rb +12 -1
  102. data/lib/nokogiri/xml/element_decl.rb +1 -1
  103. data/lib/nokogiri/xml/entity_decl.rb +1 -1
  104. data/lib/nokogiri/xml/node/save_options.rb +20 -1
  105. data/lib/nokogiri/xml/node.rb +198 -78
  106. data/lib/nokogiri/xml/node_set.rb +10 -3
  107. data/lib/nokogiri/xml/parse_options.rb +8 -0
  108. data/lib/nokogiri/xml/reader.rb +42 -6
  109. data/lib/nokogiri/xml/sax/document.rb +4 -2
  110. data/lib/nokogiri/xml/schema.rb +7 -1
  111. data/lib/nokogiri/xslt/stylesheet.rb +1 -1
  112. data/lib/nokogiri/xslt.rb +9 -5
  113. data/lib/nokogiri.rb +19 -25
  114. data/lib/xercesImpl.jar +0 -0
  115. data/nokogiri_help_responses.md +40 -0
  116. data/tasks/cross_compile.rb +130 -136
  117. data/tasks/nokogiri.org.rb +18 -0
  118. data/tasks/test.rb +2 -2
  119. data/test/css/test_parser.rb +29 -18
  120. data/test/css/test_tokenizer.rb +8 -0
  121. data/test/decorators/test_slop.rb +16 -0
  122. data/test/files/encoding.html +82 -0
  123. data/test/files/encoding.xhtml +84 -0
  124. data/test/files/metacharset.html +10 -0
  125. data/test/files/noencoding.html +47 -0
  126. data/test/helper.rb +5 -1
  127. data/test/html/sax/test_parser.rb +65 -3
  128. data/test/html/test_document.rb +75 -1
  129. data/test/html/test_document_encoding.rb +61 -0
  130. data/test/html/test_document_fragment.rb +50 -5
  131. data/test/html/test_element_description.rb +4 -2
  132. data/test/html/test_node.rb +9 -0
  133. data/test/test_memory_leak.rb +20 -35
  134. data/test/test_nokogiri.rb +14 -20
  135. data/test/test_reader.rb +23 -6
  136. data/test/test_xslt_transforms.rb +6 -2
  137. data/test/xml/node/test_save_options.rb +10 -2
  138. data/test/xml/sax/test_parser.rb +39 -8
  139. data/test/xml/sax/test_parser_context.rb +50 -0
  140. data/test/xml/sax/test_push_parser.rb +18 -1
  141. data/test/xml/test_attribute_decl.rb +7 -3
  142. data/test/xml/test_builder.rb +17 -0
  143. data/test/xml/test_document.rb +34 -5
  144. data/test/xml/test_document_fragment.rb +14 -2
  145. data/test/xml/test_dtd.rb +28 -3
  146. data/test/xml/test_element_content.rb +1 -1
  147. data/test/xml/test_element_decl.rb +1 -1
  148. data/test/xml/test_entity_decl.rb +12 -10
  149. data/test/xml/test_namespace.rb +7 -5
  150. data/test/xml/test_node.rb +65 -13
  151. data/test/xml/test_node_reparenting.rb +72 -31
  152. data/test/xml/test_node_set.rb +57 -0
  153. data/test/xml/test_schema.rb +5 -0
  154. data/test/xml/test_xpath.rb +32 -0
  155. data/test/xslt/test_custom_functions.rb +94 -0
  156. data/test/xslt/test_exception_handling.rb +37 -0
  157. metadata +512 -517
  158. data/deps.rip +0 -5
  159. data/ext/nokogiri/libcharset-1.dll +0 -0
  160. data/ext/nokogiri/libexslt.dll +0 -0
  161. data/ext/nokogiri/libiconv-2.dll +0 -0
  162. data/ext/nokogiri/libxml2.dll +0 -0
  163. data/ext/nokogiri/libxslt.dll +0 -0
  164. data/ext/nokogiri/zlib1.dll +0 -0
  165. data/lib/nokogiri/css/generated_parser.rb +0 -676
  166. data/lib/nokogiri/css/generated_tokenizer.rb +0 -146
  167. data/lib/nokogiri/ffi/encoding_handler.rb +0 -42
  168. data/lib/nokogiri/ffi/html/document.rb +0 -28
  169. data/lib/nokogiri/ffi/html/element_description.rb +0 -81
  170. data/lib/nokogiri/ffi/html/entity_lookup.rb +0 -16
  171. data/lib/nokogiri/ffi/html/sax/parser_context.rb +0 -38
  172. data/lib/nokogiri/ffi/io_callbacks.rb +0 -42
  173. data/lib/nokogiri/ffi/libxml.rb +0 -411
  174. data/lib/nokogiri/ffi/structs/common_node.rb +0 -38
  175. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +0 -24
  176. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +0 -13
  177. data/lib/nokogiri/ffi/structs/xml_alloc.rb +0 -16
  178. data/lib/nokogiri/ffi/structs/xml_attr.rb +0 -19
  179. data/lib/nokogiri/ffi/structs/xml_attribute.rb +0 -27
  180. data/lib/nokogiri/ffi/structs/xml_buffer.rb +0 -16
  181. data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +0 -11
  182. data/lib/nokogiri/ffi/structs/xml_document.rb +0 -117
  183. data/lib/nokogiri/ffi/structs/xml_dtd.rb +0 -28
  184. data/lib/nokogiri/ffi/structs/xml_element.rb +0 -26
  185. data/lib/nokogiri/ffi/structs/xml_element_content.rb +0 -17
  186. data/lib/nokogiri/ffi/structs/xml_entity.rb +0 -32
  187. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +0 -12
  188. data/lib/nokogiri/ffi/structs/xml_node.rb +0 -28
  189. data/lib/nokogiri/ffi/structs/xml_node_set.rb +0 -53
  190. data/lib/nokogiri/ffi/structs/xml_notation.rb +0 -11
  191. data/lib/nokogiri/ffi/structs/xml_ns.rb +0 -15
  192. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +0 -19
  193. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +0 -14
  194. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +0 -51
  195. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +0 -124
  196. data/lib/nokogiri/ffi/structs/xml_schema.rb +0 -13
  197. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +0 -31
  198. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +0 -12
  199. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +0 -38
  200. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +0 -35
  201. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +0 -20
  202. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +0 -13
  203. data/lib/nokogiri/ffi/weak_bucket.rb +0 -40
  204. data/lib/nokogiri/ffi/xml/attr.rb +0 -41
  205. data/lib/nokogiri/ffi/xml/attribute_decl.rb +0 -27
  206. data/lib/nokogiri/ffi/xml/cdata.rb +0 -19
  207. data/lib/nokogiri/ffi/xml/comment.rb +0 -18
  208. data/lib/nokogiri/ffi/xml/document.rb +0 -166
  209. data/lib/nokogiri/ffi/xml/document_fragment.rb +0 -21
  210. data/lib/nokogiri/ffi/xml/dtd.rb +0 -67
  211. data/lib/nokogiri/ffi/xml/element_content.rb +0 -43
  212. data/lib/nokogiri/ffi/xml/element_decl.rb +0 -19
  213. data/lib/nokogiri/ffi/xml/entity_decl.rb +0 -36
  214. data/lib/nokogiri/ffi/xml/entity_reference.rb +0 -19
  215. data/lib/nokogiri/ffi/xml/namespace.rb +0 -44
  216. data/lib/nokogiri/ffi/xml/node.rb +0 -554
  217. data/lib/nokogiri/ffi/xml/node_set.rb +0 -149
  218. data/lib/nokogiri/ffi/xml/processing_instruction.rb +0 -20
  219. data/lib/nokogiri/ffi/xml/reader.rb +0 -236
  220. data/lib/nokogiri/ffi/xml/relax_ng.rb +0 -85
  221. data/lib/nokogiri/ffi/xml/sax/parser.rb +0 -135
  222. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +0 -67
  223. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +0 -51
  224. data/lib/nokogiri/ffi/xml/schema.rb +0 -109
  225. data/lib/nokogiri/ffi/xml/syntax_error.rb +0 -98
  226. data/lib/nokogiri/ffi/xml/text.rb +0 -18
  227. data/lib/nokogiri/ffi/xml/xpath.rb +0 -9
  228. data/lib/nokogiri/ffi/xml/xpath_context.rb +0 -148
  229. data/lib/nokogiri/ffi/xslt/stylesheet.rb +0 -53
  230. data/lib/nokogiri/version_warning.rb +0 -14
  231. data/test/ffi/test_document.rb +0 -35
@@ -100,13 +100,13 @@ module Nokogiri
100
100
  def test_xml_fragment_with_leading_whitespace
101
101
  doc = " <div>b</div> "
102
102
  fragment = Nokogiri::XML::Document.new.fragment(doc)
103
- assert_equal "<div>b</div>", fragment.to_s
103
+ assert_equal " <div>b</div> ", fragment.to_s
104
104
  end
105
105
 
106
106
  def test_xml_fragment_with_leading_whitespace_and_newline
107
107
  doc = " \n<div>b</div> "
108
108
  fragment = Nokogiri::XML::Document.new.fragment(doc)
109
- assert_equal "<div>b</div>", fragment.to_s
109
+ assert_equal " \n<div>b</div> ", fragment.to_s
110
110
  end
111
111
 
112
112
  def test_fragment_children_search
@@ -175,6 +175,18 @@ module Nokogiri
175
175
  end
176
176
  assert fragment.children.respond_to?(:awesome!), fragment.children.class
177
177
  end
178
+
179
+ def test_for_libxml_in_context_fragment_parsing_bug_workaround
180
+ 10.times do
181
+ begin
182
+ fragment = Nokogiri::XML.fragment("<div></div>")
183
+ parent = fragment.children.first
184
+ child = parent.parse("<h1></h1>").first
185
+ parent.add_child child
186
+ end
187
+ GC.start
188
+ end
189
+ end
178
190
  end
179
191
  end
180
192
  end
data/test/xml/test_dtd.rb CHANGED
@@ -14,7 +14,11 @@ module Nokogiri
14
14
  end
15
15
 
16
16
  def test_external_id
17
- xml = Nokogiri::XML('<!DOCTYPE foo PUBLIC "bar" ><foo />')
17
+ if Nokogiri.uses_libxml?
18
+ xml = Nokogiri::XML('<!DOCTYPE foo PUBLIC "bar"><foo />')
19
+ else
20
+ xml = Nokogiri::XML('<!DOCTYPE foo PUBLIC "bar" ""><foo />')
21
+ end
18
22
  assert dtd = xml.internal_subset
19
23
  assert_equal 'bar', dtd.external_id
20
24
  end
@@ -25,11 +29,26 @@ module Nokogiri
25
29
  end
26
30
  end
27
31
 
32
+ def test_empty_attributes
33
+ dtd = Nokogiri::HTML("<html></html>").internal_subset
34
+ assert_equal Hash.new, dtd.attributes
35
+ end
36
+
28
37
  def test_attributes
29
38
  assert_equal ['width'], @dtd.attributes.keys
30
39
  assert_equal '0', @dtd.attributes['width'].default
31
40
  end
32
41
 
42
+ def test_keys
43
+ assert_equal ['width'], @dtd.keys
44
+ end
45
+
46
+ def test_each
47
+ hash = {}
48
+ @dtd.each { |key, value| hash[key] = value }
49
+ assert_equal @dtd.attributes, hash
50
+ end
51
+
33
52
  def test_namespace
34
53
  assert_raise NoMethodError do
35
54
  @dtd.namespace
@@ -49,8 +68,14 @@ module Nokogiri
49
68
  end
50
69
 
51
70
  def test_validate
52
- list = @xml.internal_subset.validate @xml
53
- assert_equal 44, list.length
71
+ if Nokogiri.uses_libxml?
72
+ list = @xml.internal_subset.validate @xml
73
+ assert_equal 44, list.length
74
+ else
75
+ xml = Nokogiri::XML(File.open(XML_FILE)) {|cfg| cfg.dtdvalid}
76
+ list = xml.internal_subset.validate xml
77
+ assert_equal 37, list.length
78
+ end
54
79
  end
55
80
 
56
81
  def test_external_subsets
@@ -12,7 +12,7 @@ module Nokogiri
12
12
  <!ELEMENT div1 (head, (p | list | note)*, div2*)>
13
13
  <!ELEMENT div2 (tender:love)>
14
14
  ]>
15
- </root>
15
+ <root/>
16
16
  eoxml
17
17
  @elements = @xml.internal_subset.children.find_all { |x|
18
18
  x.type == 15
@@ -14,7 +14,7 @@ module Nokogiri
14
14
  <!ATTLIST br width CDATA "0">
15
15
  <!ATTLIST br height CDATA "0">
16
16
  ]>
17
- </root>
17
+ <root/>
18
18
  eoxml
19
19
  @elements = @xml.internal_subset.children.find_all { |x|
20
20
  x.type == 15
@@ -9,7 +9,7 @@ module Nokogiri
9
9
  <?xml version="1.0"?><?TEST-STYLE PIDATA?>
10
10
  <!DOCTYPE staff SYSTEM "staff.dtd" [
11
11
  <!ENTITY ent1 "es">
12
- <!ENTITY nocontent >
12
+ <!ENTITY nocontent "">
13
13
  ]>
14
14
  <root />
15
15
  eoxml
@@ -18,19 +18,13 @@ module Nokogiri
18
18
  @entity_decl = @entities.first
19
19
  end
20
20
 
21
- def test_constants # for libffi implementation. *sigh* sorry Mike. :-(
21
+ def test_constants
22
22
  assert_equal 1, EntityDecl::INTERNAL_GENERAL
23
23
  assert_equal 2, EntityDecl::EXTERNAL_GENERAL_PARSED
24
24
  assert_equal 3, EntityDecl::EXTERNAL_GENERAL_UNPARSED
25
25
  assert_equal 4, EntityDecl::INTERNAL_PARAMETER
26
26
  assert_equal 5, EntityDecl::EXTERNAL_PARAMETER
27
27
  assert_equal 6, EntityDecl::INTERNAL_PREDEFINED
28
-
29
- # While I'm here, another problem with libffi comes to mind. If someone
30
- # upgrades their version of any particular C library, and the constants
31
- # change values, the client using Ruby code is fucked. That sucks.
32
- # Basically anything to do with the preprocessor fucks someone using
33
- # libffi. :-(
34
28
  end
35
29
 
36
30
  def test_create_typed_entity
@@ -69,12 +63,20 @@ module Nokogiri
69
63
 
70
64
  def test_original_content
71
65
  assert_equal "es", @entity_decl.original_content
72
- assert_nil @entities[1].original_content
66
+ if Nokogiri.jruby?
67
+ assert_nil @entities[1].original_content
68
+ else
69
+ assert_equal "", @entities[1].original_content
70
+ end
73
71
  end
74
72
 
75
73
  def test_content
76
74
  assert_equal "es", @entity_decl.content
77
- assert_nil @entities[1].content
75
+ if Nokogiri.jruby?
76
+ assert_nil @entities[1].content
77
+ else
78
+ assert_equal "", @entities[1].content
79
+ end
78
80
  end
79
81
 
80
82
  def test_type
@@ -12,6 +12,13 @@ module Nokogiri
12
12
  eoxml
13
13
  end
14
14
 
15
+ if Nokogiri.uses_libxml?
16
+ def test_namespace_is_in_node_cache
17
+ node = @xml.root.namespace
18
+ assert @xml.instance_variable_get(:@node_cache).include?(node)
19
+ end
20
+ end
21
+
15
22
  def test_built_nodes_keep_namespace_decls
16
23
  doc = Document.new
17
24
  e = Node.new 'element', doc
@@ -31,11 +38,6 @@ module Nokogiri
31
38
  assert_equal "#<#{ns.class.name}:#{sprintf("0x%x", ns.object_id)} href=#{ns.href.inspect}>", ns.inspect
32
39
  end
33
40
 
34
- def test_namespace_is_in_node_cache
35
- node = @xml.root.namespace
36
- assert @xml.instance_variable_get(:@node_cache).include?(node)
37
- end
38
-
39
41
  def test_namespace_node_prefix
40
42
  namespaces = @xml.root.namespace_definitions
41
43
  assert_equal [nil, 'foo'], namespaces.map { |x| x.prefix }
@@ -82,18 +82,47 @@ module Nokogiri
82
82
  assert_equal 0, list.length
83
83
  end
84
84
 
85
+ def test_parse_config_option
86
+ node = @xml.root
87
+ options = nil
88
+ node.parse("<item></item>") do |config|
89
+ options = config
90
+ end
91
+ assert_equal Nokogiri::XML::ParseOptions::DEFAULT_XML, options.to_i
92
+ end
93
+
85
94
  # descriptive, not prescriptive.
86
95
  def test_parse_invalid_html_markup_results_in_empty_nodeset
87
96
  doc = Nokogiri::HTML("<html></html>")
88
97
  nodeset = doc.root.parse "<div><div>a</div><snippet>b</snippet></div>"
89
98
  assert_equal 1, doc.errors.length # "Tag snippet invalid"
99
+ assert_equal 1, nodeset.length
100
+ end
101
+
102
+ def test_node_context_parsing_of_malformed_html_fragment_with_recover_is_corrected
103
+ doc = HTML.parse "<html><body><div></div></body></html>"
104
+ context_node = doc.at_css "div"
105
+ nodeset = context_node.parse("<div </div>") do |options|
106
+ options.recover
107
+ end
108
+ assert_equal "<div></div>", nodeset.to_s
109
+ assert_equal 1, doc.errors.length
110
+ assert_equal 1, nodeset.length
111
+ end
112
+
113
+ def test_node_context_parsing_of_malformed_html_fragment_without_recover_is_not_corrected
114
+ doc = HTML.parse "<html><body><div></div></body></html>"
115
+ context_node = doc.at_css "div"
116
+ nodeset = context_node.parse("<div </div>") do |options|
117
+ options.strict
118
+ end
119
+ assert_equal 1, doc.errors.length
90
120
  assert_equal 0, nodeset.length
91
121
  end
92
122
 
93
123
  def test_parse_error_list
94
124
  error_count = @xml.errors.length
95
- list = @xml.root.parse('<hello>')
96
- assert_equal 0, list.length
125
+ @xml.root.parse('<hello>')
97
126
  assert(error_count < @xml.errors.length, "errors should have increased")
98
127
  end
99
128
 
@@ -457,6 +486,11 @@ module Nokogiri
457
486
  assert_equal 'Yes', @xml.css('address').first[:domestic]
458
487
  end
459
488
 
489
+ def test_non_existent_attribute_should_return_nil
490
+ node = @xml.root.first_element_child
491
+ assert_nil node.attribute('type')
492
+ end
493
+
460
494
  def test_write_to_with_block
461
495
  called = false
462
496
  io = StringIO.new
@@ -468,7 +502,9 @@ module Nokogiri
468
502
  end
469
503
  io.rewind
470
504
  assert called
471
- assert_equal @xml.serialize(nil, conf.options), io.read
505
+ string = io.read
506
+ assert_equal @xml.serialize(nil, conf.options), string
507
+ assert_equal @xml.serialize(nil, conf), string
472
508
  end
473
509
 
474
510
  %w{ xml html xhtml }.each do |type|
@@ -490,6 +526,7 @@ module Nokogiri
490
526
  end
491
527
  assert called
492
528
  assert_equal @xml.serialize(nil, conf.options), string
529
+ assert_equal @xml.serialize(nil, conf), string
493
530
  end
494
531
 
495
532
  def test_hold_refence_to_subnode
@@ -667,6 +704,15 @@ module Nokogiri
667
704
  assert_equal('/staff/employee[1]', node.path)
668
705
  end
669
706
 
707
+ def test_parent_xpath
708
+ assert set = @xml.search('//employee')
709
+ assert node = set.first
710
+ assert parent_set = node.search('..')
711
+ assert parent_node = parent_set.first
712
+ assert_equal '/staff', parent_node.path
713
+ assert_equal node.parent, parent_node
714
+ end
715
+
670
716
  def test_search_by_symbol
671
717
  assert set = @xml.search(:employee)
672
718
  assert 5, set.length
@@ -686,7 +732,7 @@ module Nokogiri
686
732
  assert_equal '&amp;', foo
687
733
  end
688
734
 
689
- def test_content
735
+ def test_content_equals
690
736
  node = Nokogiri::XML::Node.new('form', @xml)
691
737
  assert_equal('', node.content)
692
738
 
@@ -696,6 +742,10 @@ module Nokogiri
696
742
  node.content = '& <foo> &amp;'
697
743
  assert_equal('& <foo> &amp;', node.content)
698
744
  assert_equal('<form>&amp; &lt;foo&gt; &amp;amp;</form>', node.to_xml)
745
+
746
+ node.content = "1234 <-> 1234"
747
+ assert_equal "1234 <-> 1234", node.content
748
+ assert_equal "<form>1234 &lt;-&gt; 1234</form>", node.to_xml
699
749
  end
700
750
 
701
751
  def test_set_content_should_unlink_existing_content
@@ -814,17 +864,19 @@ module Nokogiri
814
864
  assert_equal nil, set[3].namespace
815
865
  end
816
866
 
817
- def test_namespace_without_an_href_on_html_node
818
- # because microsoft word's HTML formatting does this. ick.
819
- xml = Nokogiri::HTML.parse <<-EOF
820
- <div><o:p>foo</o:p></div>
821
- EOF
867
+ if Nokogiri.uses_libxml?
868
+ def test_namespace_without_an_href_on_html_node
869
+ # because microsoft word's HTML formatting does this. ick.
870
+ xml = Nokogiri::HTML.parse <<-EOF
871
+ <div><o:p>foo</o:p></div>
872
+ EOF
822
873
 
823
- assert_not_nil(node = xml.at('p'))
874
+ assert_not_nil(node = xml.at('p'))
824
875
 
825
- assert_equal 1, node.namespaces.keys.size
826
- assert node.namespaces.has_key?('xmlns:o')
827
- assert_equal nil, node.namespaces['xmlns:o']
876
+ assert_equal 1, node.namespaces.keys.size
877
+ assert node.namespaces.has_key?('xmlns:o')
878
+ assert_equal nil, node.namespaces['xmlns:o']
879
+ end
828
880
  end
829
881
 
830
882
  def test_line
@@ -50,21 +50,22 @@ module Nokogiri
50
50
  # end
51
51
 
52
52
  {
53
- :add_child => {:target => "/root/a1", :returns => :reparented, :children_tags => %w[text b1 b2]},
54
- :<< => {:target => "/root/a1", :returns => :reparented, :children_tags => %w[text b1 b2]},
53
+ :add_child => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
54
+ :<< => {:target => "/root/a1", :returns_self => true, :children_tags => %w[text b1 b2]},
55
55
 
56
- :replace => {:target => "/root/a1/node()", :returns => :reparented, :children_tags => %w[b1 b2]},
57
- :swap => {:target => "/root/a1/node()", :returns => :self, :children_tags => %w[b1 b2]},
56
+ :replace => {:target => "/root/a1/node()", :returns_self => false, :children_tags => %w[b1 b2]},
57
+ :swap => {:target => "/root/a1/node()", :returns_self => true, :children_tags => %w[b1 b2]},
58
58
 
59
- :inner_html= => {:target => "/root/a1", :returns => :self, :children_tags => %w[b1 b2]},
59
+ :children= => {:target => "/root/a1", :returns_self => false, :children_tags => %w[b1 b2]},
60
+ :inner_html= => {:target => "/root/a1", :returns_self => true, :children_tags => %w[b1 b2]},
60
61
 
61
- :add_previous_sibling => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[b1 b2 text]},
62
- :previous= => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[b1 b2 text]},
63
- :before => {:target => "/root/a1/text()", :returns => :self, :children_tags => %w[b1 b2 text]},
62
+ :add_previous_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
63
+ :previous= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
64
+ :before => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[b1 b2 text]},
64
65
 
65
- :add_next_sibling => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[text b1 b2]},
66
- :next= => {:target => "/root/a1/text()", :returns => :reparented, :children_tags => %w[text b1 b2]},
67
- :after => {:target => "/root/a1/text()", :returns => :self, :children_tags => %w[text b1 b2]}
66
+ :add_next_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
67
+ :next= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
68
+ :after => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[text b1 b2]}
68
69
  }.each do |method, params|
69
70
 
70
71
  before do
@@ -95,11 +96,12 @@ module Nokogiri
95
96
  end
96
97
 
97
98
  it "returns the expected value" do
98
- if params[:returns] == :self
99
- sendee = @doc.at_xpath(params[:target])
100
- sendee.send(method, @other_node).must_equal sendee
99
+ sendee = @doc.at_xpath(params[:target])
100
+ result = sendee.send(method, @other_node)
101
+ if params[:returns_self]
102
+ result.must_equal sendee
101
103
  else
102
- @doc.at_xpath(params[:target]).send(method, @other_node).must_equal @other_node
104
+ result.must_equal @other_node
103
105
  end
104
106
  end
105
107
  end
@@ -110,6 +112,17 @@ module Nokogiri
110
112
  @doc.at_xpath(params[:target]).send(method, @fragment_string)
111
113
  @doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
112
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
113
126
  end
114
127
  describe "passed a fragment" do
115
128
  it "inserts the fragment roots in the proper position" do
@@ -153,16 +166,19 @@ module Nokogiri
153
166
  end
154
167
 
155
168
  describe "ad hoc node reparenting behavior" do
156
- before do
157
- @xml = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third node</a3></root>"
158
- @html = Nokogiri::HTML(<<-eohtml)
159
- <html>
160
- <head></head>
161
- <body>
162
- <div class='baz'><a href="foo" class="bar">first</a></div>
163
- </body>
164
- </html>
165
- eohtml
169
+ describe "#<<" do
170
+ it "allows chaining" do
171
+ doc = Nokogiri::XML::Document.new
172
+ root = Nokogiri::XML::Element.new('root', doc)
173
+ doc.root = root
174
+
175
+ child1 = Nokogiri::XML::Element.new('child1', doc)
176
+ child2 = Nokogiri::XML::Element.new('child2', doc)
177
+
178
+ doc.root << child1 << child2
179
+
180
+ assert_equal [child1, child2], doc.root.children.to_a
181
+ end
166
182
  end
167
183
 
168
184
  describe "#add_child" do
@@ -223,7 +239,34 @@ module Nokogiri
223
239
  end
224
240
  end
225
241
 
242
+ describe "#add_previous_sibling" do
243
+ it "should not merge text nodes during the operation" do
244
+ xml = Nokogiri::XML %Q(<root>text node</root>)
245
+ replacee = xml.root.children.first
246
+ replacee.add_previous_sibling "foo <p></p> bar"
247
+ assert_equal "foo <p></p> bartext node", xml.root.children.to_html
248
+ end
249
+ end
250
+
251
+ describe "#add_next_sibling" do
252
+ it "should not merge text nodes during the operation" do
253
+ xml = Nokogiri::XML %Q(<root>text node</root>)
254
+ replacee = xml.root.children.first
255
+ replacee.add_next_sibling "foo <p></p> bar"
256
+ assert_equal "text nodefoo <p></p> bar", xml.root.children.to_html
257
+ end
258
+ end
259
+
226
260
  describe "#replace" do
261
+ describe "a text node with a text node" do
262
+ it "should not merge text nodes during the operation" do
263
+ xml = Nokogiri::XML %Q(<root>text node</root>)
264
+ replacee = xml.root.children.first
265
+ replacee.replace "new text node"
266
+ assert_equal "new text node", xml.root.children.first.content
267
+ end
268
+ end
269
+
227
270
  describe "when a document has a default namespace" do
228
271
  before do
229
272
  @fruits = Nokogiri::XML(<<-eoxml)
@@ -248,8 +291,6 @@ module Nokogiri
248
291
  it "not blow up" do
249
292
  # see http://github.com/tenderlove/nokogiri/issues#issue/22
250
293
  10.times do
251
- STDOUT.putc "."
252
- STDOUT.flush
253
294
  begin
254
295
  doc = Nokogiri::XML <<-EOHTML
255
296
  <root>
@@ -260,10 +301,10 @@ module Nokogiri
260
301
  </root>
261
302
  EOHTML
262
303
 
263
- root = doc.at("root")
264
- a = root.at("a")
265
- b = a.at("b")
266
- c = a.at("c")
304
+ assert root = doc.at("root")
305
+ assert a = root.at("a")
306
+ assert b = a.at("b")
307
+ assert c = a.at("c")
267
308
  a.add_next_sibling(b.unlink)
268
309
  c.unlink
269
310
  end
@@ -30,6 +30,10 @@ module Nokogiri
30
30
  @list = @xml.css('employee')
31
31
  end
32
32
 
33
+ def test_break_works
34
+ assert_equal 7, @xml.root.elements.each { |x| break 7 }
35
+ end
36
+
33
37
  def test_filter
34
38
  list = @xml.css('address').filter('*[domestic="Yes"]')
35
39
  assert_equal(%w{ Yes } * 4, list.map { |n| n['domestic'] })
@@ -158,6 +162,16 @@ module Nokogiri
158
162
  set = html.xpath("/html/body/div")
159
163
  assert_equal set.first, set.search(".a").first
160
164
  end
165
+
166
+ def test_css_search_with_namespace
167
+ fragment = Nokogiri::XML.fragment(<<-eoxml)
168
+ <html xmlns="http://www.w3.org/1999/xhtml">
169
+ <head></head>
170
+ <body></body>
171
+ </html>
172
+ eoxml
173
+ assert_nothing_raised{ fragment.children.search( 'body', { 'xmlns' => 'http://www.w3.org/1999/xhtml' }) }
174
+ end
161
175
 
162
176
  def test_double_equal
163
177
  assert node_set_one = @xml.xpath('//employee')
@@ -224,6 +238,11 @@ module Nokogiri
224
238
  end
225
239
  end
226
240
 
241
+ def test_dup_on_empty_set
242
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
243
+ assert_equal 0, empty_set.dup.length # this shouldn't raise null pointer exception
244
+ end
245
+
227
246
  def test_xmlns_is_automatically_registered
228
247
  doc = Nokogiri::XML(<<-eoxml)
229
248
  <root xmlns="http://tenderlovemaking.com/">
@@ -348,6 +367,12 @@ module Nokogiri
348
367
  assert length, employees.length
349
368
  end
350
369
 
370
+ def test_delete_on_empty_set
371
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
372
+ employee = @xml.at_xpath("//employee")
373
+ assert_equal nil, empty_set.delete(employee)
374
+ end
375
+
351
376
  def test_unlink
352
377
  xml = Nokogiri::XML.parse(<<-eoxml)
353
378
  <root>
@@ -431,6 +456,19 @@ module Nokogiri
431
456
  assert_equal 'employee', @xml.search("//wrapper").first.children[0].name
432
457
  end
433
458
 
459
+ def test_wrap_a_fragment
460
+ frag = Nokogiri::XML::DocumentFragment.parse <<-EOXML
461
+ <employees>
462
+ <employee>hello</employee>
463
+ <employee>goodbye</employee>
464
+ </employees>
465
+ EOXML
466
+ employees = frag.xpath ".//employee"
467
+ employees.wrap("<wrapper/>")
468
+ assert_equal 'wrapper', employees[0].parent.name
469
+ assert_equal 'employee', frag.at(".//wrapper").children.first.name
470
+ end
471
+
434
472
  def test_wrap_preserves_document_structure
435
473
  assert_equal "employeeId",
436
474
  @xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
@@ -495,6 +533,13 @@ module Nokogiri
495
533
  assert_equal employees.length, employees[0, employees.length].length
496
534
  end
497
535
 
536
+ def test_slice_on_empty_node_set
537
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
538
+ assert_equal nil, empty_set[99]
539
+ assert_equal nil, empty_set[99..101]
540
+ assert_equal nil, empty_set[99,2]
541
+ end
542
+
498
543
  def test_slice_waaaaaay_off_the_end
499
544
  xml = Nokogiri::XML::Builder.new {
500
545
  root { 100.times { div } }
@@ -549,6 +594,12 @@ module Nokogiri
549
594
  assert_equal [employees[2]], (first_set & second_set).to_a
550
595
  end
551
596
 
597
+ def test_intersection_on_empty_set
598
+ empty_set = Nokogiri::XML::NodeSet.new @xml
599
+ employees = @xml.search("//employee")
600
+ assert_equal 0, (empty_set & employees).length
601
+ end
602
+
552
603
  def test_include?
553
604
  employees = @xml.search("//employee")
554
605
  yes = employees.first
@@ -558,6 +609,12 @@ module Nokogiri
558
609
  assert ! employees.include?(no)
559
610
  end
560
611
 
612
+ def test_include_on_empty_node_set
613
+ empty_set = Nokogiri::XML::NodeSet.new @xml, []
614
+ employee = @xml.at_xpath("//employee")
615
+ assert ! empty_set.include?(employee)
616
+ end
617
+
561
618
  def test_children
562
619
  employees = @xml.search("//employee")
563
620
  count = 0
@@ -74,6 +74,11 @@ module Nokogiri
74
74
  assert_equal 2, errors.length
75
75
  end
76
76
 
77
+ def test_validate_non_document
78
+ string = File.read(PO_XML_FILE)
79
+ assert_raise(ArgumentError) {@xsd.validate(string)}
80
+ end
81
+
77
82
  def test_valid?
78
83
  valid_doc = Nokogiri::XML(File.read(PO_XML_FILE))
79
84
 
@@ -61,6 +61,10 @@ module Nokogiri
61
61
  }.new
62
62
  end
63
63
 
64
+ def test_variable_binding
65
+ assert_equal 4, @xml.xpath('//address[@domestic=$value]', nil, :value => 'Yes').length
66
+ end
67
+
64
68
  def test_unknown_attribute
65
69
  assert_equal 0, @xml.xpath('//employee[@id="asdfasdf"]/@fooo').length
66
70
  assert_nil @xml.xpath('//employee[@id="asdfasdf"]/@fooo')[0]
@@ -200,6 +204,34 @@ module Nokogiri
200
204
  nokogiri = Nokogiri::HTML.parse(doc)
201
205
  assert nokogiri.xpath(xpath)
202
206
  end
207
+
208
+ def test_custom_xpath_handler_with_args_under_gc_pressure
209
+ # see http://github.com/tenderlove/nokogiri/issues/#issue/345
210
+ tool_inspector = Class.new do
211
+ def name_equals(nodeset, name, *args)
212
+ nodeset.all? do |node|
213
+ args.each { |thing| thing.inspect }
214
+ node["name"] == name
215
+ end
216
+ end
217
+ end.new
218
+
219
+ xml = <<-EOXML
220
+ <toolbox>
221
+ #{"<tool name='hammer'/><tool name='wrench'/>" * 10}
222
+ </toolbox>
223
+ EOXML
224
+ doc = Nokogiri::XML xml
225
+
226
+ # long list of long arguments, to apply GC pressure during
227
+ # ruby_funcall argument marshalling
228
+ xpath = ["//tool[name_equals(.,'hammer'"]
229
+ 1000.times { xpath << "'unused argument #{'x' * 1000}'" }
230
+ xpath << "'unused argument')]"
231
+ xpath = xpath.join(',')
232
+
233
+ assert_equal doc.xpath("//tool[@name='hammer']"), doc.xpath(xpath, tool_inspector)
234
+ end
203
235
  end
204
236
  end
205
237
  end