nokogiri-maglev- 1.5.0.1 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/CHANGELOG.ja.rdoc +56 -12
  2. data/CHANGELOG.rdoc +49 -0
  3. data/C_CODING_STYLE.rdoc +27 -0
  4. data/Manifest.txt +4 -0
  5. data/README.rdoc +11 -7
  6. data/Rakefile +42 -27
  7. data/bin/nokogiri +10 -2
  8. data/ext/nokogiri/extconf.rb +11 -3
  9. data/ext/nokogiri/html_document.c +16 -0
  10. data/ext/nokogiri/html_sax_parser_context.c +59 -37
  11. data/ext/nokogiri/html_sax_push_parser.c +87 -0
  12. data/ext/nokogiri/html_sax_push_parser.h +9 -0
  13. data/ext/nokogiri/nokogiri.c +7 -9
  14. data/ext/nokogiri/nokogiri.h +3 -0
  15. data/ext/nokogiri/xml_document.c +101 -3
  16. data/ext/nokogiri/xml_document.h +3 -3
  17. data/ext/nokogiri/xml_node.c +151 -58
  18. data/ext/nokogiri/xml_node_set.c +169 -120
  19. data/ext/nokogiri/xml_node_set.h +5 -0
  20. data/ext/nokogiri/xml_sax_parser_context.c +64 -41
  21. data/ext/nokogiri/xml_text.c +2 -0
  22. data/ext/nokogiri/xml_xpath_context.c +31 -25
  23. data/ext/nokogiri/xslt_stylesheet.c +62 -16
  24. data/ext/nokogiri/xslt_stylesheet.h +5 -0
  25. data/lib/nokogiri/css/parser.rb +165 -159
  26. data/lib/nokogiri/css/parser.y +6 -3
  27. data/lib/nokogiri/css/tokenizer.rb +1 -1
  28. data/lib/nokogiri/css/tokenizer.rex +1 -1
  29. data/lib/nokogiri/html.rb +1 -0
  30. data/lib/nokogiri/html/document.rb +82 -42
  31. data/lib/nokogiri/html/sax/push_parser.rb +16 -0
  32. data/lib/nokogiri/version.rb +1 -1
  33. data/lib/nokogiri/xml.rb +6 -0
  34. data/lib/nokogiri/xml/builder.rb +7 -1
  35. data/lib/nokogiri/xml/document.rb +32 -17
  36. data/lib/nokogiri/xml/document_fragment.rb +6 -1
  37. data/lib/nokogiri/xml/node.rb +40 -9
  38. data/lib/nokogiri/xslt.rb +5 -1
  39. data/tasks/cross_compile.rb +1 -0
  40. data/tasks/nokogiri.org.rb +6 -0
  41. data/tasks/test.rb +1 -0
  42. data/test/css/test_xpath_visitor.rb +6 -0
  43. data/test/helper.rb +1 -0
  44. data/test/html/test_document.rb +26 -0
  45. data/test/html/test_document_fragment.rb +1 -2
  46. data/test/test_memory_leak.rb +81 -1
  47. data/test/test_xslt_transforms.rb +152 -123
  48. data/test/xml/test_builder.rb +24 -2
  49. data/test/xml/test_c14n.rb +151 -0
  50. data/test/xml/test_document.rb +48 -0
  51. data/test/xml/test_namespace.rb +5 -0
  52. data/test/xml/test_node.rb +82 -1
  53. data/test/xml/test_node_attributes.rb +19 -0
  54. data/test/xml/test_node_inheritance.rb +32 -0
  55. data/test/xml/test_node_reparenting.rb +32 -0
  56. data/test/xml/test_node_set.rb +16 -8
  57. data/test/xml/test_reader_encoding.rb +16 -0
  58. data/test/xml/test_unparented_node.rb +32 -0
  59. data/test/xml/test_xinclude.rb +83 -0
  60. data/test/xml/test_xpath.rb +22 -0
  61. metadata +208 -241
