nokogiri 1.4.1-x86-mswin32 → 1.4.2.1-x86-mswin32

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 (112) hide show
  1. data/CHANGELOG.ja.rdoc +45 -0
  2. data/CHANGELOG.rdoc +53 -1
  3. data/Manifest.txt +3 -3
  4. data/README.ja.rdoc +1 -1
  5. data/README.rdoc +11 -5
  6. data/Rakefile +13 -79
  7. data/ext/nokogiri/extconf.rb +25 -74
  8. data/ext/nokogiri/html_document.c +17 -8
  9. data/ext/nokogiri/html_element_description.c +20 -16
  10. data/ext/nokogiri/html_entity_lookup.c +2 -2
  11. data/ext/nokogiri/html_sax_parser_context.c +10 -8
  12. data/ext/nokogiri/nokogiri.c +0 -1
  13. data/ext/nokogiri/nokogiri.h +33 -28
  14. data/ext/nokogiri/xml_attr.c +7 -5
  15. data/ext/nokogiri/xml_attribute_decl.c +5 -2
  16. data/ext/nokogiri/xml_cdata.c +4 -2
  17. data/ext/nokogiri/xml_comment.c +4 -2
  18. data/ext/nokogiri/xml_document.c +93 -15
  19. data/ext/nokogiri/xml_document.h +0 -1
  20. data/ext/nokogiri/xml_document_fragment.c +4 -2
  21. data/ext/nokogiri/xml_dtd.c +18 -8
  22. data/ext/nokogiri/xml_element_content.c +2 -2
  23. data/ext/nokogiri/xml_entity_decl.c +15 -2
  24. data/ext/nokogiri/xml_entity_reference.c +4 -2
  25. data/ext/nokogiri/xml_io.c +1 -1
  26. data/ext/nokogiri/xml_namespace.c +5 -3
  27. data/ext/nokogiri/xml_node.c +353 -114
  28. data/ext/nokogiri/xml_node_set.c +35 -22
  29. data/ext/nokogiri/xml_node_set.h +1 -1
  30. data/ext/nokogiri/xml_processing_instruction.c +4 -2
  31. data/ext/nokogiri/xml_reader.c +119 -47
  32. data/ext/nokogiri/xml_relax_ng.c +21 -12
  33. data/ext/nokogiri/xml_sax_parser.c +6 -3
  34. data/ext/nokogiri/xml_sax_parser.h +13 -17
  35. data/ext/nokogiri/xml_sax_parser_context.c +8 -6
  36. data/ext/nokogiri/xml_sax_push_parser.c +7 -6
  37. data/ext/nokogiri/xml_schema.c +62 -13
  38. data/ext/nokogiri/xml_syntax_error.c +18 -12
  39. data/ext/nokogiri/xml_syntax_error.h +1 -1
  40. data/ext/nokogiri/xml_text.c +4 -2
  41. data/ext/nokogiri/xml_xpath_context.c +60 -23
  42. data/ext/nokogiri/xslt_stylesheet.c +14 -3
  43. data/lib/nokogiri.rb +17 -0
  44. data/lib/nokogiri/1.8/nokogiri.so +0 -0
  45. data/lib/nokogiri/1.9/nokogiri.so +0 -0
  46. data/lib/nokogiri/css/generated_parser.rb +72 -62
  47. data/lib/nokogiri/css/generated_tokenizer.rb +23 -23
  48. data/lib/nokogiri/css/parser.y +3 -1
  49. data/lib/nokogiri/css/tokenizer.rex +3 -3
  50. data/lib/nokogiri/css/xpath_visitor.rb +8 -3
  51. data/lib/nokogiri/ffi/html/sax/parser_context.rb +3 -3
  52. data/lib/nokogiri/ffi/libxml.rb +16 -2
  53. data/lib/nokogiri/ffi/structs/common_node.rb +15 -3
  54. data/lib/nokogiri/ffi/structs/xml_document.rb +13 -4
  55. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +3 -2
  56. data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
  57. data/lib/nokogiri/ffi/xml/document.rb +27 -0
  58. data/lib/nokogiri/ffi/xml/entity_decl.rb +9 -0
  59. data/lib/nokogiri/ffi/xml/node.rb +142 -61
  60. data/lib/nokogiri/ffi/xml/node_set.rb +15 -12
  61. data/lib/nokogiri/ffi/xml/reader.rb +5 -0
  62. data/lib/nokogiri/ffi/xml/schema.rb +17 -0
  63. data/lib/nokogiri/ffi/xml/syntax_error.rb +4 -4
  64. data/lib/nokogiri/ffi/xml/xpath.rb +0 -10
  65. data/lib/nokogiri/ffi/xml/xpath_context.rb +22 -9
  66. data/lib/nokogiri/ffi/xslt/stylesheet.rb +3 -0
  67. data/lib/nokogiri/html/document.rb +5 -3
  68. data/lib/nokogiri/html/document_fragment.rb +28 -7
  69. data/lib/nokogiri/version.rb +6 -2
  70. data/lib/nokogiri/version_warning.rb +6 -3
  71. data/lib/nokogiri/xml.rb +1 -1
  72. data/lib/nokogiri/xml/builder.rb +35 -22
  73. data/lib/nokogiri/xml/document.rb +44 -12
  74. data/lib/nokogiri/xml/document_fragment.rb +16 -12
  75. data/lib/nokogiri/xml/entity_decl.rb +4 -0
  76. data/lib/nokogiri/xml/node.rb +152 -95
  77. data/lib/nokogiri/xml/node_set.rb +2 -1
  78. data/lib/nokogiri/xml/sax/push_parser.rb +1 -1
  79. data/lib/nokogiri/xml/schema.rb +1 -5
  80. data/lib/nokogiri/xml/syntax_error.rb +4 -0
  81. data/lib/nokogiri/xml/text.rb +9 -0
  82. data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
  83. data/tasks/cross_compile.rb +158 -0
  84. data/tasks/test.rb +0 -6
  85. data/test/css/test_xpath_visitor.rb +9 -0
  86. data/test/helper.rb +49 -11
  87. data/test/html/sax/test_parser.rb +11 -1
  88. data/test/html/test_document.rb +8 -0
  89. data/test/html/test_document_fragment.rb +14 -2
  90. data/test/html/test_element_description.rb +5 -1
  91. data/test/html/test_node.rb +5 -66
  92. data/test/test_reader.rb +28 -0
  93. data/test/test_xslt_transforms.rb +14 -0
  94. data/test/xml/test_builder.rb +43 -0
  95. data/test/xml/test_cdata.rb +12 -0
  96. data/test/xml/test_document.rb +74 -39
  97. data/test/xml/test_document_fragment.rb +36 -0
  98. data/test/xml/test_entity_decl.rb +37 -0
  99. data/test/xml/test_node.rb +192 -65
  100. data/test/xml/test_node_reparenting.rb +253 -236
  101. data/test/xml/test_node_set.rb +67 -0
  102. data/test/xml/test_text.rb +8 -0
  103. data/test/xml/test_xpath.rb +32 -0
  104. metadata +151 -79
  105. data/ext/nokogiri/iconv.dll +0 -0
  106. data/ext/nokogiri/libexslt.dll +0 -0
  107. data/ext/nokogiri/libxml2.dll +0 -0
  108. data/ext/nokogiri/libxslt.dll +0 -0
  109. data/ext/nokogiri/xml_xpath.c +0 -53
  110. data/ext/nokogiri/xml_xpath.h +0 -11
  111. data/ext/nokogiri/zlib1.dll +0 -0
  112. data/lib/nokogiri/xml/fragment_handler.rb +0 -79
