nokogiri 1.2.1 → 1.2.2

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 (75) hide show
  1. data/.autotest +15 -0
  2. data/{History.ja.txt → CHANGELOG.ja.rdoc} +30 -2
  3. data/{History.txt → CHANGELOG.rdoc} +28 -2
  4. data/Manifest.txt +13 -7
  5. data/{README.ja.txt → README.ja.rdoc} +3 -1
  6. data/{README.txt → README.rdoc} +7 -1
  7. data/Rakefile +8 -25
  8. data/ext/nokogiri/extconf.rb +4 -4
  9. data/ext/nokogiri/html_entity_lookup.c +30 -0
  10. data/ext/nokogiri/html_entity_lookup.h +8 -0
  11. data/ext/nokogiri/native.c +22 -0
  12. data/ext/nokogiri/native.h +27 -4
  13. data/ext/nokogiri/xml_document.c +31 -4
  14. data/ext/nokogiri/xml_document.h +11 -0
  15. data/ext/nokogiri/xml_document_fragment.c +1 -1
  16. data/ext/nokogiri/xml_node.c +71 -58
  17. data/ext/nokogiri/xml_node_set.c +26 -0
  18. data/ext/nokogiri/xml_reader.c +4 -2
  19. data/ext/nokogiri/xml_sax_parser.c +0 -37
  20. data/ext/nokogiri/xml_sax_push_parser.c +2 -2
  21. data/ext/nokogiri/xml_xpath_context.c +34 -7
  22. data/lib/nokogiri.rb +25 -0
  23. data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
  24. data/lib/nokogiri/css/node.rb +2 -0
  25. data/lib/nokogiri/css/parser.rb +3 -2
  26. data/lib/nokogiri/html.rb +9 -52
  27. data/lib/nokogiri/html/document.rb +2 -0
  28. data/lib/nokogiri/html/entity_lookup.rb +11 -0
  29. data/lib/nokogiri/version.rb +1 -1
  30. data/lib/nokogiri/xml.rb +1 -2
  31. data/lib/nokogiri/xml/builder.rb +18 -5
  32. data/lib/nokogiri/xml/document.rb +15 -1
  33. data/lib/nokogiri/xml/fragment_handler.rb +34 -0
  34. data/lib/nokogiri/xml/node.rb +104 -29
  35. data/lib/nokogiri/xml/node_set.rb +12 -10
  36. data/lib/nokogiri/xml/sax/parser.rb +3 -3
  37. data/lib/xsd/xmlparser/nokogiri.rb +53 -0
  38. data/tasks/test.rb +7 -5
  39. data/test/css/test_nthiness.rb +1 -0
  40. data/test/css/test_parser.rb +1 -0
  41. data/test/css/test_tokenizer.rb +1 -0
  42. data/test/css/test_xpath_visitor.rb +1 -0
  43. data/test/helper.rb +4 -0
  44. data/test/hpricot/test_alter.rb +1 -0
  45. data/test/html/sax/test_parser.rb +13 -0
  46. data/test/html/test_builder.rb +21 -0
  47. data/test/html/test_document.rb +36 -0
  48. data/test/html/test_document_encoding.rb +46 -0
  49. data/test/html/test_named_characters.rb +14 -0
  50. data/test/html/test_node.rb +80 -0
  51. data/test/test_convert_xpath.rb +1 -0
  52. data/test/test_css_cache.rb +1 -0
  53. data/test/test_nokogiri.rb +8 -0
  54. data/test/xml/sax/test_parser.rb +6 -0
  55. data/test/xml/sax/test_push_parser.rb +1 -0
  56. data/test/xml/test_builder.rb +9 -0
  57. data/test/xml/test_cdata.rb +1 -0
  58. data/test/xml/test_comment.rb +1 -0
  59. data/test/xml/test_document.rb +58 -0
  60. data/test/xml/test_document_encoding.rb +15 -14
  61. data/test/xml/test_document_fragment.rb +6 -0
  62. data/test/xml/test_dtd.rb +1 -0
  63. data/test/xml/test_dtd_encoding.rb +1 -0
  64. data/test/xml/test_entity_reference.rb +1 -0
  65. data/test/xml/test_node.rb +52 -4
  66. data/test/xml/test_node_encoding.rb +1 -0
  67. data/test/xml/test_node_set.rb +21 -1
  68. data/test/xml/test_processing_instruction.rb +1 -0
  69. data/test/xml/test_reader_encoding.rb +1 -0
  70. data/test/xml/test_unparented_node.rb +381 -0
  71. data/test/xml/test_xpath.rb +1 -0
  72. metadata +34 -16
  73. data/lib/nokogiri/xml/after_handler.rb +0 -18
  74. data/lib/nokogiri/xml/before_handler.rb +0 -33
  75. data/vendor/hoe.rb +0 -1020
