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
@@ -1,7 +1,36 @@
1
1
  module Nokogiri
2
2
  module XML
3
3
  module SAX
4
+ ###
5
+ # This parser is a SAX style parser that reads it's input as it
6
+ # deems necessary. The parser takes a Nokogiri::XML::SAX::Document,
7
+ # an optional encoding, then given an XML input, sends messages to
8
+ # the Nokogiri::XML::SAX::Document.
9
+ #
10
+ # Here is an example of using this parser:
11
+ #
12
+ # # Create a subclass of Nokogiri::XML::SAX::Document and implement
13
+ # # the events we care about:
14
+ # class MyDoc < Nokogiri::XML::SAX::Document
15
+ # def start_element name, attrs = []
16
+ # puts "starting: #{name}"
17
+ # end
18
+ #
19
+ # def end_element name
20
+ # puts "ending: #{name}"
21
+ # end
22
+ # end
23
+ #
24
+ # # Create our parser
25
+ # parser = Nokogiri::XML::SAX::Parser.new(MyDoc.new)
26
+ #
27
+ # # Send some XML to the parser
28
+ # parser.parse(File.read(ARGV[0]))
29
+ #
30
+ # For more information about SAX parsers, see Nokogiri::XML::SAX. Also
31
+ # see Nokogiri::XML::SAX::Document for the available events.
4
32
  class Parser
33
+ # Encodinds this parser supports
5
34
  ENCODINGS = {
6
35
  'NONE' => 0, # No char encoding detected
7
36
  'UTF-8' => 1, # UTF-8
@@ -28,8 +57,14 @@ module Nokogiri
28
57
  'ASCII' => 22, # pure ASCII
29
58
  }
30
59
 
31
- attr_accessor :document, :encoding
32
- def initialize(doc = XML::SAX::Document.new, encoding = 'ASCII')
60
+ # The Nokogiri::XML::SAX::Document where events will be sent.
61
+ attr_accessor :document
62
+
63
+ # The encoding beings used for this document.
64
+ attr_accessor :encoding
65
+
66
+ # Create a new Parser with +doc+ and +encoding+
67
+ def initialize(doc = Nokogiri::XML::SAX::Document.new, encoding = 'ASCII')
33
68
  @encoding = encoding
34
69
  @document = doc
35
70
  end
@@ -55,6 +90,7 @@ module Nokogiri
55
90
  ###
56
91
  # Parse a file with +filename+
57
92
  def parse_file filename
93
+ raise ArgumentError unless filename
58
94
  raise Errno::ENOENT unless File.exists?(filename)
59
95
  raise Errno::EISDIR if File.directory?(filename)
60
96
  native_parse_file filename
@@ -23,8 +23,14 @@ module Nokogiri
23
23
  # parser << "/div>"
24
24
  # parser.finish
25
25
  class PushParser
26
+
27
+ # The Nokogiri::XML::SAX::Document on which the PushParser will be
28
+ # operating
26
29
  attr_accessor :document
27
30
 
31
+ ###
32
+ # Create a new PushParser with +doc+ as the SAX Document, providing
33
+ # an optional +file_name+ and +encoding+
28
34
  def initialize(doc = XML::SAX::Document.new, file_name = nil, encoding = 'ASCII')
29
35
  @document = doc
30
36
  @encoding = encoding
@@ -34,11 +40,17 @@ module Nokogiri
34
40
  initialize_native(@sax_parser, file_name)
35
41
  end
36
42
 
43
+ ###
44
+ # Write a +chunk+ of XML to the PushParser. Any callback methods
45
+ # that can be called will be called immidiately.
37
46
  def write chunk, last_chunk = false
38
47
  native_write(chunk, last_chunk)
39
48
  end
40
49
  alias :<< :write
41
50
 
51
+ ###
52
+ # Finish the parsing. This method is only necessary for
53
+ # Nokogiri::XML::SAX::Document#end_document to be called.
42
54
  def finish
43
55
  write '', true
44
56
  end
