nokogiri 1.5.0.beta.2 → 1.5.0.beta.3
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/CHANGELOG.ja.rdoc +63 -0
- data/CHANGELOG.rdoc +44 -1
- data/Manifest.txt +3 -3
- data/README.ja.rdoc +4 -4
- data/README.rdoc +4 -4
- data/Rakefile +3 -0
- data/bin/nokogiri +6 -1
- data/ext/java/nokogiri/EncodingHandler.java +32 -0
- data/ext/java/nokogiri/HtmlDocument.java +36 -0
- data/ext/java/nokogiri/HtmlElementDescription.java +34 -0
- data/ext/java/nokogiri/HtmlEntityLookup.java +34 -0
- data/ext/java/nokogiri/HtmlSaxParserContext.java +41 -3
- data/ext/java/nokogiri/NokogiriService.java +109 -13
- data/ext/java/nokogiri/XmlAttr.java +40 -4
- data/ext/java/nokogiri/XmlAttributeDecl.java +32 -0
- data/ext/java/nokogiri/XmlCdata.java +41 -2
- data/ext/java/nokogiri/XmlComment.java +38 -1
- data/ext/java/nokogiri/XmlDocument.java +56 -11
- data/ext/java/nokogiri/XmlDocumentFragment.java +39 -30
- data/ext/java/nokogiri/XmlDtd.java +37 -0
- data/ext/java/nokogiri/XmlElement.java +51 -2
- data/ext/java/nokogiri/XmlElementContent.java +32 -0
- data/ext/java/nokogiri/XmlElementDecl.java +32 -0
- data/ext/java/nokogiri/XmlEntityDecl.java +32 -0
- data/ext/java/nokogiri/XmlEntityReference.java +35 -2
- data/ext/java/nokogiri/XmlNamespace.java +55 -5
- data/ext/java/nokogiri/XmlNode.java +129 -136
- data/ext/java/nokogiri/XmlNodeSet.java +36 -0
- data/ext/java/nokogiri/XmlProcessingInstruction.java +34 -1
- data/ext/java/nokogiri/XmlReader.java +36 -0
- data/ext/java/nokogiri/XmlRelaxng.java +34 -1
- data/ext/java/nokogiri/XmlSaxParserContext.java +52 -7
- data/ext/java/nokogiri/XmlSaxPushParser.java +36 -0
- data/ext/java/nokogiri/XmlSchema.java +34 -1
- data/ext/java/nokogiri/XmlSyntaxError.java +48 -18
- data/ext/java/nokogiri/XmlText.java +45 -6
- data/ext/java/nokogiri/XmlXpathContext.java +45 -0
- data/ext/java/nokogiri/XsltStylesheet.java +58 -3
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +50 -26
- data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +35 -1
- data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +51 -13
- data/ext/java/nokogiri/internals/NokogiriHandler.java +70 -21
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +95 -38
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +37 -3
- data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +39 -1
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +43 -7
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +77 -10
- data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +49 -20
- data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +34 -2
- data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -1
- data/ext/java/nokogiri/internals/ParserContext.java +32 -0
- data/ext/java/nokogiri/internals/PushInputStream.java +33 -3
- data/ext/java/nokogiri/internals/ReaderNode.java +50 -8
- data/ext/java/nokogiri/internals/SaveContext.java +35 -2
- data/ext/java/nokogiri/internals/SchemaErrorHandler.java +34 -1
- data/ext/java/nokogiri/internals/XmlDeclHandler.java +32 -0
- data/ext/java/nokogiri/internals/XmlDomParser.java +32 -0
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +43 -11
- data/ext/java/nokogiri/internals/XmlSaxParser.java +32 -0
- data/ext/java/nokogiri/internals/XsltExtensionFunction.java +72 -0
- data/ext/nokogiri/depend +358 -32
- data/ext/nokogiri/extconf.rb +1 -3
- data/ext/nokogiri/nokogiri.c +2 -0
- data/ext/nokogiri/nokogiri.h +7 -0
- data/ext/nokogiri/xml_dtd.c +2 -2
- data/ext/nokogiri/xml_io.c +2 -2
- data/ext/nokogiri/xml_node.c +31 -6
- data/ext/nokogiri/xml_node_set.c +1 -1
- data/ext/nokogiri/xml_sax_parser.c +1 -1
- data/ext/nokogiri/xml_sax_parser_context.c +40 -0
- data/ext/nokogiri/xml_xpath_context.c +33 -2
- data/ext/nokogiri/xslt_stylesheet.c +122 -6
- data/lib/nokogiri.rb +12 -5
- data/lib/nokogiri/css/generated_tokenizer.rb +1 -2
- data/lib/nokogiri/css/xpath_visitor.rb +15 -7
- data/lib/nokogiri/decorators/slop.rb +5 -3
- data/lib/nokogiri/html/document.rb +3 -3
- data/lib/nokogiri/html/document_fragment.rb +19 -17
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml/document.rb +26 -1
- data/lib/nokogiri/xml/document_fragment.rb +2 -2
- data/lib/nokogiri/xml/dtd.rb +11 -0
- data/lib/nokogiri/xml/node.rb +156 -45
- data/lib/nokogiri/xml/node_set.rb +2 -2
- data/lib/nokogiri/xml/reader.rb +36 -0
- data/lib/nokogiri/xml/sax/document.rb +4 -2
- data/lib/nokogiri/xslt.rb +9 -5
- data/lib/nokogiri/xslt/stylesheet.rb +1 -1
- data/tasks/cross_compile.rb +27 -8
- data/test/css/test_parser.rb +29 -18
- data/test/decorators/test_slop.rb +16 -0
- data/test/html/test_document_fragment.rb +46 -3
- data/test/html/test_node.rb +9 -0
- data/test/xml/sax/test_parser.rb +11 -3
- data/test/xml/sax/test_parser_context.rb +50 -0
- data/test/xml/sax/test_push_parser.rb +18 -1
- data/test/xml/test_document_fragment.rb +15 -8
- data/test/xml/test_dtd.rb +15 -0
- data/test/xml/test_node.rb +31 -2
- data/test/xml/test_node_reparenting.rb +59 -31
- data/test/xml/test_node_set.rb +13 -0
- data/test/xml/test_xpath.rb +32 -0
- data/test/xslt/test_custom_functions.rb +94 -0
- metadata +83 -81
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/spec/helper.rb +0 -3
- data/spec/xml/reader_spec.rb +0 -307
@@ -42,7 +42,7 @@ module Nokogiri
|
|
42
42
|
end
|
43
43
|
|
44
44
|
###
|
45
|
-
# Returns the index of the first node in self that is == to +node+. Returns nil if no match is found.
|
45
|
+
# Returns the index of the first node in self that is == to +node+. Returns nil if no match is found.
|
46
46
|
def index(node)
|
47
47
|
each_with_index { |member, j| return j if member == node }
|
48
48
|
nil
|
@@ -257,7 +257,7 @@ module Nokogiri
|
|
257
257
|
# Wrap this NodeSet with +html+ or the results of the builder in +blk+
|
258
258
|
def wrap(html, &blk)
|
259
259
|
each do |j|
|
260
|
-
new_parent = document.
|
260
|
+
new_parent = document.parse(html).first
|
261
261
|
j.add_next_sibling(new_parent)
|
262
262
|
new_parent.add_child(j)
|
263
263
|
end
|
data/lib/nokogiri/xml/reader.rb
CHANGED
@@ -30,6 +30,42 @@ module Nokogiri
|
|
30
30
|
class Reader
|
31
31
|
include Enumerable
|
32
32
|
|
33
|
+
TYPE_NONE = 0
|
34
|
+
# Element node type
|
35
|
+
TYPE_ELEMENT = 1
|
36
|
+
# Attribute node type
|
37
|
+
TYPE_ATTRIBUTE = 2
|
38
|
+
# Text node type
|
39
|
+
TYPE_TEXT = 3
|
40
|
+
# CDATA node type
|
41
|
+
TYPE_CDATA = 4
|
42
|
+
# Entity Reference node type
|
43
|
+
TYPE_ENTITY_REFERENCE = 5
|
44
|
+
# Entity node type
|
45
|
+
TYPE_ENTITY = 6
|
46
|
+
# PI node type
|
47
|
+
TYPE_PROCESSING_INSTRUCTION = 7
|
48
|
+
# Comment node type
|
49
|
+
TYPE_COMMENT = 8
|
50
|
+
# Document node type
|
51
|
+
TYPE_DOCUMENT = 9
|
52
|
+
# Document Type node type
|
53
|
+
TYPE_DOCUMENT_TYPE = 10
|
54
|
+
# Document Fragment node type
|
55
|
+
TYPE_DOCUMENT_FRAGMENT = 11
|
56
|
+
# Notation node type
|
57
|
+
TYPE_NOTATION = 12
|
58
|
+
# Whitespace node type
|
59
|
+
TYPE_WHITESPACE = 13
|
60
|
+
# Significant Whitespace node type
|
61
|
+
TYPE_SIGNIFICANT_WHITESPACE = 14
|
62
|
+
# Element end node type
|
63
|
+
TYPE_END_ELEMENT = 15
|
64
|
+
# Entity end node type
|
65
|
+
TYPE_END_ENTITY = 16
|
66
|
+
# XML Declaration node type
|
67
|
+
TYPE_XML_DECLARATION = 17
|
68
|
+
|
33
69
|
# A list of errors encountered while parsing
|
34
70
|
attr_accessor :errors
|
35
71
|
|
@@ -85,7 +85,9 @@ module Nokogiri
|
|
85
85
|
|
86
86
|
###
|
87
87
|
# Called at the beginning of an element
|
88
|
-
# +name+ is the name of the tag
|
88
|
+
# * +name+ is the name of the tag
|
89
|
+
# * +attrs+ are an assoc list of namespaces and attributes, e.g.:
|
90
|
+
# [ ["xmlns:foo", "http://sample.net"], ["size", "large"] ]
|
89
91
|
def start_element name, attrs = []
|
90
92
|
end
|
91
93
|
|
@@ -110,7 +112,7 @@ module Nokogiri
|
|
110
112
|
[['xmlns', ns_prefix].compact.join(':'), ns_uri]
|
111
113
|
} + attrs.map { |attr|
|
112
114
|
[[attr.prefix, attr.localname].compact.join(':'), attr.value]
|
113
|
-
}
|
115
|
+
}
|
114
116
|
start_element name, attributes
|
115
117
|
end
|
116
118
|
|
data/lib/nokogiri/xslt.rb
CHANGED
@@ -9,8 +9,8 @@ module Nokogiri
|
|
9
9
|
#
|
10
10
|
# xslt = Nokogiri::XSLT(File.read(ARGV[0]))
|
11
11
|
#
|
12
|
-
def XSLT stylesheet
|
13
|
-
XSLT.parse(stylesheet)
|
12
|
+
def XSLT stylesheet, modules = {}
|
13
|
+
XSLT.parse(stylesheet, modules)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -20,11 +20,15 @@ module Nokogiri
|
|
20
20
|
module XSLT
|
21
21
|
class << self
|
22
22
|
###
|
23
|
-
# Parse the stylesheet in +string+
|
24
|
-
def parse string
|
23
|
+
# Parse the stylesheet in +string+, register any +modules+
|
24
|
+
def parse string, modules = {}
|
25
|
+
modules.each do |url, klass|
|
26
|
+
XSLT.register url, klass
|
27
|
+
end
|
28
|
+
|
25
29
|
Stylesheet.parse_stylesheet_doc(XML.parse(string))
|
26
30
|
end
|
27
|
-
|
31
|
+
|
28
32
|
###
|
29
33
|
# Quote parameters in +params+ for stylesheet safety
|
30
34
|
def quote_params params
|
@@ -6,7 +6,7 @@ module Nokogiri
|
|
6
6
|
# an XML::Document with a Stylesheet:
|
7
7
|
#
|
8
8
|
# doc = Nokogiri::XML(File.read('some_file.xml'))
|
9
|
-
# xslt =
|
9
|
+
# xslt = Nokogiri::XSLT(File.read('some_transformer.xslt'))
|
10
10
|
#
|
11
11
|
# puts xslt.transform(doc)
|
12
12
|
#
|
data/tasks/cross_compile.rb
CHANGED
@@ -6,6 +6,7 @@ ZLIB = 'zlib-1.2.5'
|
|
6
6
|
ICONV = 'libiconv-1.13.1'
|
7
7
|
LIBXML = 'libxml2-2.7.7'
|
8
8
|
LIBXSLT = 'libxslt-1.1.26'
|
9
|
+
RAKE_COMPILER_PKGCONFIG = File.expand_path(File.join(Dir.pwd, "tmp/cross/lib/pkgconfig/"))
|
9
10
|
|
10
11
|
### Build zlib ###
|
11
12
|
file "tmp/cross/download/#{ZLIB}" do |t|
|
@@ -108,7 +109,7 @@ file "tmp/cross/download/#{LIBXSLT}" do |t|
|
|
108
109
|
|
109
110
|
Dir.chdir t.name do
|
110
111
|
# FIXME: need to make the host dynamic
|
111
|
-
sh "CFLAGS='-DIN_LIBXML' ./configure --host=#{HOST} --target=#{TARGET} --enable-static --disable-shared --prefix=#{CROSS_DIR} --with-libxml-prefix=#{CROSS_DIR} --without-python"
|
112
|
+
sh "CFLAGS='-DIN_LIBXML' ./configure --host=#{HOST} --target=#{TARGET} --enable-static --disable-shared --prefix=#{CROSS_DIR} --with-libxml-prefix=#{CROSS_DIR} --without-python --without-crypto"
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
@@ -120,7 +121,7 @@ file 'tmp/cross/bin/xslt-config' => "tmp/cross/download/#{LIBXSLT}" do |t|
|
|
120
121
|
end
|
121
122
|
### End build libxslt ###
|
122
123
|
|
123
|
-
file 'lib/nokogiri/nokogiri.rb' => 'cross:
|
124
|
+
file 'lib/nokogiri/nokogiri.rb' => 'cross:check' do
|
124
125
|
File.open("lib/#{HOE.name}/#{HOE.name}.rb", 'wb') do |f|
|
125
126
|
f.write <<-eoruby
|
126
127
|
require "#{HOE.name}/\#{RUBY_VERSION.sub(/\\.\\d+$/, '')}/#{HOE.name}"
|
@@ -134,25 +135,43 @@ namespace :cross do
|
|
134
135
|
task :libxml2 => ['cross:zlib', 'cross:iconv', 'tmp/cross/bin/xml2-config']
|
135
136
|
task :libxslt => ['cross:libxml2', 'tmp/cross/bin/xslt-config']
|
136
137
|
|
137
|
-
task :
|
138
|
-
|
139
|
-
|
138
|
+
task :check => ["cross:libxslt"] do
|
139
|
+
unless File.directory?(RAKE_COMPILER_PKGCONFIG)
|
140
|
+
raise RuntimeError.new("looks like rake-compiler changed where pkgconfig info is kept. (#{RAKE_COMPILER_PKGCONFIG})")
|
140
141
|
end
|
141
142
|
end
|
142
143
|
|
143
|
-
task :file_list
|
144
|
+
task :file_list do
|
144
145
|
HOE.spec.extensions = []
|
145
146
|
HOE.spec.files += Dir["lib/#{HOE.name}/#{HOE.name}.rb"]
|
146
147
|
HOE.spec.files += Dir["lib/#{HOE.name}/1.{8,9}/#{HOE.name}.so"]
|
147
|
-
HOE.spec.files += Dir["ext/nokogiri/*.dll"]
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
151
|
CLOBBER.include("lib/nokogiri/nokogiri.{so,dylib,rb,bundle}")
|
152
152
|
CLOBBER.include("lib/nokogiri/1.{8,9}")
|
153
|
-
CLOBBER.include("ext/nokogiri/*.dll")
|
154
153
|
|
155
154
|
if Rake::Task.task_defined?(:cross)
|
156
155
|
Rake::Task[:cross].prerequisites << "lib/nokogiri/nokogiri.rb"
|
157
156
|
Rake::Task[:cross].prerequisites << "cross:file_list"
|
158
157
|
end
|
158
|
+
|
159
|
+
desc "build a windows gem without all the ceremony."
|
160
|
+
task "gem:windows" do
|
161
|
+
rake_compiler_config = YAML.load_file("#{ENV['HOME']}/.rake-compiler/config.yml")
|
162
|
+
|
163
|
+
# check that rake-compiler config contains the right patchlevels of 1.8.6 and 1.9.1. see #279.
|
164
|
+
["1.8.6-p383", "1.9.1-p243"].each do |version|
|
165
|
+
majmin, patchlevel = version.split("-")
|
166
|
+
rbconfig = "rbconfig-#{majmin}"
|
167
|
+
unless rake_compiler_config.key?(rbconfig) && rake_compiler_config[rbconfig] =~ /-#{patchlevel}/
|
168
|
+
raise "rake-compiler '#{rbconfig}' not #{patchlevel}. try running 'rake-compiler cross-ruby VERSION=#{version}'"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# verify that --export-all is in the 1.9.1 rbconfig. see #279,#374,#375.
|
173
|
+
rbconfig_191 = rake_compiler_config["rbconfig-1.9.1"]
|
174
|
+
raise "rbconfig #{rbconfig_191} needs --export-all in its DLDFLAGS value" if File.read(rbconfig_191).grep(/CONFIG\["DLDFLAGS"\].*--export-all/).empty?
|
175
|
+
|
176
|
+
system("env PKG_CONFIG_PATH=#{RAKE_COMPILER_PKGCONFIG} RUBY_CC_VERSION=1.8.6:1.9.1 rake cross native gem") || raise("build failed!")
|
177
|
+
end
|
data/test/css/test_parser.rb
CHANGED
@@ -142,30 +142,31 @@ module Nokogiri
|
|
142
142
|
|
143
143
|
def test_nonstandard_nth_selectors
|
144
144
|
## These are non standard CSS
|
145
|
-
assert_xpath '//a[position() =
|
146
|
-
assert_xpath '//a[position() = 1]',
|
147
|
-
assert_xpath '//a[position() =
|
148
|
-
assert_xpath '//a[position() = 99]',
|
149
|
-
assert_xpath '//a[position() =
|
150
|
-
assert_xpath '//a[position() = last()]',
|
151
|
-
assert_xpath '//a[node()]',
|
145
|
+
assert_xpath '//a[position() = 1]', @parser.parse('a:first()')
|
146
|
+
assert_xpath '//a[position() = 1]', @parser.parse('a:first') # no parens
|
147
|
+
assert_xpath '//a[position() = 99]', @parser.parse('a:eq(99)')
|
148
|
+
assert_xpath '//a[position() = 99]', @parser.parse('a:nth(99)')
|
149
|
+
assert_xpath '//a[position() = last()]', @parser.parse('a:last()')
|
150
|
+
assert_xpath '//a[position() = last()]', @parser.parse('a:last') # no parens
|
151
|
+
assert_xpath '//a[node()]', @parser.parse('a:parent')
|
152
152
|
end
|
153
153
|
|
154
154
|
def test_standard_nth_selectors
|
155
|
-
assert_xpath '//a[position() =
|
156
|
-
assert_xpath '//a[position() = 1]',
|
157
|
-
assert_xpath '//a[position() =
|
158
|
-
assert_xpath '//a[position() =
|
159
|
-
assert_xpath '//a[position() = last()]',
|
160
|
-
assert_xpath '//a[position() = last()
|
161
|
-
assert_xpath '//a[position() = last() -
|
155
|
+
assert_xpath '//a[position() = 1]', @parser.parse('a:first-of-type()')
|
156
|
+
assert_xpath '//a[position() = 1]', @parser.parse('a:first-of-type') # no parens
|
157
|
+
assert_xpath '//a[position() = 99]', @parser.parse('a:nth-of-type(99)')
|
158
|
+
assert_xpath '//a[position() = last()]', @parser.parse('a:last-of-type()')
|
159
|
+
assert_xpath '//a[position() = last()]', @parser.parse('a:last-of-type') # no parens
|
160
|
+
assert_xpath '//a[position() = last()]', @parser.parse('a:nth-last-of-type(1)')
|
161
|
+
assert_xpath '//a[position() = last() - 98]', @parser.parse('a:nth-last-of-type(99)')
|
162
162
|
end
|
163
163
|
|
164
164
|
def test_nth_child_selectors
|
165
|
-
assert_xpath '//*[position() = 1 and self::a]',
|
166
|
-
assert_xpath '//*[position() =
|
167
|
-
assert_xpath '//*[position() =
|
168
|
-
assert_xpath '//*[position() = last()
|
165
|
+
assert_xpath '//*[position() = 1 and self::a]', @parser.parse('a:first-child')
|
166
|
+
assert_xpath '//*[position() = 99 and self::a]', @parser.parse('a:nth-child(99)')
|
167
|
+
assert_xpath '//*[position() = last() and self::a]', @parser.parse('a:last-child')
|
168
|
+
assert_xpath '//*[position() = last() and self::a]', @parser.parse('a:nth-last-child(1)')
|
169
|
+
assert_xpath '//*[position() = last() - 98 and self::a]', @parser.parse('a:nth-last-child(99)')
|
169
170
|
end
|
170
171
|
|
171
172
|
def test_miscellaneous_selectors
|
@@ -185,6 +186,16 @@ module Nokogiri
|
|
185
186
|
assert_xpath '//a[(position() <= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(-n+3)')
|
186
187
|
assert_xpath '//a[(position() >= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(1n+3)')
|
187
188
|
assert_xpath '//a[(position() >= 3) and (((position()-3) mod 1) = 0)]', @parser.parse('a:nth-of-type(n+3)')
|
189
|
+
|
190
|
+
assert_xpath '//a[((last()-position()+1) mod 2) = 0]', @parser.parse('a:nth-last-of-type(2n)')
|
191
|
+
assert_xpath '//a[((last()-position()+1) >= 1) and ((((last()-position()+1)-1) mod 2) = 0)]', @parser.parse('a:nth-last-of-type(2n+1)')
|
192
|
+
assert_xpath '//a[((last()-position()+1) mod 2) = 0]', @parser.parse('a:nth-last-of-type(even)')
|
193
|
+
assert_xpath '//a[((last()-position()+1) >= 1) and ((((last()-position()+1)-1) mod 2) = 0)]', @parser.parse('a:nth-last-of-type(odd)')
|
194
|
+
assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 4) = 0)]', @parser.parse('a:nth-last-of-type(4n+3)')
|
195
|
+
assert_xpath '//a[((last()-position()+1) <= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(-1n+3)')
|
196
|
+
assert_xpath '//a[((last()-position()+1) <= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(-n+3)')
|
197
|
+
assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(1n+3)')
|
198
|
+
assert_xpath '//a[((last()-position()+1) >= 3) and ((((last()-position()+1)-3) mod 1) = 0)]', @parser.parse('a:nth-last-of-type(n+3)')
|
188
199
|
end
|
189
200
|
|
190
201
|
def test_preceding_selector
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
class TestSlop < Nokogiri::TestCase
|
5
|
+
def test_description_tag
|
6
|
+
doc = Nokogiri.Slop(<<-eoxml)
|
7
|
+
<item>
|
8
|
+
<title>foo</title>
|
9
|
+
<description>this is the foo thing</description>
|
10
|
+
</item>
|
11
|
+
eoxml
|
12
|
+
assert doc.item.title
|
13
|
+
assert doc.item._description, 'should have description'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -74,6 +74,16 @@ module Nokogiri
|
|
74
74
|
assert Nokogiri::HTML::DocumentFragment.new(@html)
|
75
75
|
end
|
76
76
|
|
77
|
+
def test_body_fragment_should_contain_body
|
78
|
+
fragment = Nokogiri::HTML::DocumentFragment.parse(" <body><div>foo</div></body>")
|
79
|
+
assert_match(/^<body>/, fragment.to_s)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_nonbody_fragment_should_not_contain_body
|
83
|
+
fragment = Nokogiri::HTML::DocumentFragment.parse("<div>foo</div>")
|
84
|
+
assert_match(/^<div>/, fragment.to_s)
|
85
|
+
end
|
86
|
+
|
77
87
|
def test_fragment_should_have_document
|
78
88
|
fragment = Nokogiri::HTML::DocumentFragment.new(@html)
|
79
89
|
assert_equal @html, fragment.document
|
@@ -140,13 +150,13 @@ module Nokogiri
|
|
140
150
|
def test_html_fragment_with_leading_whitespace
|
141
151
|
doc = " <div>b</div> "
|
142
152
|
fragment = Nokogiri::HTML::Document.new.fragment(doc)
|
143
|
-
|
153
|
+
assert_match %r% <div>b</div> *%, fragment.to_s
|
144
154
|
end
|
145
155
|
|
146
156
|
def test_html_fragment_with_leading_whitespace_and_newline
|
147
157
|
doc = " \n<div>b</div> "
|
148
158
|
fragment = Nokogiri::HTML::Document.new.fragment(doc)
|
149
|
-
|
159
|
+
assert_match %r% \n<div>b</div> *%, fragment.to_s
|
150
160
|
end
|
151
161
|
|
152
162
|
def test_html_fragment_with_leading_text_and_newline
|
@@ -156,7 +166,7 @@ module Nokogiri
|
|
156
166
|
|
157
167
|
def test_html_fragment_with_leading_whitespace_and_text_and_newline
|
158
168
|
fragment = HTML::Document.new.fragment(" First line\nSecond line<br>Broken line")
|
159
|
-
assert_equal "First line\nSecond line<br>Broken line", fragment.to_s
|
169
|
+
assert_equal " First line\nSecond line<br>Broken line", fragment.to_s
|
160
170
|
end
|
161
171
|
|
162
172
|
def test_html_fragment_with_leading_entity
|
@@ -207,6 +217,39 @@ module Nokogiri
|
|
207
217
|
assert_equal("<p>hello<!-- your ad here --></p>",
|
208
218
|
fragment.to_s)
|
209
219
|
end
|
220
|
+
|
221
|
+
def test_malformed_fragment_is_corrected
|
222
|
+
fragment = HTML::DocumentFragment.parse("<div </div>")
|
223
|
+
assert_equal "<div></div>", fragment.to_s
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_unclosed_script_tag
|
227
|
+
# see GH#315
|
228
|
+
fragment = HTML::DocumentFragment.parse("foo <script>bar")
|
229
|
+
assert_equal "foo <script>bar</script>", fragment.to_html
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_error_propagation_on_fragment_parse
|
233
|
+
frag = Nokogiri::HTML::DocumentFragment.parse "<hello>oh, hello there.</hello>"
|
234
|
+
assert frag.errors.any?{|err| err.to_s =~ /Tag hello invalid/}, "errors should be copied to the fragment"
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_error_propagation_on_fragment_parse_in_node_context
|
238
|
+
doc = Nokogiri::HTML::Document.parse "<html><body><div></div></body></html>"
|
239
|
+
context_node = doc.at_css "div"
|
240
|
+
frag = Nokogiri::HTML::DocumentFragment.new doc, "<hello>oh, hello there.</hello>", context_node
|
241
|
+
assert frag.errors.any?{|err| err.to_s =~ /Tag hello invalid/}, "errors should be on the context node's document"
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_error_propagation_on_fragment_parse_in_node_context_should_not_include_preexisting_errors
|
245
|
+
doc = Nokogiri::HTML::Document.parse "<html><body><div></div><jimmy></jimmy></body></html>"
|
246
|
+
assert doc.errors.any?{|err| err.to_s =~ /jimmy/}, "assert on setup"
|
247
|
+
|
248
|
+
context_node = doc.at_css "div"
|
249
|
+
frag = Nokogiri::HTML::DocumentFragment.new doc, "<hello>oh, hello there.</hello>", context_node
|
250
|
+
assert frag.errors.any?{|err| err.to_s =~ /Tag hello invalid/}, "errors should be on the context node's document"
|
251
|
+
assert frag.errors.none?{|err| err.to_s =~ /jimmy/}, "errors should not include pre-existing document errors"
|
252
|
+
end
|
210
253
|
end
|
211
254
|
end
|
212
255
|
end
|
data/test/html/test_node.rb
CHANGED
@@ -127,6 +127,15 @@ module Nokogiri
|
|
127
127
|
assert_equal 'foo&bar&baz', node['href']
|
128
128
|
end
|
129
129
|
|
130
|
+
def test_parse_config_option
|
131
|
+
node = @html.at('div')
|
132
|
+
options = nil
|
133
|
+
node.parse("<div></div>") do |config|
|
134
|
+
options = config
|
135
|
+
end
|
136
|
+
assert_equal Nokogiri::XML::ParseOptions::DEFAULT_HTML, options.to_i
|
137
|
+
end
|
138
|
+
|
130
139
|
def test_fragment_handler_does_not_regurge_on_invalid_attributes
|
131
140
|
iframe = %Q{<iframe style="width: 0%; height: 0px" src="http://someurl" allowtransparency></iframe>}
|
132
141
|
assert_nothing_raised { @html.at('div').fragment(iframe) }
|
data/test/xml/sax/test_parser.rb
CHANGED
@@ -24,7 +24,7 @@ module Nokogiri
|
|
24
24
|
|
25
25
|
assert block_called
|
26
26
|
|
27
|
-
assert_equal ['a', '&b'], doc.start_elements
|
27
|
+
assert_equal [['foo', [['a', '&b']]]], doc.start_elements
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_parser_context_yielded_in_memory
|
@@ -40,7 +40,7 @@ module Nokogiri
|
|
40
40
|
|
41
41
|
assert block_called
|
42
42
|
|
43
|
-
assert_equal ['a', '&b'], doc.start_elements
|
43
|
+
assert_equal [['foo', [['a', '&b']]]], doc.start_elements
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_xml_decl
|
@@ -296,7 +296,15 @@ module Nokogiri
|
|
296
296
|
@parser.parse_memory(<<-eoxml)
|
297
297
|
<p id="asdfasdf">Paragraph 1</p>
|
298
298
|
eoxml
|
299
|
-
assert_equal [["p", ["id", "asdfasdf"]]],
|
299
|
+
assert_equal [["p", [["id", "asdfasdf"]]]],
|
300
|
+
@parser.document.start_elements
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_start_element_attrs_include_namespaces
|
304
|
+
@parser.parse_memory(<<-eoxml)
|
305
|
+
<p xmlns:foo='http://foo.example.com/'>Paragraph 1</p>
|
306
|
+
eoxml
|
307
|
+
assert_equal [["p", [['xmlns:foo', 'http://foo.example.com/']]]],
|
300
308
|
@parser.document.start_elements
|
301
309
|
end
|
302
310
|
|
@@ -6,6 +6,56 @@ module Nokogiri
|
|
6
6
|
module XML
|
7
7
|
module SAX
|
8
8
|
class TestParserContext < Nokogiri::SAX::TestCase
|
9
|
+
def setup
|
10
|
+
@xml = '<hello>
|
11
|
+
|
12
|
+
world
|
13
|
+
<inter>
|
14
|
+
<net>
|
15
|
+
</net>
|
16
|
+
</inter>
|
17
|
+
|
18
|
+
</hello>'
|
19
|
+
end
|
20
|
+
|
21
|
+
class Counter < Nokogiri::XML::SAX::Document
|
22
|
+
attr_accessor :context, :lines, :columns
|
23
|
+
def initialize
|
24
|
+
@context = nil
|
25
|
+
@lines = []
|
26
|
+
@columns = []
|
27
|
+
end
|
28
|
+
|
29
|
+
def start_element name, attrs = []
|
30
|
+
@lines << [name, context.line]
|
31
|
+
@columns << [name, context.column]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_line_numbers
|
36
|
+
sax_handler = Counter.new
|
37
|
+
|
38
|
+
parser = Nokogiri::XML::SAX::Parser.new(sax_handler)
|
39
|
+
parser.parse(@xml) do |ctx|
|
40
|
+
sax_handler.context = ctx
|
41
|
+
end
|
42
|
+
|
43
|
+
assert_equal [["hello", 1], ["inter", 4], ["net", 5]],
|
44
|
+
sax_handler.lines
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_column_numbers
|
48
|
+
sax_handler = Counter.new
|
49
|
+
|
50
|
+
parser = Nokogiri::XML::SAX::Parser.new(sax_handler)
|
51
|
+
parser.parse(@xml) do |ctx|
|
52
|
+
sax_handler.context = ctx
|
53
|
+
end
|
54
|
+
|
55
|
+
assert_equal [["hello", 7], ["inter", 7], ["net", 9]],
|
56
|
+
sax_handler.columns
|
57
|
+
end
|
58
|
+
|
9
59
|
def test_replace_entities
|
10
60
|
pc = ParserContext.new StringIO.new('<root />'), 'UTF-8'
|
11
61
|
pc.replace_entities = false
|