data/test/test_reader.rb CHANGED
@@ -332,6 +332,34 @@ class TestReader < Nokogiri::TestCase
332
332
  reader.map { |n| n.name })
333
333
  end
334
334
 
335
+ def test_base_uri
336
+ reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
337
+ <x xml:base="http://base.example.org/base/">
338
+ <link href="link"/>
339
+ <other xml:base="http://other.example.org/"/>
340
+ <relative xml:base="relative">
341
+ <link href="stuff" />
342
+ </relative>
343
+ </x>
344
+ eoxml
345
+
346
+ assert_nil reader.base_uri
347
+ assert_equal(["http://base.example.org/base/",
348
+ "http://base.example.org/base/",
349
+ "http://base.example.org/base/",
350
+ "http://base.example.org/base/",
351
+ "http://other.example.org/",
352
+ "http://base.example.org/base/",
353
+ "http://base.example.org/base/relative",
354
+ "http://base.example.org/base/relative",
355
+ "http://base.example.org/base/relative",
356
+ "http://base.example.org/base/relative",
357
+ "http://base.example.org/base/relative",
358
+ "http://base.example.org/base/",
359
+ "http://base.example.org/base/"],
360
+ reader.map {|n| n.base_uri })
361
+ end
362
+
335
363
  def test_read_from_memory
336
364
  called = false
337
365
  reader = Nokogiri::XML::Reader.from_memory('<foo>bar</foo>')
@@ -70,6 +70,20 @@ encoding="iso-8859-1" indent="yes"/>
70
70
  assert_no_match(/<td>/, xslt.apply_to(@doc, ['title', 'foo']))
