assert_xpath 0.4.2 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|