@@ -11,6 +11,7 @@ end
11
11
  class TestConvertXPath < Nokogiri::TestCase
12
12
 
13
13
  def setup
14
+ super
14
15
  @N = Nokogiri(File.read(HTML_FILE))
15
16
  @NH = Nokogiri.Hpricot(File.read(HTML_FILE)) # decorated document
16
17
  @H = Hpricot(File.read(HTML_FILE)) if HAS_HPRICOT
@@ -3,6 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
3
3
  class TestCssCache < Nokogiri::TestCase
4
4
 
5
5
  def setup
6
+ super
6
7
  @css = "a1 > b2 > c3"
7
8
  @parse_result = Nokogiri::CSS.parse(@css)
8
9
  @to_xpath_result = @parse_result.map {|ast| ast.to_xpath}
@@ -1,6 +1,14 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
2
2
 
3
3
  class TestNokogiri < Nokogiri::TestCase
4
+ def test_version
5
+ Nokogiri::LIBXML_PARSER_VERSION =~ /(\d)(\d{2})(\d{2})/
6
+ major = $1.to_i
7
+ minor = $2.to_i
8
+ bug = $3.to_i
9
+ assert_equal "#{major}.#{minor}.#{bug}", Nokogiri::LIBXML_VERSION
10
+ end
11
+
4
12
  def test_xml?
5
13
  doc = Nokogiri.parse(File.read(XML_FILE))
6
14
  assert doc.xml?
@@ -5,6 +5,7 @@ module Nokogiri
5
5
  module SAX
6
6
  class TestParser < Nokogiri::SAX::TestCase
7
7
  def setup
8
+ super
8
9
  @parser = XML::SAX::Parser.new(Doc.new)
9
10
  end
10
11
 
@@ -14,6 +15,11 @@ module Nokogiri
14
15
  assert @parser.document.errors.length > 0
15
16
  end
16
17
 
18
+ def test_parser_sets_encoding
19
+ parser = XML::SAX::Parser.new(Doc.new, 'UTF-8')
20
+ assert_equal 'UTF-8', parser.encoding
21
+ end
22
+
17
23
  def test_errors_set_after_parsing_bad_dom
18
24
  doc = Nokogiri::XML('<foo><bar></foo>')
19
25
  assert doc.errors
@@ -5,6 +5,7 @@ module Nokogiri
5
5
  module SAX
6
6
  class TestPushParser < Nokogiri::SAX::TestCase
7
7
  def setup
8
+ super
8
9
  @parser = XML::SAX::PushParser.new(Doc.new)
9
10
  end
10
11
 
@@ -11,6 +11,15 @@ module Nokogiri
11
11
  end
12
12
  assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>", builder.to_xml.gsub(/\n/, ''))
13
13
  end
14
+
15
+ def test_builder_no_block
16
+ string = "hello world"
17
+ builder = Nokogiri::XML::Builder.new
18
+ builder.root {
19
+ cdata string
20
+ }
21
+ assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>", builder.to_xml.gsub(/\n/, ''))
22
+ end
14
23
  end
15
24
  end
16
25
  end
@@ -4,6 +4,7 @@ module Nokogiri
4
4
  module XML
5
5
  class TestCDATA < Nokogiri::TestCase
6
6
  def setup
7
+ super
7
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
9
  end
9
10
 
@@ -4,6 +4,7 @@ module Nokogiri
4
4
  module XML
5
5
  class TestComment < Nokogiri::TestCase
6
6
  def setup
7
+ super
7
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
9
  end
9
10
 
@@ -6,9 +6,32 @@ module Nokogiri
6
6
  module XML
7
7
  class TestDocument < Nokogiri::TestCase
8
8
  def setup
9
+ super
9
10
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
10
11
  end
11
12
 