71
71
  end
72
72
 
73
+ def test_transform_arg_error
74
+ assert style = Nokogiri::XSLT(File.read(XSLT_FILE))
75
+ assert_raises(TypeError) do
76
+ style.transform(@doc, :foo)
77
+ end
78
+ end
79
+
80
+ def test_transform_with_hash
81
+ assert style = Nokogiri::XSLT(File.read(XSLT_FILE))
82
+ result = style.transform(@doc, {'title' => '"Booyah"'})
83
+ assert result.html?
84
+ assert_equal "Booyah", result.at_css("h1").content
85
+ end
86
+
73
87
  def test_transform2
74
88
  assert style = Nokogiri::XSLT(File.open(XSLT_FILE))
75
89
  assert result_doc = style.transform(@doc)
@@ -3,6 +3,43 @@ require "helper"
3
3
  module Nokogiri
4
4
  module XML
5
5
  class TestBuilder < Nokogiri::TestCase
6
+ def test_builder_namespace
7
+ doc = Nokogiri::XML::Builder.new { |xml|
8
+ xml.a("xmlns:a" => "x") do
9
+ xml.b("xmlns:a" => "x", "xmlns:b" => "y")
10
+ end
11
+ }.doc
12
+
13
+ b = doc.at('b')
14
+ assert b
15
+ assert_equal({"xmlns:a"=>"x", "xmlns:b"=>"y"}, b.namespaces)
16
+ assert_equal({"xmlns:b"=>"y"}, namespaces_defined_on(b))
17
+ end
18
+
19
+ def test_builder_namespace_part_deux
20
+ doc = Nokogiri::XML::Builder.new { |xml|
21
+ xml.a("xmlns:b" => "y") do
22
+ xml.b("xmlns:a" => "x", "xmlns:b" => "y", "xmlns:c" => "z")
23
+ end
24
+ }.doc
25
+
26
+ b = doc.at('b')
27
+ assert b
28
+ assert_equal({"xmlns:a"=>"x", "xmlns:b"=>"y", "xmlns:c"=>"z"}, b.namespaces)
29
+ assert_equal({"xmlns:a"=>"x", "xmlns:c"=>"z"}, namespaces_defined_on(b))
30
+ end
31
+
32
+ def test_builder_with_unlink
33
+ assert_nothing_raised do
34
+ Nokogiri::XML::Builder.new do |xml|
35
+ xml.foo do
36
+ xml.bar { xml.parent.unlink }
37
+ xml.bar2
38
+ end
39
+ end
40
+ end
41
+ end
42
+
6
43
  def test_with_root
7
44
  doc = Nokogiri::XML(File.read(XML_FILE))
8
45
  Nokogiri::XML::Builder.with(doc.at('employee')) do |xml|
@@ -162,6 +199,12 @@ module Nokogiri
162
199
  }
163
200
  assert_equal("<?xml version=\"1.0\"?><root><![CDATA[hello world]]></root>", builder.to_xml.gsub(/\n/, ''))
164
201
  end
202
+
203
+ private
204
+
205
+ def namespaces_defined_on(node)
206
+ Hash[*node.namespace_definitions.collect{|n| ["xmlns:" + n.prefix, n.href]}.flatten]
207
+ end
165
208
  end
166
209
  end
167
210
  end
@@ -33,6 +33,18 @@ module Nokogiri
33
33
  node = CDATA.new(@xml, "asdfasdf")
34
34
  }
35
35
  end
36
+
37
+ def test_content=
38
+ node = CDATA.new(@xml, 'foo')
39
+ assert_equal('foo', node.content)
40
+
41
+ node.content = '& <foo> &amp;'
42
+ assert_equal('& <foo> &amp;', node.content)
43
+ assert_equal('<![CDATA[& <foo> &amp;]]>', node.to_xml)
44
+
45
+ node.content = 'foo ]]> bar'
46
+ assert_equal('foo ]]> bar', node.content)
47
+ end
36
48
  end
37
49
  end
38
50
  end
@@ -5,11 +5,28 @@ require 'uri'
5
5
  module Nokogiri
6
6
  module XML
7
7
  class TestDocument < Nokogiri::TestCase
8
+ URI = if URI.const_defined?(:DEFAULT_PARSER)
9
+ ::URI::DEFAULT_PARSER
10
+ else
11
+ ::URI
12
+ end
13
+
8
14
  def setup
9
15
  super
10
16
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
11
17
  end
12
18
 
19
+ def test_root_set_to_nil
20
+ @xml.root = nil
21
+ assert_equal nil, @xml.root
22
+ end
23
+
24
+ def test_parse_should_not_exist
25
+ assert_raises(NoMethodError) do
26
+ @xml.parse("foo")
27
+ end
28
+ end
29
+
13
30
  def test_collect_namespaces