@@ -199,13 +199,34 @@ module Nokogiri
199
199
  assert_equal 'hello', builder.doc.at('/root').content
200
200
  end
201
201
 
202
+ def test_raw_xml_append
203
+ builder = Nokogiri::XML::Builder.new do |xml|
204
+ xml.root do
205
+ xml << '<aaa><bbb/><ccc/></aaa>'
206
+ end
207
+ end
208
+
209
+ assert_equal ["aaa"], builder.doc.at_css("root").children.collect(&:name)
210
+ assert_equal ["bbb","ccc"], builder.doc.at_css("aaa").children.collect(&:name)
211
+ end
212
+
202
213
  def test_cdata
203
214
  builder = Nokogiri::XML::Builder.new do
204
215
  root {
205
216
  cdata "hello world"
206
217
  }
207
218
  end
208
- assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>", builder.to_xml.gsub(/\n/, ''))
219
+ assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>",
220
+ builder.to_xml.gsub(/\n/, ""))
221
+ end
222
+
223
+ def test_comment
224
+ builder = Nokogiri::XML::Builder.new do
225
+ root {
226
+ comment "this is a comment"
227
+ }
228
+ end
229
+ assert builder.doc.root.children.first.comment?
209
230
  end
210
231
 
211
232
  def test_builder_no_block
@@ -214,7 +235,8 @@ module Nokogiri
214
235
  builder.root {
215
236
  cdata string
216
237
  }
217
- assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>", builder.to_xml.gsub(/\n/, ''))
238
+ assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>",
239
+ builder.to_xml.gsub(/\n/, ''))
218
240
  end
219
241
 
220
242
  private