13
+ def test_namespace_should_not_exist
14
+ assert_raises(NoMethodError) {
15
+ @xml.namespace
16
+ }
17
+ end
18
+
19
+ def test_non_existant_function
20
+ assert_raises(RuntimeError) {
21
+ @xml.xpath('//name[foo()]')
22
+ }
23
+ end
24
+
25
+ def test_ancestors
26
+ assert_equal [], @xml.ancestors
27
+ end
28
+
29
+ def test_root_node_parent_is_document
30
+ parent = @xml.root.parent
31
+ assert_equal @xml, parent
32
+ assert_instance_of Nokogiri::XML::Document, parent
33
+ end
34
+
12
35
  def test_xmlns_is_automatically_registered
13
36
  doc = Nokogiri::XML(<<-eoxml)
14
37
  <root xmlns="http://tenderlovemaking.com/">
@@ -20,6 +43,29 @@ module Nokogiri
20
43
  assert_equal 1, doc.css('xmlns|foo').length
21
44
  assert_equal 1, doc.css('foo').length
22
45
  assert_equal 0, doc.css('|foo').length
46
+ assert_equal 1, doc.xpath('//xmlns:foo').length
47
+ assert_equal 1, doc.search('xmlns|foo').length
48
+ assert_equal 1, doc.search('//xmlns:foo').length
49
+ assert doc.at('xmlns|foo')
50
+ assert doc.at('//xmlns:foo')
51
+ assert doc.at('foo')
52
+ end
53
+
54
+ def test_xmlns_is_registered_for_nodesets
55
+ doc = Nokogiri::XML(<<-eoxml)
56
+ <root xmlns="http://tenderlovemaking.com/">
57
+ <foo>
58
+ <bar>
59
+ baz
60
+ </bar>
61
+ </foo>
62
+ </root>
63
+ eoxml
64
+ assert_equal 1, doc.css('xmlns|foo').css('xmlns|bar').length
65
+ assert_equal 1, doc.css('foo').css('bar').length
66
+ assert_equal 1, doc.xpath('//xmlns:foo').xpath('./xmlns:bar').length
67
+ assert_equal 1, doc.search('xmlns|foo').search('xmlns|bar').length
68
+ assert_equal 1, doc.search('//xmlns:foo').search('./xmlns:bar').length
23
69
  end
24
70
 
25
71
  # wtf... osx's libxml sucks.
@@ -83,6 +129,12 @@ module Nokogiri
83
129
  doc = Nokogiri::XML::Document.new
84
130
  ns = doc.search('//foo')
85
131
  assert_equal 0, ns.length
132
+
133
+ ns = doc.css('foo')
134
+ assert_equal 0, ns.length
135
+
136
+ ns = doc.xpath('//foo')
137
+ assert_equal 0, ns.length
86
138
  end
87
139
 
88
140
  def test_bad_xpath_raises_syntax_error
@@ -172,6 +224,12 @@ module Nokogiri
172
224
  assert @xml.to_xml
173
225
  end
174
226
 
227
+ def test_dup
228
+ dup = @xml.dup
229
+ assert_instance_of Nokogiri::XML::Document, dup
230
+ assert dup.xml?, 'duplicate should be xml'
231
+ end
232
+
175
233
  def test_subset_is_decorated
176
234
  x = Module.new do
177
235
  def awesome!
@@ -2,24 +2,25 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', "helper"))
2
2
 
3
3
  module Nokogiri
4
4
  module XML
5
- if RUBY_VERSION =~ /^1\.9/
6
- class TestDocumentEncoding < Nokogiri::TestCase
7
- def setup
8
- @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE, 'UTF-8')
9
- end
5
+ if RUBY_VERSION =~ /^1\.9/
6
+ class TestDocumentEncoding < Nokogiri::TestCase
7
+ def setup
8
+ super
9
+ @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE, 'UTF-8')
10
+ end
10
11
 
11
- def test_url
12
- assert_equal @xml.encoding, @xml.url.encoding.name
13
- end
12
+ def test_url
13
+ assert_equal @xml.encoding, @xml.url.encoding.name
14
+ end
14
15
 
15
- def test_encoding
16
- assert_equal @xml.encoding, @xml.encoding.encoding.name
17
- end
16
+ def test_encoding
17
+ assert_equal @xml.encoding, @xml.encoding.encoding.name
18
+ end
18
19
 
19
- def test_dotted_version
20
- assert_equal 'UTF-8', Nokogiri::LIBXML_VERSION.encoding.name
20
+ def test_dotted_version
21
+ assert_equal 'UTF-8', Nokogiri::LIBXML_VERSION.encoding.name
22
+ end
21
23
  end
