nokogiri 1.2.3-x86-mswin32-60 → 1.4.5-x86-mswin32-60
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.
- data/.autotest +18 -7
- data/.gemtest +0 -0
- data/CHANGELOG.ja.rdoc +297 -3
- data/CHANGELOG.rdoc +289 -0
- data/Manifest.txt +148 -37
- data/README.ja.rdoc +20 -20
- data/README.rdoc +53 -22
- data/Rakefile +127 -211
- data/bin/nokogiri +54 -0
- data/ext/nokogiri/depend +358 -0
- data/ext/nokogiri/extconf.rb +89 -54
- data/ext/nokogiri/html_document.c +34 -27
- data/ext/nokogiri/html_document.h +1 -1
- data/ext/nokogiri/html_element_description.c +276 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.c +7 -5
- data/ext/nokogiri/html_entity_lookup.h +1 -1
- data/ext/nokogiri/html_sax_parser_context.c +94 -0
- data/ext/nokogiri/html_sax_parser_context.h +11 -0
- data/ext/nokogiri/{native.c → nokogiri.c} +31 -7
- data/ext/nokogiri/{native.h → nokogiri.h} +68 -41
- data/ext/nokogiri/xml_attr.c +20 -9
- data/ext/nokogiri/xml_attr.h +1 -1
- data/ext/nokogiri/xml_attribute_decl.c +70 -0
- data/ext/nokogiri/xml_attribute_decl.h +9 -0
- data/ext/nokogiri/xml_cdata.c +21 -9
- data/ext/nokogiri/xml_cdata.h +1 -1
- data/ext/nokogiri/xml_comment.c +18 -6
- data/ext/nokogiri/xml_comment.h +1 -1
- data/ext/nokogiri/xml_document.c +247 -68
- data/ext/nokogiri/xml_document.h +5 -3
- data/ext/nokogiri/xml_document_fragment.c +15 -7
- data/ext/nokogiri/xml_document_fragment.h +1 -1
- data/ext/nokogiri/xml_dtd.c +110 -10
- 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 +16 -5
- data/ext/nokogiri/xml_entity_reference.h +1 -1
- data/ext/nokogiri/xml_io.c +40 -8
- data/ext/nokogiri/xml_io.h +2 -1
- data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
- data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
- data/ext/nokogiri/xml_namespace.c +84 -0
- data/ext/nokogiri/xml_namespace.h +13 -0
- data/ext/nokogiri/xml_node.c +782 -225
- data/ext/nokogiri/xml_node.h +2 -4
- data/ext/nokogiri/xml_node_set.c +253 -34
- data/ext/nokogiri/xml_node_set.h +2 -2
- data/ext/nokogiri/xml_processing_instruction.c +17 -5
- data/ext/nokogiri/xml_processing_instruction.h +1 -1
- data/ext/nokogiri/xml_reader.c +277 -85
- data/ext/nokogiri/xml_reader.h +1 -1
- data/ext/nokogiri/xml_relax_ng.c +168 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +183 -111
- data/ext/nokogiri/xml_sax_parser.h +30 -1
- data/ext/nokogiri/xml_sax_parser_context.c +199 -0
- data/ext/nokogiri/xml_sax_parser_context.h +10 -0
- data/ext/nokogiri/xml_sax_push_parser.c +42 -12
- data/ext/nokogiri/xml_sax_push_parser.h +1 -1
- data/ext/nokogiri/xml_schema.c +205 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.c +28 -173
- data/ext/nokogiri/xml_syntax_error.h +2 -1
- data/ext/nokogiri/xml_text.c +16 -6
- data/ext/nokogiri/xml_text.h +1 -1
- data/ext/nokogiri/xml_xpath_context.c +104 -47
- data/ext/nokogiri/xml_xpath_context.h +1 -1
- data/ext/nokogiri/xslt_stylesheet.c +161 -19
- data/ext/nokogiri/xslt_stylesheet.h +1 -1
- data/lib/nokogiri.rb +47 -8
- data/lib/nokogiri/1.8/nokogiri.so +0 -0
- data/lib/nokogiri/1.9/nokogiri.so +0 -0
- data/lib/nokogiri/css.rb +6 -3
- data/lib/nokogiri/css/node.rb +14 -12
- data/lib/nokogiri/css/parser.rb +665 -62
- data/lib/nokogiri/css/parser.y +20 -10
- data/lib/nokogiri/css/parser_extras.rb +91 -0
- data/lib/nokogiri/css/tokenizer.rb +148 -5
- data/lib/nokogiri/css/tokenizer.rex +10 -9
- data/lib/nokogiri/css/xpath_visitor.rb +47 -44
- data/lib/nokogiri/decorators/slop.rb +8 -4
- data/lib/nokogiri/ffi/encoding_handler.rb +42 -0
- data/lib/nokogiri/ffi/html/document.rb +28 -0
- data/lib/nokogiri/ffi/html/element_description.rb +81 -0
- data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
- data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
- data/lib/nokogiri/ffi/io_callbacks.rb +42 -0
- data/lib/nokogiri/ffi/libxml.rb +420 -0
- data/lib/nokogiri/ffi/structs/common_node.rb +38 -0
- data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
- data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_attr.rb +20 -0
- data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
- data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +11 -0
- data/lib/nokogiri/ffi/structs/xml_document.rb +117 -0
- data/lib/nokogiri/ffi/structs/xml_dtd.rb +28 -0
- data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
- data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
- data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
- data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
- data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
- data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
- data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
- data/lib/nokogiri/ffi/structs/xml_parser_context.rb +20 -0
- data/lib/nokogiri/ffi/structs/xml_parser_input.rb +19 -0
- data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
- data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +124 -0
- data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
- data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +38 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
- data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
- data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
- data/lib/nokogiri/ffi/xml/attr.rb +41 -0
- data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
- data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
- data/lib/nokogiri/ffi/xml/comment.rb +18 -0
- data/lib/nokogiri/ffi/xml/document.rb +174 -0
- data/lib/nokogiri/ffi/xml/document_fragment.rb +21 -0
- data/lib/nokogiri/ffi/xml/dtd.rb +67 -0
- data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
- data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
- data/lib/nokogiri/ffi/xml/entity_decl.rb +36 -0
- data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/ffi/xml/namespace.rb +44 -0
- data/lib/nokogiri/ffi/xml/node.rb +559 -0
- data/lib/nokogiri/ffi/xml/node_set.rb +150 -0
- data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
- data/lib/nokogiri/ffi/xml/reader.rb +236 -0
- data/lib/nokogiri/ffi/xml/relax_ng.rb +85 -0
- data/lib/nokogiri/ffi/xml/sax/parser.rb +143 -0
- data/lib/nokogiri/ffi/xml/sax/parser_context.rb +79 -0
- data/lib/nokogiri/ffi/xml/sax/push_parser.rb +51 -0
- data/lib/nokogiri/ffi/xml/schema.rb +109 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +98 -0
- data/lib/nokogiri/ffi/xml/text.rb +18 -0
- data/lib/nokogiri/ffi/xml/xpath.rb +9 -0
- data/lib/nokogiri/ffi/xml/xpath_context.rb +153 -0
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +77 -0
- data/lib/nokogiri/html.rb +13 -47
- data/lib/nokogiri/html/builder.rb +27 -1
- data/lib/nokogiri/html/document.rb +201 -7
- data/lib/nokogiri/html/document_fragment.rb +41 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/entity_lookup.rb +2 -0
- data/lib/nokogiri/html/sax/parser.rb +34 -3
- data/lib/nokogiri/html/sax/parser_context.rb +16 -0
- data/lib/nokogiri/nokogiri.rb +1 -0
- data/lib/nokogiri/version.rb +40 -1
- data/lib/nokogiri/version_warning.rb +14 -0
- data/lib/nokogiri/xml.rb +32 -53
- data/lib/nokogiri/xml/attr.rb +5 -0
- data/lib/nokogiri/xml/attribute_decl.rb +18 -0
- data/lib/nokogiri/xml/builder.rb +349 -29
- data/lib/nokogiri/xml/cdata.rb +3 -1
- data/lib/nokogiri/xml/character_data.rb +7 -0
- data/lib/nokogiri/xml/document.rb +166 -14
- data/lib/nokogiri/xml/document_fragment.rb +76 -1
- data/lib/nokogiri/xml/dtd.rb +16 -3
- 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.rb +561 -166
- data/lib/nokogiri/xml/node/save_options.rb +22 -2
- data/lib/nokogiri/xml/node_set.rb +202 -40
- data/lib/nokogiri/xml/parse_options.rb +93 -0
- data/lib/nokogiri/xml/pp.rb +2 -0
- data/lib/nokogiri/xml/pp/character_data.rb +18 -0
- data/lib/nokogiri/xml/pp/node.rb +56 -0
- data/lib/nokogiri/xml/processing_instruction.rb +2 -0
- data/lib/nokogiri/xml/reader.rb +93 -8
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax.rb +1 -7
- data/lib/nokogiri/xml/sax/document.rb +107 -2
- data/lib/nokogiri/xml/sax/parser.rb +57 -7
- data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
- data/lib/nokogiri/xml/sax/push_parser.rb +13 -1
- data/lib/nokogiri/xml/schema.rb +63 -0
- data/lib/nokogiri/xml/syntax_error.rb +25 -1
- data/lib/nokogiri/xml/text.rb +4 -1
- data/lib/nokogiri/xml/xpath.rb +1 -1
- data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
- data/lib/nokogiri/xml/xpath_context.rb +2 -0
- data/lib/nokogiri/xslt.rb +26 -2
- data/lib/nokogiri/xslt/stylesheet.rb +19 -0
- data/lib/xsd/xmlparser/nokogiri.rb +45 -9
- data/tasks/cross_compile.rb +173 -0
- data/tasks/test.rb +25 -69
- data/test/css/test_nthiness.rb +3 -4
- data/test/css/test_parser.rb +75 -20
- data/test/css/test_tokenizer.rb +23 -1
- data/test/css/test_xpath_visitor.rb +10 -1
- data/test/decorators/test_slop.rb +16 -0
- data/test/ffi/test_document.rb +35 -0
- data/test/files/2ch.html +108 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/bar/bar.xsd +4 -0
- data/test/files/encoding.html +82 -0
- data/test/files/encoding.xhtml +84 -0
- data/test/files/foo/foo.xsd +4 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/files/shift_jis.html +10 -0
- data/test/files/shift_jis.xml +5 -0
- data/test/files/snuggles.xml +3 -0
- data/test/files/staff.dtd +10 -0
- data/test/files/valid_bar.xml +2 -0
- data/test/helper.rb +101 -23
- data/test/html/sax/test_parser.rb +81 -2
- data/test/html/sax/test_parser_context.rb +48 -0
- data/test/html/test_builder.rb +39 -8
- data/test/html/test_document.rb +186 -23
- data/test/html/test_document_encoding.rb +78 -1
- data/test/html/test_document_fragment.rb +253 -0
- data/test/html/test_element_description.rb +98 -0
- data/test/html/test_named_characters.rb +1 -1
- data/test/html/test_node.rb +124 -36
- data/test/html/test_node_encoding.rb +27 -0
- data/test/test_convert_xpath.rb +1 -52
- data/test/test_css_cache.rb +2 -13
- data/test/test_encoding_handler.rb +46 -0
- data/test/test_memory_leak.rb +88 -19
- data/test/test_nokogiri.rb +38 -5
- data/test/test_reader.rb +188 -6
- data/test/test_soap4r_sax.rb +52 -0
- data/test/test_xslt_transforms.rb +183 -83
- data/test/xml/node/test_save_options.rb +1 -1
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +175 -4
- data/test/xml/sax/test_parser_context.rb +113 -0
- data/test/xml/sax/test_push_parser.rb +90 -2
- data/test/xml/test_attr.rb +35 -1
- data/test/xml/test_attribute_decl.rb +82 -0
- data/test/xml/test_builder.rb +186 -1
- data/test/xml/test_cdata.rb +32 -1
- data/test/xml/test_comment.rb +13 -1
- data/test/xml/test_document.rb +415 -43
- data/test/xml/test_document_encoding.rb +1 -1
- data/test/xml/test_document_fragment.rb +173 -5
- data/test/xml/test_dtd.rb +61 -6
- data/test/xml/test_dtd_encoding.rb +3 -1
- 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 +120 -0
- data/test/xml/test_entity_reference.rb +5 -1
- data/test/xml/test_namespace.rb +68 -0
- data/test/xml/test_node.rb +546 -201
- data/test/xml/test_node_attributes.rb +34 -0
- data/test/xml/test_node_encoding.rb +33 -3
- data/test/xml/test_node_reparenting.rb +321 -0
- data/test/xml/test_node_set.rb +538 -2
- data/test/xml/test_parse_options.rb +52 -0
- data/test/xml/test_processing_instruction.rb +6 -1
- data/test/xml/test_reader_encoding.rb +1 -1
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +94 -0
- data/test/xml/test_syntax_error.rb +12 -0
- data/test/xml/test_text.rb +35 -1
- data/test/xml/test_unparented_node.rb +5 -5
- data/test/xml/test_xpath.rb +142 -11
- data/test/xslt/test_custom_functions.rb +94 -0
- metadata +328 -92
- data/ext/nokogiri/html_sax_parser.c +0 -57
- data/ext/nokogiri/html_sax_parser.h +0 -11
- data/ext/nokogiri/iconv.dll +0 -0
- data/ext/nokogiri/libexslt.dll +0 -0
- data/ext/nokogiri/libxml2.dll +0 -0
- data/ext/nokogiri/libxslt.dll +0 -0
- data/ext/nokogiri/native.so +0 -0
- data/ext/nokogiri/xml_xpath.c +0 -53
- data/ext/nokogiri/xml_xpath.h +0 -11
- data/ext/nokogiri/zlib1.dll +0 -0
- data/lib/action-nokogiri.rb +0 -30
- data/lib/nokogiri/css/generated_parser.rb +0 -713
- data/lib/nokogiri/css/generated_tokenizer.rb +0 -144
- data/lib/nokogiri/decorators.rb +0 -2
- data/lib/nokogiri/decorators/hpricot.rb +0 -3
- data/lib/nokogiri/decorators/hpricot/node.rb +0 -56
- data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -54
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -28
- data/lib/nokogiri/hpricot.rb +0 -51
- data/lib/nokogiri/xml/comment.rb +0 -6
- data/lib/nokogiri/xml/element.rb +0 -6
- data/lib/nokogiri/xml/entity_declaration.rb +0 -9
- data/lib/nokogiri/xml/fragment_handler.rb +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 -11
- data/test/hpricot/test_alter.rb +0 -68
- data/test/hpricot/test_builder.rb +0 -20
- data/test/hpricot/test_parser.rb +0 -426
- data/test/hpricot/test_paths.rb +0 -15
- data/test/hpricot/test_preserved.rb +0 -77
- data/test/hpricot/test_xml.rb +0 -30
- data/test/test_gc.rb +0 -15
@@ -0,0 +1,34 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
class TestNodeAttributes < Nokogiri::TestCase
|
6
|
+
def test_attribute_with_ns
|
7
|
+
doc = Nokogiri::XML <<-eoxml
|
8
|
+
<root xmlns:tlm='http://tenderlovemaking.com/'>
|
9
|
+
<node tlm:foo='bar' foo='baz' />
|
10
|
+
</root>
|
11
|
+
eoxml
|
12
|
+
|
13
|
+
node = doc.at('node')
|
14
|
+
|
15
|
+
assert_equal 'bar',
|
16
|
+
node.attribute_with_ns('foo', 'http://tenderlovemaking.com/').value
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_namespace_key?
|
20
|
+
doc = Nokogiri::XML <<-eoxml
|
21
|
+
<root xmlns:tlm='http://tenderlovemaking.com/'>
|
22
|
+
<node tlm:foo='bar' foo='baz' />
|
23
|
+
</root>
|
24
|
+
eoxml
|
25
|
+
|
26
|
+
node = doc.at('node')
|
27
|
+
|
28
|
+
assert node.namespaced_key?('foo', 'http://tenderlovemaking.com/')
|
29
|
+
assert node.namespaced_key?('foo', nil)
|
30
|
+
assert !node.namespaced_key?('foo', 'foo')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "helper"
|
2
2
|
|
3
3
|
module Nokogiri
|
4
4
|
module XML
|
@@ -14,6 +14,29 @@ module Nokogiri
|
|
14
14
|
assert_equal @html.encoding, node['href'].encoding.name
|
15
15
|
end
|
16
16
|
|
17
|
+
def test_text_encoding_is_utf_8
|
18
|
+
@html = Nokogiri::HTML(File.open(NICH_FILE))
|
19
|
+
assert_equal 'UTF-8', @html.text.encoding.name
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_serialize_encoding_html
|
23
|
+
@html = Nokogiri::HTML(File.open(NICH_FILE))
|
24
|
+
assert_equal @html.encoding.downcase,
|
25
|
+
@html.serialize.encoding.name.downcase
|
26
|
+
|
27
|
+
@doc = Nokogiri::HTML(@html.serialize)
|
28
|
+
assert_equal @html.serialize, @doc.serialize
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_serialize_encoding_xml
|
32
|
+
@xml = Nokogiri::XML(File.open(SHIFT_JIS_XML))
|
33
|
+
assert_equal @xml.encoding.downcase,
|
34
|
+
@xml.serialize.encoding.name.downcase
|
35
|
+
|
36
|
+
@doc = Nokogiri::XML(@xml.serialize)
|
37
|
+
assert_equal @xml.serialize, @doc.serialize
|
38
|
+
end
|
39
|
+
|
17
40
|
def test_encode_special_chars
|
18
41
|
foo = @html.css('a').first.encode_special_chars('foo')
|
19
42
|
assert_equal @html.encoding, foo.encoding.name
|
@@ -49,7 +72,8 @@ module Nokogiri
|
|
49
72
|
assert_equal 'UTF-8', doc.encoding
|
50
73
|
n = doc.xpath('//part:tire', { 'part' => 'http://schwinn.com/' }).first
|
51
74
|
assert n
|
52
|
-
assert_equal doc.encoding, n.namespace.encoding.name
|
75
|
+
assert_equal doc.encoding, n.namespace.href.encoding.name
|
76
|
+
assert_equal doc.encoding, n.namespace.prefix.encoding.name
|
53
77
|
end
|
54
78
|
|
55
79
|
def test_namespace_as_hash
|
@@ -66,9 +90,15 @@ module Nokogiri
|
|
66
90
|
doc = Nokogiri::XML(xml, nil, 'UTF-8')
|
67
91
|
assert_equal 'UTF-8', doc.encoding
|
68
92
|
assert n = doc.xpath('//car').first
|
93
|
+
|
94
|
+
n.namespace_definitions.each do |nd|
|
95
|
+
assert_equal doc.encoding, nd.href.encoding.name
|
96
|
+
assert_equal doc.encoding, nd.prefix.encoding.name
|
97
|
+
end
|
98
|
+
|
69
99
|
n.namespaces.each do |k,v|
|
70
|
-
assert_equal doc.encoding, v.encoding.name
|
71
100
|
assert_equal doc.encoding, k.encoding.name
|
101
|
+
assert_equal doc.encoding, v.encoding.name
|
72
102
|
end
|
73
103
|
end
|
74
104
|
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
class TestNodeReparenting < Nokogiri::TestCase
|
6
|
+
|
7
|
+
describe "standard node reparenting behavior" do
|
8
|
+
# describe "namespace handling during reparenting" do
|
9
|
+
# describe "given a Node" do
|
10
|
+
# describe "with a Namespace" do
|
11
|
+
# it "keeps the Namespace"
|
12
|
+
# end
|
13
|
+
# describe "given a parent Node with a default and a non-default Namespace" do
|
14
|
+
# describe "passed an Node without a namespace" do
|
15
|
+
# it "inserts an Node that inherits the default Namespace"
|
16
|
+
# end
|
17
|
+
# describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
|
18
|
+
# it "inserts a Node that inherits the matching parent Namespace"
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# describe "given a markup string" do
|
23
|
+
# describe "parsed relative to the document" do
|
24
|
+
# describe "with a Namespace" do
|
25
|
+
# it "keeps the Namespace"
|
26
|
+
# end
|
27
|
+
# describe "given a parent Node with a default and a non-default Namespace" do
|
28
|
+
# describe "passed an Node without a namespace" do
|
29
|
+
# it "inserts an Node that inherits the default Namespace"
|
30
|
+
# end
|
31
|
+
# describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
|
32
|
+
# it "inserts a Node that inherits the matching parent Namespace"
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
# describe "parsed relative to a specific node" do
|
37
|
+
# describe "with a Namespace" do
|
38
|
+
# it "keeps the Namespace"
|
39
|
+
# end
|
40
|
+
# describe "given a parent Node with a default and a non-default Namespace" do
|
41
|
+
# describe "passed an Node without a namespace" do
|
42
|
+
# it "inserts an Node that inherits the default Namespace"
|
43
|
+
# end
|
44
|
+
# describe "passed a Node with a Namespace that matches the parent's non-default Namespace" do
|
45
|
+
# it "inserts a Node that inherits the matching parent Namespace"
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
|
52
|
+
{
|
53
|
+
:add_child => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
|
54
|
+
:<< => {:target => "/root/a1", :returns_self => false, :children_tags => %w[text b1 b2]},
|
55
|
+
|
56
|
+
:replace => {:target => "/root/a1/node()", :returns_self => false, :children_tags => %w[b1 b2]},
|
57
|
+
:swap => {:target => "/root/a1/node()", :returns_self => true, :children_tags => %w[b1 b2]},
|
58
|
+
|
59
|
+
:children= => {:target => "/root/a1", :returns_self => false, :children_tags => %w[b1 b2]},
|
60
|
+
:inner_html= => {:target => "/root/a1", :returns_self => true, :children_tags => %w[b1 b2]},
|
61
|
+
|
62
|
+
:add_previous_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
|
63
|
+
:previous= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[b1 b2 text]},
|
64
|
+
:before => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[b1 b2 text]},
|
65
|
+
|
66
|
+
:add_next_sibling => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
|
67
|
+
:next= => {:target => "/root/a1/text()", :returns_self => false, :children_tags => %w[text b1 b2]},
|
68
|
+
:after => {:target => "/root/a1/text()", :returns_self => true, :children_tags => %w[text b1 b2]}
|
69
|
+
}.each do |method, params|
|
70
|
+
|
71
|
+
before do
|
72
|
+
@doc = Nokogiri::XML "<root><a1>First node</a1><a2>Second node</a2><a3>Third <bx />node</a3></root>"
|
73
|
+
@doc2 = @doc.dup
|
74
|
+
@fragment_string = "<b1>foo</b1><b2>bar</b2>"
|
75
|
+
@fragment = Nokogiri::XML::DocumentFragment.parse @fragment_string
|
76
|
+
@node_set = Nokogiri::XML("<root><b1>foo</b1><b2>bar</b2></root>").xpath("/root/node()")
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "##{method}" do
|
80
|
+
describe "passed a Node" do
|
81
|
+
[:current, :another].each do |which|
|
82
|
+
describe "passed a Node in the #{which} document" do
|
83
|
+
before do
|
84
|
+
@other_doc = which == :current ? @doc : @doc2
|
85
|
+
@other_node = @other_doc.at_xpath("/root/a2")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "unlinks the Node from its previous position" do
|
89
|
+
@doc.at_xpath(params[:target]).send(method, @other_node)
|
90
|
+
@other_doc.at_xpath("/root/a2").must_be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "inserts the Node in the proper position" do
|
94
|
+
@doc.at_xpath(params[:target]).send(method, @other_node)
|
95
|
+
@doc.at_xpath("/root/a1/a2").wont_be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns the expected value" do
|
99
|
+
sendee = @doc.at_xpath(params[:target])
|
100
|
+
result = sendee.send(method, @other_node)
|
101
|
+
if params[:returns_self]
|
102
|
+
result.must_equal sendee
|
103
|
+
else
|
104
|
+
result.must_equal @other_node
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
describe "passed a markup string" do
|
111
|
+
it "inserts the fragment roots in the proper position" do
|
112
|
+
@doc.at_xpath(params[:target]).send(method, @fragment_string)
|
113
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns the expected value" do
|
117
|
+
sendee = @doc.at_xpath(params[:target])
|
118
|
+
result = sendee.send(method, @fragment_string)
|
119
|
+
if params[:returns_self]
|
120
|
+
result.must_equal sendee
|
121
|
+
else
|
122
|
+
result.must_be_kind_of Nokogiri::XML::NodeSet
|
123
|
+
result.to_html.must_equal @fragment_string
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
describe "passed a fragment" do
|
128
|
+
it "inserts the fragment roots in the proper position" do
|
129
|
+
@doc.at_xpath(params[:target]).send(method, @fragment)
|
130
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
describe "passed a document" do
|
134
|
+
it "raises an exception" do
|
135
|
+
proc { @doc.at_xpath("/root/a1").send(method, @doc2) }.must_raise(ArgumentError)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
describe "passed a non-Node" do
|
139
|
+
it "raises an exception" do
|
140
|
+
proc { @doc.at_xpath("/root/a1").send(method, 42) }.must_raise(ArgumentError)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
describe "passed a NodeSet" do
|
144
|
+
it "inserts each member of the NodeSet in the proper order" do
|
145
|
+
@doc.at_xpath(params[:target]).send(method, @node_set)
|
146
|
+
@doc.xpath("/root/a1/node()").collect {|n| n.name}.must_equal params[:children_tags]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "text node merging" do
|
153
|
+
describe "#add_child" do
|
154
|
+
it "merges the Text node with adjacent Text nodes" do
|
155
|
+
@doc.at_xpath("/root/a1").add_child Nokogiri::XML::Text.new('hello', @doc)
|
156
|
+
@doc.at_xpath("/root/a1/text()").content.must_equal "First nodehello"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
describe "#replace" do
|
160
|
+
it "merges the Text node with adjacent Text nodes" do
|
161
|
+
@doc.at_xpath("/root/a3/bx").replace Nokogiri::XML::Text.new('hello', @doc)
|
162
|
+
@doc.at_xpath("/root/a3/text()").content.must_equal "Third hellonode"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "ad hoc node reparenting behavior" do
|
169
|
+
describe "#add_child" do
|
170
|
+
describe "given a new node with a namespace" do
|
171
|
+
it "keeps the namespace" do
|
172
|
+
doc = Nokogiri::XML::Document.new
|
173
|
+
item = Nokogiri::XML::Element.new('item', doc)
|
174
|
+
doc.root = item
|
175
|
+
|
176
|
+
entry = Nokogiri::XML::Element.new('entry', doc)
|
177
|
+
entry.add_namespace('tlm', 'http://tenderlovemaking.com')
|
178
|
+
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
179
|
+
item.add_child(entry)
|
180
|
+
assert_equal 'http://tenderlovemaking.com', entry.namespaces['xmlns:tlm']
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "given a parent node with a default namespace" do
|
185
|
+
before do
|
186
|
+
@doc = Nokogiri::XML(<<-eoxml)
|
187
|
+
<root xmlns="http://tenderlovemaking.com/">
|
188
|
+
<first>
|
189
|
+
</first>
|
190
|
+
</root>
|
191
|
+
eoxml
|
192
|
+
end
|
193
|
+
|
194
|
+
it "inserts a node that inherits the default namespace" do
|
195
|
+
assert node = @doc.at('//xmlns:first')
|
196
|
+
child = Nokogiri::XML::Node.new('second', @doc)
|
197
|
+
node.add_child(child)
|
198
|
+
assert @doc.at('//xmlns:second')
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "given a parent node with a non-default namespace" do
|
203
|
+
before do
|
204
|
+
@doc = Nokogiri::XML(<<-eoxml)
|
205
|
+
<root xmlns="http://tenderlovemaking.com/" xmlns:foo="http://flavorjon.es/">
|
206
|
+
<first>
|
207
|
+
</first>
|
208
|
+
</root>
|
209
|
+
eoxml
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "and a child node with a namespace matching the parent's non-default namespace" do
|
213
|
+
it "inserts a node that inherits the matching parent namespace" do
|
214
|
+
assert node = @doc.at('//xmlns:first')
|
215
|
+
child = Nokogiri::XML::Node.new('second', @doc)
|
216
|
+
|
217
|
+
ns = @doc.root.namespace_definitions.detect { |x| x.prefix == "foo" }
|
218
|
+
child.namespace = ns
|
219
|
+
|
220
|
+
node.add_child(child)
|
221
|
+
assert @doc.at('//foo:second', "foo" => "http://flavorjon.es/")
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe "#add_previous_sibling" do
|
228
|
+
it "should not merge text nodes during the operation" do
|
229
|
+
xml = Nokogiri::XML %Q(<root>text node</root>)
|
230
|
+
replacee = xml.root.children.first
|
231
|
+
replacee.add_previous_sibling "foo <p></p> bar"
|
232
|
+
assert_equal "foo <p></p> bartext node", xml.root.children.to_html
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "#add_next_sibling" do
|
237
|
+
it "should not merge text nodes during the operation" do
|
238
|
+
xml = Nokogiri::XML %Q(<root>text node</root>)
|
239
|
+
replacee = xml.root.children.first
|
240
|
+
replacee.add_next_sibling "foo <p></p> bar"
|
241
|
+
assert_equal "text nodefoo <p></p> bar", xml.root.children.to_html
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe "#replace" do
|
246
|
+
describe "a text node with a text node" do
|
247
|
+
it "should not merge text nodes during the operation" do
|
248
|
+
xml = Nokogiri::XML %Q(<root>text node</root>)
|
249
|
+
replacee = xml.root.children.first
|
250
|
+
replacee.replace "new text node"
|
251
|
+
assert_equal "new text node", xml.root.children.first.content
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "when a document has a default namespace" do
|
256
|
+
before do
|
257
|
+
@fruits = Nokogiri::XML(<<-eoxml)
|
258
|
+
<fruit xmlns="http://fruits.org">
|
259
|
+
<apple />
|
260
|
+
</fruit>
|
261
|
+
eoxml
|
262
|
+
end
|
263
|
+
|
264
|
+
it "inserts a node with default namespaces" do
|
265
|
+
apple = @fruits.css('apple').first
|
266
|
+
|
267
|
+
orange = Nokogiri::XML::Node.new('orange', @fruits)
|
268
|
+
apple.replace(orange)
|
269
|
+
|
270
|
+
assert_equal orange, @fruits.css('orange').first
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "unlinking a node and then reparenting it" do
|
276
|
+
it "not blow up" do
|
277
|
+
# see http://github.com/tenderlove/nokogiri/issues#issue/22
|
278
|
+
10.times do
|
279
|
+
STDOUT.putc "."
|
280
|
+
STDOUT.flush
|
281
|
+
begin
|
282
|
+
doc = Nokogiri::XML <<-EOHTML
|
283
|
+
<root>
|
284
|
+
<a>
|
285
|
+
<b/>
|
286
|
+
<c/>
|
287
|
+
</a>
|
288
|
+
</root>
|
289
|
+
EOHTML
|
290
|
+
|
291
|
+
assert root = doc.at("root")
|
292
|
+
assert a = root.at("a")
|
293
|
+
assert b = a.at("b")
|
294
|
+
assert c = a.at("c")
|
295
|
+
a.add_next_sibling(b.unlink)
|
296
|
+
c.unlink
|
297
|
+
end
|
298
|
+
GC.start
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
describe "replace-merging text nodes" do
|
304
|
+
[
|
305
|
+
['<root>a<br/></root>', 'afoo'],
|
306
|
+
['<root>a<br/>b</root>', 'afoob'],
|
307
|
+
['<root><br/>b</root>', 'foob']
|
308
|
+
].each do |xml, result|
|
309
|
+
it "doesn't blow up on #{xml}" do
|
310
|
+
doc = Nokogiri::XML.parse(xml)
|
311
|
+
saved_nodes = doc.root.children
|
312
|
+
doc.at_xpath("/root/br").replace(Nokogiri::XML::Text.new('foo', doc))
|
313
|
+
saved_nodes.each { |child| child.inspect } # try to cause a crash
|
314
|
+
assert_equal result, doc.at_xpath("/root/text()").inner_text
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
data/test/xml/test_node_set.rb
CHANGED
@@ -1,11 +1,228 @@
|
|
1
|
-
require
|
1
|
+
require "helper"
|
2
2
|
|
3
3
|
module Nokogiri
|
4
4
|
module XML
|
5
5
|
class TestNodeSet < Nokogiri::TestCase
|
6
|
+
class TestNodeSetNamespaces < Nokogiri::TestCase
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
@xml = Nokogiri.XML('<foo xmlns:n0="http://example.com" />')
|
10
|
+
@list = @xml.xpath('//namespace::*')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_include?
|
14
|
+
assert @list.include?(@list.first), 'list should have item'
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_push
|
18
|
+
@list.push @list.first
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_delete
|
22
|
+
@list.push @list.first
|
23
|
+
@list.delete @list.first
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
6
27
|
def setup
|
7
28
|
super
|
8
|
-
@xml = Nokogiri::XML
|
29
|
+
@xml = Nokogiri::XML(File.read(XML_FILE), XML_FILE)
|
30
|
+
@list = @xml.css('employee')
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_filter
|
34
|
+
list = @xml.css('address').filter('*[domestic="Yes"]')
|
35
|
+
assert_equal(%w{ Yes } * 4, list.map { |n| n['domestic'] })
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_remove_attr
|
39
|
+
@list.each { |x| x['class'] = 'blah' }
|
40
|
+
assert_equal @list, @list.remove_attr('class')
|
41
|
+
@list.each { |x| assert_nil x['class'] }
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_add_class
|
45
|
+
assert_equal @list, @list.add_class('bar')
|
46
|
+
@list.each { |x| assert_equal 'bar', x['class'] }
|
47
|
+
|
48
|
+
@list.add_class('bar')
|
49
|
+
@list.each { |x| assert_equal 'bar', x['class'] }
|
50
|
+
|
51
|
+
@list.add_class('baz')
|
52
|
+
@list.each { |x| assert_equal 'bar baz', x['class'] }
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_remove_class_with_no_class
|
56
|
+
assert_equal @list, @list.remove_class('bar')
|
57
|
+
@list.each { |e| assert_nil e['class'] }
|
58
|
+
|
59
|
+
@list.each { |e| e['class'] = '' }
|
60
|
+
assert_equal @list, @list.remove_class('bar')
|
61
|
+
@list.each { |e| assert_nil e['class'] }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_remove_class_single
|
65
|
+
@list.each { |e| e['class'] = 'foo bar' }
|
66
|
+
|
67
|
+
assert_equal @list, @list.remove_class('bar')
|
68
|
+
@list.each { |e| assert_equal 'foo', e['class'] }
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_remove_class_completely
|
72
|
+
@list.each { |e| e['class'] = 'foo' }
|
73
|
+
|
74
|
+
assert_equal @list, @list.remove_class
|
75
|
+
@list.each { |e| assert_nil e['class'] }
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_attribute_set
|
79
|
+
@list.each { |e| assert_nil e['foo'] }
|
80
|
+
|
81
|
+
[ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
|
82
|
+
@list.send(t.first.to_sym, 'foo', t.last)
|
83
|
+
@list.each { |e| assert_equal t.last, e['foo'] }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_attribute_set_with_block
|
88
|
+
@list.each { |e| assert_nil e['foo'] }
|
89
|
+
|
90
|
+
[ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
|
91
|
+
@list.send(t.first.to_sym, 'foo') { |x| t.last }
|
92
|
+
@list.each { |e| assert_equal t.last, e['foo'] }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_attribute_set_with_hash
|
97
|
+
@list.each { |e| assert_nil e['foo'] }
|
98
|
+
|
99
|
+
[ ['attribute', 'bar'], ['attr', 'biz'], ['set', 'baz'] ].each do |t|
|
100
|
+
@list.send(t.first.to_sym, 'foo' => t.last)
|
101
|
+
@list.each { |e| assert_equal t.last, e['foo'] }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_attribute_no_args
|
106
|
+
@list.first['foo'] = 'bar'
|
107
|
+
assert_equal @list.first.attribute('foo'), @list.attribute('foo')
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_search_empty_node_set
|
111
|
+
set = Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
|
112
|
+
assert_equal 0, set.css('foo').length
|
113
|
+
assert_equal 0, set.xpath('.//foo').length
|
114
|
+
assert_equal 0, set.search('foo').length
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_xpath_with_custom_object
|
118
|
+
set = @xml.xpath('//staff')
|
119
|
+
custom_employees = set.xpath('//*[awesome(.)]', Class.new {
|
120
|
+
def awesome ns
|
121
|
+
ns.select { |n| n.name == 'employee' }
|
122
|
+
end
|
123
|
+
}.new)
|
124
|
+
|
125
|
+
assert_equal @xml.xpath('//employee'), custom_employees
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_css_with_custom_object
|
129
|
+
set = @xml.xpath('//staff')
|
130
|
+
custom_employees = set.css('*:awesome', Class.new {
|
131
|
+
def awesome ns
|
132
|
+
ns.select { |n| n.name == 'employee' }
|
133
|
+
end
|
134
|
+
}.new)
|
135
|
+
|
136
|
+
assert_equal @xml.xpath('//employee'), custom_employees
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_search_with_custom_object
|
140
|
+
set = @xml.xpath('//staff')
|
141
|
+
custom_employees = set.search('//*[awesome(.)]', Class.new {
|
142
|
+
def awesome ns
|
143
|
+
ns.select { |n| n.name == 'employee' }
|
144
|
+
end
|
145
|
+
}.new)
|
146
|
+
|
147
|
+
assert_equal @xml.xpath('//employee'), custom_employees
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_css_searches_match_self
|
151
|
+
html = Nokogiri::HTML("<html><body><div class='a'></div></body></html>")
|
152
|
+
set = html.xpath("/html/body/div")
|
153
|
+
assert_equal set.first, set.css(".a").first
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_search_with_css_matches_self
|
157
|
+
html = Nokogiri::HTML("<html><body><div class='a'></div></body></html>")
|
158
|
+
set = html.xpath("/html/body/div")
|
159
|
+
assert_equal set.first, set.search(".a").first
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_css_search_with_namespace
|
163
|
+
fragment = Nokogiri::XML.fragment(<<-eoxml)
|
164
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
165
|
+
<head></head>
|
166
|
+
<body></body>
|
167
|
+
</html>
|
168
|
+
eoxml
|
169
|
+
assert_nothing_raised{ fragment.children.search( 'body', { 'xmlns' => 'http://www.w3.org/1999/xhtml' }) }
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_double_equal
|
173
|
+
assert node_set_one = @xml.xpath('//employee')
|
174
|
+
assert node_set_two = @xml.xpath('//employee')
|
175
|
+
|
176
|
+
assert_not_equal node_set_one.object_id, node_set_two.object_id
|
177
|
+
|
178
|
+
assert_equal node_set_one, node_set_two
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_node_set_not_equal_to_string
|
182
|
+
node_set_one = @xml.xpath('//employee')
|
183
|
+
assert_not_equal node_set_one, "asdfadsf"
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_out_of_order_not_equal
|
187
|
+
one = @xml.xpath('//employee')
|
188
|
+
two = @xml.xpath('//employee')
|
189
|
+
two.push two.shift
|
190
|
+
assert_not_equal one, two
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_shorter_is_not_equal
|
194
|
+
node_set_one = @xml.xpath('//employee')
|
195
|
+
node_set_two = @xml.xpath('//employee')
|
196
|
+
node_set_two.delete(node_set_two.first)
|
197
|
+
|
198
|
+
assert_not_equal node_set_one, node_set_two
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_pop
|
202
|
+
set = @xml.xpath('//employee')
|
203
|
+
last = set.last
|
204
|
+
assert_equal last, set.pop
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_shift
|
208
|
+
set = @xml.xpath('//employee')
|
209
|
+
first = set.first
|
210
|
+
assert_equal first, set.shift
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_shift_empty
|
214
|
+
set = Nokogiri::XML::NodeSet.new(@xml)
|
215
|
+
assert_nil set.shift
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_pop_empty
|
219
|
+
set = Nokogiri::XML::NodeSet.new(@xml)
|
220
|
+
assert_nil set.pop
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_first_takes_arguments
|
224
|
+
assert node_set = @xml.xpath('//employee')
|
225
|
+
assert_equal 2, node_set.first(2).length
|
9
226
|
end
|
10
227
|
|
11
228
|
def test_dup
|
@@ -36,6 +253,12 @@ module Nokogiri
|
|
36
253
|
assert set.at('bar')
|
37
254
|
end
|
38
255
|
|
256
|
+
def test_children_has_document
|
257
|
+
set = @xml.root.children
|
258
|
+
assert_instance_of(NodeSet, set)
|
259
|
+
assert_equal @xml, set.document
|
260
|
+
end
|
261
|
+
|
39
262
|
def test_length_size
|
40
263
|
assert node_set = @xml.search('//employee')
|
41
264
|
assert_equal node_set.length, node_set.size
|
@@ -63,11 +286,31 @@ module Nokogiri
|
|
63
286
|
assert_match '<a>', html
|
64
287
|
end
|
65
288
|
|
289
|
+
def test_gt_string_arg
|
290
|
+
assert node_set = @xml.search('//employee')
|
291
|
+
assert_equal node_set.xpath('./employeeId'), (node_set > 'employeeId')
|
292
|
+
end
|
293
|
+
|
66
294
|
def test_at
|
67
295
|
assert node_set = @xml.search('//employee')
|
68
296
|
assert_equal node_set.first, node_set.at(0)
|
69
297
|
end
|
70
298
|
|
299
|
+
def test_at_xpath
|
300
|
+
assert node_set = @xml.search('//employee')
|
301
|
+
assert_equal node_set.first.first_element_child, node_set.at_xpath('./employeeId')
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_at_css
|
305
|
+
assert node_set = @xml.search('//employee')
|
306
|
+
assert_equal node_set.first.first_element_child, node_set.at_css('employeeId')
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_percent
|
310
|
+
assert node_set = @xml.search('//employee')
|
311
|
+
assert_equal node_set.first, node_set % 0
|
312
|
+
end
|
313
|
+
|
71
314
|
def test_to_ary
|
72
315
|
assert node_set = @xml.search('//employee')
|
73
316
|
foo = []
|
@@ -85,6 +328,36 @@ module Nokogiri
|
|
85
328
|
assert node_set.include?(node)
|
86
329
|
end
|
87
330
|
|
331
|
+
def test_delete_with_invalid_argument
|
332
|
+
employees = @xml.search("//employee")
|
333
|
+
positions = @xml.search("//position")
|
334
|
+
|
335
|
+
assert_raises(ArgumentError) { employees.delete(positions) }
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_delete_when_present
|
339
|
+
employees = @xml.search("//employee")
|
340
|
+
wally = employees.first
|
341
|
+
assert employees.include?(wally) # testing setup
|
342
|
+
length = employees.length
|
343
|
+
|
344
|
+
result = employees.delete(wally)
|
345
|
+
assert_equal result, wally
|
346
|
+
assert ! employees.include?(wally)
|
347
|
+
assert length-1, employees.length
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_delete_when_not_present
|
351
|
+
employees = @xml.search("//employee")
|
352
|
+
phb = @xml.search("//position").first
|
353
|
+
assert ! employees.include?(phb) # testing setup
|
354
|
+
length = employees.length
|
355
|
+
|
356
|
+
result = employees.delete(phb)
|
357
|
+
assert_nil result
|
358
|
+
assert length, employees.length
|
359
|
+
end
|
360
|
+
|
88
361
|
def test_unlink
|
89
362
|
xml = Nokogiri::XML.parse(<<-eoxml)
|
90
363
|
<root>
|
@@ -167,6 +440,269 @@ module Nokogiri
|
|
167
440
|
assert_equal 'wrapper', employees[0].parent.name
|
168
441
|
assert_equal 'employee', @xml.search("//wrapper").first.children[0].name
|
169
442
|
end
|
443
|
+
|
444
|
+
def test_wrap_a_fragment
|
445
|
+
frag = Nokogiri::XML::DocumentFragment.parse <<-EOXML
|
446
|
+
<employees>
|
447
|
+
<employee>hello</employee>
|
448
|
+
<employee>goodbye</employee>
|
449
|
+
</employees>
|
450
|
+
EOXML
|
451
|
+
employees = frag.xpath ".//employee"
|
452
|
+
employees.wrap("<wrapper/>")
|
453
|
+
assert_equal 'wrapper', employees[0].parent.name
|
454
|
+
assert_equal 'employee', frag.at(".//wrapper").children.first.name
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_wrap_preserves_document_structure
|
458
|
+
assert_equal "employeeId",
|
459
|
+
@xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
|
460
|
+
@xml.xpath("//employeeId[text()='EMP0001']").wrap("<wrapper/>")
|
461
|
+
assert_equal "wrapper",
|
462
|
+
@xml.at_xpath("//employee").children.detect{|j| ! j.text? }.name
|
463
|
+
end
|
464
|
+
|
465
|
+
def test_plus_operator
|
466
|
+
names = @xml.search("name")
|
467
|
+
positions = @xml.search("position")
|
468
|
+
|
469
|
+
names_len = names.length
|
470
|
+
positions_len = positions.length
|
471
|
+
|
472
|
+
assert_raises(ArgumentError) { names + positions.first }
|
473
|
+
|
474
|
+
result = names + positions
|
475
|
+
assert_equal names_len, names.length
|
476
|
+
assert_equal positions_len, positions.length
|
477
|
+
assert_equal names.length + positions.length, result.length
|
478
|
+
|
479
|
+
names += positions
|
480
|
+
assert_equal result.length, names.length
|
481
|
+
end
|
482
|
+
|
483
|
+
def test_union
|
484
|
+
names = @xml.search("name")
|
485
|
+
|
486
|
+
assert_equal(names.length, (names | @xml.search("name")).length)
|
487
|
+
end
|
488
|
+
|
489
|
+
def test_minus_operator
|
490
|
+
employees = @xml.search("//employee")
|
491
|
+
females = @xml.search("//employee[gender[text()='Female']]")
|
492
|
+
|
493
|
+
employees_len = employees.length
|
494
|
+
females_len = females.length
|
495
|
+
|
496
|
+
assert_raises(ArgumentError) { employees - females.first }
|
497
|
+
|
498
|
+
result = employees - females
|
499
|
+
assert_equal employees_len, employees.length
|
500
|
+
assert_equal females_len, females.length
|
501
|
+
assert_equal employees.length - females.length, result.length
|
502
|
+
|
503
|
+
employees -= females
|
504
|
+
assert_equal result.length, employees.length
|
505
|
+
end
|
506
|
+
|
507
|
+
def test_array_index
|
508
|
+
employees = @xml.search("//employee")
|
509
|
+
other = @xml.search("//position").first
|
510
|
+
|
511
|
+
assert_equal 3, employees.index(employees[3])
|
512
|
+
assert_nil employees.index(other)
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_slice_too_far
|
516
|
+
employees = @xml.search("//employee")
|
517
|
+
assert_equal employees.length, employees[0, employees.length + 1].length
|
518
|
+
assert_equal employees.length, employees[0, employees.length].length
|
519
|
+
end
|
520
|
+
|
521
|
+
def test_slice_waaaaaay_off_the_end
|
522
|
+
xml = Nokogiri::XML::Builder.new {
|
523
|
+
root { 100.times { div } }
|
524
|
+
}.doc
|
525
|
+
nodes = xml.css "div"
|
526
|
+
assert_equal 1, nodes.slice(99, 100_000).length
|
527
|
+
assert_equal 0, nodes.slice(100, 100_000).length
|
528
|
+
end
|
529
|
+
|
530
|
+
def test_array_slice_with_start_and_end
|
531
|
+
employees = @xml.search("//employee")
|
532
|
+
assert_equal [employees[1], employees[2], employees[3]], employees[1,3].to_a
|
533
|
+
end
|
534
|
+
|
535
|
+
def test_array_index_bracket_equivalence
|
536
|
+
employees = @xml.search("//employee")
|
537
|
+
assert_equal [employees[1], employees[2], employees[3]], employees[1,3].to_a
|
538
|
+
assert_equal [employees[1], employees[2], employees[3]], employees.slice(1,3).to_a
|
539
|
+
end
|
540
|
+
|
541
|
+
def test_array_slice_with_negative_start
|
542
|
+
employees = @xml.search("//employee")
|
543
|
+
assert_equal [employees[2]], employees[-3,1].to_a
|
544
|
+
assert_equal [employees[2], employees[3]], employees[-3,2].to_a
|
545
|
+
end
|
546
|
+
|
547
|
+
def test_array_slice_with_invalid_args
|
548
|
+
employees = @xml.search("//employee")
|
549
|
+
assert_nil employees[99, 1] # large start
|
550
|
+
assert_nil employees[1, -1] # negative len
|
551
|
+
assert_equal [], employees[1, 0].to_a # zero len
|
552
|
+
end
|
553
|
+
|
554
|
+
def test_array_slice_with_range
|
555
|
+
employees = @xml.search("//employee")
|
556
|
+
assert_equal [employees[1], employees[2], employees[3]], employees[1..3].to_a
|
557
|
+
assert_equal [employees[0], employees[1], employees[2], employees[3]], employees[0..3].to_a
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_intersection_with_no_overlap
|
561
|
+
employees = @xml.search("//employee")
|
562
|
+
positions = @xml.search("//position")
|
563
|
+
|
564
|
+
assert_equal [], (employees & positions).to_a
|
565
|
+
end
|
566
|
+
|
567
|
+
def test_intersection
|
568
|
+
employees = @xml.search("//employee")
|
569
|
+
first_set = employees[0..2]
|
570
|
+
second_set = employees[2..4]
|
571
|
+
|
572
|
+
assert_equal [employees[2]], (first_set & second_set).to_a
|
573
|
+
end
|
574
|
+
|
575
|
+
def test_include?
|
576
|
+
employees = @xml.search("//employee")
|
577
|
+
yes = employees.first
|
578
|
+
no = @xml.search("//position").first
|
579
|
+
|
580
|
+
assert employees.include?(yes)
|
581
|
+
assert ! employees.include?(no)
|
582
|
+
end
|
583
|
+
|
584
|
+
def test_children
|
585
|
+
employees = @xml.search("//employee")
|
586
|
+
count = 0
|
587
|
+
employees.each do |employee|
|
588
|
+
count += employee.children.length
|
589
|
+
end
|
590
|
+
set = employees.children
|
591
|
+
assert_equal count, set.length
|
592
|
+
end
|
593
|
+
|
594
|
+
def test_inspect
|
595
|
+
employees = @xml.search("//employee")
|
596
|
+
inspected = employees.inspect
|
597
|
+
|
598
|
+
assert_equal "[#{employees.map { |x| x.inspect }.join(', ')}]",
|
599
|
+
inspected
|
600
|
+
end
|
601
|
+
|
602
|
+
def test_should_not_splode_when_accessing_namespace_declarations_in_a_node_set
|
603
|
+
xml = Nokogiri::XML "<foo></foo>"
|
604
|
+
node_set = xml.xpath("//namespace::*")
|
605
|
+
assert_equal 1, node_set.size
|
606
|
+
node = node_set.first
|
607
|
+
node.to_s # segfaults in 1.4.0 and earlier
|
608
|
+
|
609
|
+
# if we haven't segfaulted, let's make sure we handled it correctly
|
610
|
+
assert_instance_of Nokogiri::XML::Namespace, node
|
611
|
+
end
|
612
|
+
|
613
|
+
def test_should_not_splode_when_arrayifying_node_set_containing_namespace_declarations
|
614
|
+
xml = Nokogiri::XML "<foo></foo>"
|
615
|
+
node_set = xml.xpath("//namespace::*")
|
616
|
+
assert_equal 1, node_set.size
|
617
|
+
|
618
|
+
node_array = node_set.to_a
|
619
|
+
node = node_array.first
|
620
|
+
node.to_s # segfaults in 1.4.0 and earlier
|
621
|
+
|
622
|
+
# if we haven't segfaulted, let's make sure we handled it correctly
|
623
|
+
assert_instance_of Nokogiri::XML::Namespace, node
|
624
|
+
end
|
625
|
+
|
626
|
+
def test_should_not_splode_when_unlinking_node_set_containing_namespace_declarations
|
627
|
+
xml = Nokogiri::XML "<foo></foo>"
|
628
|
+
node_set = xml.xpath("//namespace::*")
|
629
|
+
assert_equal 1, node_set.size
|
630
|
+
|
631
|
+
node_set.unlink
|
632
|
+
end
|
633
|
+
|
634
|
+
def test_reverse
|
635
|
+
xml = Nokogiri::XML "<root><a />b<c />d<e /></root>"
|
636
|
+
children = xml.root.children
|
637
|
+
assert_instance_of Nokogiri::XML::NodeSet, children
|
638
|
+
|
639
|
+
reversed = children.reverse
|
640
|
+
assert_equal reversed[0], children[4]
|
641
|
+
assert_equal reversed[1], children[3]
|
642
|
+
assert_equal reversed[2], children[2]
|
643
|
+
assert_equal reversed[3], children[1]
|
644
|
+
assert_equal reversed[4], children[0]
|
645
|
+
|
646
|
+
assert_equal children, children.reverse.reverse
|
647
|
+
end
|
648
|
+
|
649
|
+
def test_node_set_dup_result_has_document_and_is_decorated
|
650
|
+
x = Module.new do
|
651
|
+
def awesome! ; end
|
652
|
+
end
|
653
|
+
util_decorate(@xml, x)
|
654
|
+
node_set = @xml.css("address")
|
655
|
+
new_set = node_set.dup
|
656
|
+
assert_equal node_set.document, new_set.document
|
657
|
+
assert new_set.respond_to?(:awesome!)
|
658
|
+
end
|
659
|
+
|
660
|
+
def test_node_set_union_result_has_document_and_is_decorated
|
661
|
+
x = Module.new do
|
662
|
+
def awesome! ; end
|
663
|
+
end
|
664
|
+
util_decorate(@xml, x)
|
665
|
+
node_set1 = @xml.css("address")
|
666
|
+
node_set2 = @xml.css("address")
|
667
|
+
new_set = node_set1 | node_set2
|
668
|
+
assert_equal node_set1.document, new_set.document
|
669
|
+
assert new_set.respond_to?(:awesome!)
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_node_set_intersection_result_has_document_and_is_decorated
|
673
|
+
x = Module.new do
|
674
|
+
def awesome! ; end
|
675
|
+
end
|
676
|
+
util_decorate(@xml, x)
|
677
|
+
node_set1 = @xml.css("address")
|
678
|
+
node_set2 = @xml.css("address")
|
679
|
+
new_set = node_set1 & node_set2
|
680
|
+
assert_equal node_set1.document, new_set.document
|
681
|
+
assert new_set.respond_to?(:awesome!)
|
682
|
+
end
|
683
|
+
|
684
|
+
def test_node_set_difference_result_has_document_and_is_decorated
|
685
|
+
x = Module.new do
|
686
|
+
def awesome! ; end
|
687
|
+
end
|
688
|
+
util_decorate(@xml, x)
|
689
|
+
node_set1 = @xml.css("address")
|
690
|
+
node_set2 = @xml.css("address")
|
691
|
+
new_set = node_set1 - node_set2
|
692
|
+
assert_equal node_set1.document, new_set.document
|
693
|
+
assert new_set.respond_to?(:awesome!)
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_node_set_slice_result_has_document_and_is_decorated
|
697
|
+
x = Module.new do
|
698
|
+
def awesome! ; end
|
699
|
+
end
|
700
|
+
util_decorate(@xml, x)
|
701
|
+
node_set = @xml.css("address")
|
702
|
+
new_set = node_set[0..-1]
|
703
|
+
assert_equal node_set.document, new_set.document
|
704
|
+
assert new_set.respond_to?(:awesome!)
|
705
|
+
end
|
170
706
|
end
|
171
707
|
end
|
172
708
|
end
|