nokogiri 1.4.2-java → 1.4.3-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (56) hide show
  1. data/CHANGELOG.ja.rdoc +28 -8
  2. data/CHANGELOG.rdoc +24 -1
  3. data/Manifest.txt +2 -1
  4. data/README.ja.rdoc +1 -1
  5. data/README.rdoc +22 -4
  6. data/Rakefile +6 -2
  7. data/ext/nokogiri/extconf.rb +55 -32
  8. data/ext/nokogiri/nokogiri.h +2 -0
  9. data/ext/nokogiri/xml_document.c +5 -0
  10. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  11. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  12. data/ext/nokogiri/xml_node.c +58 -12
  13. data/ext/nokogiri/xml_node_set.c +7 -7
  14. data/ext/nokogiri/xml_reader.c +20 -1
  15. data/ext/nokogiri/xml_xpath_context.c +2 -0
  16. data/lib/nokogiri/css/generated_parser.rb +155 -148
  17. data/lib/nokogiri/css/generated_tokenizer.rb +2 -1
  18. data/lib/nokogiri/css/parser.y +3 -0
  19. data/lib/nokogiri/css/xpath_visitor.rb +1 -7
  20. data/lib/nokogiri/ffi/libxml.rb +29 -4
  21. data/lib/nokogiri/ffi/xml/document.rb +4 -0
  22. data/lib/nokogiri/ffi/xml/node.rb +27 -19
  23. data/lib/nokogiri/ffi/xml/node_set.rb +3 -3
  24. data/lib/nokogiri/ffi/xml/reader.rb +4 -0
  25. data/lib/nokogiri/html.rb +2 -2
  26. data/lib/nokogiri/html/document_fragment.rb +7 -4
  27. data/lib/nokogiri/version.rb +2 -1
  28. data/lib/nokogiri/xml/builder.rb +1 -1
  29. data/lib/nokogiri/xml/document.rb +1 -2
  30. data/lib/nokogiri/xml/document_fragment.rb +7 -0
  31. data/lib/nokogiri/xml/node.rb +4 -2
  32. data/lib/nokogiri/xml/node_set.rb +25 -0
  33. data/lib/nokogiri/xml/reader.rb +2 -0
  34. data/lib/nokogiri/xml/sax/document.rb +3 -1
  35. data/tasks/cross_compile.rb +7 -6
  36. data/test/css/test_parser.rb +11 -1
  37. data/test/html/sax/test_parser_context.rb +2 -2
  38. data/test/html/test_document.rb +2 -2
  39. data/test/html/test_document_fragment.rb +34 -6
  40. data/test/test_memory_leak.rb +2 -2
  41. data/test/test_reader.rb +28 -6
  42. data/test/test_xslt_transforms.rb +29 -28
  43. data/test/xml/test_attr.rb +31 -4
  44. data/test/xml/test_builder.rb +5 -5
  45. data/test/xml/test_cdata.rb +3 -3
  46. data/test/xml/test_document.rb +8 -8
  47. data/test/xml/test_document_fragment.rb +2 -2
  48. data/test/xml/test_node.rb +1 -1
  49. data/test/xml/test_node_reparenting.rb +26 -11
  50. data/test/xml/test_node_set.rb +38 -2
  51. data/test/xml/test_text.rb +11 -2
  52. data/test/xml/test_unparented_node.rb +1 -1
  53. data/test/xml/test_xpath.rb +78 -11
  54. metadata +26 -6
  55. data/lib/nokogiri/nokogiri.rb +0 -1
  56. data/lib/nokogiri/version_warning.rb +0 -14
@@ -16,6 +16,10 @@ module Nokogiri
16
16
  assert_raises(CSS::SyntaxError) { @parser.parse("a[x=]") }
17
17
  end
18
18
 
19
+ def test_function_and_pseudo
20
+ assert_xpath '//child::text()[position() = 99]', @parser.parse('text():nth-of-type(99)')
21
+ end
22
+
19
23
  def test_find_by_type
20
24
  ast = @parser.parse("a:nth-child(2)").first