@@ -0,0 +1,65 @@
1
+ module Nokogiri
2
+ module XML
3
+ class << self
4
+ ###
5
+ # Create a new Nokogiri::XML::Schema object using a +string_or_io+
6
+ # object.
7
+ def Schema string_or_io
8
+ Schema.new(string_or_io)
9
+ end
10
+ end
11
+
12
+ ###
13
+ # Nokogiri::XML::Schema is used for validating XML against a schema
14
+ # (usually from an xsd file).
15
+ #
16
+ # == Synopsis
17
+ #
18
+ # Validate an XML document against a Schema. Loop over the errors that
19
+ # are returned and print them out:
20
+ #
21
+ # xsd = Nokogiri::XML::Schema(File.read(PO_SCHEMA_FILE))
22
+ # doc = Nokogiri::XML(File.read(PO_XML_FILE))
23
+ #
24
+ # xsd.validate(doc).each do |error|
25
+ # puts error.message
26
+ # end
27
+ #
28
+ # The list of errors are Nokogiri::XML::SyntaxError objects.
29
+ class Schema
30
+ # Errors while parsing the schema file
31
+ attr_accessor :errors
32
+
33
+ ###
34
+ # Create a new Nokogiri::XML::Schema object using a +string_or_io+
35
+ # object.
36
+ def self.new string_or_io
37
+ if string_or_io.respond_to?(:read)
38
+ string_or_io = string_or_io.read
39
+ end
40
+
41
+ read_memory(string_or_io)
42
+ end
43
+
44
+ ###
45
+ # Validate +thing+ against this schema. +thing+ can be a
46
+ # Nokogiri::XML::Document object, or a filename. An Array of
47
+ # Nokogiri::XML::SyntaxError objects found while validating the
48
+ # +thing+ is returned.
49
+ def validate thing
50
+ return validate_document(thing) if thing.is_a?(Nokogiri::XML::Document)
51
+
52
+ # FIXME libxml2 has an api for validating files. We should switch
53
+ # to that because it will probably save memory.
54
+ validate_document(Nokogiri::XML(File.read(thing)))
55
+ end
56
+
57
+ ###
58
+ # Returns true if +thing+ is a valid Nokogiri::XML::Document or
59
+ # file.
60
+ def valid? thing
61
+ validate(thing).length == 0
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,18 +1,29 @@
1
1
  module Nokogiri
2
2
  module XML
3
+ ###
4
+ # This class provides information about XML SyntaxErrors. These
5
+ # exceptions are typically stored on Nokogiri::XML::Document#errors.
3
6
  class SyntaxError < ::Nokogiri::SyntaxError
7
+ ###
8
+ # return true if this is a non error
4
9
  def none?
5
10
  level == 0
6
11
  end
7
12
 
13
+ ###
14
+ # return true if this is a warning
8
15
  def warning?
9
16
  level == 1
10
17
  end
11
18
 
19
+ ###
20
+ # return true if this is an error
12
21
  def error?
13
22
  level == 2
14
23
  end
15
24
 
25
+ ###
26
+ # return true if this error is fatal
16
27
  def fatal?
17
28
  level == 3
18
29
  end
@@ -3,8 +3,8 @@ require 'nokogiri/xml/xpath/syntax_error'
3
3
  module Nokogiri
4
4
  module XML
5
5
  class XPath
6
+ # The Nokogiri::XML::Document tied to this XPath instance
6
7
  attr_accessor :document
7
-
8
8
  end
9
9
  end
10
10
  end
@@ -2,6 +2,8 @@ module Nokogiri
2
2
  module XML
3
3
  class XPathContext
4
4
 
5
+ ###
6
+ # Register namespaces in +namespaces+
5
7
  def register_namespaces(namespaces)
6
8
  namespaces.each do |k, v|
7
9
  k = k.gsub(/.*:/,'') # strip off 'xmlns:' or 'xml:'
@@ -1,12 +1,32 @@
1
1
  require 'nokogiri/xslt/stylesheet'
2
2
 
3
3
  module Nokogiri
4
+ class << self
5
+ ###
6
+ # Create a Nokogiri::XSLT::Stylesheet with +stylesheet+.
7
+ #
8
+ # Example:
9
+ #
10
+ # xslt = Nokogiri::XSLT(File.read(ARGV[0]))
11
+ #
12
+ def XSLT stylesheet
13
+ XSLT.parse(stylesheet)
14
+ end
15
+ end
16
+
17
+ ###
18
+ # See Nokogiri::XSLT::Stylesheet for creating and maniuplating
19
+ # Stylesheet object.
4
20
  module XSLT