14
31
  doc = Nokogiri::XML(<<-eoxml)
15
32
  <xml>
@@ -47,6 +64,29 @@ module Nokogiri
47
64
  assert_equal @xml, elm.document
48
65
  end
49
66
 
67
+ def test_create_element_with_attributes
68
+ elm = @xml.create_element('foo',:a => "1")
69
+ assert_instance_of Nokogiri::XML::Element, elm
70
+ assert_instance_of Nokogiri::XML::Attr, elm.attributes["a"]
71
+ assert_equal "1", elm["a"]
72
+ end
73
+
74
+ def test_create_element_with_namespace
75
+ elm = @xml.create_element('foo',:'xmlns:foo' => 'http://tenderlovemaking.com')
76
+ assert_equal 'http://tenderlovemaking.com', elm.namespaces['xmlns:foo']
77
+ end
78
+
79
+ def test_create_element_with_content
80
+ elm = @xml.create_element('foo',"needs more xml/violence")
81
+ assert_equal "needs more xml/violence", elm.content
82
+ end
83
+
84
+ def test_create_cdata
85
+ cdata = @xml.create_cdata("abc")
86
+ assert_instance_of Nokogiri::XML::CDATA, cdata
87
+ assert_equal "abc", cdata.content
88
+ end
89
+
50
90
  def test_pp
51
91
  out = StringIO.new('')
52
92
  assert_nothing_raised do
@@ -467,21 +507,21 @@ module Nokogiri
467
507
 
468
508
  ctx = Nokogiri::XML::XPathContext.new(doc)
469
509
  ctx.register_ns 'tenderlove', 'http://tenderlovemaking.com/'
470
- set = ctx.evaluate('//tenderlove:foo').node_set
510
+ set = ctx.evaluate('//tenderlove:foo')
471
511
  assert_equal 1, set.length
472
512
  assert_equal 'foo', set.first.name
473
513
 
474
514
  # It looks like only the URI is important:
475
515
  ctx = Nokogiri::XML::XPathContext.new(doc)
476
516
  ctx.register_ns 'america', 'http://tenderlovemaking.com/'
477
- set = ctx.evaluate('//america:foo').node_set
517
+ set = ctx.evaluate('//america:foo')
478
518
  assert_equal 1, set.length
479
519
  assert_equal 'foo', set.first.name
480
520
 
481
521
  # Its so important that a missing slash will cause it to return nothing
482
522
  ctx = Nokogiri::XML::XPathContext.new(doc)
483
523
  ctx.register_ns 'america', 'http://tenderlovemaking.com'
484
- set = ctx.evaluate('//america:foo').node_set
524
+ set = ctx.evaluate('//america:foo')
485
525
  assert_equal 0, set.length
486
526
  end
487
527
 
@@ -540,38 +580,6 @@ module Nokogiri
540
580
  assert dup.xml?, 'duplicate should be xml'
541
581
  end
542
582
 
543
- def test_subset_is_decorated
544
- x = Module.new do
545
- def awesome!
546
- end
547
- end
548
- util_decorate(@xml, x)
549
-
550
- assert @xml.respond_to?(:awesome!)
551
- assert node_set = @xml.search('//staff')
552
- assert node_set.respond_to?(:awesome!)
553
- assert subset = node_set.search('.//employee')
554
- assert subset.respond_to?(:awesome!)
555
- assert sub_subset = node_set.search('.//name')
556
- assert sub_subset.respond_to?(:awesome!)
557
- end
558
-
559
- def test_decorator_is_applied
560
- x = Module.new do
561
- def awesome!
562
- end
563
- end
564
- util_decorate(@xml, x)
565
-
566
- assert @xml.respond_to?(:awesome!)
567
- assert node_set = @xml.search('//employee')
568
- assert node_set.respond_to?(:awesome!)
569
- node_set.each do |node|
570
- assert node.respond_to?(:awesome!), node.class
571
- end
572
- assert @xml.root.respond_to?(:awesome!)
573
- end
574
-
575
583
  def test_new
576
584
  doc = nil