21
25
  matches = ast.find_by_type(
@@ -184,13 +188,19 @@ module Nokogiri
184
188
  end
185
189
 
186
190
  def test_preceding_selector
187
- assert_xpath "//F[preceding-sibling::E]",
191
+ assert_xpath "//E/following-sibling::F",
188
192
  @parser.parse("E ~ F")
193
+
194
+ assert_xpath "//E/following-sibling::F//G",
195
+ @parser.parse("E ~ F G")
189
196
  end
190
197
 
191
198
  def test_direct_preceding_selector
192
199
  assert_xpath "//E/following-sibling::*[1]/self::F",
193
200
  @parser.parse("E + F")
201
+
202
+ assert_xpath "//E/following-sibling::*[1]/self::F//G",
203
+ @parser.parse("E + F G")
194
204
  end
195
205
 
196
206
  def test_attribute
@@ -8,13 +8,13 @@ module Nokogiri
8
8
  class TestParserContext < Nokogiri::SAX::TestCase
9
9
  def test_from_io
10
10
  assert_nothing_raised do
11
- ctx = ParserContext.new StringIO.new('fo'), 'UTF-8'
11
+ ParserContext.new StringIO.new('fo'), 'UTF-8'
12
12
  end
13
13
  end
14
14
 
15
15
  def test_from_string
16
16
  assert_nothing_raised do
17
- ctx = ParserContext.new 'blah blah'
17
+ ParserContext.new 'blah blah'
18
18
  end
19
19
  end
20
20
 
@@ -160,7 +160,7 @@ module Nokogiri
160
160
  end
161
161
 
162
162
  def test_parse_io
163
- assert doc = File.open(HTML_FILE, 'rb') { |f|
163
+ assert File.open(HTML_FILE, 'rb') { |f|
164
164
  Document.read_io(f, nil, 'UTF-8',
165
165
  XML::ParseOptions::NOERROR | XML::ParseOptions::NOWARNING
166
166
  )
@@ -261,7 +261,7 @@ module Nokogiri
261
261
  end
262
262
 
263
263
  def test_find_with_function
264
- found = @html.css("div:awesome() h1", Class.new {
264
+ assert @html.css("div:awesome() h1", Class.new {
265
265
  def awesome divs
266
266
  [divs.first]
267
267
  end
@@ -9,18 +9,46 @@ module Nokogiri
9
9
  @html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
10
10
  end
11
11
 
12
- def test_no_contextual_parsing_on_unlinked_nodes
13
- node = @html.css('body').first
14
- node.unlink
15
- assert_raises(RuntimeError) do
16
- node.parse('<br />')
12
+ if RUBY_VERSION >= '1.9'
13
+ def test_inspect_encoding
14
+ fragment = "<div>こんにちは!</div>".encode('EUC-JP')
15
+ f = Nokogiri::HTML::DocumentFragment.parse fragment
16
+ assert_equal "こんにちは!", f.content
17
17
  end
18
+
19
+ def test_html_parse_encoding
20
+ fragment = "<div>こんにちは!</div>".encode 'EUC-JP'
21
+ f = Nokogiri::HTML.fragment fragment
22
+ assert_equal 'EUC-JP', f.document.encoding
23
+ assert_equal "こんにちは!", f.content
24
+ end
25
+ end
26
+
27
+ def test_parse_encoding
28
+ fragment = "<div>hello world</div>"
29
+ f = Nokogiri::HTML::DocumentFragment.parse fragment, 'ISO-8859-1'
30
+ assert_equal 'ISO-8859-1', f.document.encoding
31
+ assert_equal "hello world", f.content
32
+ end
33
+
34
+ def test_html_parse_with_encoding
35
+ fragment = "<div>hello world</div>"
36
+ f = Nokogiri::HTML.fragment fragment, 'ISO-8859-1'
37
+ assert_equal 'ISO-8859-1', f.document.encoding
38
+ assert_equal "hello world", f.content
18
39
  end
19
40
 
20
41
  def test_parse_in_context
21
42
  assert_equal('<br>', @html.root.parse('<br />').to_s)
22
43
  end
23
44
 
45
+ def test_inner_html=
46
+ fragment = Nokogiri::HTML.fragment '<hr />'
47
+
48
+ fragment.inner_html = "hello"
49
+ assert_equal 'hello', fragment.inner_html
50
+ end
51
+
24
52
  def test_ancestors_search
25
53
  html = %q{
26
54
  <div>
@@ -43,7 +71,7 @@ module Nokogiri
43
71
  end
44
72
 
45
73
  def test_new
46
- fragment = Nokogiri::HTML::DocumentFragment.new(@html)
74
+ assert Nokogiri::HTML::DocumentFragment.new(@html)
47
75
  end
48
76
 
49
77
  def test_fragment_should_have_document
@@ -8,8 +8,8 @@ class TestMemoryLeak < Nokogiri::TestCase
8
8
  content = File.open("#{File.dirname(__FILE__)}/files/dont_hurt_em_why.xml").read
9
9
  ndoc = Nokogiri::XML(content)
10
10
  2.times do
11
- info = ndoc.search('status text').first.inner_text
12
- url = ndoc.search('user name').first.inner_text
11
+ ndoc.search('status text').first.inner_text
12
+ ndoc.search('user name').first.inner_text
13
13
  GC.start
14
14
  end
15
15
  end
@@ -8,6 +8,32 @@ class TestReader < Nokogiri::TestCase
8
8
  assert_equal io, reader.source
9
9
  end
10
10
 
11
+ def test_empty_element?
12
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
13
+ <xml><city>Paris</city><state/></xml>
14
+ eoxml
15
+
16
+ results = reader.map do |node|
17
+ if node.node_type == Nokogiri::XML::Node::ELEMENT_NODE
18
+ node.empty_element?
19
+ end
20
+ end
21
+ assert_equal [false, false, nil, nil, true, nil], results
22
+ end
23
+
24
+ def test_self_closing?
25
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
26
+ <xml><city>Paris</city><state/></xml>
27
+ eoxml
28
+
29
+ results = reader.map do |node|
30
+ if node.node_type == Nokogiri::XML::Node::ELEMENT_NODE
31
+ node.self_closing?
32
+ end
33
+ end
34
+ assert_equal [false, false, nil, nil, true, nil], results
35
+ end
36
+
11
37
  def test_reader_takes_block
12
38
  options = nil
13
39
  Nokogiri::XML::Reader(File.read(XML_FILE), XML_FILE) do |cfg|
@@ -57,7 +83,7 @@ class TestReader < Nokogiri::TestCase
57
83
  end
58
84
 
59
85
  def test_in_memory
60
- reader = Nokogiri::XML::Reader(<<-eoxml)
86
+ assert Nokogiri::XML::Reader(<<-eoxml)
61
87
  <x xmlns:tenderlove='http://tenderlovemaking.com/'>
62
88
  <tenderlove:foo awesome='true'>snuggles!</tenderlove:foo>
63
89
  </x>
@@ -108,13 +134,9 @@ class TestReader < Nokogiri::TestCase
108
134
  <foo>
109
135
  </x>
110
136
  eoxml
111
- error_happened = false
112
- begin
137
+ assert_raises(Nokogiri::XML::SyntaxError) do
113
138
  reader.each { |node| }
114
- rescue Nokogiri::XML::SyntaxError => ex
115
- error_happened = true
116
139
  end
117
- assert error_happened
118
140
  assert 1, reader.errors.length
119
141
  end
120
142
 
@@ -6,8 +6,7 @@ class TestXsltTransforms < Nokogiri::TestCase
6
6
  @doc = Nokogiri::XML(File.open(XML_FILE))
7
7
  end
8
8
 
9
- if Nokogiri::VERSION_INFO['libxml']['loaded'] > '2.6.16'
10
-
9
+ if Nokogiri.uses_libxml?
11
10
  def test_class_methods
12
11
  style = Nokogiri::XSLT(File.read(XSLT_FILE))
13
12
 
@@ -130,33 +129,35 @@ encoding="iso-8859-1" indent="yes"/>
130
129
  assert_equal result_array, result_hash
131
130
  end
132
131
 
133
- def test_exslt
134
- assert doc = Nokogiri::XML.parse(File.read(EXML_FILE))
135
- assert doc.xml?
136
-
137
- assert style = Nokogiri::XSLT.parse(File.read(EXSLT_FILE))
138
- params = {
139
- :p1 => 'xxx',
140
- :p2 => "x'x'x",
141
- :p3 => 'x"x"x',
142
- :p4 => '"xxx"'
143
- }
144
- result_doc = Nokogiri::XML.parse(style.apply_to(doc,
145
- Nokogiri::XSLT.quote_params(params)))
146
-
147
- assert_equal 'func-result', result_doc.at('/root/function').content
148
- assert_equal 3, result_doc.at('/root/max').content.to_i
149
- assert_match(
150
- /\d{4}-\d\d-\d\d([-|+]\d\d:\d\d)?/,
151
- result_doc.at('/root/date').content
152
- )
153
- result_doc.xpath('/root/params/*').each do |p|
154
- assert_equal p.content, params[p.name.intern]
132
+ if Nokogiri.uses_libxml? # By now, cannot get it working on JRuby.
133
+ def test_exslt
134
+ assert doc = Nokogiri::XML.parse(File.read(EXML_FILE))
135
+ assert doc.xml?
136
+
137
+ assert style = Nokogiri::XSLT.parse(File.read(EXSLT_FILE))
138
+ params = {
139
+ :p1 => 'xxx',
140
+ :p2 => "x'x'x",
141
+ :p3 => 'x"x"x',
142
+ :p4 => '"xxx"'
143
+ }
144
+ result_doc = Nokogiri::XML.parse(style.apply_to(doc,
145
+ Nokogiri::XSLT.quote_params(params)))
146
+
147
+ assert_equal 'func-result', result_doc.at('/root/function').content
148
+ assert_equal 3, result_doc.at('/root/max').content.to_i
149
+ assert_match(
150
+ /\d{4}-\d\d-\d\d([-|+]\d\d:\d\d)?/,
151
+ result_doc.at('/root/date').content
152
+ )
153
+ result_doc.xpath('/root/params/*').each do |p|
154
+ assert_equal p.content, params[p.name.intern]
155
+ end
156
+ check_params result_doc, params
157
+ result_doc = Nokogiri::XML.parse(style.apply_to(doc,
158
+ Nokogiri::XSLT.quote_params(params.to_a.flatten)))
159
+ check_params result_doc, params
155
160
  end
156
- check_params result_doc, params
157
- result_doc = Nokogiri::XML.parse(style.apply_to(doc,
158
- Nokogiri::XSLT.quote_params(params.to_a.flatten)))
159
- check_params result_doc, params
160
161
  end
161
162
 
162
163
  def test_xslt_parse_error
@@ -4,10 +4,12 @@ module Nokogiri
4
4
  module XML
5
5
  class TestAttr < Nokogiri::TestCase
6
6
  def test_new
7
- 100.times {
8
- doc = Nokogiri::XML::Document.new
9
- attribute = Nokogiri::XML::Attr.new(doc, 'foo')
10
- }
7
+ assert_nothing_raised do
8
+ 100.times {
9
+ doc = Nokogiri::XML::Document.new
10
+ Nokogiri::XML::Attr.new(doc, 'foo')
11
+ }
12
+ end
11
13
  end
12
14
 
13
15
  def test_content=
@@ -33,6 +35,31 @@ module Nokogiri
33
35
  address.attribute_nodes.first.unlink
34
36
  assert_nil address['domestic']
35
37
  end
38
+
39
+ def test_parsing_attribute_namespace
40
+ doc = Nokogiri::XML <<-EOXML
41
+ <root xmlns='http://google.com/' xmlns:f='http://flavorjon.es/'>
42
+ <div f:myattr='foo'></div>
43
+ </root>
44
+ EOXML
45
+
46
+ node = doc.at_css "div"
47
+ attr = node.attributes["myattr"]
48
+ assert_equal "http://flavorjon.es/", attr.namespace.href
49
+ end
50
+
51
+ def test_setting_attribute_namespace
52
+ doc = Nokogiri::XML <<-EOXML
53
+ <root xmlns='http://google.com/' xmlns:f='http://flavorjon.es/'>
54
+ <div f:myattr='foo'></div>
55
+ </root>
56
+ EOXML
57
+
58
+ node = doc.at_css "div"
59
+ attr = node.attributes["myattr"]
60
+ attr.add_namespace("fizzle", "http://fizzle.com/")
61
+ assert_equal "http://fizzle.com/", attr.namespace.href
62
+ end
36
63
  end
37
64
  end
38
65
  end
@@ -83,8 +83,8 @@ module Nokogiri
83
83
  end
84
84
  }
85
85
  doc = b.doc
86
- assert_equal 'bar', b.doc.at('foo|bar', 'foo' => 'bar').namespace.href
87
- assert_equal 'bar', b.doc.at('foo|baz', 'foo' => 'bar').namespace.href
86
+ assert_equal 'bar', doc.at('foo|bar', 'foo' => 'bar').namespace.href
87
+ assert_equal 'bar', doc.at('foo|baz', 'foo' => 'bar').namespace.href
88
88
  end
89
89
 
90
90
  def test_specify_namespace_nested
@@ -100,12 +100,12 @@ module Nokogiri
100
100
  end
101
101
  }
102
102
  doc = b.doc
103
- assert_equal 'bar', b.doc.at('foo|bar', 'foo' => 'bar').namespace.href
104
- assert_equal 'bar', b.doc.at('foo|baz', 'foo' => 'bar').namespace.href
103
+ assert_equal 'bar', doc.at('foo|bar', 'foo' => 'bar').namespace.href
104
+ assert_equal 'bar', doc.at('foo|baz', 'foo' => 'bar').namespace.href
105
105
  end
106
106
 
107
107
  def test_specified_namespace_undeclared
108
- b = Nokogiri::XML::Builder.new { |xml|
108
+ Nokogiri::XML::Builder.new { |xml|
109
109
  xml.root do
110
110
  assert_raises(ArgumentError) do
111
111
  xml[:foo]
@@ -29,9 +29,9 @@ module Nokogiri
29
29
  end
30
30
 
31
31
  def test_lots_of_new_cdata
32
- 100.times {
33
- node = CDATA.new(@xml, "asdfasdf")
34
- }
32
+ assert_nothing_raised do
33
+ 100.times { CDATA.new(@xml, "asdfasdf") }
34
+ end
35
35
  end
36
36
 
37
37
  def test_content=
@@ -21,12 +21,6 @@ module Nokogiri
21
21
  assert_equal nil, @xml.root
22
22
  end
23
23
 
24
- def test_parse_should_not_exist
25
- assert_raises(NoMethodError) do
26
- @xml.parse("foo")
27
- end
28
- end
29
-
30
24
  def test_collect_namespaces
31
25
  doc = Nokogiri::XML(<<-eoxml)
32
26
  <xml>
@@ -617,7 +611,11 @@ module Nokogiri
617
611
  </root>
618
612
  EOX
619
613
 
614
+ namespaces = doc.root.namespaces
615
+
620
616
  # assert on setup
617
+ assert_equal 2, doc.root.namespaces.length
618
+ assert_equal 3, doc.at_xpath("//container").namespaces.length
621
619
  assert_equal 0, doc.xpath("//foo").length
622
620
  assert_equal 1, doc.xpath("//a:foo").length
623
621
  assert_equal 1, doc.xpath("//a:foo").length
@@ -625,9 +623,11 @@ module Nokogiri
625
623
 
626
624
  doc.remove_namespaces!
627
625
 
626
+ assert_equal 0, doc.root.namespaces.length
627
+ assert_equal 0, doc.at_xpath("//container").namespaces.length
628
628
  assert_equal 3, doc.xpath("//foo").length
629
- assert_equal 0, doc.xpath("//a:foo").length
630
- assert_equal 0, doc.xpath("//a:foo").length
629
+ assert_equal 0, doc.xpath("//a:foo", namespaces).length
630
+ assert_equal 0, doc.xpath("//a:foo", namespaces).length
631
631
  assert_equal 0, doc.xpath("//x:foo", "x" => "http://c.flavorjon.es/").length
632
632
  end
633
633
 
@@ -20,7 +20,7 @@ module Nokogiri
20
20
 
21
21
  def test_node_fragment_is_relative
22
22
  doc = Nokogiri::XML('<root><a xmlns="blah" /></root>')
23
- ctx = doc.root.child
23
+ assert doc.root.child
24
24
  fragment = doc.root.child.fragment('<hello />')
25
25
  hello = fragment.child
26
26
 
@@ -29,7 +29,7 @@ module Nokogiri
29
29
  end
30
30
 
31
31
  def test_new
32
- fragment = Nokogiri::XML::DocumentFragment.new(@xml)
32
+ assert Nokogiri::XML::DocumentFragment.new(@xml)
33
33
  end
34
34
 
35
35
  def test_fragment_should_have_document
@@ -385,7 +385,7 @@ module Nokogiri
385
385
  def test_add_namespace_does_not_associate_node
386
386
  node = @xml.at('address')
387
387
  assert_nil node.namespace
388
- definition = node.add_namespace_definition 'foo', 'http://tlm.com/'
388
+ assert node.add_namespace_definition 'foo', 'http://tlm.com/'
389
389
  assert_nil node.namespace
390
390
  end
391
391
 
@@ -134,19 +134,19 @@ module Nokogiri
134
134
  end
135
135
  end
136
136
  end
137
+ end
137
138
 
138
- describe "text node merging" do
139
- describe "#add_child" do
140
- it "merges the Text node with adjacent Text nodes" do
141
- @doc.at_xpath("/root/a1").add_child Nokogiri::XML::Text.new('hello', @doc)
142
- @doc.at_xpath("/root/a1/text()").content.must_equal "First nodehello"
143
- end
139
+ describe "text node merging" do
140
+ describe "#add_child" do
141
+ it "merges the Text node with adjacent Text nodes" do
142
+ @doc.at_xpath("/root/a1").add_child Nokogiri::XML::Text.new('hello', @doc)
143
+ @doc.at_xpath("/root/a1/text()").content.must_equal "First nodehello"
144
144
  end
145
- describe "#replace" do
146
- it "merges the Text node with adjacent Text nodes" do
147
- @doc.at_xpath("/root/a3/bx").replace Nokogiri::XML::Text.new('hello', @doc)
148
- @doc.at_xpath("/root/a3/text()").content.must_equal "Third hellonode"
149
- end
145
+ end
146
+ describe "#replace" do
147
+ it "merges the Text node with adjacent Text nodes" do
148
+ @doc.at_xpath("/root/a3/bx").replace Nokogiri::XML::Text.new('hello', @doc)
149
+ @doc.at_xpath("/root/a3/text()").content.must_equal "Third hellonode"
150
150
  end
151
151
  end
152
152
  end
@@ -272,6 +272,21 @@ module Nokogiri
272
272
  end
273
273
  end
274
274
 
275
+ describe "replace-merging text nodes" do
276
+ [
277
+ ['<root>a<br/></root>', 'afoo'],
278
+ ['<root>a<br/>b</root>', 'afoob'],
279
+ ['<root><br/>b</root>', 'foob']
280
+ ].each do |xml, result|
281
+ it "doesn't blow up on #{xml}" do
282
+ doc = Nokogiri::XML.parse(xml)
283
+ saved_nodes = doc.root.children
284
+ doc.at_xpath("/root/br").replace(Nokogiri::XML::Text.new('foo', doc))
285
+ saved_nodes.each { |child| child.inspect } # try to cause a crash
286
+ assert_equal result, doc.at_xpath("/root/text()").inner_text
287
+ end
288
+ end
289
+ end
275
290
  end
276
291
  end
277
292
  end