assert_xpath 0.4.2 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/assert_css.rb +52 -0
- data/lib/assert_javascript.rb +1 -1
- data/lib/assert_xpath.rb +94 -83
- data/lib/jsToXml.pl +0 -0
- data/lib/rdoc_patch.rb +254 -0
- metadata +77 -47
- data/lib/assert_xpath.rb~ +0 -997
data/lib/assert_css.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/assert_xpath.rb'
|
2
|
+
require 'css_parser'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
|
6
|
+
module AssertCSS
|
7
|
+
|
8
|
+
def assert_css(block)
|
9
|
+
@_cp ||= CssParser::Parser.new
|
10
|
+
@_cp.add_block!(block)
|
11
|
+
end
|
12
|
+
|
13
|
+
# from http://www.w3.org/TR/CSS21/page.html#page-selectors
|
14
|
+
|
15
|
+
def assert_css_selector(selector)
|
16
|
+
raise 'selector must be a string' unless selector.kind_of? String
|
17
|
+
# ERGO why no return me a RuleSet??
|
18
|
+
return @_cp.find_by_selector(selector)
|
19
|
+
end
|
20
|
+
|
21
|
+
def _find_css_style(selector, rule)
|
22
|
+
@_cp.each_rule_set do |rule_set|
|
23
|
+
if rule_set.selectors.include?(selector) and
|
24
|
+
value = rule_set.get_value(rule)
|
25
|
+
return value.sub(/;$/, '')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def assert_css_public_folder(root)
|
32
|
+
@_public_folder = root
|
33
|
+
end
|
34
|
+
|
35
|
+
def assert_css_style(selector, rule)
|
36
|
+
if selector.respond_to? :delete_attribute
|
37
|
+
#p selector.name
|
38
|
+
return _find_css_style(selector.name, rule)
|
39
|
+
else
|
40
|
+
_find_css_style(selector, rule) or
|
41
|
+
flunk "#{selector}{#{rule}} not found"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def assert_style(path = :style)
|
46
|
+
assert_any_xpath path do |style|
|
47
|
+
assert_css style.text
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/assert_javascript.rb
CHANGED
@@ -244,7 +244,7 @@ module AssertJavaScript
|
|
244
244
|
splitter = using(:libxml?) ? '&' : '&'
|
245
245
|
query.split(splitter).each do |item|
|
246
246
|
key, value = item.split('=')
|
247
|
-
params[key.to_sym] = CGI::unescape(value)
|
247
|
+
params[key.to_sym] = CGI::unescape(value || '')
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
data/lib/assert_xpath.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
require 'rexml/document'
|
2
2
|
require 'stringio'
|
3
|
+
require 'rubygems'
|
3
4
|
require 'libxml' # FIXME soften that requirement!
|
5
|
+
require 'xml'
|
4
6
|
|
5
7
|
RAILS_ENV = ENV.fetch('RAILS_ENV', 'test') unless defined?(RAILS_ENV)
|
6
8
|
AFE = Test::Unit::AssertionFailedError unless defined?(AFE)
|
7
9
|
|
8
10
|
=begin
|
9
11
|
#:stopdoc:
|
10
|
-
# "We had so much fun robbing the bank we forgot to take the money"
|
12
|
+
# "We had so much fun robbing the bank we forgot to take the money"
|
11
13
|
#
|
12
14
|
# ERGO comic book: programmers hunting bugs portrayed as big game hunters in jungle
|
13
|
-
|
15
|
+
|
14
16
|
# ERGO use length not size
|
15
17
|
|
16
18
|
# ERGO complain to ZenTest forum that
|
@@ -75,7 +77,7 @@ module AssertXPath
|
|
75
77
|
def symbolic?(index)
|
76
78
|
return index.to_s if (index.kind_of? String or index.kind_of? Symbol)
|
77
79
|
end
|
78
|
-
|
80
|
+
|
79
81
|
def[](index)
|
80
82
|
if symbol = symbolic?(index)
|
81
83
|
return attributes[symbol] if attributes.has_key? symbol
|
@@ -103,7 +105,7 @@ module AssertXPath
|
|
103
105
|
|
104
106
|
if block
|
105
107
|
varz = instance_variables
|
106
|
-
|
108
|
+
|
107
109
|
attributes.each do |key, value|
|
108
110
|
if identifiable?(key) # deal if the key ain't a valid variable
|
109
111
|
key = "@#{ key }"
|
@@ -118,15 +120,15 @@ module AssertXPath
|
|
118
120
|
ensure # put them back!
|
119
121
|
stash.each{|key, value| instance_variable_set(key, value) }
|
120
122
|
end # this utterly sick convenience helps Ruby {@id} look like XPathic [@id]
|
121
|
-
|
123
|
+
|
122
124
|
end
|
123
|
-
|
125
|
+
|
124
126
|
# ERGO document me
|
125
127
|
def drill(&block)
|
126
128
|
if block
|
127
129
|
# ERGO harmonize with bang! version
|
128
130
|
# ERGO deal if the key ain't a valid variable
|
129
|
-
|
131
|
+
|
130
132
|
unless tribute(block) # ERGO pass in self (node)?
|
131
133
|
sib = self
|
132
134
|
nil while (sib = sib.next_sibling) and sib.node_type != :element
|
@@ -136,7 +138,7 @@ p sib # ERGO do tests ever get here?
|
|
136
138
|
raise Test::Unit::AssertionFailedError.new("can't find beyond <#{xpath}>")
|
137
139
|
end
|
138
140
|
end
|
139
|
-
|
141
|
+
|
140
142
|
return self
|
141
143
|
# ERGO if block returns false/nil, find siblings until it passes.
|
142
144
|
# throw a test failure if it don't.
|
@@ -147,7 +149,7 @@ end
|
|
147
149
|
|
148
150
|
# ERGO node.descendant{ @type == 'text' and @id == 'foo' }.value
|
149
151
|
# ERGO node..a_descendant - overload ..
|
150
|
-
|
152
|
+
|
151
153
|
def _bequeath_attributes(node) #:nodoc:
|
152
154
|
return node if node.kind_of?(::Hpricot::Elem) or node.kind_of?(::Hpricot::Doc)
|
153
155
|
# ERGO shouldn't this be in a stinkin' module??
|
@@ -188,21 +190,21 @@ module AssertXPath
|
|
188
190
|
end
|
189
191
|
|
190
192
|
class HpricotHelper < XmlHelper #:nodoc:
|
191
|
-
def hpricot? ; true end
|
193
|
+
def hpricot? ; true end
|
192
194
|
def symbol_to_xpath(tag) tag.to_s end
|
193
195
|
def assert_xml(suite, *args, &block)
|
194
196
|
return suite.assert_hpricot(*args, &block)
|
195
197
|
end
|
196
198
|
end
|
197
|
-
|
199
|
+
|
198
200
|
class LibxmlHelper < XmlHelper #:nodoc:
|
199
|
-
def libxml? ; true end
|
201
|
+
def libxml? ; true end
|
200
202
|
def symbol_to_xpath(tag) "descendant-or-self::#{tag}" end
|
201
203
|
def assert_xml(suite, *args, &block)
|
202
204
|
return suite.assert_libxml(*args, &block)
|
203
205
|
end
|
204
206
|
end
|
205
|
-
|
207
|
+
|
206
208
|
class RexmlHelper < XmlHelper #:nodoc:
|
207
209
|
def rexml? ; true end
|
208
210
|
def symbol_to_xpath(tag) ".//#{tag}" end
|
@@ -210,13 +212,13 @@ module AssertXPath
|
|
210
212
|
return suite.assert_rexml(*args, &block)
|
211
213
|
end
|
212
214
|
end
|
213
|
-
|
214
|
-
# Subsequent +assert_xml+ calls will use
|
215
|
-
# Hpricot[http://code.whytheluckystiff.net/hpricot/].
|
215
|
+
|
216
|
+
# Subsequent +assert_xml+ calls will use
|
217
|
+
# Hpricot[http://code.whytheluckystiff.net/hpricot/].
|
216
218
|
# (Alternately,
|
217
219
|
# +assert_hpricot+ will run one assertion in Hpricot mode.)
|
218
|
-
# Put +invoke_hpricot+ into +setup+() method, to
|
219
|
-
# run entire suites in this mode. These test cases
|
220
|
+
# Put +invoke_hpricot+ into +setup+() method, to
|
221
|
+
# run entire suites in this mode. These test cases
|
220
222
|
# explore some differences between the two assertion systems:
|
221
223
|
# %transclude AssertXPathSuite#test_assert_long_xpath
|
222
224
|
#
|
@@ -225,11 +227,11 @@ module AssertXPath
|
|
225
227
|
@helper = HpricotHelper.new
|
226
228
|
end
|
227
229
|
|
228
|
-
# Subsequent +assert_xml+ calls will use
|
229
|
-
# LibXML[http://libxml.rubyforge.org/].
|
230
|
+
# Subsequent +assert_xml+ calls will use
|
231
|
+
# LibXML[http://libxml.rubyforge.org/].
|
230
232
|
# (Alternately,
|
231
233
|
# +assert_libxml+ will run one assertion in Hpricot mode.)
|
232
|
-
# Put +invoke_libxml+ into +setup+() method, to
|
234
|
+
# Put +invoke_libxml+ into +setup+() method, to
|
233
235
|
# run entire suites in this mode.
|
234
236
|
#
|
235
237
|
def invoke_libxml(favorite_flavor = :html)
|
@@ -241,7 +243,7 @@ module AssertXPath
|
|
241
243
|
def _doc_type # ERGO document all these!
|
242
244
|
{ :html => '<!DOCTYPE HTML PUBLIC ' +
|
243
245
|
'"-//W3C//DTD HTML 4.01 Transitional//EN" '+
|
244
|
-
'"http://www.w3.org/TR/html4/loose.dtd">',
|
246
|
+
'"http://www.w3.org/TR/html4/loose.dtd">',
|
245
247
|
:xhtml => '<!DOCTYPE html PUBLIC ' +
|
246
248
|
'"-//W3C//DTD XHTML 1.0 Transitional//EN" ' +
|
247
249
|
'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >',
|
@@ -251,8 +253,8 @@ module AssertXPath
|
|
251
253
|
private :_doc_type
|
252
254
|
|
253
255
|
# ERGO what happens to assert_js_replace_html bearing entities??
|
254
|
-
|
255
|
-
# Subsequent +assert_xml+ calls will use REXML. See
|
256
|
+
|
257
|
+
# Subsequent +assert_xml+ calls will use REXML. See
|
256
258
|
# +invoke_hpricot+ to learn the various differences between the
|
257
259
|
# two systems
|
258
260
|
def invoke_rexml
|
@@ -269,12 +271,12 @@ module AssertXPath
|
|
269
271
|
# call-seq:
|
270
272
|
# assert_xml(xml = @response.body <em>[, assert_xpath arguments]</em>) -> @xdoc, or assert_xpath's return value
|
271
273
|
#
|
272
|
-
# Assertions based on +assert_xpath+ will call this automatically if
|
274
|
+
# Assertions based on +assert_xpath+ will call this automatically if
|
273
275
|
# the secret <code>@xdoc</code> is +nil+. This implies we may freely call
|
274
276
|
# +assert_xpath+ after any method that populates <code>@response.body</code>
|
275
277
|
# -- if <code>@xdoc</code> is +nil+. When in doubt, call +assert_xml+ explicitly
|
276
278
|
#
|
277
|
-
# +assert_xml+ also translates the contents of +assert_select+ nodes. Use this to
|
279
|
+
# +assert_xml+ also translates the contents of +assert_select+ nodes. Use this to
|
278
280
|
# bridge assertions from one system to another. For example:
|
279
281
|
#
|
280
282
|
# Returns the first node in the XML
|
@@ -320,7 +322,7 @@ module AssertXPath
|
|
320
322
|
raise e unless e.message =~ /attempted adding second root element to document/
|
321
323
|
@xdoc = REXML::Document.new("<xhtml>#{ contents }</xhtml>")
|
322
324
|
end
|
323
|
-
|
325
|
+
|
324
326
|
_bequeath_attributes(@xdoc)
|
325
327
|
assert_xpath(*args, &block) if args != []
|
326
328
|
return (assert_xpath('/*') rescue nil) if @xdoc
|
@@ -338,13 +340,13 @@ module AssertXPath
|
|
338
340
|
def assert_libxml(*args, &block)
|
339
341
|
xml = args.shift || @xdoc || @response.body
|
340
342
|
xhtml = xml.to_s
|
341
|
-
|
343
|
+
|
342
344
|
# CONSIDER fix this like at the source??
|
343
345
|
xhtml.gsub!('<![CDATA[>', '')
|
344
346
|
xhtml.gsub!('<![CDATA[', '')
|
345
347
|
xhtml.gsub!('//]]]]>', '')
|
346
348
|
xhtml.gsub!(']]>', '')
|
347
|
-
|
349
|
+
|
348
350
|
if xhtml !~ /^\<\!DOCTYPE\b/ and xhtml !~ /\<\?xml\b/
|
349
351
|
xhtml = _doc_type[@_favorite_flavor || :html] + "\n" + xhtml if _doc_type[@_favorite_flavor]
|
350
352
|
end # ERGO document we pass HTML level into invoker
|
@@ -369,7 +371,7 @@ module AssertXPath
|
|
369
371
|
#puts doc.debug_dump
|
370
372
|
@xdoc = doc.root
|
371
373
|
# @xdoc.namespace ||= XML::NS.new('')
|
372
|
-
|
374
|
+
|
373
375
|
#pp (@xdoc.root.public_methods - public_methods).sort
|
374
376
|
return assert_xpath(*args, &block) if args.length > 0
|
375
377
|
return @xdoc
|
@@ -379,15 +381,15 @@ module AssertXPath
|
|
379
381
|
@helper ||= RexmlHelper.new # ERGO escallate this!
|
380
382
|
return @helper.send(kode)
|
381
383
|
end
|
382
|
-
|
384
|
+
|
383
385
|
# FIXME test that the helper system withstands this effect:
|
384
386
|
# ""
|
385
|
-
|
387
|
+
|
386
388
|
# %html <a name='assert_hpricot'></a>
|
387
389
|
#
|
388
390
|
# This parses one XML string using Hpricot, so subsequent
|
389
391
|
# calls to +assert_xpath+ will use Hpricot expressions.
|
390
|
-
# This method does not depend on +invoke_hpricot+, and
|
392
|
+
# This method does not depend on +invoke_hpricot+, and
|
391
393
|
# subsequent test cases will run in their suite's mode.
|
392
394
|
#
|
393
395
|
# Example:
|
@@ -406,22 +408,22 @@ module AssertXPath
|
|
406
408
|
|
407
409
|
# ENCORE Bus to Julian! (-;
|
408
410
|
# ERGO why %html <a name='assert_xpath' /> screws up?
|
409
|
-
|
411
|
+
|
410
412
|
# %html <a name='assert_xpath'></a>
|
411
413
|
#
|
412
414
|
# Return the first XML node matching a query string. Depends on +assert_xml+
|
413
415
|
# to populate our secret internal REXML::Element, <code>@xdoc</code>
|
414
|
-
# * +xpath+ - a query string describing a path among XML nodes.
|
416
|
+
# * +xpath+ - a query string describing a path among XML nodes.
|
415
417
|
# See: {XPath Tutorial Roundup}[http://krow.livejournal.com/523993.html]
|
416
418
|
# * +diagnostic+ - optional string to add to failure message
|
417
|
-
# * <code>block|node|</code> - optional block containing assertions, based on +assert_xpath+,
|
419
|
+
# * <code>block|node|</code> - optional block containing assertions, based on +assert_xpath+,
|
418
420
|
# which operate on this node as the XPath '.' current +node+
|
419
421
|
# Returns the obtained REXML::Element +node+
|
420
422
|
#
|
421
423
|
# Examples:
|
422
424
|
#
|
423
425
|
# render :partial => 'my_partial'
|
424
|
-
#
|
426
|
+
#
|
425
427
|
# assert_xpath '/table' do |table|
|
426
428
|
# assert_xpath './/p[ @class = "brown_text" ]/a' do |a|
|
427
429
|
# assert_equal user.login, a.text # <-- native <code>REXML::Element#text</code> method
|
@@ -432,14 +434,16 @@ module AssertXPath
|
|
432
434
|
#
|
433
435
|
# %transclude AssertXPathSuite#test_assert_xpath
|
434
436
|
#
|
435
|
-
# See: AssertXPathSuite#test_indent_xml,
|
437
|
+
# See: AssertXPathSuite#test_indent_xml,
|
436
438
|
# {XPath Checker}[https://addons.mozilla.org/en-US/firefox/addon/1095]
|
437
439
|
#
|
438
|
-
def assert_xpath(
|
440
|
+
def assert_xpath(*args, &block)
|
441
|
+
return assert_tag_id(*args, &block) if args.length > 1 and args[1].kind_of?(Symbol) or args[1].kind_of?(Hash)
|
439
442
|
# return assert_any_xpath(xpath, diagnostic) {
|
440
443
|
# block.call(@xdoc) if block
|
441
444
|
# true
|
442
445
|
# }
|
446
|
+
xpath, diagnostic = args
|
443
447
|
stash_xdoc do
|
444
448
|
xpath = symbol_to_xpath(xpath)
|
445
449
|
node = @xdoc.search(xpath).first
|
@@ -462,7 +466,9 @@ module AssertXPath
|
|
462
466
|
#
|
463
467
|
# %transclude AssertXPathSuite#test_deny_xpath
|
464
468
|
#
|
465
|
-
def deny_xpath(
|
469
|
+
def deny_xpath(*args)
|
470
|
+
return deny_tag_id(*args) if args.length > 1 and args[1].kind_of?(Symbol) or args[1].kind_of?(Hash)
|
471
|
+
xpath, diagnostic = args
|
466
472
|
@xdoc or assert_xml
|
467
473
|
xpath = symbol_to_xpath(xpath)
|
468
474
|
|
@@ -471,12 +477,12 @@ module AssertXPath
|
|
471
477
|
end
|
472
478
|
|
473
479
|
# Search nodes for a matching XPath whose <code>AssertXPath::Element#inner_text</code> matches a Regular Expression. Depends on +assert_xml+
|
474
|
-
# * +xpath+ - a query string describing a path among XML nodes.
|
480
|
+
# * +xpath+ - a query string describing a path among XML nodes.
|
475
481
|
# See: {XPath Tutorial Roundup}[http://krow.livejournal.com/523993.html]
|
476
482
|
# * +matcher+ - optional Regular Expression to test node contents
|
477
483
|
# * +diagnostic+ - optional string to add to failure message
|
478
484
|
# * <code>block|node|</code> - optional block called once per match.
|
479
|
-
# If this block returns a value other than +false+ or +nil+,
|
485
|
+
# If this block returns a value other than +false+ or +nil+,
|
480
486
|
# assert_any_xpath stops looping and returns the current +node+
|
481
487
|
#
|
482
488
|
# Example:
|
@@ -495,7 +501,7 @@ module AssertXPath
|
|
495
501
|
if !using(:rexml?)
|
496
502
|
@xdoc.search(xpath) do |@xdoc|
|
497
503
|
found_any = true
|
498
|
-
|
504
|
+
|
499
505
|
if @xdoc.inner_text =~ matcher
|
500
506
|
found_match = true
|
501
507
|
_bequeath_attributes(@xdoc)
|
@@ -506,7 +512,7 @@ module AssertXPath
|
|
506
512
|
else # ERGO merge!
|
507
513
|
@xdoc.each_element(xpath) do |@xdoc|
|
508
514
|
found_any = true
|
509
|
-
|
515
|
+
|
510
516
|
if @xdoc.inner_text =~ matcher
|
511
517
|
found_match = true
|
512
518
|
_bequeath_attributes(@xdoc)
|
@@ -519,10 +525,10 @@ module AssertXPath
|
|
519
525
|
|
520
526
|
found_any or
|
521
527
|
flunk_xpath(diagnostic, "should find xpath <#{_esc xpath}>")
|
522
|
-
|
528
|
+
|
523
529
|
found_match or
|
524
530
|
flunk_xpath(
|
525
|
-
diagnostic,
|
531
|
+
diagnostic,
|
526
532
|
"can find xpath <#{_esc xpath}> but can't find pattern <?>",
|
527
533
|
matcher
|
528
534
|
)
|
@@ -538,12 +544,12 @@ module AssertXPath
|
|
538
544
|
#
|
539
545
|
# Contrived example:
|
540
546
|
# assert_xml '<heathrow><terminal>5</terminal><lean>methods</lean></heathrow>'
|
541
|
-
#
|
547
|
+
#
|
542
548
|
# assert_raise_message Test::Unit::AssertionFailedError,
|
543
549
|
# /all xpath.*\.\/\/lean.*not have.*methods/ do
|
544
550
|
# deny_any_xpath :lean, /methods/
|
545
551
|
# end
|
546
|
-
#
|
552
|
+
#
|
547
553
|
# deny_any_xpath :lean, /denver/
|
548
554
|
#
|
549
555
|
# See: AssertXPathSuite#test_deny_any_xpath,
|
@@ -556,7 +562,7 @@ module AssertXPath
|
|
556
562
|
assert_any_xpath xpath, nil, diagnostic do |node|
|
557
563
|
if node.inner_text =~ matcher
|
558
564
|
flunk_xpath(
|
559
|
-
diagnostic,
|
565
|
+
diagnostic,
|
560
566
|
"all xpath <#{_esc xpath}> nodes should not have pattern <?>",
|
561
567
|
matcher
|
562
568
|
)
|
@@ -567,11 +573,11 @@ module AssertXPath
|
|
567
573
|
# FIXME @helper -> @_helper
|
568
574
|
|
569
575
|
# Wraps the common idiom <code>assert_xpath('descendant-or-self::./<em>my_tag</em>[ @id = "<em>my_id</em>" ]')</code>. Depends on +assert_xml+
|
570
|
-
# * +tag+ - an XML node name, such as +div+ or +input+.
|
576
|
+
# * +tag+ - an XML node name, such as +div+ or +input+.
|
571
577
|
# If this is a <code>:symbol</code>, we prefix "<code>.//</code>"
|
572
578
|
# * +id+ - string, symbol, or hash identifying the node. ids must not contain punctuation
|
573
579
|
# * +diagnostic+ - optional string to add to failure message
|
574
|
-
# * <code>block|node|</code> - optional block containing assertions, based on
|
580
|
+
# * <code>block|node|</code> - optional block containing assertions, based on
|
575
581
|
# +assert_xpath+, which operate on this node as the XPath '.' current node.
|
576
582
|
# Returns the obtained REXML::Element +node+
|
577
583
|
#
|
@@ -651,7 +657,7 @@ module AssertXPath
|
|
651
657
|
# will repress all of Tidy's screams of horror regarding the quality of your HTML.
|
652
658
|
# The resulting XHTML loads into +assert_xml+. Use this to retrofit +assert_xpath+ tests
|
653
659
|
# to less-than-pristine HTML.
|
654
|
-
#
|
660
|
+
#
|
655
661
|
# +assert_tidy+ obeys +invoke_rexml+ and +invoke_hpricot+, to
|
656
662
|
# select its HTML parser
|
657
663
|
#
|
@@ -672,18 +678,18 @@ module AssertXPath
|
|
672
678
|
File.open(scratch_html, 'w'){|f| f.write(messy) }
|
673
679
|
gripes = `tidy -eq #{scratch_html} 2>&1`
|
674
680
|
gripes.split("\n")
|
675
|
-
|
681
|
+
|
676
682
|
# TODO kvetch about client_input_channel_req: channel 0 rtype keepalive@openssh.com reply 1
|
677
|
-
|
683
|
+
|
678
684
|
puts gripes if verbosity == :verbose
|
679
|
-
|
685
|
+
|
680
686
|
puts gripes.reject{|g|
|
681
687
|
g =~ / - Info\: / or
|
682
688
|
g =~ /Warning\: missing \<\!DOCTYPE\> declaration/ or
|
683
689
|
g =~ /proprietary attribute/ or
|
684
690
|
g =~ /lacks "(summary|alt)" attribute/
|
685
691
|
} if verbosity == :noisy
|
686
|
-
|
692
|
+
|
687
693
|
assert_xml `tidy -wrap 1001 -asxhtml #{ scratch_html } 2>/dev/null`
|
688
694
|
# CONSIDER that should report serious HTML deformities
|
689
695
|
end # CONSIDER how to tidy <% escaped %> eRB code??
|
@@ -694,8 +700,7 @@ module AssertXPath
|
|
694
700
|
|
695
701
|
private
|
696
702
|
|
697
|
-
# ERGO
|
698
|
-
# ERGO then update documentation of those who use this
|
703
|
+
# ERGO update documentation of those who use this
|
699
704
|
def symbol_to_xpath(tag)
|
700
705
|
return tag unless tag.class == Symbol
|
701
706
|
@helper or using :libxml? # prop-ulates @helper
|
@@ -709,7 +714,15 @@ module AssertXPath
|
|
709
714
|
end )
|
710
715
|
|
711
716
|
options.merge!(diagnostic) if diagnostic.kind_of? Hash
|
712
|
-
|
717
|
+
|
718
|
+
predicate = options.map{|k,v|
|
719
|
+
if k.kind_of? Symbol
|
720
|
+
"@#{k} = \"#{v}\""
|
721
|
+
else
|
722
|
+
"#{k} = #{v}"
|
723
|
+
end
|
724
|
+
}.join(' and ')
|
725
|
+
|
713
726
|
return symbol_to_xpath(tag) + "[ #{predicate} ]"
|
714
727
|
end
|
715
728
|
|
@@ -752,7 +765,7 @@ module Relevate
|
|
752
765
|
def relevant?
|
753
766
|
return ! blank?
|
754
767
|
end
|
755
|
-
|
768
|
+
|
756
769
|
def relevance
|
757
770
|
return to_s if relevant?
|
758
771
|
end
|
@@ -776,8 +789,8 @@ NilClass.send :include, Relevate
|
|
776
789
|
String .send :include, Relevate
|
777
790
|
|
778
791
|
#:enddoc:
|
779
|
-
|
780
|
-
# props: http://www.intertwingly.net/blog/2007/11/02/MonkeyPatch-for-Ruby-1-8-6
|
792
|
+
|
793
|
+
# props: http://www.intertwingly.net/blog/2007/11/02/MonkeyPatch-for-Ruby-1-8-6
|
781
794
|
doc = REXML::Document.new '<doc xmlns="ns"><item name="foo"/></doc>'
|
782
795
|
if not doc.root.elements["item[@name='foo']"]
|
783
796
|
class REXML::Element
|
@@ -795,7 +808,7 @@ end
|
|
795
808
|
module Hpricot #:nodoc:
|
796
809
|
class Doc #:nodoc:
|
797
810
|
include AssertXPath::CommonXPathExtensions
|
798
|
-
|
811
|
+
|
799
812
|
def [](index) #:nodoc:
|
800
813
|
return root[index] if symbolic? index
|
801
814
|
super
|
@@ -823,14 +836,14 @@ module Hpricot #:nodoc:
|
|
823
836
|
|
824
837
|
class Elem #:nodoc:
|
825
838
|
include AssertXPath::CommonXPathExtensions
|
826
|
-
|
839
|
+
|
827
840
|
def [](index) #:nodoc:
|
828
841
|
# ERGO do this conflict with anything?
|
829
842
|
if symbol = symbolic?(index)
|
830
843
|
return attributes[symbol] if attributes.has_key? symbol
|
831
844
|
raise_magic_member_not_found(symbol, caller)
|
832
845
|
end
|
833
|
-
|
846
|
+
|
834
847
|
super
|
835
848
|
end
|
836
849
|
|
@@ -855,7 +868,7 @@ module Hpricot #:nodoc:
|
|
855
868
|
raise Test::Unit::AssertionFailedError.new("can't find beyond <#{_esc xpath}>")
|
856
869
|
end
|
857
870
|
end
|
858
|
-
|
871
|
+
|
859
872
|
return self
|
860
873
|
# ERGO if block returns false/nil, find siblings until it passes.
|
861
874
|
# throw a test failure if it don't.
|
@@ -864,7 +877,7 @@ module Hpricot #:nodoc:
|
|
864
877
|
|
865
878
|
def method_missing(*args, &block) #:nodoc:
|
866
879
|
symbol = args.shift.to_s.sub(/\!$/, '')
|
867
|
-
|
880
|
+
|
868
881
|
children.grep(Hpricot::Elem).each do |kid|
|
869
882
|
if kid.name == symbol
|
870
883
|
kid.tribute(block)
|
@@ -893,24 +906,22 @@ module XML
|
|
893
906
|
return [find_first(xpath, "x:http://www.w3.org/1999/xhtml")]
|
894
907
|
end
|
895
908
|
alias each_element search
|
896
|
-
|
909
|
+
|
897
910
|
def text
|
898
|
-
#p text?
|
899
911
|
find_first('text()').to_s
|
900
|
-
#text? ? content : ''
|
901
912
|
end
|
902
|
-
|
913
|
+
|
903
914
|
def inner_text(interstitial = '')
|
904
915
|
array = []
|
905
916
|
self.find( 'descendant-or-self::text()' ).each{|x| array << x }
|
906
917
|
return array.join(interstitial)
|
907
918
|
end # ERGO match??
|
908
919
|
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
920
|
+
# def attributes
|
921
|
+
# hash = {}
|
922
|
+
# each_attr{|attr| hash[attr.name] = attr.value }
|
923
|
+
# return hash # ERGO uh, was there a leaner way??
|
924
|
+
# end
|
914
925
|
|
915
926
|
def [](index) #:nodoc:
|
916
927
|
return attributes[index.to_s] || super
|
@@ -927,8 +938,8 @@ module XML
|
|
927
938
|
# ERGO use the define_method trick here
|
928
939
|
symbol = args.shift.to_s
|
929
940
|
symbol.sub!(/\!$/, '')
|
930
|
-
|
931
|
-
kid = if symbol == '/'
|
941
|
+
|
942
|
+
kid = if symbol == '/'
|
932
943
|
find_first('/')
|
933
944
|
else
|
934
945
|
find_first("./#{symbol}")
|
@@ -943,22 +954,22 @@ end
|
|
943
954
|
|
944
955
|
class REXML::Element
|
945
956
|
include AssertXPath::CommonXPathExtensions
|
946
|
-
|
957
|
+
|
947
958
|
# Semi-private method to match Hpricotic abilities
|
948
959
|
def search(xpath)
|
949
960
|
return self.each_element( xpath ){}
|
950
961
|
end
|
951
|
-
|
962
|
+
|
952
963
|
def method_missing(*args, &block) #:nodoc:
|
953
964
|
symbol = args.shift
|
954
|
-
|
965
|
+
|
955
966
|
each_element("./#{symbol}") do |kid|
|
956
967
|
return _bequeath_attributes(kid).drill(&block)
|
957
968
|
end # ERGO element/:child - def/
|
958
969
|
|
959
970
|
raise_magic_member_not_found(symbol, caller) # ERGO repurpose!
|
960
971
|
end # ERGO convert attribute chain to xpath
|
961
|
-
|
972
|
+
|
962
973
|
# Returns all text contents from a node and its descendants
|
963
974
|
#
|
964
975
|
# Example:
|
@@ -975,7 +986,7 @@ class REXML::Element
|
|
975
986
|
node = each_element(xpath.to_s){}.first
|
976
987
|
return _bequeath_attributes(node) if node
|
977
988
|
end # ERGO test that attributes are bequeathed!
|
978
|
-
|
989
|
+
|
979
990
|
alias :/ get_path
|
980
991
|
|
981
992
|
# ERGO use set_backtrace to seat the backtracer to your code
|