@@ -0,0 +1,151 @@
1
+ require "helper"
2
+
3
+ module Nokogiri
4
+ module XML
5
+ class TestC14N < Nokogiri::TestCase
6
+ # http://www.w3.org/TR/xml-c14n#Example-OutsideDoc
7
+ def test_3_1
8
+ doc = Nokogiri.XML <<-eoxml
9
+ <?xml version="1.0"?>
10
+
11
+ <?xml-stylesheet href="doc.xsl"
12
+ type="text/xsl" ?>
13
+
14
+ <!DOCTYPE doc SYSTEM "doc.dtd">
15
+
16
+ <doc>Hello, world!<!-- Comment 1 --></doc>
17
+
18
+ <?pi-without-data ?>
19
+
20
+ <!-- Comment 2 -->
21
+
22
+ <!-- Comment 3 -->
23
+ eoxml
24
+
25
+ c14n = doc.canonicalize
26
+ assert_no_match(/version=/, c14n)
27
+ assert_match(/Hello, world/, c14n)
28
+ assert_no_match(/Comment/, c14n)
29
+ c14n = doc.canonicalize(nil, nil, true)
30
+ assert_match(/Comment/, c14n)
31
+ end
32
+
33
+ def test_exclude_block_params
34
+ xml = '<a><b></b></a>'
35
+ doc = Nokogiri.XML xml
36
+
37
+ list = []
38
+ doc.canonicalize do |node, parent|
39
+ list << [node, parent]
40
+ true
41
+ end
42
+ if Nokogiri.jruby?
43
+ assert_equal(
44
+ ['a', 'document', 'document', nil, 'b', 'a'],
45
+ list.flatten.map { |x| x ? x.name : x }
46
+ )
47
+ else
48
+ assert_equal(
49
+ ['a', 'document', 'document', nil, 'b', 'a', 'a', 'document'],
50
+ list.flatten.map { |x| x ? x.name : x }
51
+ )
52
+ end
53
+ end
54
+
55
+ def test_exclude_block_true
56
+ xml = '<a><b></b></a>'
57
+ doc = Nokogiri.XML xml
58
+
59
+ c14n = doc.canonicalize do |node, parent|
60
+ true
61
+ end
62
+ assert_equal xml, c14n
63
+ end
64
+
65
+ def test_exclude_block_false
66
+ xml = '<a><b></b></a>'
67
+ doc = Nokogiri.XML xml
68
+
69
+ c14n = doc.canonicalize do |node, parent|
70
+ false
71
+ end
72
+ assert_equal '', c14n
73
+ end
74
+
75
+ def test_exclude_block_nil
76
+ xml = '<a><b></b></a>'
77
+ doc = Nokogiri.XML xml
78
+
79
+ c14n = doc.canonicalize do |node, parent|
80
+ nil
81
+ end
82
+ assert_equal '', c14n
83
+ end
84
+
85
+ def test_exclude_block_object
86
+ xml = '<a><b></b></a>'
87
+ doc = Nokogiri.XML xml
88
+
89
+ c14n = doc.canonicalize do |node, parent|
90
+ Object.new
91
+ end
92
+ assert_equal xml, c14n
93
+ end
94
+
95
+ def test_c14n_node
96
+ xml = '<a><b><c></c></b></a>'
97
+ doc = Nokogiri.XML xml
98
+ c14n = doc.at_xpath('//b').canonicalize
99
+ assert_equal '<b><c></c></b>', c14n
100
+ end
101
+
102
+ def test_c14n_modes
103
+ skip("C14N Exclusive implementation will complete by next version after 1.5.1") if Nokogiri.jruby?
104
+ # http://www.w3.org/TR/xml-exc-c14n/#sec-Enveloping
105
+
106
+ doc1 = Nokogiri.XML <<-eoxml
107
+ <n0:local xmlns:n0="http://foobar.org" xmlns:n3="ftp://example.org">
108
+ <n1:elem2 xmlns:n1="http://example.net" xml:lang="en">
109
+ <n3:stuff xmlns:n3="ftp://example.org"/>
110
+ </n1:elem2>
111
+ </n0:local>
112
+ eoxml
113
+ doc2 = Nokogiri.XML <<-eoxml
114
+ <n2:pdu xmlns:n1="http://example.com"
115
+ xmlns:n2="http://foo.example"
116
+ xml:lang="fr"
117
+ xml:space="retain">
118
+ <n1:elem2 xmlns:n1="http://example.net" xml:lang="en">
119
+ <n3:stuff xmlns:n3="ftp://example.org"/>
120
+ </n1:elem2>
121
+ </n2:pdu>
122
+ eoxml
123
+
124
+ c14n = doc1.at_xpath('//n1:elem2', {'n1' => 'http://example.net'}).canonicalize
125
+ assert_equal '<n1:elem2 xmlns:n0="http://foobar.org" xmlns:n1="http://example.net" xmlns:n3="ftp://example.org" xml:lang="en">
126
+ <n3:stuff></n3:stuff>
127
+ </n1:elem2>', c14n
128
+ c14n = doc2.at_xpath('//n1:elem2', {'n1' => 'http://example.net'}).canonicalize
129
+ assert_equal '<n1:elem2 xmlns:n1="http://example.net" xmlns:n2="http://foo.example" xml:lang="en" xml:space="retain">
130
+ <n3:stuff xmlns:n3="ftp://example.org"></n3:stuff>
131
+ </n1:elem2>', c14n
132
+
133
+ excl_c14n = '<n1:elem2 xmlns:n1="http://example.net" xml:lang="en">
134
+ <n3:stuff xmlns:n3="ftp://example.org"></n3:stuff>
135
+ </n1:elem2>'
136
+ c14n = doc1.at_xpath('//n1:elem2', {'n1' => 'http://example.net'}).canonicalize(XML::XML_C14N_EXCLUSIVE_1_0)
137
+ assert_equal excl_c14n, c14n
138
+ c14n = doc2.at_xpath('//n1:elem2', {'n1' => 'http://example.net'}).canonicalize(XML::XML_C14N_EXCLUSIVE_1_0)
139
+ assert_equal excl_c14n, c14n
140
+
141
+ c14n = doc2.at_xpath('//n1:elem2', {'n1' => 'http://example.net'}).canonicalize(XML::XML_C14N_EXCLUSIVE_1_0, ['n2'])
142
+ assert_equal '<n1:elem2 xmlns:n1="http://example.net" xmlns:n2="http://foo.example" xml:lang="en">
143
+ <n3:stuff xmlns:n3="ftp://example.org"></n3:stuff>
144
+ </n1:elem2>', c14n
145
+
146
+ end
147
+
148
+
149
+ end
150
+ end
151
+ end
@@ -51,6 +51,14 @@ module Nokogiri
51
51
  assert_equal @xml, txt.document