5
21
  class << self
6
- def parse(string)
22
+ ###
23
+ # Parse the stylesheet in +string+
24
+ def parse string
7
25
  Stylesheet.parse_stylesheet_doc(XML.parse(string))
8
26
  end
9
27
 
28
+ ###
29
+ # Quote parameters in +params+ for stylesheet safety
10
30
  def quote_params params
11
31
  parray = (params.instance_of?(Hash) ? params.to_a.flatten : params).dup
12
32
  parray.each_with_index do |v,i|
@@ -1,6 +1,25 @@
1
1
  module Nokogiri
2
2
  module XSLT
3
+ ###
4
+ # A Stylesheet represents an XSLT Stylesheet object. Stylesheet creation
5
+ # is done through Nokogiri.XSLT. Here is an example of transforming
6
+ # an XML::Document with a Stylesheet:
7
+ #
8
+ # doc = Nokogiri::XML(File.read('some_file.xml'))
9
+ # xslt = Nokogir::XSLT(File.read('some_transformer.xslt'))
10
+ #
11
+ # puts xslt.transform(doc)
12
+ #
13
+ # See Nokogiri::XSLT::Stylesheet#transform for more transformation
14
+ # information.
3
15
  class Stylesheet
16
+ ###
17
+ # Apply an XSLT stylesheet to an XML::Document.
18
+ # +params+ is an array of strings used as XSLT parameters.
19
+ # returns serialized document
20
+ def apply_to document, params = []
21
+ serialize(transform(document, params))
22
+ end
4
23
  end
5
24
  end
6
25
  end
@@ -1,7 +1,7 @@
1
1
  require 'nokogiri'
2
2
 
3
- module XSD
4
- module XMLParser
3
+ module XSD # :nodoc:
4
+ module XMLParser # :nodoc:
5
5
  ###
6
6
  # Nokogiri XML parser for soap4r.
7
7
  #
@@ -23,24 +23,34 @@ module XSD
23
23
  # ...
24
24
  # end
25
25
  class Nokogiri < XSD::XMLParser::Parser
26
+ ###
27
+ # Create a new XSD parser with +host+ and +opt+
26
28
  def initialize host, opt = {}
27
29
  super
28
30
  @parser = ::Nokogiri::XML::SAX::Parser.new(self, @charset || 'UTF-8')
29
31
  end
30
32
 
33
+ ###
34
+ # Start parsing +string_or_readable+
31
35
  def do_parse string_or_readable
32
36
  @parser.parse(string_or_readable)
33
37
  end
34
38
 
39
+ ###
40
+ # Handle the start_element event with +name+ and +attrs+
35
41
  def start_element name, attrs = []
36
42
  super(name, Hash[*attrs])
37
43
  end
38
44
 
45
+ ###
46
+ # Handle errors with message +msg+
39
47
  def error msg
40
48
  raise ParseError.new(msg)
41
49
  end
42
50
  alias :warning :error
43
51
 
52
+ ###
53
+ # Handle cdata_blocks containing +string+
44
54
  def cdata_block string
45
55
  characters string
46
56
  end
@@ -19,36 +19,28 @@ end
19
19
  desc "run test suite under valgrind with basic ruby options"
20
20
  NokogiriTestTask.new('test:valgrind').extend(Module.new {
21
21
  def ruby *args
22
- cmd = "valgrind #{VALGRIND_BASIC_OPTS} #{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
23
- puts cmd
24
- system cmd
22
+ run_with_env "valgrind #{VALGRIND_BASIC_OPTS} #{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
25
23
  end
26
24
  })
27
25
 
28
26
  desc "run test suite under valgrind with memory-fill ruby options"
29
27
  NokogiriTestTask.new('test:valgrind_mem').extend(Module.new {
30
28
  def ruby *args
31
- cmd = "valgrind #{VALGRIND_BASIC_OPTS} --freelist-vol=100000000 --malloc-fill=6D --free-fill=66 #{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
32
- puts cmd
33
- system cmd
29
+ run_with_env "valgrind #{VALGRIND_BASIC_OPTS} --freelist-vol=100000000 --malloc-fill=6D --free-fill=66 #{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
34
30
  end
35
31
  })