577
585
  assert_nothing_raised {
@@ -623,10 +631,37 @@ module Nokogiri
623
631
  assert_equal 0, doc.xpath("//x:foo", "x" => "http://c.flavorjon.es/").length
624
632
  end
625
633
 
626
- def util_decorate(document, x)
627
- document.decorators(XML::Node) << x
628
- document.decorators(XML::NodeSet) << x
629
- document.decorate!
634
+ def test_subset_is_decorated
635
+ x = Module.new do
636
+ def awesome!
637
+ end
638
+ end
639
+ util_decorate(@xml, x)
640
+
641
+ assert @xml.respond_to?(:awesome!)
642
+ assert node_set = @xml.search('//staff')
643
+ assert node_set.respond_to?(:awesome!)
644
+ assert subset = node_set.search('.//employee')
645
+ assert subset.respond_to?(:awesome!)
646
+ assert sub_subset = node_set.search('.//name')
647
+ assert sub_subset.respond_to?(:awesome!)
648
+ end
649
+
650
+ def test_decorator_is_applied
651
+ x = Module.new do
652
+ def awesome!
653
+ end
654
+ end
655
+ util_decorate(@xml, x)
656
+
657
+ assert @xml.respond_to?(:awesome!)
658
+ assert node_set = @xml.search('//employee')
659
+ assert node_set.respond_to?(:awesome!)
660
+ node_set.each do |node|
661
+ assert node.respond_to?(:awesome!), node.class
662
+ end
663
+ assert @xml.root.respond_to?(:awesome!)
664
+ assert @xml.children.respond_to?(:awesome!)
630
665
  end
631
666
  end
632
667
  end
@@ -8,6 +8,26 @@ module Nokogiri
8
8
  @xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
9
9
  end
10
10
 
11
+ def test_fragment_is_relative
12
+ doc = Nokogiri::XML('<root><a xmlns="blah" /></root>')
13
+ ctx = doc.root.child
14
+ fragment = Nokogiri::XML::DocumentFragment.new(doc, '<hello />', ctx)
15
+ hello = fragment.child
16
+
17
+ assert_equal 'hello', hello.name
18
+ assert_equal doc.root.child.namespace, hello.namespace
19
+ end
20
+
21
+ def test_node_fragment_is_relative
22
+ doc = Nokogiri::XML('<root><a xmlns="blah" /></root>')
23
+ ctx = doc.root.child
24
+ fragment = doc.root.child.fragment('<hello />')
25
+ hello = fragment.child
26
+
27
+ assert_equal 'hello', hello.name
28
+ assert_equal doc.root.child.namespace, hello.namespace
29
+ end
30
+
11
31
  def test_new
12
32
  fragment = Nokogiri::XML::DocumentFragment.new(@xml)
13
33
  end
@@ -139,6 +159,22 @@ module Nokogiri
139
159
  frag = doc.fragment "<baz:newnode></baz:newnode>"
140
160
  assert_nil frag.children.first.namespace
141
161
  end
162
+
163
+ def test_decorator_is_applied
164
+ x = Module.new do
165
+ def awesome!
166
+ end
167
+ end
168
+ util_decorate(@xml, x)
169
+ fragment = Nokogiri::XML::DocumentFragment.new(@xml, "<div>a</div><div>b</div>")
170
+
171
+ assert node_set = fragment.css('div')
172
+ assert node_set.respond_to?(:awesome!)
173
+ node_set.each do |node|
174
+ assert node.respond_to?(:awesome!), node.class
175
+ end
176
+ assert fragment.children.respond_to?(:awesome!), fragment.children.class
177
+ end
142
178
  end
143
179
  end
144
180
  end
@@ -18,6 +18,43 @@ module Nokogiri
18
18
  @entity_decl = @entities.first
19
19
  end
20
20
 
21
+ def test_constants # for libffi implementation. *sigh* sorry Mike. :-(
22
+ assert_equal 1, EntityDecl::INTERNAL_GENERAL
23
+ assert_equal 2, EntityDecl::EXTERNAL_GENERAL_PARSED
24
+ assert_equal 3, EntityDecl::EXTERNAL_GENERAL_UNPARSED
25
+ assert_equal 4, EntityDecl::INTERNAL_PARAMETER
26
+ assert_equal 5, EntityDecl::EXTERNAL_PARAMETER
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
+ end
35
+
36
+ def test_create_typed_entity
37
+ entity = @xml.create_entity(
38
+ 'foo', EntityDecl::INTERNAL_GENERAL, nil, nil, nil
39
+ )
40
+ assert_equal EntityDecl::INTERNAL_GENERAL, entity.entity_type
41
+ assert_equal 'foo', entity.name
42
+ end
43
+
44
+ def test_new
45
+ entity = Nokogiri::XML::EntityDecl.new(
46
+ 'foo', @xml, EntityDecl::INTERNAL_GENERAL, nil, nil, nil
47
+ )
48
+ assert_equal EntityDecl::INTERNAL_GENERAL, entity.entity_type
49
+ assert_equal 'foo', entity.name
50
+ end
51
+
52
+ def test_create_default_args
53
+ entity = @xml.create_entity('foo')
54
+ assert_equal EntityDecl::INTERNAL_GENERAL, entity.entity_type
55
+ assert_equal 'foo', entity.name
56
+ end
57
+
21
58
  def test_external_id
22
59
  assert_nil @entity_decl.external_id
23
60
  end
@@ -10,6 +10,99 @@ module Nokogiri
10
10
  @xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
11
11
  end
12
12
 
13
+ def test_first_element_child
14
+ node = @xml.root.first_element_child
15
+ assert_equal 'employee', node.name
16
+ assert node.element?, 'node is an element'
17
+ end
18
+
19
+ def test_element_children
20
+ nodes = @xml.root.element_children
21
+ assert_equal @xml.root.first_element_child, nodes.first
22
+ assert nodes.all? { |node| node.element? }, 'all nodes are elements'
23
+ end
24
+
25
+ def test_last_element_child
26
+ nodes = @xml.root.element_children
27
+ assert_equal nodes.last, @xml.root.element_children.last
28
+ end
29
+
30
+ def test_bad_xpath
31
+ bad_xpath = '//foo['
32
+
33
+ begin
34
+ @xml.xpath(bad_xpath)
35
+ rescue Nokogiri::XML::XPath::SyntaxError => e
36
+ assert_match(bad_xpath, e.to_s)
37
+ end
38
+ end
39
+
40
+ def test_namespace_type_error
41
+ assert_raises(TypeError) do
42
+ @xml.root.namespace = Object.new
43
+ end
44
+ end
45
+
46
+ def test_remove_namespace
47
+ @xml = Nokogiri::XML('<r xmlns="v"><s /></r>')
48
+ tag = @xml.at('s')
49
+ assert tag.namespace
50
+ tag.namespace = nil
51
+ assert_nil tag.namespace
52
+ end
53
+
54
+ def test_parse_needs_doc
55
+ list = @xml.root.parse('fooooooo <hello />')
56
+ assert_equal 1, list.css('hello').length
57
+ end
58
+
59
+ def test_parse
60
+ list = @xml.root.parse('fooooooo <hello />')
61
+ assert_equal 2, list.length
62
+ end
63
+
64
+ def test_parse_with_block
65
+ called = false
66
+ list = @xml.root.parse('<hello />') { |cfg|
67
+ called = true
68
+ assert_instance_of Nokogiri::XML::ParseOptions, cfg
69
+ }
70
+ assert called, 'config block called'
71
+ assert_equal 1, list.length
72
+ end
73
+
74
+ def test_parse_with_io
75
+ list = @xml.root.parse(StringIO.new('<hello />'))
76
+ assert_equal 1, list.length
77
+ assert_equal 'hello', list.first.name
78
+ end
79
+
80
+ def test_parse_with_empty_string
81
+ list = @xml.root.parse('')
82
+ assert_equal 0, list.length
83
+ end
84
+
85
+ # descriptive, not prescriptive.
86
+ def test_parse_invalid_html_markup_results_in_empty_nodeset
87
+ doc = Nokogiri::HTML("<html></html>")
88
+ nodeset = doc.root.parse "<div><div>a</div><snippet>b</snippet></div>"
89
+ assert_equal 1, doc.errors.length # "Tag snippet invalid"
90
+ assert_equal 0, nodeset.length
91
+ end
92
+
93
+ def test_parse_error_list
94
+ error_count = @xml.errors.length
95
+ list = @xml.root.parse('<hello>')
96
+ assert_equal 0, list.length
97
+ assert(error_count < @xml.errors.length, "errors should have increased")
98
+ end
99
+
100
+ def test_subclass_dup
101
+ subclass = Class.new(Nokogiri::XML::Node)
102
+ node = subclass.new('foo', @xml).dup
103
+ assert_instance_of subclass, node
104
+ end
105
+
13
106
  def test_gt_string_arg
14
107
  node = @xml.at('employee')
15
108
  nodes = (node > 'name')
@@ -111,32 +204,24 @@ module Nokogiri
111
204
  end
112
205
  end
113
206
 
114
- def test_namespace_nodes
207
+ def test_namespace_definitions_when_some_exist
115
208
  xml = Nokogiri::XML <<-eoxml
116
209
  <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
117
210
  <awesome/>
118
211
  </root>
119
212
  eoxml
120
- awesome = xml.root
121
- namespaces = awesome.namespace_definitions
122
- assert_equal 2, namespaces.length
213
+ namespace_definitions = xml.root.namespace_definitions
214
+ assert_equal 2, namespace_definitions.length
123
215
  end
124
216
 
125
- def test_no_definitions
217
+ def test_namespace_definitions_when_no_exist
126
218
  xml = Nokogiri::XML <<-eoxml
127
219
  <root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
128
220
  <awesome/>
129
221
  </root>
130
222
  eoxml
131
- awesome = xml.at('//xmlns:awesome')
132
- namespaces = awesome.namespace_definitions
133
- assert_equal 0, namespaces.length
134
- end
135
-
136
- def test_subclass_dup
137
- subclass = Class.new(Nokogiri::XML::Node)
138
- node = subclass.new('foo', @xml).dup
139
- assert_instance_of subclass, node
223
+ namespace_definitions = xml.at_xpath('//xmlns:awesome').namespace_definitions
224
+ assert_equal 0, namespace_definitions.length
140
225
  end
141
226
 
142
227
  def test_namespace_goes_to_children
@@ -607,6 +692,17 @@ module Nokogiri
607
692
 
608
693
  node.content = 'hello world!'
609
694
  assert_equal('hello world!', node.content)
695
+
696
+ node.content = '& <foo> &amp;'
697
+ assert_equal('& <foo> &amp;', node.content)
698
+ assert_equal('<form>&amp; &lt;foo&gt; &amp;amp;</form>', node.to_xml)
699
+ end
700
+
701
+ def test_set_content_should_unlink_existing_content
702
+ node = @xml.at_css("employee")
703
+ children = node.children
704
+ node.content = "hello"
705
+ children.each { |child| assert_nil child.parent }
610
706
  end
611
707
 
612
708
  def test_whitespace_nodes
@@ -629,16 +725,16 @@ module Nokogiri
629
725
  assert_equal address1_1, address1_2 # two references to the exact same node
630
726
  end
631
727
 
632
- def test_namespace_as_hash
728
+ def test_namespace_search_with_xpath_and_hash
633
729
  xml = Nokogiri::XML.parse(<<-eoxml)
634
- <root>
635
- <car xmlns:part="http://general-motors.com/">
636
- <part:tire>Michelin Model XGV</part:tire>
637
- </car>
638
- <bicycle xmlns:part="http://schwinn.com/">
639
- <part:tire>I'm a bicycle tire!</part:tire>
640
- </bicycle>
641
- </root>
730
+ <root>
731
+ <car xmlns:part="http://general-motors.com/">
732
+ <part:tire>Michelin Model XGV</part:tire>
733
+ </car>
734
+ <bicycle xmlns:part="http://schwinn.com/">
735
+ <part:tire>I'm a bicycle tire!</part:tire>
736
+ </bicycle>
737
+ </root>
642
738
  eoxml
643
739
 
644
740
  tires = xml.xpath('//bike:tire', {'bike' => 'http://schwinn.com/'})
@@ -647,58 +743,70 @@ module Nokogiri
647
743
 
648
744
  def test_namespace_search_with_css
649
745
  xml = Nokogiri::XML.parse(<<-eoxml)
650
- <root>
651
- <car xmlns:part="http://general-motors.com/">
652
- <part:tire>Michelin Model XGV</part:tire>
653
- </car>
654
- <bicycle xmlns:part="http://schwinn.com/">
655
- <part:tire>I'm a bicycle tire!</part:tire>
656
- </bicycle>
657
- </root>
746
+ <root>
747
+ <car xmlns:part="http://general-motors.com/">
748
+ <part:tire>Michelin Model XGV</part:tire>
749
+ </car>
750
+ <bicycle xmlns:part="http://schwinn.com/">
751
+ <part:tire>I'm a bicycle tire!</part:tire>
752
+ </bicycle>
753
+ </root>
658
754
  eoxml
659
755
 
660
756
  tires = xml.css('bike|tire', 'bike' => 'http://schwinn.com/')
661
757
  assert_equal 1, tires.length
662
758
  end
663
759
 
664
- def test_namespaces
760
+ def test_namespaces_should_include_all_namespace_definitions
665
761
  xml = Nokogiri::XML.parse(<<-EOF)
666
- <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
667
- <y xmlns:c='http://bazz.com/'>
668
- <a:div>hello a</a:div>
669
- <b:div>hello b</b:div>
670
- <c:div>hello c</c:div>
671
- </y>
672
- </x>
673
- EOF
674
- assert namespaces = xml.root.namespaces
675
- assert namespaces.key?('xmlns:a')
676
- assert_equal 'http://foo.com/', namespaces['xmlns:a']
677
- assert namespaces.key?('xmlns:b')
678
- assert_equal 'http://bar.com/', namespaces['xmlns:b']
679
- assert ! namespaces.key?('xmlns:c')
680
-
681
- assert namespaces = xml.namespaces
682
- assert namespaces.key?('xmlns:a')
683
- assert_equal 'http://foo.com/', namespaces['xmlns:a']
684
- assert namespaces.key?('xmlns:b')
685
- assert_equal 'http://bar.com/', namespaces['xmlns:b']
686
-
687
- assert_equal "hello a", xml.search("//a:div", xml.namespaces).first.inner_text
688
- assert_equal "hello b", xml.search("//b:div", xml.namespaces).first.inner_text
762
+ <x xmlns="http://quux.com/" xmlns:a="http://foo.com/" xmlns:b="http://bar.com/">
763
+ <y xmlns:c="http://bazz.com/">
764
+ <z>hello</z>
765
+ <a xmlns:c="http://newc.com/" />
766
+ </y>
767
+ </x>
768
+ EOF
769
+
770
+ namespaces = xml.namespaces # Document#namespace
771
+ assert_equal({"xmlns" => "http://quux.com/",
772
+ "xmlns:a" => "http://foo.com/",
773
+ "xmlns:b" => "http://bar.com/"}, namespaces)
774
+
775
+ namespaces = xml.root.namespaces
776
+ assert_equal({"xmlns" => "http://quux.com/",
777
+ "xmlns:a" => "http://foo.com/",
778
+ "xmlns:b" => "http://bar.com/"}, namespaces)
779
+
780
+ namespaces = xml.at_xpath("//xmlns:y").namespaces
781
+ assert_equal({"xmlns" => "http://quux.com/",
782
+ "xmlns:a" => "http://foo.com/",
783
+ "xmlns:b" => "http://bar.com/",
784
+ "xmlns:c" => "http://bazz.com/"}, namespaces)
785
+
786
+ namespaces = xml.at_xpath("//xmlns:z").namespaces
787
+ assert_equal({"xmlns" => "http://quux.com/",
788
+ "xmlns:a" => "http://foo.com/",
789
+ "xmlns:b" => "http://bar.com/",
790
+ "xmlns:c" => "http://bazz.com/"}, namespaces)
791
+
792
+ namespaces = xml.at_xpath("//xmlns:a").namespaces
793
+ assert_equal({"xmlns" => "http://quux.com/",
794
+ "xmlns:a" => "http://foo.com/",
795
+ "xmlns:b" => "http://bar.com/",
796
+ "xmlns:c" => "http://newc.com/"}, namespaces)
689
797
  end
690
798
 
691
799
  def test_namespace
692
800
  xml = Nokogiri::XML.parse(<<-EOF)
693
- <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
694
- <y xmlns:c='http://bazz.com/'>
695
- <a:div>hello a</a:div>
696
- <b:div>hello b</b:div>
697
- <c:div>hello c</c:div>
698
- <div>hello moon</div>
699
- </y>
700
- </x>
701
- EOF
801
+ <x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
802
+ <y xmlns:c='http://bazz.com/'>
803
+ <a:div>hello a</a:div>
804
+ <b:div>hello b</b:div>
805
+ <c:div>hello c</c:div>
806
+ <div>hello moon</div>
807
+ </y>
808
+ </x>
809
+ EOF
702
810
  set = xml.search("//y/*")
703
811
  assert_equal "a", set[0].namespace.prefix
704
812
  assert_equal "b", set[1].namespace.prefix
@@ -709,7 +817,7 @@ EOF
709
817
  def test_namespace_without_an_href_on_html_node
710
818
  # because microsoft word's HTML formatting does this. ick.
711
819
  xml = Nokogiri::HTML.parse <<-EOF
712
- <div><o:p>foo</o:p></div>
820
+ <div><o:p>foo</o:p></div>
713
821
  EOF
714
822
 
715
823
  assert_not_nil(node = xml.at('p'))
@@ -733,6 +841,25 @@ EOF
733
841
  assert_equal 2, node.line
734
842
  end
735
843
 
844
+ def test_xpath_results_have_document_and_are_decorated
845
+ x = Module.new do
846
+ def awesome! ; end
847
+ end
848
+ util_decorate(@xml, x)
849
+ node_set = @xml.xpath("//employee")
850
+ assert_equal @xml, node_set.document
851
+ assert node_set.respond_to?(:awesome!)
852
+ end
853
+
854
+ def test_css_results_have_document_and_are_decorated
855
+ x = Module.new do
856
+ def awesome! ; end
857
+ end
858
+ util_decorate(@xml, x)
859
+ node_set = @xml.css("employee")
860
+ assert_equal @xml, node_set.document
861
+ assert node_set.respond_to?(:awesome!)
862
+ end
736
863
  end
737
864
  end
738
865
  end