22
24
  end
23
- end
24
25
  end
25
26
  end
@@ -8,6 +8,12 @@ module Nokogiri
8
8
  fragment = Nokogiri::XML::DocumentFragment.new(@xml)
9
9
  end
10
10
 
11
+ def test_fragment_should_have_document
12
+ @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
13
+ fragment = Nokogiri::XML::DocumentFragment.new(@xml)
14
+ assert_equal @xml, fragment.document
15
+ end
16
+
11
17
  def test_name
12
18
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
13
19
  fragment = Nokogiri::XML::DocumentFragment.new(@xml)
@@ -4,6 +4,7 @@ module Nokogiri
4
4
  module HTML
5
5
  class TestDTD < Nokogiri::TestCase
6
6
  def setup
7
+ super
7
8
  @xml = Nokogiri::XML(File.open(XML_FILE))
8
9
  assert @dtd = @xml.internal_subset
9
10
  end
@@ -5,6 +5,7 @@ module Nokogiri
5
5
  if RUBY_VERSION =~ /^1\.9/
6
6
  class TestDTDEncoding < Nokogiri::TestCase
7
7
  def setup
8
+ super
8
9
  @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE, 'UTF-8')
9
10
  assert @dtd = @xml.internal_subset
10
11
  end
@@ -4,6 +4,7 @@ module Nokogiri
4
4
  module XML
5
5
  class TestEntityReference < Nokogiri::TestCase
6
6
  def setup
7
+ super
7
8
  @xml = Nokogiri::XML(File.open(XML_FILE), XML_FILE)
8
9
  end
9
10
 
@@ -6,6 +6,7 @@ module Nokogiri
6
6
  module XML
7
7
  class TestNode < Nokogiri::TestCase
8
8
  def setup
9
+ super
9
10
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
10
11
  end
11
12
 
@@ -15,6 +16,19 @@ module Nokogiri
15
16
  assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
16
17
  end
17
18
 
19
+ def test_add_child_should_inherit_namespace
20
+ doc = Nokogiri::XML(<<-eoxml)
21
+ <root xmlns="http://tenderlovemaking.com/">
22
+ <first>
23
+ </first>
24
+ </root>
25
+ eoxml
26
+ assert node = doc.at('//xmlns:first')
27
+ child = Nokogiri::XML::Node.new('second', doc)
28
+ node.add_child(child)
29
+ assert doc.at('//xmlns:second')
30
+ end
31
+
18
32
  def test_write_to
19
33
  io = StringIO.new
20
34
  @xml.write_to io
@@ -22,6 +36,10 @@ module Nokogiri
22
36
  assert_equal @xml.to_xml, io.read
23
37
  end
24
38
 
39
+ def test_attribute_with_symbol
40
+ assert_equal 'Yes', @xml.css('address').first[:domestic]
41
+ end
42
+
25
43
  def test_write_to_with_block
26
44
  called = false
27
45
  io = StringIO.new
@@ -57,6 +75,20 @@ module Nokogiri
57
75
  assert_equal @xml.serialize(nil, conf.options), string
58
76
  end
59
77
 
78
+ def test_hold_refence_to_subnode
79
+ doc = Nokogiri::XML(<<-eoxml)
80
+ <root>
81
+ <a>
82
+ <b />
83
+ </a>
84
+ </root>
85
+ eoxml
86
+ assert node_a = doc.css('a').first
87
+ assert node_b = node_a.css('b').first
88
+ node_a.unlink
89
+ assert_equal 'b', node_b.name
90
+ end
91
+
60
92
  def test_values
61
93
  assert_equal %w{ Yes Yes }, @xml.xpath('//address')[1].values
62
94
  end
@@ -87,7 +119,7 @@ module Nokogiri
87
119
  def test_ancestors
88
120
  address = @xml.xpath('//address').first
89
121
  assert_equal 3, address.ancestors.length
90
- assert_equal ['employee', 'staff', nil],
122
+ assert_equal ['employee', 'staff', 'document'],
91
123
  address.ancestors.map { |x| x.name }
92
124
  end
93
125
 
@@ -112,7 +144,7 @@ module Nokogiri
112
144
  assert_nil address['domestic']
113
145
  end
114
146
 
115
- def test_angry_add_child
147
+ def test_add_child_in_same_document
116
148
  child = @xml.css('employee').first
117
149
 
118
150
  assert previous_last_child = child.children.last