36
32
 
37
33
  desc "run test suite under valgrind with memory-zero ruby options"
38
34
  NokogiriTestTask.new('test:valgrind_mem0').extend(Module.new {
39
35
  def ruby *args
40
- cmd = "valgrind #{VALGRIND_BASIC_OPTS} --freelist-vol=100000000 --malloc-fill=00 --free-fill=00 #{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
41
- puts cmd
42
- system cmd
36
+ run_with_env "valgrind #{VALGRIND_BASIC_OPTS} --freelist-vol=100000000 --malloc-fill=00 --free-fill=00 #{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
43
37
  end
44
38
  })
45
39
 
46
40
  desc "run test suite under gdb"
47
41
  NokogiriTestTask.new('test:gdb').extend(Module.new {
48
42
  def ruby *args
49
- cmd = "gdb --args #{RUBY} #{args.join(' ')}"
50
- puts cmd
51
- system cmd
43
+ run_with_env "gdb --args #{RUBY} #{args.join(' ')}"
52
44
  end
53
45
  })
54
46
 
@@ -56,12 +48,23 @@ desc "test coverage"
56
48
  NokogiriTestTask.new('test:coverage').extend(Module.new {
57
49
  def ruby *args
58
50
  rm_rf "coverage"
59
- cmd = "rcov -x Library -I lib:ext:test #{args.join(' ')}"
60
- puts cmd
61
- system cmd
51
+ run_with_env "rcov -x Library -I lib:ext:test #{args.join(' ')}"
62
52
  end
63
53
  })
64
54
 
55
+ desc "run test suite with verbose output"
56
+ NokogiriTestTask.new('test:verbose').extend(Module.new {
57
+ def ruby *args
58
+ run_with_env "#{RUBY} #{args.join(' ')} test/test_nokogiri.rb --verbose=verbose"
59
+ end
60
+ })
61
+
62
+ def run_with_env(cmd)
63
+ cmd = "LD_LIBRARY_PATH='#{ENV['LD_LIBRARY_PATH']}' #{cmd}"
64
+ puts "=> #{cmd}"
65
+ system cmd
66
+ end
67
+
65
68
  namespace :test do
66
69
  desc "run test suite with aggressive GC"
67
70
  task :gc => :build do
@@ -70,14 +73,32 @@ namespace :test do
70
73
  end
71
74
 
72
75
  desc "find call-seq in the rdoc"
73
- task :rdoc => 'docs' do
76
+ task :rdoc_call_seq => 'docs' do
74
77
  Dir['doc/**/*.html'].each { |docfile|
75
78
  next if docfile =~ /\.src/
76
79
  puts "FAIL: #{docfile}" if File.read(docfile) =~ /call-seq/
77
80
  }
78
81
  end
79
82
 
80
- desc "Test against multiple versions of libxml2"
83
+ desc "find all undocumented things"
84
+ task :rdoc => 'docs' do
85
+ base = File.expand_path(File.join(File.dirname(__FILE__), '..', 'doc'))
86
+ require 'test/unit'
87
+ test = Class.new(Test::Unit::TestCase)
88
+ Dir["#{base}/**/*.html"].each { |docfile|
89
+ test.class_eval(<<-eotest)
90
+ def test_#{docfile.sub("#{base}/", '').gsub(/[\/\.-]/, '_')}
91
+ assert_no_match(
92
+ /Not documented/,
93
+ File.read('#{docfile}'),
94
+ '#{docfile} has undocumented things'
95
+ )
96
+ end
97
+ eotest
98
+ }
99
+ end
100
+
101
+ desc "Test against multiple versions of libxml2 (MULTIXML2_DIR=directory)"
81
102
  task :multixml2 do
82
103
  MULTI_XML = File.join(ENV['HOME'], '.multixml2')
83
104
  unless File.exists?(MULTI_XML)
@@ -117,10 +138,12 @@ namespace :test do
117
138
 
118
139
  test_results = {}
119
140
  libxslt = Dir[File.join(MULTI_XML, 'install', 'libxslt*')].first