52
52
  end
53
53
 
54
+ def test_create_text_node_with_block
55
+ @xml.create_text_node 'foo' do |txt|
56
+ assert_instance_of Nokogiri::XML::Text, txt
57
+ assert_equal 'foo', txt.text
58
+ assert_equal @xml, txt.document
59
+ end
60
+ end
61
+
54
62
  def test_create_element
55
63
  elm = @xml.create_element('foo')
56
64
  assert_instance_of Nokogiri::XML::Element, elm
@@ -58,6 +66,14 @@ module Nokogiri
58
66
  assert_equal @xml, elm.document
59
67
  end
60
68
 
69
+ def test_create_element_with_block
70
+ @xml.create_element('foo') do |elm|
71
+ assert_instance_of Nokogiri::XML::Element, elm
72
+ assert_equal 'foo', elm.name
73
+ assert_equal @xml, elm.document
74
+ end
75
+ end
76
+
61
77
  def test_create_element_with_attributes
62
78
  elm = @xml.create_element('foo',:a => "1")
63
79
  assert_instance_of Nokogiri::XML::Element, elm
@@ -70,6 +86,11 @@ module Nokogiri
70
86
  assert_equal 'http://tenderlovemaking.com', elm.namespaces['xmlns:foo']
71
87
  end
72
88
 
89
+ def test_create_element_with_hyphenated_namespace
90
+ elm = @xml.create_element('foo',:'xmlns:SOAP-ENC' => 'http://tenderlovemaking.com')
91
+ assert_equal 'http://tenderlovemaking.com', elm.namespaces['xmlns:SOAP-ENC']
92
+ end
93
+
73
94
  def test_create_element_with_content
74
95
  elm = @xml.create_element('foo',"needs more xml/violence")
75
96
  assert_equal "needs more xml/violence", elm.content
@@ -81,6 +102,26 @@ module Nokogiri
81
102
  assert_equal "abc", cdata.content
82
103
  end
83
104
 
105
+ def test_create_cdata_with_block
106
+ @xml.create_cdata("abc") do |cdata|
107
+ assert_instance_of Nokogiri::XML::CDATA, cdata
108
+ assert_equal "abc", cdata.content
109
+ end
110
+ end
111
+
112
+ def test_create_comment
113
+ comment = @xml.create_comment("abc")
114
+ assert_instance_of Nokogiri::XML::Comment, comment
115
+ assert_equal "abc", comment.content
116
+ end
117
+
118
+ def test_create_comment_with_block
119
+ @xml.create_comment("abc") do |comment|
120
+ assert_instance_of Nokogiri::XML::Comment, comment
121
+ assert_equal "abc", comment.content
122
+ end
123
+ end
124
+
84
125
  def test_pp
85
126
  out = StringIO.new('')
86
127
  assert_nothing_raised do
@@ -204,6 +245,13 @@ module Nokogiri
204
245
  end
205
246
  end
206
247
 
248
+ def test_add_child_with_string
249
+ doc = Nokogiri::XML::Document.new
250
+ doc.add_child "<div>quack!</div>"
251
+ assert_equal 1, doc.root.children.length
252
+ assert_equal "quack!", doc.root.children.first.content
253
+ end
254
+
207
255
  def test_move_root_to_document_with_no_root
