nokogiri 1.0.0 → 1.6.8.1
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.
- checksums.yaml +7 -0
- data/.autotest +26 -0
- data/.cross_rubies +9 -0
- data/.editorconfig +17 -0
- data/.gemtest +0 -0
- data/.travis.yml +51 -0
- data/CHANGELOG.rdoc +1160 -0
- data/CONTRIBUTING.md +42 -0
- data/C_CODING_STYLE.rdoc +33 -0
- data/Gemfile +22 -0
- data/LICENSE.txt +31 -0
- data/Manifest.txt +284 -40
- data/README.md +166 -0
- data/ROADMAP.md +111 -0
- data/Rakefile +310 -199
- data/STANDARD_RESPONSES.md +47 -0
- data/Y_U_NO_GEMSPEC.md +155 -0
- data/appveyor.yml +22 -0
- data/bin/nokogiri +118 -0
- data/build_all +45 -0
- data/dependencies.yml +29 -0
- data/ext/nokogiri/depend +358 -0
- data/ext/nokogiri/extconf.rb +664 -34
- data/ext/nokogiri/html_document.c +120 -33
- data/ext/nokogiri/html_document.h +1 -1
- data/ext/nokogiri/html_element_description.c +279 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +32 -0
- data/ext/nokogiri/html_entity_lookup.h +8 -0
- data/ext/nokogiri/html_sax_parser_context.c +116 -0
- data/ext/nokogiri/html_sax_parser_context.h +11 -0
- data/ext/nokogiri/html_sax_push_parser.c +87 -0
- data/ext/nokogiri/html_sax_push_parser.h +9 -0
- data/ext/nokogiri/nokogiri.c +145 -0
- data/ext/nokogiri/nokogiri.h +131 -0
- data/ext/nokogiri/xml_attr.c +94 -0
- data/ext/nokogiri/xml_attr.h +9 -0
- data/ext/nokogiri/xml_attribute_decl.c +70 -0
- data/ext/nokogiri/xml_attribute_decl.h +9 -0
- data/ext/nokogiri/xml_cdata.c +23 -19
- data/ext/nokogiri/xml_cdata.h +1 -1
- data/ext/nokogiri/xml_comment.c +69 -0
- data/ext/nokogiri/xml_comment.h +9 -0
- data/ext/nokogiri/xml_document.c +501 -54
- data/ext/nokogiri/xml_document.h +14 -1
- data/ext/nokogiri/xml_document_fragment.c +48 -0
- data/ext/nokogiri/xml_document_fragment.h +10 -0
- data/ext/nokogiri/xml_dtd.c +109 -24
- data/ext/nokogiri/xml_dtd.h +3 -1
- data/ext/nokogiri/xml_element_content.c +123 -0
- data/ext/nokogiri/xml_element_content.h +10 -0
- data/ext/nokogiri/xml_element_decl.c +69 -0
- data/ext/nokogiri/xml_element_decl.h +9 -0
- data/ext/nokogiri/xml_encoding_handler.c +79 -0
- data/ext/nokogiri/xml_encoding_handler.h +8 -0
- data/ext/nokogiri/xml_entity_decl.c +110 -0
- data/ext/nokogiri/xml_entity_decl.h +10 -0
- data/ext/nokogiri/xml_entity_reference.c +52 -0
- data/ext/nokogiri/xml_entity_reference.h +9 -0
- data/ext/nokogiri/xml_io.c +60 -0
- data/ext/nokogiri/xml_io.h +11 -0
- data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
- data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
- data/ext/nokogiri/xml_namespace.c +117 -0
- data/ext/nokogiri/xml_namespace.h +13 -0
- data/ext/nokogiri/xml_node.c +1285 -315
- data/ext/nokogiri/xml_node.h +4 -6
- data/ext/nokogiri/xml_node_set.c +415 -54
- data/ext/nokogiri/xml_node_set.h +6 -2
- data/ext/nokogiri/xml_processing_instruction.c +56 -0
- data/ext/nokogiri/xml_processing_instruction.h +9 -0
- data/ext/nokogiri/xml_reader.c +316 -77
- data/ext/nokogiri/xml_reader.h +1 -1
- data/ext/nokogiri/xml_relax_ng.c +161 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +215 -80
- data/ext/nokogiri/xml_sax_parser.h +30 -1
- data/ext/nokogiri/xml_sax_parser_context.c +262 -0
- data/ext/nokogiri/xml_sax_parser_context.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +115 -0
- data/ext/nokogiri/xml_sax_push_parser.h +9 -0
- data/ext/nokogiri/xml_schema.c +205 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +45 -175
- data/ext/nokogiri/xml_syntax_error.h +4 -2
- data/ext/nokogiri/xml_text.c +37 -14
- data/ext/nokogiri/xml_text.h +1 -1
- data/ext/nokogiri/xml_xpath_context.c +230 -13
- data/ext/nokogiri/xml_xpath_context.h +2 -1
- data/ext/nokogiri/xslt_stylesheet.c +196 -34
- data/ext/nokogiri/xslt_stylesheet.h +6 -1
- data/lib/nokogiri/css/node.rb +18 -61
- data/lib/nokogiri/css/parser.rb +725 -17
- data/lib/nokogiri/css/parser.y +126 -63
- data/lib/nokogiri/css/parser_extras.rb +91 -0
- data/lib/nokogiri/css/syntax_error.rb +7 -0
- data/lib/nokogiri/css/tokenizer.rb +148 -5
- data/lib/nokogiri/css/tokenizer.rex +31 -39
- data/lib/nokogiri/css/xpath_visitor.rb +109 -51
- data/lib/nokogiri/css.rb +24 -3
- data/lib/nokogiri/decorators/slop.rb +42 -0
- data/lib/nokogiri/html/builder.rb +27 -1
- data/lib/nokogiri/html/document.rb +329 -3
- data/lib/nokogiri/html/document_fragment.rb +39 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/element_description_defaults.rb +671 -0
- data/lib/nokogiri/html/entity_lookup.rb +13 -0
- data/lib/nokogiri/html/sax/parser.rb +35 -4
- data/lib/nokogiri/html/sax/parser_context.rb +16 -0
- data/lib/nokogiri/html/sax/push_parser.rb +36 -0
- data/lib/nokogiri/html.rb +18 -76
- data/lib/nokogiri/syntax_error.rb +4 -0
- data/lib/nokogiri/version.rb +106 -1
- data/lib/nokogiri/xml/attr.rb +14 -0
- data/lib/nokogiri/xml/attribute_decl.rb +18 -0
- data/lib/nokogiri/xml/builder.rb +395 -31
- data/lib/nokogiri/xml/cdata.rb +4 -2
- data/lib/nokogiri/xml/character_data.rb +7 -0
- data/lib/nokogiri/xml/document.rb +267 -12
- data/lib/nokogiri/xml/document_fragment.rb +149 -0
- data/lib/nokogiri/xml/dtd.rb +27 -1
- data/lib/nokogiri/xml/element_content.rb +36 -0
- data/lib/nokogiri/xml/element_decl.rb +13 -0
- data/lib/nokogiri/xml/entity_decl.rb +19 -0
- data/lib/nokogiri/xml/namespace.rb +13 -0
- data/lib/nokogiri/xml/node/save_options.rb +61 -0
- data/lib/nokogiri/xml/node.rb +748 -109
- data/lib/nokogiri/xml/node_set.rb +200 -72
- data/lib/nokogiri/xml/parse_options.rb +120 -0
- data/lib/nokogiri/xml/pp/character_data.rb +18 -0
- data/lib/nokogiri/xml/pp/node.rb +56 -0
- data/lib/nokogiri/xml/pp.rb +2 -0
- data/lib/nokogiri/xml/processing_instruction.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +102 -4
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax/document.rb +114 -2
- data/lib/nokogiri/xml/sax/parser.rb +97 -7
- data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
- data/lib/nokogiri/xml/sax.rb +2 -7
- data/lib/nokogiri/xml/schema.rb +63 -0
- data/lib/nokogiri/xml/searchable.rb +221 -0
- data/lib/nokogiri/xml/syntax_error.rb +27 -1
- data/lib/nokogiri/xml/text.rb +4 -1
- data/lib/nokogiri/xml/xpath/syntax_error.rb +11 -0
- data/lib/nokogiri/xml/xpath.rb +4 -0
- data/lib/nokogiri/xml/xpath_context.rb +3 -1
- data/lib/nokogiri/xml.rb +45 -38
- data/lib/nokogiri/xslt/stylesheet.rb +19 -0
- data/lib/nokogiri/xslt.rb +47 -2
- data/lib/nokogiri.rb +117 -24
- data/lib/xsd/xmlparser/nokogiri.rb +102 -0
- data/patches/sort-patches-by-date +25 -0
- data/ports/archives/libxml2-2.9.4.tar.gz +0 -0
- data/ports/archives/libxslt-1.1.29.tar.gz +0 -0
- data/suppressions/README.txt +1 -0
- data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
- data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
- data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
- data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
- data/tasks/test.rb +100 -0
- data/test/css/test_nthiness.rb +73 -6
- data/test/css/test_parser.rb +184 -39
- data/test/css/test_tokenizer.rb +72 -19
- data/test/css/test_xpath_visitor.rb +44 -2
- data/test/decorators/test_slop.rb +20 -0
- data/test/files/2ch.html +108 -0
- data/test/files/GH_1042.html +18 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/atom.xml +344 -0
- data/test/files/bar/bar.xsd +4 -0
- data/test/files/bogus.xml +0 -0
- data/test/files/dont_hurt_em_why.xml +422 -0
- data/test/files/encoding.html +82 -0
- data/test/files/encoding.xhtml +84 -0
- data/test/files/exslt.xml +8 -0
- data/test/files/exslt.xslt +35 -0
- data/test/files/foo/foo.xsd +4 -0
- data/test/files/metacharset.html +10 -0
- data/test/files/namespace_pressure_test.xml +1684 -0
- data/test/files/noencoding.html +47 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/files/saml/saml20assertion_schema.xsd +283 -0
- data/test/files/saml/saml20protocol_schema.xsd +302 -0
- data/test/files/saml/xenc_schema.xsd +146 -0
- data/test/files/saml/xmldsig_schema.xsd +318 -0
- data/test/files/shift_jis.html +10 -0
- data/test/files/shift_jis.xml +5 -0
- data/test/files/shift_jis_no_charset.html +9 -0
- data/test/files/slow-xpath.xml +25509 -0
- data/test/files/snuggles.xml +3 -0
- data/test/files/staff.dtd +10 -0
- data/test/files/test_document_url/bar.xml +2 -0
- data/test/files/test_document_url/document.dtd +4 -0
- data/test/files/test_document_url/document.xml +6 -0
- data/test/files/tlm.html +2 -1
- data/test/files/to_be_xincluded.xml +2 -0
- data/test/files/valid_bar.xml +2 -0
- data/test/files/xinclude.xml +4 -0
- data/test/helper.rb +124 -13
- data/test/html/sax/test_parser.rb +118 -4
- data/test/html/sax/test_parser_context.rb +46 -0
- data/test/html/sax/test_push_parser.rb +87 -0
- data/test/html/test_builder.rb +94 -8
- data/test/html/test_document.rb +626 -11
- data/test/html/test_document_encoding.rb +145 -0
- data/test/html/test_document_fragment.rb +301 -0
- data/test/html/test_element_description.rb +105 -0
- data/test/html/test_named_characters.rb +14 -0
- data/test/html/test_node.rb +212 -0
- data/test/html/test_node_encoding.rb +85 -0
- data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +14 -0
- data/test/namespaces/test_namespaces_aliased_default.rb +24 -0
- data/test/namespaces/test_namespaces_in_builder_doc.rb +75 -0
- data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
- data/test/namespaces/test_namespaces_in_created_doc.rb +75 -0
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +80 -0
- data/test/namespaces/test_namespaces_preservation.rb +31 -0
- data/test/test_convert_xpath.rb +2 -47
- data/test/test_css_cache.rb +45 -0
- data/test/test_encoding_handler.rb +48 -0
- data/test/test_memory_leak.rb +156 -0
- data/test/test_nokogiri.rb +103 -1
- data/test/test_soap4r_sax.rb +52 -0
- data/test/test_xslt_transforms.rb +293 -8
- data/test/xml/node/test_save_options.rb +28 -0
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +309 -8
- data/test/xml/sax/test_parser_context.rb +115 -0
- data/test/xml/sax/test_push_parser.rb +157 -0
- data/test/xml/test_attr.rb +67 -0
- data/test/xml/test_attribute_decl.rb +86 -0
- data/test/xml/test_builder.rb +327 -2
- data/test/xml/test_c14n.rb +180 -0
- data/test/xml/test_cdata.rb +32 -2
- data/test/xml/test_comment.rb +40 -0
- data/test/xml/test_document.rb +846 -35
- data/test/xml/test_document_encoding.rb +31 -0
- data/test/xml/test_document_fragment.rb +271 -0
- data/test/xml/test_dtd.rb +153 -9
- data/test/xml/test_dtd_encoding.rb +31 -0
- data/test/xml/test_element_content.rb +56 -0
- data/test/xml/test_element_decl.rb +73 -0
- data/test/xml/test_entity_decl.rb +122 -0
- data/test/xml/test_entity_reference.rb +251 -0
- data/test/xml/test_namespace.rb +96 -0
- data/test/xml/test_node.rb +1126 -105
- data/test/xml/test_node_attributes.rb +115 -0
- data/test/xml/test_node_encoding.rb +69 -0
- data/test/xml/test_node_inheritance.rb +32 -0
- data/test/xml/test_node_reparenting.rb +549 -0
- data/test/xml/test_node_set.rb +668 -9
- data/test/xml/test_parse_options.rb +64 -0
- data/test/xml/test_processing_instruction.rb +30 -0
- data/test/xml/test_reader.rb +589 -0
- data/test/xml/test_reader_encoding.rb +134 -0
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +142 -0
- data/test/xml/test_syntax_error.rb +30 -0
- data/test/xml/test_text.rb +49 -2
- data/test/xml/test_unparented_node.rb +440 -0
- data/test/xml/test_xinclude.rb +83 -0
- data/test/xml/test_xpath.rb +445 -0
- data/test/xslt/test_custom_functions.rb +133 -0
- data/test/xslt/test_exception_handling.rb +37 -0
- data/test_all +107 -0
- metadata +459 -115
- data/History.txt +0 -6
- data/README.ja.txt +0 -86
- data/README.txt +0 -87
- data/ext/nokogiri/html_sax_parser.c +0 -32
- data/ext/nokogiri/html_sax_parser.h +0 -11
- data/ext/nokogiri/native.c +0 -40
- data/ext/nokogiri/native.h +0 -51
- data/ext/nokogiri/xml_xpath.c +0 -46
- data/ext/nokogiri/xml_xpath.h +0 -11
- data/lib/nokogiri/css/generated_parser.rb +0 -653
- data/lib/nokogiri/css/generated_tokenizer.rb +0 -159
- data/lib/nokogiri/decorators/hpricot/node.rb +0 -58
- data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -14
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -17
- data/lib/nokogiri/decorators/hpricot.rb +0 -3
- data/lib/nokogiri/decorators.rb +0 -1
- data/lib/nokogiri/hpricot.rb +0 -47
- data/lib/nokogiri/xml/after_handler.rb +0 -18
- data/lib/nokogiri/xml/before_handler.rb +0 -32
- data/lib/nokogiri/xml/element.rb +0 -6
- data/lib/nokogiri/xml/entity_declaration.rb +0 -9
- data/nokogiri.gemspec +0 -34
- data/test/hpricot/files/basic.xhtml +0 -17
- data/test/hpricot/files/boingboing.html +0 -2266
- data/test/hpricot/files/cy0.html +0 -3653
- data/test/hpricot/files/immob.html +0 -400
- data/test/hpricot/files/pace_application.html +0 -1320
- data/test/hpricot/files/tenderlove.html +0 -16
- data/test/hpricot/files/uswebgen.html +0 -220
- data/test/hpricot/files/utf8.html +0 -1054
- data/test/hpricot/files/week9.html +0 -1723
- data/test/hpricot/files/why.xml +0 -19
- data/test/hpricot/load_files.rb +0 -7
- data/test/hpricot/test_alter.rb +0 -67
- data/test/hpricot/test_builder.rb +0 -27
- data/test/hpricot/test_parser.rb +0 -423
- data/test/hpricot/test_paths.rb +0 -15
- data/test/hpricot/test_preserved.rb +0 -78
- data/test/hpricot/test_xml.rb +0 -30
- data/test/test_reader.rb +0 -222
data/test/xml/test_node.rb
CHANGED
@@ -1,8 +1,705 @@
|
|
1
|
-
require
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
require 'stringio'
|
2
4
|
|
3
5
|
module Nokogiri
|
4
6
|
module XML
|
5
7
|
class TestNode < Nokogiri::TestCase
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
@xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
|
11
|
+
end
|
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?(&: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
|
+
def test_parse_config_option
|
86
|
+
node = @xml.root
|
87
|
+
options = nil
|
88
|
+
node.parse("<item></item>") do |config|
|
89
|
+
options = config
|
90
|
+
end
|
91
|
+
assert_equal Nokogiri::XML::ParseOptions::DEFAULT_XML, options.to_i
|
92
|
+
end
|
93
|
+
|
94
|
+
# descriptive, not prescriptive.
|
95
|
+
def test_parse_invalid_html_markup_results_in_empty_nodeset
|
96
|
+
doc = Nokogiri::HTML("<html></html>")
|
97
|
+
nodeset = doc.root.parse "<div><div>a</div><snippet>b</snippet></div>"
|
98
|
+
assert_equal 1, doc.errors.length # "Tag snippet invalid"
|
99
|
+
assert_equal 1, nodeset.length
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_node_context_parsing_of_malformed_html_fragment_with_recover_is_corrected
|
103
|
+
doc = HTML.parse "<html><body><div></div></body></html>"
|
104
|
+
context_node = doc.at_css "div"
|
105
|
+
nodeset = context_node.parse("<div </div>") do |options|
|
106
|
+
options.recover
|
107
|
+
end
|
108
|
+
assert_equal "<div></div>", nodeset.to_s
|
109
|
+
assert_equal 1, doc.errors.length
|
110
|
+
assert_equal 1, nodeset.length
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_node_context_parsing_of_malformed_html_fragment_without_recover_is_not_corrected
|
114
|
+
doc = HTML.parse "<html><body><div></div></body></html>"
|
115
|
+
context_node = doc.at_css "div"
|
116
|
+
nodeset = context_node.parse("<div </div>") do |options|
|
117
|
+
options.strict
|
118
|
+
end
|
119
|
+
assert_equal 1, doc.errors.length
|
120
|
+
assert_equal 0, nodeset.length
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_parse_error_list
|
124
|
+
error_count = @xml.errors.length
|
125
|
+
@xml.root.parse('<hello>')
|
126
|
+
assert(error_count < @xml.errors.length, "errors should have increased")
|
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
|
135
|
+
|
136
|
+
def test_parse_with_unparented_text_context_node
|
137
|
+
doc = XML::Document.new
|
138
|
+
elem = XML::Text.new("foo", doc)
|
139
|
+
x = elem.parse("<bar/>") # should not raise an exception
|
140
|
+
assert_equal x.first.name, "bar"
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_parse_with_unparented_html_text_context_node
|
144
|
+
doc = HTML::Document.new
|
145
|
+
elem = XML::Text.new("div", doc)
|
146
|
+
x = elem.parse("<div/>") # should not raise an exception
|
147
|
+
assert_equal x.first.name, "div"
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_parse_with_unparented_fragment_text_context_node
|
151
|
+
doc = XML::DocumentFragment.parse "<div><span>foo</span></div>"
|
152
|
+
elem = doc.at_css "span"
|
153
|
+
x = elem.parse("<span/>") # should not raise an exception
|
154
|
+
assert_equal x.first.name, "span"
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_parse_with_unparented_html_fragment_text_context_node
|
158
|
+
doc = HTML::DocumentFragment.parse "<div><span>foo</span></div>"
|
159
|
+
elem = doc.at_css "span"
|
160
|
+
x = elem.parse("<span/>") # should not raise an exception
|
161
|
+
assert_equal x.first.name, "span"
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_subclass_dup
|
165
|
+
subclass = Class.new(Nokogiri::XML::Node)
|
166
|
+
node = subclass.new('foo', @xml).dup
|
167
|
+
assert_instance_of subclass, node
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_gt_string_arg
|
171
|
+
node = @xml.at('employee')
|
172
|
+
nodes = (node > 'name')
|
173
|
+
assert_equal 1, nodes.length
|
174
|
+
assert_equal node, nodes.first.parent
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_next_element_when_next_sibling_is_element_should_return_next_sibling
|
178
|
+
doc = Nokogiri::XML "<root><foo /><quux /></root>"
|
179
|
+
node = doc.at_css("foo")
|
180
|
+
next_element = node.next_element
|
181
|
+
assert next_element.element?
|
182
|
+
assert_equal doc.at_css("quux"), next_element
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_next_element_when_there_is_no_next_sibling_should_return_nil
|
186
|
+
doc = Nokogiri::XML "<root><foo /><quux /></root>"
|
187
|
+
assert_nil doc.at_css("quux").next_element
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_next_element_when_next_sibling_is_not_an_element_should_return_closest_next_element_sibling
|
191
|
+
doc = Nokogiri::XML "<root><foo />bar<quux /></root>"
|
192
|
+
node = doc.at_css("foo")
|
193
|
+
next_element = node.next_element
|
194
|
+
assert next_element.element?
|
195
|
+
assert_equal doc.at_css("quux"), next_element
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_next_element_when_next_sibling_is_not_an_element_and_no_following_element_should_return_nil
|
199
|
+
doc = Nokogiri::XML "<root><foo />bar</root>"
|
200
|
+
node = doc.at_css("foo")
|
201
|
+
next_element = node.next_element
|
202
|
+
assert_nil next_element
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_previous_element_when_previous_sibling_is_element_should_return_previous_sibling
|
206
|
+
doc = Nokogiri::XML "<root><foo /><quux /></root>"
|
207
|
+
node = doc.at_css("quux")
|
208
|
+
previous_element = node.previous_element
|
209
|
+
assert previous_element.element?
|
210
|
+
assert_equal doc.at_css("foo"), previous_element
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_previous_element_when_there_is_no_previous_sibling_should_return_nil
|
214
|
+
doc = Nokogiri::XML "<root><foo /><quux /></root>"
|
215
|
+
assert_nil doc.at_css("foo").previous_element
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_previous_element_when_previous_sibling_is_not_an_element_should_return_closest_previous_element_sibling
|
219
|
+
doc = Nokogiri::XML "<root><foo />bar<quux /></root>"
|
220
|
+
node = doc.at_css("quux")
|
221
|
+
previous_element = node.previous_element
|
222
|
+
assert previous_element.element?
|
223
|
+
assert_equal doc.at_css("foo"), previous_element
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_previous_element_when_previous_sibling_is_not_an_element_and_no_following_element_should_return_nil
|
227
|
+
doc = Nokogiri::XML "<root>foo<bar /></root>"
|
228
|
+
node = doc.at_css("bar")
|
229
|
+
previous_element = node.previous_element
|
230
|
+
assert_nil previous_element
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_element?
|
234
|
+
assert @xml.root.element?, 'is an element'
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_slash_search
|
238
|
+
assert_equal 'EMP0001', (@xml/:staff/:employee/:employeeId).first.text
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_append_with_document
|
242
|
+
assert_raises(ArgumentError) do
|
243
|
+
@xml.root << Nokogiri::XML::Document.new
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_append_with_attr
|
248
|
+
r = Nokogiri.XML('<r a="1" />').root
|
249
|
+
assert_raises(ArgumentError) do
|
250
|
+
r << r.at_xpath('@a')
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_inspect_ns
|
255
|
+
xml = Nokogiri::XML(<<-eoxml) { |c| c.noblanks }
|
256
|
+
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
|
257
|
+
<awesome/>
|
258
|
+
</root>
|
259
|
+
eoxml
|
260
|
+
ins = xml.inspect
|
261
|
+
|
262
|
+
xml.traverse do |node|
|
263
|
+
assert_match node.class.name, ins
|
264
|
+
if node.respond_to? :attributes
|
265
|
+
node.attributes.each do |k,v|
|
266
|
+
assert_match k, ins
|
267
|
+
assert_match v, ins
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
if node.respond_to?(:namespace) && node.namespace
|
272
|
+
assert_match node.namespace.class.name, ins
|
273
|
+
assert_match node.namespace.href, ins
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_namespace_definitions_when_some_exist
|
279
|
+
xml = Nokogiri::XML <<-eoxml
|
280
|
+
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
|
281
|
+
<awesome/>
|
282
|
+
</root>
|
283
|
+
eoxml
|
284
|
+
namespace_definitions = xml.root.namespace_definitions
|
285
|
+
assert_equal 2, namespace_definitions.length
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_namespace_definitions_when_no_exist
|
289
|
+
xml = Nokogiri::XML <<-eoxml
|
290
|
+
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="bar">
|
291
|
+
<awesome/>
|
292
|
+
</root>
|
293
|
+
eoxml
|
294
|
+
namespace_definitions = xml.at_xpath('//xmlns:awesome').namespace_definitions
|
295
|
+
assert_equal 0, namespace_definitions.length
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_namespace_goes_to_children
|
299
|
+
fruits = Nokogiri::XML(<<-eoxml)
|
300
|
+
<Fruit xmlns='www.fruits.org'>
|
301
|
+
</Fruit>
|
302
|
+
eoxml
|
303
|
+
apple = Nokogiri::XML::Node.new('Apple', fruits)
|
304
|
+
orange = Nokogiri::XML::Node.new('Orange', fruits)
|
305
|
+
apple << orange
|
306
|
+
fruits.root << apple
|
307
|
+
assert fruits.at('//fruit:Orange',{'fruit'=>'www.fruits.org'})
|
308
|
+
assert fruits.at('//fruit:Apple',{'fruit'=>'www.fruits.org'})
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_description
|
312
|
+
assert_nil @xml.at('employee').description
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_spaceship
|
316
|
+
nodes = @xml.xpath('//employee')
|
317
|
+
assert_equal(-1, (nodes.first <=> nodes.last))
|
318
|
+
list = [nodes.first, nodes.last].sort
|
319
|
+
assert_equal nodes.first, list.first
|
320
|
+
assert_equal nodes.last, list.last
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_incorrect_spaceship
|
324
|
+
nodes = @xml.xpath('//employee')
|
325
|
+
assert_nil(nodes.first <=> 'asdf')
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_document_compare
|
329
|
+
nodes = @xml.xpath('//employee')
|
330
|
+
assert_equal(-1, (nodes.first <=> @xml))
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_different_document_compare
|
334
|
+
nodes = @xml.xpath('//employee')
|
335
|
+
doc = Nokogiri::XML('<a><b/></a>')
|
336
|
+
b = doc.at('b')
|
337
|
+
assert_nil(nodes.first <=> b)
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_duplicate_node_removes_namespace
|
341
|
+
fruits = Nokogiri::XML(<<-eoxml)
|
342
|
+
<Fruit xmlns='www.fruits.org'>
|
343
|
+
<Apple></Apple>
|
344
|
+
</Fruit>
|
345
|
+
eoxml
|
346
|
+
apple = fruits.root.xpath('fruit:Apple', {'fruit'=>'www.fruits.org'})[0]
|
347
|
+
new_apple = apple.dup
|
348
|
+
fruits.root << new_apple
|
349
|
+
assert_equal 2, fruits.xpath('//xmlns:Apple').length
|
350
|
+
assert_equal 1, fruits.to_xml.scan('www.fruits.org').length
|
351
|
+
end
|
352
|
+
|
353
|
+
[:clone, :dup].each do |symbol|
|
354
|
+
define_method "test_#{symbol}" do
|
355
|
+
node = @xml.at('//employee')
|
356
|
+
other = node.send(symbol)
|
357
|
+
assert_equal "employee", other.name
|
358
|
+
assert_nil other.parent
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def test_fragment_creates_elements
|
363
|
+
apple = @xml.fragment('<Apple/>')
|
364
|
+
apple.children.each do |child|
|
365
|
+
assert_equal Nokogiri::XML::Node::ELEMENT_NODE, child.type
|
366
|
+
assert_instance_of Nokogiri::XML::Element, child
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_node_added_to_root_should_get_namespace
|
371
|
+
fruits = Nokogiri::XML(<<-eoxml)
|
372
|
+
<Fruit xmlns='http://www.fruits.org'>
|
373
|
+
</Fruit>
|
374
|
+
eoxml
|
375
|
+
apple = fruits.fragment('<Apple/>')
|
376
|
+
fruits.root << apple
|
377
|
+
assert_equal 1, fruits.xpath('//xmlns:Apple').length
|
378
|
+
end
|
379
|
+
|
380
|
+
def test_new_node_can_have_ancestors
|
381
|
+
xml = Nokogiri::XML('<root>text</root>')
|
382
|
+
item = Nokogiri::XML::Element.new('item', xml)
|
383
|
+
assert_equal 0, item.ancestors.length
|
384
|
+
end
|
385
|
+
|
386
|
+
def test_children
|
387
|
+
doc = Nokogiri::XML(<<-eoxml)
|
388
|
+
<root>#{'<a/>' * 9 }</root>
|
389
|
+
eoxml
|
390
|
+
assert_equal 9, doc.root.children.length
|
391
|
+
assert_equal 9, doc.root.children.to_a.length
|
392
|
+
|
393
|
+
doc = Nokogiri::XML(<<-eoxml)
|
394
|
+
<root>#{'<a/>' * 15 }</root>
|
395
|
+
eoxml
|
396
|
+
assert_equal 15, doc.root.children.length
|
397
|
+
assert_equal 15, doc.root.children.to_a.length
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_add_namespace
|
401
|
+
node = @xml.at('address')
|
402
|
+
node.add_namespace('foo', 'http://tenderlovemaking.com')
|
403
|
+
assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_add_namespace_twice
|
407
|
+
node = @xml.at('address')
|
408
|
+
ns = node.add_namespace('foo', 'http://tenderlovemaking.com')
|
409
|
+
ns2 = node.add_namespace('foo', 'http://tenderlovemaking.com')
|
410
|
+
assert_equal ns, ns2
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_add_default_ns
|
414
|
+
node = @xml.at('address')
|
415
|
+
node.add_namespace(nil, 'http://tenderlovemaking.com')
|
416
|
+
assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_add_multiple_namespaces
|
420
|
+
node = @xml.at('address')
|
421
|
+
|
422
|
+
node.add_namespace(nil, 'http://tenderlovemaking.com')
|
423
|
+
assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
|
424
|
+
|
425
|
+
node.add_namespace('foo', 'http://tenderlovemaking.com')
|
426
|
+
assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns:foo']
|
427
|
+
end
|
428
|
+
|
429
|
+
def test_default_namespace=
|
430
|
+
node = @xml.at('address')
|
431
|
+
node.default_namespace = 'http://tenderlovemaking.com'
|
432
|
+
assert_equal 'http://tenderlovemaking.com', node.namespaces['xmlns']
|
433
|
+
end
|
434
|
+
|
435
|
+
def test_namespace=
|
436
|
+
node = @xml.at('address')
|
437
|
+
assert_nil node.namespace
|
438
|
+
definition = node.add_namespace_definition 'bar', 'http://tlm.com/'
|
439
|
+
|
440
|
+
node.namespace = definition
|
441
|
+
|
442
|
+
assert_equal definition, node.namespace
|
443
|
+
|
444
|
+
assert_equal node, @xml.at('//foo:address', {
|
445
|
+
'foo' => 'http://tlm.com/'
|
446
|
+
})
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_add_namespace_with_nil_associates_node
|
450
|
+
node = @xml.at('address')
|
451
|
+
assert_nil node.namespace
|
452
|
+
definition = node.add_namespace_definition nil, 'http://tlm.com/'
|
453
|
+
assert_equal definition, node.namespace
|
454
|
+
end
|
455
|
+
|
456
|
+
def test_add_namespace_does_not_associate_node
|
457
|
+
node = @xml.at('address')
|
458
|
+
assert_nil node.namespace
|
459
|
+
assert node.add_namespace_definition 'foo', 'http://tlm.com/'
|
460
|
+
assert_nil node.namespace
|
461
|
+
end
|
462
|
+
|
463
|
+
def test_set_namespace_from_different_doc
|
464
|
+
node = @xml.at('address')
|
465
|
+
doc = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
|
466
|
+
decl = doc.root.add_namespace_definition 'foo', 'bar'
|
467
|
+
|
468
|
+
assert_raises(ArgumentError) do
|
469
|
+
node.namespace = decl
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_set_namespace_must_only_take_a_namespace
|
474
|
+
node = @xml.at('address')
|
475
|
+
assert_raises(TypeError) do
|
476
|
+
node.namespace = node
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
def test_at
|
481
|
+
node = @xml.at('address')
|
482
|
+
assert_equal node, @xml.xpath('//address').first
|
483
|
+
end
|
484
|
+
|
485
|
+
def test_at_self
|
486
|
+
node = @xml.at('address')
|
487
|
+
assert_equal node, node.at('.')
|
488
|
+
end
|
489
|
+
|
490
|
+
def test_at_xpath
|
491
|
+
node = @xml.at_xpath('//address')
|
492
|
+
nodes = @xml.xpath('//address')
|
493
|
+
assert_equal 5, nodes.size
|
494
|
+
assert_equal node, nodes.first
|
495
|
+
end
|
496
|
+
|
497
|
+
def test_at_css
|
498
|
+
node = @xml.at_css('address')
|
499
|
+
nodes = @xml.css('address')
|
500
|
+
assert_equal 5, nodes.size
|
501
|
+
assert_equal node, nodes.first
|
502
|
+
end
|
503
|
+
|
504
|
+
def test_percent
|
505
|
+
node = @xml % ('address')
|
506
|
+
assert_equal node, @xml.xpath('//address').first
|
507
|
+
end
|
508
|
+
|
509
|
+
def test_accept
|
510
|
+
visitor = Class.new {
|
511
|
+
attr_accessor :visited
|
512
|
+
def accept target
|
513
|
+
target.accept(self)
|
514
|
+
end
|
515
|
+
|
516
|
+
def visit node
|
517
|
+
node.children.each { |c| c.accept(self) }
|
518
|
+
@visited = true
|
519
|
+
end
|
520
|
+
}.new
|
521
|
+
visitor.accept(@xml.root)
|
522
|
+
assert visitor.visited
|
523
|
+
end
|
524
|
+
|
525
|
+
def test_write_to
|
526
|
+
io = StringIO.new
|
527
|
+
@xml.write_to io
|
528
|
+
io.rewind
|
529
|
+
assert_equal @xml.to_xml, io.read
|
530
|
+
end
|
531
|
+
|
532
|
+
def test_attribute_with_symbol
|
533
|
+
assert_equal 'Yes', @xml.css('address').first[:domestic]
|
534
|
+
end
|
535
|
+
|
536
|
+
def test_non_existent_attribute_should_return_nil
|
537
|
+
node = @xml.root.first_element_child
|
538
|
+
assert_nil node.attribute('type')
|
539
|
+
end
|
540
|
+
|
541
|
+
def test_write_to_with_block
|
542
|
+
called = false
|
543
|
+
io = StringIO.new
|
544
|
+
conf = nil
|
545
|
+
@xml.write_to io do |config|
|
546
|
+
called = true
|
547
|
+
conf = config
|
548
|
+
config.format.as_html.no_empty_tags
|
549
|
+
end
|
550
|
+
io.rewind
|
551
|
+
assert called
|
552
|
+
string = io.read
|
553
|
+
assert_equal @xml.serialize(nil, conf.options), string
|
554
|
+
assert_equal @xml.serialize(nil, conf), string
|
555
|
+
end
|
556
|
+
|
557
|
+
%w{ xml html xhtml }.each do |type|
|
558
|
+
define_method(:"test_write_#{type}_to") do
|
559
|
+
io = StringIO.new
|
560
|
+
assert @xml.send(:"write_#{type}_to", io)
|
561
|
+
io.rewind
|
562
|
+
assert_match @xml.send(:"to_#{type}"), io.read
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
def test_serialize_with_block
|
567
|
+
called = false
|
568
|
+
conf = nil
|
569
|
+
string = @xml.serialize do |config|
|
570
|
+
called = true
|
571
|
+
conf = config
|
572
|
+
config.format.as_html.no_empty_tags
|
573
|
+
end
|
574
|
+
assert called
|
575
|
+
assert_equal @xml.serialize(nil, conf.options), string
|
576
|
+
assert_equal @xml.serialize(nil, conf), string
|
577
|
+
end
|
578
|
+
|
579
|
+
def test_hold_refence_to_subnode
|
580
|
+
doc = Nokogiri::XML(<<-eoxml)
|
581
|
+
<root>
|
582
|
+
<a>
|
583
|
+
<b />
|
584
|
+
</a>
|
585
|
+
</root>
|
586
|
+
eoxml
|
587
|
+
assert node_a = doc.css('a').first
|
588
|
+
assert node_b = node_a.css('b').first
|
589
|
+
node_a.unlink
|
590
|
+
assert_equal 'b', node_b.name
|
591
|
+
end
|
592
|
+
|
593
|
+
def test_values
|
594
|
+
assert_equal %w{ Yes Yes }, @xml.xpath('//address')[1].values
|
595
|
+
end
|
596
|
+
|
597
|
+
def test_keys
|
598
|
+
assert_equal %w{ domestic street }, @xml.xpath('//address')[1].keys
|
599
|
+
end
|
600
|
+
|
601
|
+
def test_each
|
602
|
+
attributes = []
|
603
|
+
@xml.xpath('//address')[1].each do |key, value|
|
604
|
+
attributes << [key, value]
|
605
|
+
end
|
606
|
+
assert_equal [['domestic', 'Yes'], ['street', 'Yes']], attributes
|
607
|
+
end
|
608
|
+
|
609
|
+
def test_new
|
610
|
+
assert node = Nokogiri::XML::Node.new('input', @xml)
|
611
|
+
assert_equal 1, node.node_type
|
612
|
+
assert_instance_of Nokogiri::XML::Element, node
|
613
|
+
end
|
614
|
+
|
615
|
+
def test_to_str
|
616
|
+
name = @xml.xpath('//name').first
|
617
|
+
assert_match(/Margaret/, '' + name)
|
618
|
+
assert_equal('Margaret Martin', '' + name.children.first)
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_ancestors
|
622
|
+
address = @xml.xpath('//address').first
|
623
|
+
assert_equal 3, address.ancestors.length
|
624
|
+
assert_equal ['employee', 'staff', 'document'],
|
625
|
+
address.ancestors.map(&:name)
|
626
|
+
end
|
627
|
+
|
628
|
+
def test_read_only?
|
629
|
+
assert entity_decl = @xml.internal_subset.children.find { |x|
|
630
|
+
x.type == Node::ENTITY_DECL
|
631
|
+
}
|
632
|
+
assert entity_decl.read_only?
|
633
|
+
end
|
634
|
+
|
635
|
+
def test_remove_attribute
|
636
|
+
address = @xml.xpath('/staff/employee/address').first
|
637
|
+
assert_equal 'Yes', address['domestic']
|
638
|
+
attr = address.attributes['domestic']
|
639
|
+
|
640
|
+
returned_attr = address.remove_attribute 'domestic'
|
641
|
+
assert_nil address['domestic']
|
642
|
+
assert_equal attr, returned_attr
|
643
|
+
end
|
644
|
+
|
645
|
+
def test_remove_attribute_when_not_found
|
646
|
+
address = @xml.xpath('/staff/employee/address').first
|
647
|
+
attr = address.remove_attribute 'not-an-attribute'
|
648
|
+
assert_nil attr
|
649
|
+
end
|
650
|
+
|
651
|
+
def test_attribute_setter_accepts_non_string
|
652
|
+
address = @xml.xpath("/staff/employee/address").first
|
653
|
+
assert_equal "Yes", address[:domestic]
|
654
|
+
address[:domestic] = "Altered Yes"
|
655
|
+
assert_equal "Altered Yes", address[:domestic]
|
656
|
+
end
|
657
|
+
|
658
|
+
def test_attribute_accessor_accepts_non_string
|
659
|
+
address = @xml.xpath("/staff/employee/address").first
|
660
|
+
assert_equal "Yes", address["domestic"]
|
661
|
+
assert_equal "Yes", address[:domestic]
|
662
|
+
end
|
663
|
+
|
664
|
+
def test_empty_attribute_reading
|
665
|
+
node = Nokogiri::XML '<foo empty="" whitespace=" "/>'
|
666
|
+
|
667
|
+
assert_equal '', node.root['empty']
|
668
|
+
assert_equal ' ', node.root['whitespace']
|
669
|
+
end
|
670
|
+
|
671
|
+
def test_delete
|
672
|
+
address = @xml.xpath('/staff/employee/address').first
|
673
|
+
assert_equal 'Yes', address['domestic']
|
674
|
+
address.delete 'domestic'
|
675
|
+
assert_nil address['domestic']
|
676
|
+
end
|
677
|
+
|
678
|
+
def test_set_content_with_symbol
|
679
|
+
node = @xml.at('//name')
|
680
|
+
node.content = :foo
|
681
|
+
assert_equal 'foo', node.content
|
682
|
+
end
|
683
|
+
|
684
|
+
def test_set_native_content_is_unescaped
|
685
|
+
comment = Nokogiri.XML('<r><!-- foo --></r>').at('//comment()')
|
686
|
+
|
687
|
+
comment.native_content = " < " # content= will escape this string
|
688
|
+
assert_equal "<!-- < -->", comment.to_xml
|
689
|
+
end
|
690
|
+
|
691
|
+
def test_find_by_css_class_with_nonstandard_whitespace
|
692
|
+
doc = Nokogiri::HTML '
|
693
|
+
<html>
|
694
|
+
<body>
|
695
|
+
<div class="a
|
696
|
+
b"></div>
|
697
|
+
</body>
|
698
|
+
</html>
|
699
|
+
'
|
700
|
+
assert_not_nil doc.at_css(".b")
|
701
|
+
end
|
702
|
+
|
6
703
|
def test_find_by_css_with_tilde_eql
|
7
704
|
xml = Nokogiri::XML.parse(<<-eoxml)
|
8
705
|
<root>
|
@@ -17,7 +714,7 @@ module Nokogiri
|
|
17
714
|
eoxml
|
18
715
|
set = xml.css('a[@class~="bar"]')
|
19
716
|
assert_equal 4, set.length
|
20
|
-
assert_equal ['Bar'], set.map
|
717
|
+
assert_equal ['Bar'], set.map(&:content).uniq
|
21
718
|
end
|
22
719
|
|
23
720
|
def test_unlink
|
@@ -39,185 +736,509 @@ module Nokogiri
|
|
39
736
|
assert node.document
|
40
737
|
assert node.previous_sibling
|
41
738
|
assert node.next_sibling
|
42
|
-
assert node.instance_eval{ owned? }
|
43
739
|
node.unlink
|
44
740
|
assert !node.parent
|
45
|
-
#
|
741
|
+
#assert !node.document
|
46
742
|
assert !node.previous_sibling
|
47
743
|
assert !node.next_sibling
|
48
|
-
assert !node.instance_eval{ owned? }
|
49
744
|
assert_no_match(/Hello world/, xml.to_s)
|
50
745
|
end
|
51
746
|
|
52
|
-
def test_dup
|
53
|
-
html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
|
54
|
-
found = html.search('//div/a').first
|
55
|
-
dup = found.dup
|
56
|
-
assert dup
|
57
|
-
assert_equal found.content, dup.content
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_search_can_handle_xpath_and_css
|
61
|
-
html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
|
62
|
-
found = html.search('//div/a', 'div > p')
|
63
|
-
length = html.xpath('//div/a').length +
|
64
|
-
html.css('div > p').length
|
65
|
-
assert_equal length, found.length
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_find_by_xpath
|
69
|
-
html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
|
70
|
-
found = html.xpath('//div/a')
|
71
|
-
assert_equal 3, found.length
|
72
|
-
end
|
73
|
-
|
74
|
-
def test_find_by_css
|
75
|
-
html = Nokogiri::HTML.parse(File.read(HTML_FILE), HTML_FILE)
|
76
|
-
found = html.css('div > a')
|
77
|
-
assert_equal 3, found.length
|
78
|
-
end
|
79
|
-
|
80
747
|
def test_next_sibling
|
81
|
-
|
82
|
-
assert node = xml.root
|
748
|
+
assert node = @xml.root
|
83
749
|
assert sibling = node.child.next_sibling
|
84
750
|
assert_equal('employee', sibling.name)
|
85
751
|
end
|
86
752
|
|
87
753
|
def test_previous_sibling
|
88
|
-
|
89
|
-
assert node = xml.root
|
754
|
+
assert node = @xml.root
|
90
755
|
assert sibling = node.child.next_sibling
|
91
756
|
assert_equal('employee', sibling.name)
|
92
757
|
assert_equal(sibling.previous_sibling, node.child)
|
93
758
|
end
|
94
759
|
|
95
760
|
def test_name=
|
96
|
-
|
97
|
-
assert node = xml.root
|
761
|
+
assert node = @xml.root
|
98
762
|
node.name = 'awesome'
|
99
763
|
assert_equal('awesome', node.name)
|
100
764
|
end
|
101
765
|
|
102
766
|
def test_child
|
103
|
-
|
104
|
-
assert node = xml.root
|
767
|
+
assert node = @xml.root
|
105
768
|
assert child = node.child
|
106
769
|
assert_equal('text', child.name)
|
107
770
|
end
|
108
771
|
|
109
772
|
def test_key?
|
110
|
-
|
111
|
-
assert node = xml.search('//address').first
|
773
|
+
assert node = @xml.search('//address').first
|
112
774
|
assert(!node.key?('asdfasdf'))
|
113
775
|
end
|
114
776
|
|
115
777
|
def test_set_property
|
116
|
-
|
117
|
-
assert node = xml.search('//address').first
|
778
|
+
assert node = @xml.search('//address').first
|
118
779
|
node['foo'] = 'bar'
|
119
780
|
assert_equal('bar', node['foo'])
|
120
781
|
end
|
121
782
|
|
783
|
+
def test_set_property_non_string
|
784
|
+
assert node = @xml.search('//address').first
|
785
|
+
node['foo'] = 1
|
786
|
+
assert_equal('1', node['foo'])
|
787
|
+
node['foo'] = false
|
788
|
+
assert_equal('false', node['foo'])
|
789
|
+
end
|
790
|
+
|
122
791
|
def test_attributes
|
123
|
-
|
124
|
-
assert node = xml.search('//address').first
|
792
|
+
assert node = @xml.search('//address').first
|
125
793
|
assert_nil(node['asdfasdfasdf'])
|
126
794
|
assert_equal('Yes', node['domestic'])
|
127
795
|
|
128
|
-
assert node = xml.search('//address')[2]
|
796
|
+
assert node = @xml.search('//address')[2]
|
129
797
|
attr = node.attributes
|
130
798
|
assert_equal 2, attr.size
|
131
|
-
assert_equal 'Yes', attr['domestic']
|
132
|
-
assert_equal '
|
799
|
+
assert_equal 'Yes', attr['domestic'].value
|
800
|
+
assert_equal 'Yes', attr['domestic'].to_s
|
801
|
+
assert_equal 'No', attr['street'].value
|
133
802
|
end
|
134
803
|
|
135
804
|
def test_path
|
136
|
-
|
137
|
-
assert set = xml.search('//employee')
|
805
|
+
assert set = @xml.search('//employee')
|
138
806
|
assert node = set.first
|
139
807
|
assert_equal('/staff/employee[1]', node.path)
|
140
808
|
end
|
141
809
|
|
810
|
+
def test_parent_xpath
|
811
|
+
assert set = @xml.search('//employee')
|
812
|
+
assert node = set.first
|
813
|
+
assert parent_set = node.search('..')
|
814
|
+
assert parent_node = parent_set.first
|
815
|
+
assert_equal '/staff', parent_node.path
|
816
|
+
assert_equal node.parent, parent_node
|
817
|
+
end
|
818
|
+
|
819
|
+
def test_search_self
|
820
|
+
node = @xml.at('//employee')
|
821
|
+
assert_equal node.search('.').to_a, [node]
|
822
|
+
end
|
823
|
+
|
824
|
+
def test_search_by_symbol
|
825
|
+
assert set = @xml.search(:employee)
|
826
|
+
assert 5, set.length
|
827
|
+
|
828
|
+
assert node = @xml.at(:employee)
|
829
|
+
assert node.text =~ /EMP0001/
|
830
|
+
end
|
831
|
+
|
142
832
|
def test_new_node
|
143
|
-
node = Nokogiri::XML::Node.new('form')
|
833
|
+
node = Nokogiri::XML::Node.new('form', @xml)
|
144
834
|
assert_equal('form', node.name)
|
145
|
-
|
835
|
+
assert(node.document)
|
836
|
+
end
|
837
|
+
|
838
|
+
def test_encode_special_chars
|
839
|
+
foo = @xml.css('employee').first.encode_special_chars('&')
|
840
|
+
assert_equal '&', foo
|
146
841
|
end
|
147
842
|
|
148
|
-
def
|
149
|
-
node = Nokogiri::XML::Node.new('form')
|
843
|
+
def test_content_equals
|
844
|
+
node = Nokogiri::XML::Node.new('form', @xml)
|
150
845
|
assert_equal('', node.content)
|
151
846
|
|
152
847
|
node.content = 'hello world!'
|
153
848
|
assert_equal('hello world!', node.content)
|
849
|
+
|
850
|
+
node.content = '& <foo> &'
|
851
|
+
assert_equal('& <foo> &', node.content)
|
852
|
+
assert_equal('<form>& <foo> &amp;</form>', node.to_xml)
|
853
|
+
|
854
|
+
node.content = "1234 <-> 1234"
|
855
|
+
assert_equal "1234 <-> 1234", node.content
|
856
|
+
assert_equal "<form>1234 <-> 1234</form>", node.to_xml
|
857
|
+
|
858
|
+
node.content = '1234'
|
859
|
+
node.add_child '<foo>5678</foo>'
|
860
|
+
assert_equal '12345678', node.content
|
154
861
|
end
|
155
862
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
863
|
+
# issue #839
|
864
|
+
def test_encoding_of_copied_nodes
|
865
|
+
d1 = Nokogiri::XML('<r><a>&</a></r>')
|
866
|
+
d2 = Nokogiri::XML('<r></r>')
|
867
|
+
ne = d1.root.xpath('//a').first.dup(1)
|
868
|
+
ne.content += "& < & > \" &"
|
869
|
+
d2.root << ne
|
870
|
+
assert_match(/<a>&& < & > \" &<\/a>/, d2.to_s)
|
871
|
+
end
|
161
872
|
|
162
|
-
|
163
|
-
|
873
|
+
def test_content_after_appending_text
|
874
|
+
doc = Nokogiri::XML '<foo />'
|
875
|
+
node = doc.children.first
|
876
|
+
node.content = 'bar'
|
877
|
+
node << 'baz'
|
878
|
+
assert_equal 'barbaz', node.content
|
879
|
+
end
|
164
880
|
|
165
|
-
|
166
|
-
first
|
881
|
+
def test_content_depth_first
|
882
|
+
node = Nokogiri::XML '<foo>first<baz>second</baz>third</foo>'
|
883
|
+
assert_equal 'firstsecondthird', node.content
|
884
|
+
end
|
167
885
|
|
168
|
-
|
169
|
-
|
170
|
-
|
886
|
+
def test_set_content_should_unlink_existing_content
|
887
|
+
node = @xml.at_css("employee")
|
888
|
+
children = node.children
|
889
|
+
node.content = "hello"
|
890
|
+
children.each { |child| assert_nil child.parent }
|
891
|
+
end
|
171
892
|
|
172
|
-
|
893
|
+
def test_whitespace_nodes
|
894
|
+
doc = Nokogiri::XML.parse("<root><b>Foo</b>\n<i>Bar</i> <p>Bazz</p></root>")
|
895
|
+
children = doc.at('//root').children.collect(&:to_s)
|
896
|
+
assert_equal "\n", children[1]
|
897
|
+
assert_equal " ", children[3]
|
173
898
|
end
|
174
899
|
|
175
|
-
def
|
900
|
+
def test_node_equality
|
901
|
+
doc1 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
|
902
|
+
doc2 = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
|
903
|
+
|
904
|
+
address1_1 = doc1.xpath('//address').first
|
905
|
+
address1_2 = doc1.xpath('//address').first
|
906
|
+
|
907
|
+
address2 = doc2.xpath('//address').first
|
908
|
+
|
909
|
+
assert_not_equal address1_1, address2 # two references to very, very similar nodes
|
910
|
+
assert_equal address1_1, address1_2 # two references to the exact same node
|
911
|
+
end
|
912
|
+
|
913
|
+
def test_namespace_search_with_xpath_and_hash
|
176
914
|
xml = Nokogiri::XML.parse(<<-eoxml)
|
177
|
-
<root>
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
</root>
|
915
|
+
<root>
|
916
|
+
<car xmlns:part="http://general-motors.com/">
|
917
|
+
<part:tire>Michelin Model XGV</part:tire>
|
918
|
+
</car>
|
919
|
+
<bicycle xmlns:part="http://schwinn.com/">
|
920
|
+
<part:tire>I'm a bicycle tire!</part:tire>
|
921
|
+
</bicycle>
|
922
|
+
</root>
|
185
923
|
eoxml
|
186
924
|
|
187
925
|
tires = xml.xpath('//bike:tire', {'bike' => 'http://schwinn.com/'})
|
188
926
|
assert_equal 1, tires.length
|
189
927
|
end
|
190
928
|
|
191
|
-
def
|
929
|
+
def test_namespace_search_with_xpath_and_hash_with_symbol_keys
|
930
|
+
xml = Nokogiri::XML.parse(<<-eoxml)
|
931
|
+
<root>
|
932
|
+
<car xmlns:part="http://general-motors.com/">
|
933
|
+
<part:tire>Michelin Model XGV</part:tire>
|
934
|
+
</car>
|
935
|
+
<bicycle xmlns:part="http://schwinn.com/">
|
936
|
+
<part:tire>I'm a bicycle tire!</part:tire>
|
937
|
+
</bicycle>
|
938
|
+
</root>
|
939
|
+
eoxml
|
940
|
+
|
941
|
+
tires = xml.xpath('//bike:tire', :bike => 'http://schwinn.com/')
|
942
|
+
assert_equal 1, tires.length
|
943
|
+
end
|
944
|
+
|
945
|
+
def test_namespace_search_with_css
|
946
|
+
xml = Nokogiri::XML.parse(<<-eoxml)
|
947
|
+
<root>
|
948
|
+
<car xmlns:part="http://general-motors.com/">
|
949
|
+
<part:tire>Michelin Model XGV</part:tire>
|
950
|
+
</car>
|
951
|
+
<bicycle xmlns:part="http://schwinn.com/">
|
952
|
+
<part:tire>I'm a bicycle tire!</part:tire>
|
953
|
+
</bicycle>
|
954
|
+
</root>
|
955
|
+
eoxml
|
956
|
+
|
957
|
+
tires = xml.css('bike|tire', 'bike' => 'http://schwinn.com/' )
|
958
|
+
assert_equal 1, tires.length
|
959
|
+
end
|
960
|
+
|
961
|
+
def test_namespaced_attribute_search_with_xpath
|
962
|
+
# from #593
|
963
|
+
xmlContent = <<-EOXML
|
964
|
+
<?xml version="1.0"?>
|
965
|
+
<ns1:el1 xmlns:ns1="http://blabla.com" >
|
966
|
+
<ns1:el2 ns1:att="123">with namespace</ns1:el2 >
|
967
|
+
<ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
|
968
|
+
</ns1:el1>
|
969
|
+
EOXML
|
970
|
+
xml_doc = Nokogiri::XML(xmlContent)
|
971
|
+
|
972
|
+
no_ns = xml_doc.xpath("//*[@att]")
|
973
|
+
assert_equal no_ns.length, 1
|
974
|
+
assert_equal no_ns.first.content, "no namespace"
|
975
|
+
|
976
|
+
with_ns = xml_doc.xpath("//*[@ns1:att]")
|
977
|
+
assert_equal with_ns.length, 1
|
978
|
+
assert_equal with_ns.first.content, "with namespace"
|
979
|
+
end
|
980
|
+
|
981
|
+
def test_namespaced_attribute_search_with_css
|
982
|
+
# from #593
|
983
|
+
xmlContent = <<-EOXML
|
984
|
+
<?xml version="1.0"?>
|
985
|
+
<ns1:el1 xmlns:ns1="http://blabla.com" >
|
986
|
+
<ns1:el2 ns1:att="123">with namespace</ns1:el2 >
|
987
|
+
<ns1:el2 att="noNameSpace">no namespace</ns1:el2 >
|
988
|
+
</ns1:el1>
|
989
|
+
EOXML
|
990
|
+
xml_doc = Nokogiri::XML(xmlContent)
|
991
|
+
|
992
|
+
no_ns = xml_doc.css('*[att]')
|
993
|
+
assert_equal no_ns.length, 1
|
994
|
+
assert_equal no_ns.first.content, "no namespace"
|
995
|
+
|
996
|
+
with_ns = xml_doc.css('*[ns1|att]')
|
997
|
+
assert_equal with_ns.length, 1
|
998
|
+
assert_equal with_ns.first.content, "with namespace"
|
999
|
+
end
|
1000
|
+
|
1001
|
+
def test_namespaces_should_include_all_namespace_definitions
|
192
1002
|
xml = Nokogiri::XML.parse(<<-EOF)
|
193
|
-
<x xmlns:a=
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
assert_equal
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
assert_equal
|
1003
|
+
<x xmlns="http://quux.com/" xmlns:a="http://foo.com/" xmlns:b="http://bar.com/">
|
1004
|
+
<y xmlns:c="http://bazz.com/">
|
1005
|
+
<z>hello</z>
|
1006
|
+
<a xmlns:c="http://newc.com/" />
|
1007
|
+
</y>
|
1008
|
+
</x>
|
1009
|
+
EOF
|
1010
|
+
|
1011
|
+
namespaces = xml.namespaces # Document#namespace
|
1012
|
+
assert_equal({"xmlns" => "http://quux.com/",
|
1013
|
+
"xmlns:a" => "http://foo.com/",
|
1014
|
+
"xmlns:b" => "http://bar.com/"}, namespaces)
|
1015
|
+
|
1016
|
+
namespaces = xml.root.namespaces
|
1017
|
+
assert_equal({"xmlns" => "http://quux.com/",
|
1018
|
+
"xmlns:a" => "http://foo.com/",
|
1019
|
+
"xmlns:b" => "http://bar.com/"}, namespaces)
|
1020
|
+
|
1021
|
+
namespaces = xml.at_xpath("//xmlns:y").namespaces
|
1022
|
+
assert_equal({"xmlns" => "http://quux.com/",
|
1023
|
+
"xmlns:a" => "http://foo.com/",
|
1024
|
+
"xmlns:b" => "http://bar.com/",
|
1025
|
+
"xmlns:c" => "http://bazz.com/"}, namespaces)
|
1026
|
+
|
1027
|
+
namespaces = xml.at_xpath("//xmlns:z").namespaces
|
1028
|
+
assert_equal({"xmlns" => "http://quux.com/",
|
1029
|
+
"xmlns:a" => "http://foo.com/",
|
1030
|
+
"xmlns:b" => "http://bar.com/",
|
1031
|
+
"xmlns:c" => "http://bazz.com/"}, namespaces)
|
1032
|
+
|
1033
|
+
namespaces = xml.at_xpath("//xmlns:a").namespaces
|
1034
|
+
assert_equal({"xmlns" => "http://quux.com/",
|
1035
|
+
"xmlns:a" => "http://foo.com/",
|
1036
|
+
"xmlns:b" => "http://bar.com/",
|
1037
|
+
"xmlns:c" => "http://newc.com/"}, namespaces)
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
def test_namespace
|
1041
|
+
xml = Nokogiri::XML.parse(<<-EOF)
|
1042
|
+
<x xmlns:a='http://foo.com/' xmlns:b='http://bar.com/'>
|
1043
|
+
<y xmlns:c='http://bazz.com/'>
|
1044
|
+
<a:div>hello a</a:div>
|
1045
|
+
<b:div>hello b</b:div>
|
1046
|
+
<c:div x="1" b:y="2">hello c</c:div>
|
1047
|
+
<div x="1" xmlns="http://ns.example.com/d"/>
|
1048
|
+
<div x="1">hello moon</div>
|
1049
|
+
</y>
|
1050
|
+
</x>
|
1051
|
+
EOF
|
1052
|
+
set = xml.search("//y/*")
|
1053
|
+
assert_equal "a", set[0].namespace.prefix
|
1054
|
+
assert_equal 'http://foo.com/', set[0].namespace.href
|
1055
|
+
assert_equal "b", set[1].namespace.prefix
|
1056
|
+
assert_equal 'http://bar.com/', set[1].namespace.href
|
1057
|
+
assert_equal "c", set[2].namespace.prefix
|
1058
|
+
assert_equal 'http://bazz.com/', set[2].namespace.href
|
1059
|
+
assert_equal nil, set[3].namespace.prefix # default namespace
|
1060
|
+
assert_equal 'http://ns.example.com/d', set[3].namespace.href
|
1061
|
+
assert_equal nil, set[4].namespace # no namespace
|
1062
|
+
|
1063
|
+
assert_equal 'b', set[2].attributes['y'].namespace.prefix
|
1064
|
+
assert_equal 'http://bar.com/', set[2].attributes['y'].namespace.href
|
1065
|
+
assert_equal nil, set[2].attributes['x'].namespace
|
1066
|
+
assert_equal nil, set[3].attributes['x'].namespace
|
1067
|
+
assert_equal nil, set[4].attributes['x'].namespace
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
if Nokogiri.uses_libxml?
|
1071
|
+
def test_namespace_without_an_href_on_html_node
|
1072
|
+
# because microsoft word's HTML formatting does this. ick.
|
1073
|
+
xml = Nokogiri::HTML.parse <<-EOF
|
1074
|
+
<div><o:p>foo</o:p></div>
|
1075
|
+
EOF
|
1076
|
+
|
1077
|
+
assert_not_nil(node = xml.at('p'))
|
1078
|
+
|
1079
|
+
assert_equal 1, node.namespaces.keys.size
|
1080
|
+
assert node.namespaces.has_key?('xmlns:o')
|
1081
|
+
assert_equal nil, node.namespaces['xmlns:o']
|
1082
|
+
end
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
def test_line
|
1086
|
+
xml = Nokogiri::XML(<<-eoxml)
|
1087
|
+
<root>
|
1088
|
+
<a>
|
1089
|
+
Hello world
|
1090
|
+
</a>
|
1091
|
+
</root>
|
1092
|
+
eoxml
|
1093
|
+
|
1094
|
+
set = xml.search("//a")
|
1095
|
+
node = set.first
|
1096
|
+
assert_equal 2, node.line
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def test_xpath_results_have_document_and_are_decorated
|
1100
|
+
x = Module.new do
|
1101
|
+
def awesome! ; end
|
1102
|
+
end
|
1103
|
+
util_decorate(@xml, x)
|
1104
|
+
node_set = @xml.xpath("//employee")
|
1105
|
+
assert_equal @xml, node_set.document
|
1106
|
+
assert node_set.respond_to?(:awesome!)
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def test_css_results_have_document_and_are_decorated
|
1110
|
+
x = Module.new do
|
1111
|
+
def awesome! ; end
|
1112
|
+
end
|
1113
|
+
util_decorate(@xml, x)
|
1114
|
+
node_set = @xml.css("employee")
|
1115
|
+
assert_equal @xml, node_set.document
|
1116
|
+
assert node_set.respond_to?(:awesome!)
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def test_blank
|
1120
|
+
doc = Nokogiri::XML('')
|
1121
|
+
assert_equal false, doc.blank?
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
def test_to_xml_allows_to_serialize_with_as_xml_save_option
|
1125
|
+
xml = Nokogiri::XML("<root><ul><li>Hello world</li></ul></root>")
|
1126
|
+
set = xml.search("//ul")
|
1127
|
+
node = set.first
|
1128
|
+
|
1129
|
+
assert_no_match("<ul>\n <li>", xml.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
|
1130
|
+
assert_no_match("<ul>\n <li>", node.to_xml(:save_with => XML::Node::SaveOptions::AS_XML))
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
# issue 647
|
1134
|
+
def test_default_namespace_should_be_created
|
1135
|
+
subject = Nokogiri::XML.parse('<foo xml:bar="http://bar.com"/>').root
|
1136
|
+
ns = subject.attributes['bar'].namespace
|
1137
|
+
assert_not_nil ns
|
1138
|
+
assert_equal ns.class, Nokogiri::XML::Namespace
|
1139
|
+
assert_equal 'xml', ns.prefix
|
1140
|
+
assert_equal "http://www.w3.org/XML/1998/namespace", ns.href
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
# issue 648
|
1144
|
+
def test_namespace_without_prefix_should_be_set
|
1145
|
+
node = Nokogiri::XML.parse('<foo xmlns="http://bar.com"/>').root
|
1146
|
+
subject = Nokogiri::XML::Node.new 'foo', node.document
|
1147
|
+
subject.namespace = node.namespace
|
1148
|
+
ns = subject.namespace
|
1149
|
+
assert_equal ns.class, Nokogiri::XML::Namespace
|
1150
|
+
assert_nil ns.prefix
|
1151
|
+
assert_equal ns.href, "http://bar.com"
|
219
1152
|
end
|
220
1153
|
|
1154
|
+
# issue 695
|
1155
|
+
def test_namespace_in_rendered_xml
|
1156
|
+
document = Nokogiri::XML::Document.new
|
1157
|
+
subject = Nokogiri::XML::Node.new 'foo', document
|
1158
|
+
ns = subject.add_namespace nil, 'bar'
|
1159
|
+
subject.namespace = ns
|
1160
|
+
assert_match(/xmlns="bar"/, subject.to_xml)
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
# issue 771
|
1164
|
+
def test_format_noblank
|
1165
|
+
content = <<eoxml
|
1166
|
+
<foo>
|
1167
|
+
<bar>hello</bar>
|
1168
|
+
</foo>
|
1169
|
+
eoxml
|
1170
|
+
subject = Nokogiri::XML(content) do |conf|
|
1171
|
+
conf.default_xml.noblanks
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
assert_match %r{<bar>hello</bar>}, subject.to_xml(:indent => 2)
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
def test_text_node_colon
|
1178
|
+
document = Nokogiri::XML::Document.new
|
1179
|
+
root = Nokogiri::XML::Node.new 'foo', document
|
1180
|
+
document.root = root
|
1181
|
+
root << "<a>hello:with_colon</a>"
|
1182
|
+
assert_match(/hello:with_colon/, document.to_xml)
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
def test_document_eh
|
1186
|
+
html_doc = Nokogiri::HTML "<div>foo</div>"
|
1187
|
+
xml_doc = Nokogiri::XML "<div>foo</div>"
|
1188
|
+
html_node = html_doc.at_css "div"
|
1189
|
+
xml_node = xml_doc.at_css "div"
|
1190
|
+
|
1191
|
+
assert html_doc.document?
|
1192
|
+
assert xml_doc.document?
|
1193
|
+
assert ! html_node.document?
|
1194
|
+
assert ! xml_node.document?
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
def test_processing_instruction_eh
|
1198
|
+
xml_doc = Nokogiri::XML %Q{<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="foo.xsl"?>\n<?xml-stylesheet type="text/xsl" href="foo2.xsl"?>\n<root><div>foo</div></root>}
|
1199
|
+
pi_node = xml_doc.children.first
|
1200
|
+
div_node = xml_doc.at_css "div"
|
1201
|
+
assert pi_node.processing_instruction?
|
1202
|
+
assert ! div_node.processing_instruction?
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
def test_node_lang
|
1206
|
+
document = Nokogiri::XML <<-EOXML
|
1207
|
+
<root>
|
1208
|
+
<div class='english' xml:lang='en'>
|
1209
|
+
<div class='english_child'>foo</div>
|
1210
|
+
</div>
|
1211
|
+
<div class='japanese' xml:lang='jp'>bar</div>
|
1212
|
+
<div class='unspecified'>bar</div>
|
1213
|
+
</root>
|
1214
|
+
EOXML
|
1215
|
+
assert_equal "en", document.at_css(".english").lang
|
1216
|
+
assert_equal "en", document.at_css(".english_child").lang
|
1217
|
+
assert_equal "jp", document.at_css(".japanese").lang
|
1218
|
+
assert_nil document.at_css(".unspecified").lang
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
def test_set_node_lang
|
1222
|
+
document = Nokogiri::XML "<root><div class='subject'>foo</div></root>"
|
1223
|
+
subject = document.at_css(".subject")
|
1224
|
+
|
1225
|
+
subject.lang = "de"
|
1226
|
+
assert_equal "de", subject.lang
|
1227
|
+
|
1228
|
+
subject.lang = "fr"
|
1229
|
+
assert_equal "fr", subject.lang
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
def test_text_node_robustness_gh1426
|
1233
|
+
# notably, the original bug report was about libxml-ruby interactions
|
1234
|
+
# this test should blow up under valgrind if we regress on libxml-ruby workarounds
|
1235
|
+
message = "<h2>BOOM!</h2>"
|
1236
|
+
10_000.times do
|
1237
|
+
node = Nokogiri::HTML::DocumentFragment.parse(message)
|
1238
|
+
node.add_previous_sibling(Nokogiri::XML::Text.new('before', node.document))
|
1239
|
+
node.add_next_sibling(Nokogiri::XML::Text.new('after', node.document))
|
1240
|
+
end
|
1241
|
+
end
|
221
1242
|
end
|
222
1243
|
end
|
223
1244
|
end
|