120
- Dir[File.join(MULTI_XML, 'install', '*')].each do |xml2_version|
141
+
142
+ directories = ENV['MULTIXML2_DIR'] ? [ENV['MULTIXML2_DIR']] : Dir[File.join(MULTI_XML, 'install', '*')]
143
+ directories.sort.reverse.each do |xml2_version|
121
144
  next unless xml2_version =~ /libxml2/
122
145
  extopts = "--with-xml2-include=#{xml2_version}/include/libxml2 --with-xml2-lib=#{xml2_version}/lib --with-xslt-dir=#{libxslt}"
123
- cmd = "#{$0} clean test EXTOPTS='#{extopts}'"
146
+ cmd = "#{$0} clean test EXTOPTS='#{extopts}' LD_LIBRARY_PATH='#{xml2_version}/lib'"
124
147
 
125
148
  version = File.basename(xml2_version)
126
149
  result = system(cmd)
@@ -54,6 +54,20 @@ module Nokogiri
54
54
  )
55
55
  end
56
56
 
57
+ def test_dashmatch
58
+ assert_xpath "//a[@class = 'bar' or starts-with(@class, concat('bar', '-'))]",
59
+ @parser.parse("a[@class|='bar']")
60
+ assert_xpath "//a[@class = 'bar' or starts-with(@class, concat('bar', '-'))]",
61
+ @parser.parse("a[@class |= 'bar']")
62
+ end
63
+
64
+ def test_includes
65
+ assert_xpath "//a[contains(concat(\" \", @class, \" \"),concat(\" \", 'bar', \" \"))]",
66
+ @parser.parse("a[@class~='bar']")
67
+ assert_xpath "//a[contains(concat(\" \", @class, \" \"),concat(\" \", 'bar', \" \"))]",
68
+ @parser.parse("a[@class ~= 'bar']")
69
+ end
70
+
57
71
  def test_function_with_arguments
58
72
  assert_xpath "//*[position() = 2 and self::a]",
59
73
  @parser.parse("a[2]")
@@ -64,12 +78,23 @@ module Nokogiri
64
78
  def test_carrot
65
79
  assert_xpath "//a[starts-with(@id, 'Boing')]",
66
80
  @parser.parse("a[id^='Boing']")
81
+ assert_xpath "//a[starts-with(@id, 'Boing')]",
82
+ @parser.parse("a[id ^= 'Boing']")
83
+ end
84
+
85
+ def test_suffix_match
86
+ assert_xpath "//a[substring(@id, string-length(@id) - string-length('Boing') + 1, string-length('Boing')) = 'Boing']",
87
+ @parser.parse("a[id$='Boing']")
88
+ assert_xpath "//a[substring(@id, string-length(@id) - string-length('Boing') + 1, string-length('Boing')) = 'Boing']",
89
+ @parser.parse("a[id $= 'Boing']")
67
90
  end
68
91
 
69
92
  def test_attributes_with_at
70
93
  ## This is non standard CSS
71
94
  assert_xpath "//a[@id = 'Boing']",
72
95
  @parser.parse("a[@id='Boing']")
96
+ assert_xpath "//a[@id = 'Boing']",
97
+ @parser.parse("a[@id = 'Boing']")
73
98
  end
74
99
 
75
100
  def test_attributes_with_at_and_stuff
@@ -82,6 +107,8 @@ module Nokogiri
82
107
  ## This is non standard CSS
83
108
  assert_xpath "//a[child::text() != 'Boing']",
84
109
  @parser.parse("a[text()!='Boing']")
110
+ assert_xpath "//a[child::text() != 'Boing']",
111
+ @parser.parse("a[text() != 'Boing']")
85
112
  end
86
113
 
87
114
  def test_function
@@ -96,6 +123,8 @@ module Nokogiri
96
123
  ## This is non standard CSS
97
124
  assert_xpath "//a[contains(child::text(), 'Boing')]",
98
125
  @parser.parse("a[text()*='Boing']")
126
+ assert_xpath "//a[contains(child::text(), 'Boing')]",
127
+ @parser.parse("a[text() *= 'Boing']")
99
128
 
100
129
  ## This is non standard CSS
101
130
  assert_xpath "//script//comment()",