208
256
  sender = Nokogiri::XML('<root>foo</root>')
209
257
  newdoc = Nokogiri::XML::Document.new
@@ -65,6 +65,11 @@ module Nokogiri
65
65
  ns = @xml.root.add_namespace_definition('baz', 'bar')
66
66
  assert_equal 'baz', ns.prefix
67
67
  end
68
+
69
+ def test_remove_entity_namespace
70
+ s = %q{<?xml version='1.0'?><!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" [<!ENTITY % p ''>]>}
71
+ Nokogiri::XML(s).remove_namespaces!
72
+ end
68
73
  end
69
74
  end
70
75
  end
@@ -125,6 +125,13 @@ module Nokogiri
125
125
  @xml.root.parse('<hello>')
126
126
  assert(error_count < @xml.errors.length, "errors should have increased")
127
127
  end
128
+
129
+ def test_parse_error_on_fragment_with_empty_document
130
+ doc = Document.new
131
+ fragment = DocumentFragment.new(doc, '<foo><bar/></foo>')
132
+ node = fragment%'bar'
133
+ node.parse('<baz><</baz>')
134
+ end
128
135
 
129
136
  def test_subclass_dup
130
137
  subclass = Class.new(Nokogiri::XML::Node)
@@ -209,6 +216,13 @@ module Nokogiri
209
216
  end
210
217
  end
211
218
 
219
+ def test_append_with_attr
220
+ r = Nokogiri.XML('<r a="1" />').root
221
+ assert_raises(ArgumentError) do
222
+ r << r.at_xpath('@a')
223
+ end
224
+ end
225
+
212
226
  def test_inspect_ns
213
227
  xml = Nokogiri::XML(<<-eoxml) { |c| c.noblanks }
214
228
  <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
@@ -592,6 +606,19 @@ module Nokogiri
592
606
  assert_nil address['domestic']
593
607
  end
594
608
 
609
+ def test_attribute_setter_accepts_non_string
610
+ address = @xml.xpath("/staff/employee/address").first
611
+ assert_equal "Yes", address[:domestic]
612
+ address[:domestic] = "Altered Yes"
613
+ assert_equal "Altered Yes", address[:domestic]
614
+ end
615
+
616
+ def test_attribute_accessor_accepts_non_string
617
+ address = @xml.xpath("/staff/employee/address").first
618
+ assert_equal "Yes", address["domestic"]
619
+ assert_equal "Yes", address[:domestic]
620
+ end
621
+
595
622
  def test_delete
596
623
  address = @xml.xpath('/staff/employee/address').first
597
624
  assert_equal 'Yes', address['domestic']
@@ -807,6 +834,46 @@ module Nokogiri
807
834
  assert_equal 1, tires.length
808
835
  end
809
836
 
837
+ def test_namespaced_attribute_search_with_xpath
838
+ # from #593
839
+ xmlContent = <<-EOXML
840
+ <?xml version="1.0"?>
841
+ <ns1:el1 xmlns:ns1="http://blabla.com" >
842
+ <ns1:el2 ns1:att="123">with namespace</ns1:el2 >
843
+ <ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
844
+ </ns1:el1>
845
+ EOXML
846
+ xml_doc = Nokogiri::XML(xmlContent)
847
+
848
+ no_ns = xml_doc.xpath("//*[@att]")
849
+ assert_equal no_ns.length, 1
850
+ assert_equal no_ns.first.content, "no namespace"
851
+
852
+ with_ns = xml_doc.xpath("//*[@ns1:att]")
853
+ assert_equal with_ns.length, 1
854
+ assert_equal with_ns.first.content, "with namespace"
855
+ end
856
+
857
+ def test_namespaced_attribute_search_with_css
858
+ # from #593
859
+ xmlContent = <<-EOXML
860
+ <?xml version="1.0"?>
861
+ <ns1:el1 xmlns:ns1="http://blabla.com" >
862
+ <ns1:el2 ns1:att="123">with namespace</ns1:el2 >
863
+ <ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
864
+ </ns1:el1>
865
+ EOXML
866
+ xml_doc = Nokogiri::XML(xmlContent)
867
+
868
+ no_ns = xml_doc.css('*[att]')
869
+ assert_equal no_ns.length, 1
870
+ assert_equal no_ns.first.content, "no namespace"
871
+
872
+ with_ns = xml_doc.css('*[ns1|att]')
873
+ assert_equal with_ns.length, 1
874
+ assert_equal with_ns.first.content, "with namespace"
875
+ end
876
+
810
877
  def test_namespaces_should_include_all_namespace_definitions
811
878
  xml = Nokogiri::XML.parse(<<-EOF)
812
879
  <x xmlns="http://quux.com/" xmlns:a="http://foo.com/" xmlns:b="http://bar.com/">
@@ -854,7 +921,7 @@ module Nokogiri
854
921
  <b:div>hello b</b:div>
855
922
  <c:div>hello c</c:div>
856
923
  <div>hello moon</div>
857
- </y>
924
+ </y>
858
925
  </x>
859
926
  EOF
860
927
  set = xml.search("//y/*")
@@ -912,6 +979,20 @@ module Nokogiri
912
979
  assert_equal @xml, node_set.document
913
980
  assert node_set.respond_to?(:awesome!)
914
981
  end
982
+
983
+ def test_blank
984
+ doc = Nokogiri::XML('')
985
+ assert_equal false, doc.blank?
986
+ end
987
+
988
+ def test_to_xml_allows_to_serialize_with_as_xml_save_option
989
+ xml = Nokogiri::XML("<root><ul><li>Hello world</li></ul></root>")
990
+ set = xml.search("//ul")
991
+ node = set.first
992
+
993
+ assert_no_match("<ul>\n <li>", xml.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
994
+ assert_no_match("<ul>\n <li>", node.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
995
+ end
915
996
  end
916
997
  end
917
998
  end
@@ -29,6 +29,25 @@ module Nokogiri
29
29
  assert node.namespaced_key?('foo', nil)
30
30
  assert !node.namespaced_key?('foo', 'foo')
31
31
  end
32
+
33
+ def test_set_attribute_frees_nodes # testing a segv
34
+ skip("JRuby doesn't do GC.") if Nokogiri.jruby?
35
+ document = Nokogiri::XML.parse("<foo></foo>")
36
+
37
+ node = document.root
38
+ node['visible'] = 'foo'
39
+ attribute = node.attribute('visible')
40
+ text = Nokogiri::XML::Text.new 'bar', document
41
+ attribute.add_child(text)
42
+
43
+ begin
44
+ gc_previous = GC.stress
45
+ GC.stress = true
46
+ node['visible'] = 'attr'
47
+ ensure
48
+ GC.stress = gc_previous
49
+ end
50
+ end
32
51
  end
33
52
  end
34
53
  end
@@ -0,0 +1,32 @@
1
+ # issue#560
2
+
3
+ require 'helper'
4
+
5
+ module Nokogiri
6
+ module XML
7
+ class TestNodeInheritance < Nokogiri::TestCase
8
+ MyNode = Class.new Nokogiri::XML::Node
9
+ def setup
10
+ super
11
+ @node = MyNode.new 'foo', Nokogiri::XML::Document.new
12
+ @node['foo'] = 'bar'
13
+ end
14
+
15
+ def test_node_name
16
+ assert @node.name == 'foo'
17
+ end
18
+
19
+ def test_node_writing_an_attribute_accessing_via_attributes
20
+ assert @node.attributes['foo']
21
+ end
22
+
23
+ def test_node_writing_an_attribute_accessing_via_key
24
+ assert @node.key? 'foo'
25
+ end
26
+
27
+ def test_node_writing_an_attribute_accessing_via_brackets
28
+ assert @node['foo'] == 'bar'
29
+ end
30
+ end
31
+ end
32
+ end