@@ -120,12 +152,23 @@ module Nokogiri
120
152
 
121
153
  last = child.children.last
122
154
 
123
- # Magic! Don't try this at home folks
124
155
  child.add_child(new_child)
125
156
  assert_equal new_child, child.children.last
126
157
  assert_equal last, child.children.last
127
158
  end
128
159
 
160
+ def test_add_child_from_other_document
161
+ d1 = Nokogiri::XML("<root><item>1</item><item>2</item></root>")
162
+ d2 = Nokogiri::XML("<root><item>3</item><item>4</item></root>")
163
+
164
+ d2.at('root').search('item').each do |i|
165
+ d1.at('root').add_child i
166
+ end
167
+
168
+ assert_equal 0, d2.search('item').size
169
+ assert_equal 4, d1.search('item').size
170
+ end
171
+
129
172
  def test_add_child
130
173
  xml = Nokogiri::XML(<<-eoxml)
131
174
  <root>
@@ -237,7 +280,7 @@ module Nokogiri
237
280
  assert node.next_sibling
238
281
  node.unlink
239
282
  assert !node.parent
240
- # assert !node.document # ugh. libxml doesn't clear node->doc pointer, due to xmlDict implementation.
283
+ #assert !node.document
241
284
  assert !node.previous_sibling
242
285
  assert !node.next_sibling
243
286
  assert_no_match(/Hello world/, xml.to_s)
@@ -312,6 +355,11 @@ module Nokogiri
312
355
  assert(node.document)
313
356
  end
314
357
 
358
+ def test_encode_special_chars
359
+ foo = @xml.css('employee').first.encode_special_chars('&')
360
+ assert_equal '&amp;', foo
361
+ end
362
+
315
363
  def test_content
316
364
  node = Nokogiri::XML::Node.new('form', @xml)
317
365
  assert_equal('', node.content)
@@ -5,6 +5,7 @@ module Nokogiri
5
5
  if RUBY_VERSION =~ /^1\.9/
6
6
  class TestNodeEncoding < Nokogiri::TestCase
7
7
  def setup
8
+ super
8
9
  @html = Nokogiri::HTML(File.read(HTML_FILE), HTML_FILE)
9
10
  end
10
11
 
@@ -4,9 +4,29 @@ module Nokogiri
4
4
  module XML
5
5
  class TestNodeSet < Nokogiri::TestCase
6
6
  def setup
7
+ super
7
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
9
  end
9
10
 
11
+ def test_xmlns_is_automatically_registered
12
+ doc = Nokogiri::XML(<<-eoxml)
13
+ <root xmlns="http://tenderlovemaking.com/">
14
+ <foo>
15
+ <bar/>
16
+ </foo>
17
+ </root>
18
+ eoxml
19
+ set = doc.css('foo')
20
+ assert_equal 1, set.css('xmlns|bar').length
21
+ assert_equal 0, set.css('|bar').length
22
+ assert_equal 1, set.xpath('//xmlns:bar').length
23
+ assert_equal 1, set.search('xmlns|bar').length
24
+ assert_equal 1, set.search('//xmlns:bar').length
25
+ assert set.at('//xmlns:bar')
26
+ assert set.at('xmlns|bar')
27
+ assert set.at('bar')
28
+ end
29
+
10
30
  def test_length_size
11
31
  assert node_set = @xml.search('//employee')
12
32
  assert_equal node_set.length, node_set.size
@@ -72,7 +92,7 @@ module Nokogiri
72
92
  set.unlink
73
93
  set.each do |node|
74
94
  assert !node.parent
75
- # assert !node.document # ugh. libxml doesn't clear node->doc pointer, due to xmlDict implementation.
95
+ #assert !node.document
76
96
  assert !node.previous_sibling
77
97
  assert !node.next_sibling
78
98
  end
@@ -4,6 +4,7 @@ module Nokogiri
4
4
  module XML
5
5
  class TestProcessingInstruction < Nokogiri::TestCase
6
6
  def setup
7
+ super
7
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
8
9
  end
9
10
 
@@ -6,6 +6,7 @@ module Nokogiri
6
6
  if RUBY_VERSION =~ /^1\.9/
7
7
  class TestReaderEncoding < Nokogiri::TestCase
8
8
  def setup
9
+ super
9
10
  @reader = Nokogiri::XML::Reader(
10
11
  File.read(XML_FILE),
11
12
  XML_FILE,