assert2 0.3.2 → 0.3.3
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/assert2.rb +323 -216
- data/lib/assert2/flunk.rb +87 -0
- data/lib/assert2/null_reflector.rb +0 -0
- data/lib/assert2/ripdoc.html.erb +182 -0
- data/lib/assert2/ripdoc.rb +413 -0
- data/lib/assert2/ripper_reflector.rb +726 -0
- data/lib/{ruby_reflector.rb → assert2/rubynode_reflector.rb} +100 -71
- data/lib/assert2/xpath.rb +159 -0
- metadata +47 -41
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rubynode'
|
3
1
|
require 'pp'
|
4
2
|
|
5
3
|
|
6
|
-
module
|
7
|
-
|
4
|
+
module Test; module Unit; module Assertions
|
5
|
+
|
8
6
|
# ERGO
|
9
7
|
# :bmethod => [:cval],
|
10
8
|
# :cfunc => [:argc, :cfnc],
|
@@ -34,101 +32,103 @@ module RubyNodeReflector
|
|
34
32
|
#
|
35
33
|
def reflect(&block)
|
36
34
|
result = block.call
|
37
|
-
rf = RubyReflector.new
|
35
|
+
rf = RubyReflector.new
|
36
|
+
rf.block = block
|
38
37
|
|
39
38
|
begin
|
40
39
|
waz = rf.colorize?
|
41
40
|
rf.colorize(false)
|
42
|
-
return rf.result + arrow_result(result) + "\n" + rf.format_evaluations
|
41
|
+
return rf.result + rf.arrow_result(result) + "\n" + rf.format_evaluations
|
43
42
|
ensure
|
44
43
|
rf.colorize(waz)
|
45
44
|
end
|
46
45
|
end
|
47
|
-
|
48
|
-
def arrow_result(result) #:nodoc:
|
49
|
-
return "\t--> #{ result.inspect }"
|
50
|
-
end
|
51
|
-
private :arrow_result
|
52
|
-
|
46
|
+
|
53
47
|
# This +reflect+s a block of code, /without/ evaluating it.
|
54
48
|
# The function only compiles the source and reflects it as
|
55
49
|
# a string of disassembled Ruby
|
56
50
|
#
|
57
51
|
def reflect_source(&block)
|
58
|
-
|
52
|
+
rf = RubyReflector.new(nil, false)
|
53
|
+
rf.block = block
|
54
|
+
return rf.result
|
59
55
|
end
|
60
56
|
|
61
57
|
# This compiles a string and +reflect+s its source...
|
62
58
|
# as another string.
|
63
59
|
#
|
64
|
-
def reflect_string(string)
|
65
|
-
rf = RubyReflector.new
|
60
|
+
def reflect_string(string)
|
61
|
+
rf = RubyReflector.new # def initialize
|
62
|
+
rf.block = proc{}
|
66
63
|
rf.reflect_values = false
|
67
64
|
# pp string.parse_to_nodes.transform
|
68
65
|
got = rf.reflect_nodes(string.parse_to_nodes)
|
69
66
|
return got
|
70
67
|
end
|
71
68
|
|
72
|
-
|
73
|
-
|
74
|
-
@@we_color = we_color
|
75
|
-
end
|
76
|
-
unless defined? BOLD
|
77
|
-
BOLD = "\e[1m"
|
78
|
-
CLEAR = "\e[0m"
|
79
|
-
end # ERGO modularize these; anneal with Win32
|
80
|
-
def colour(text, colour_code)
|
81
|
-
return colour_code + text + CLEAR if colorize?
|
82
|
-
return text
|
83
|
-
end
|
84
|
-
def colorize? # ERGO how other libraries set these options transparent??
|
85
|
-
we_color = (@@we_color rescue true ) # ERGO parens needed?
|
86
|
-
return (we_color == :always or we_color && $stdout.tty?)
|
87
|
-
end
|
88
|
-
def bold(text)
|
89
|
-
return BOLD + text + CLEAR if colorize?
|
90
|
-
return text
|
91
|
-
end
|
92
|
-
def green(text); colour(text, "\e[32m"); end
|
93
|
-
def red(text); colour(text, "\e[31m"); end
|
94
|
-
def magenta(text); colour(text, "\e[35m"); end
|
95
|
-
def blue(text); colour(text, "\e[34m"); end
|
96
|
-
def orange(text); colour(text, "\e[3Bm"); end
|
97
|
-
end
|
69
|
+
class RubyReflector # this class turns hamburger back into live cattle
|
70
|
+
HAS_RIPPER = false
|
98
71
|
|
99
|
-
|
100
|
-
|
72
|
+
begin
|
73
|
+
raise LoadError, 'whatever' if ENV['TEST_ASSERT_2_IN_1_8_7_MODE'] == 'true'
|
74
|
+
require 'rubygems'
|
75
|
+
require 'rubynode'
|
76
|
+
HAS_RUBYNODE = true
|
77
|
+
rescue LoadError
|
78
|
+
HAS_RUBYNODE = false
|
79
|
+
end
|
80
|
+
|
101
81
|
attr_reader :evaluations,
|
102
|
-
:result
|
103
|
-
|
104
|
-
|
105
|
-
|
82
|
+
:result,
|
83
|
+
:transformation
|
84
|
+
attr_writer :block,
|
85
|
+
:reflect_values
|
86
|
+
|
87
|
+
def initialize(called = nil, yo_block = nil, reflect_values = true) # note that a block, from your context, is not optional
|
88
|
+
# FIXME these args are bogus use or lose
|
106
89
|
@reflect_values = reflect_values
|
107
90
|
@evaluations = []
|
108
91
|
@result = ''
|
109
|
-
@block = block
|
110
92
|
@line = 0
|
111
|
-
|
93
|
+
self.block = yo_block
|
112
94
|
end
|
113
|
-
|
95
|
+
|
96
|
+
def block=(yo_block)
|
97
|
+
@block = yo_block and HAS_RUBYNODE and
|
98
|
+
reflect_nodes(@block.body_node)
|
99
|
+
end
|
100
|
+
|
114
101
|
def reflect_nodes(body_node)
|
115
102
|
return unless body_node
|
116
103
|
@transformation = body_node.transform(:include_node => true)
|
117
104
|
return @result = _send(@transformation)
|
118
105
|
rescue
|
119
106
|
puts "\nOffending line: #{ @line }"
|
120
|
-
# pp @transformation
|
121
|
-
# puts @result
|
122
107
|
raise
|
123
108
|
end
|
124
|
-
|
125
|
-
def
|
109
|
+
|
110
|
+
def absorb_block_args(code_fragments) # CONSIDER a suckier way of detecting
|
111
|
+
@captured_block_vars = nil # the block args is indeed remotely possible...
|
112
|
+
if code_fragments.first =~ /\|(.*)\|/ or code_fragments[1].to_s =~ /\|(.*)\|/
|
113
|
+
@captured_block_vars = $1
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def detect(expression)
|
118
|
+
expr = expression
|
119
|
+
$__args = nil
|
120
|
+
if @args and @captured_block_vars
|
121
|
+
expr = "#{@captured_block_vars} = $__args.kind_of?(Array) && $__args.length == 1 ? $__args.first : $__args\n" +
|
122
|
+
expr
|
123
|
+
$__args = @args
|
124
|
+
end
|
125
|
+
|
126
126
|
begin
|
127
|
-
intermediate = eval(
|
127
|
+
intermediate = eval(expr, @block.binding)
|
128
128
|
@evaluations << [expression, intermediate, nil]
|
129
129
|
rescue SyntaxError => e
|
130
130
|
if e.message.index('syntax error, unexpected \',\'') and expression !~ /\[ /
|
131
|
-
return
|
131
|
+
return detect('[ ' + expression + ' ]')
|
132
132
|
end # faint prayer to infinite recursion diety here! (-;
|
133
133
|
|
134
134
|
@evaluations << [expression, nil, e.message]
|
@@ -138,7 +138,7 @@ module RubyNodeReflector
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def eval_intermediate(expression)
|
141
|
-
|
141
|
+
detect(expression) if @reflect_values
|
142
142
|
return expression
|
143
143
|
end
|
144
144
|
|
@@ -552,13 +552,13 @@ p node
|
|
552
552
|
|
553
553
|
return head_(node)
|
554
554
|
end
|
555
|
-
|
555
|
+
|
556
556
|
def _splat(node)
|
557
557
|
if (head = node[:head]) and
|
558
558
|
((we_b_array = head.first == :array) or head.first == :lvar)
|
559
559
|
return '*' + nest_if(we_b_array, '[', ']'){ head_(node) }
|
560
560
|
end
|
561
|
-
|
561
|
+
|
562
562
|
return '*' + head_(node)
|
563
563
|
end # ERGO raise if any other key!
|
564
564
|
|
@@ -576,7 +576,7 @@ p node
|
|
576
576
|
lit.gsub!('\\\\', '\\') if regex
|
577
577
|
return lit
|
578
578
|
end
|
579
|
-
|
579
|
+
|
580
580
|
def _dstr(node, delim = '"')
|
581
581
|
regex = delim == '/'
|
582
582
|
expression = delim + scrape_literal(node, regex)
|
@@ -590,7 +590,7 @@ p node
|
|
590
590
|
end
|
591
591
|
end
|
592
592
|
end
|
593
|
-
|
593
|
+
|
594
594
|
return eval_intermediate(expression + delim)
|
595
595
|
end
|
596
596
|
|
@@ -598,13 +598,13 @@ p node
|
|
598
598
|
raise '_retry called with unexpected arguments' unless node == {} or node.keys == [:node]
|
599
599
|
return 'retry'
|
600
600
|
end
|
601
|
-
|
601
|
+
|
602
602
|
def recv_zero_self(node, plus = '')
|
603
603
|
recv = node[:recv]
|
604
604
|
return 'self' + plus if recv == 0
|
605
605
|
return recv_(node, plus)
|
606
606
|
end
|
607
|
-
|
607
|
+
|
608
608
|
def _attrasgn(node)
|
609
609
|
recv, args = node.values_at(:recv, :args)
|
610
610
|
|
@@ -816,16 +816,45 @@ p node
|
|
816
816
|
return head_(node) + ', *' +
|
817
817
|
nest_if(node[:body].first == :array, '[', ']'){ body_(node) }
|
818
818
|
end
|
819
|
-
|
819
|
+
|
820
|
+
def diagnose(diagnostic, result, called, options, block, additional_diagnostics)
|
821
|
+
@__additional_diagnostics = additional_diagnostics
|
822
|
+
@__additional_diagnostics.unshift diagnostic
|
823
|
+
self.args = options.fetch(:args, [])
|
824
|
+
rf = self
|
825
|
+
polarity = 'assert{ '
|
826
|
+
lines = rf.split_and_read(called)
|
827
|
+
|
828
|
+
if lines.first =~ /^\s*(assert|deny)/
|
829
|
+
polarity = $1 + '{ '
|
830
|
+
end
|
831
|
+
|
832
|
+
rf.absorb_block_args lines
|
833
|
+
rf.block = block
|
834
|
+
effect = " - should #{ 'not ' if polarity =~ /deny/ }pass\n"
|
835
|
+
|
836
|
+
report = rf.magenta(polarity) + rf.bold(rf.result) + rf.magenta(" }") +
|
837
|
+
rf.red(arrow_result(result) + effect) +
|
838
|
+
rf.format_evaluations
|
839
|
+
|
840
|
+
return __build_message(report)
|
841
|
+
end
|
842
|
+
|
843
|
+
def arrow_result(result) #:nodoc:
|
844
|
+
return "\t--> #{ result.inspect }"
|
845
|
+
end
|
846
|
+
|
820
847
|
end
|
821
848
|
|
822
|
-
end
|
849
|
+
end; end; end
|
823
850
|
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
851
|
+
unless [].respond_to? :in_groups_of
|
852
|
+
class Array
|
853
|
+
def in_groups_of(number, fill_with = nil, &block)
|
854
|
+
require 'enumerator'
|
855
|
+
collection = dup
|
856
|
+
collection << fill_with until collection.size.modulo(number).zero?
|
857
|
+
collection.each_slice(number, &block)
|
830
858
|
end
|
859
|
+
end
|
831
860
|
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'assert2'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'rexml/entity'
|
5
|
+
require 'rexml/formatters/pretty'
|
6
|
+
|
7
|
+
module Test; module Unit; module Assertions
|
8
|
+
|
9
|
+
def assert_xhtml(xhtml)
|
10
|
+
return _assert_xml(xhtml) # , XML::HTMLParser)
|
11
|
+
end
|
12
|
+
|
13
|
+
def _assert_xml(xml) #, parser = XML::Parser)
|
14
|
+
if false
|
15
|
+
xp = parser.new()
|
16
|
+
xp.string = xml
|
17
|
+
|
18
|
+
if XML.respond_to? :'default_pedantic_parser='
|
19
|
+
XML.default_pedantic_parser = true
|
20
|
+
else
|
21
|
+
XML::Parser.default_pedantic_parser = true
|
22
|
+
end # CONSIDER uh, figure out the best libxml-ruby??
|
23
|
+
|
24
|
+
@xdoc = xp.parse.root
|
25
|
+
else
|
26
|
+
# CONSIDER figure out how entities are supposed to work!!
|
27
|
+
xml = xml.gsub('—', '--')
|
28
|
+
doc = REXML::Document.new(xml)
|
29
|
+
@xdoc = doc.root
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class AssertXPathArguments
|
34
|
+
|
35
|
+
def initialize(path = '', id = nil, options = {})
|
36
|
+
@subs = {}
|
37
|
+
@xpath = ''
|
38
|
+
to_xpath(path, id, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :subs
|
42
|
+
attr_reader :xpath
|
43
|
+
|
44
|
+
def to_conditions(hash)
|
45
|
+
xml_attribute_name = /^[a-z][_a-z0-9]+$/i # CONSIDER is that an XML attribute name match?
|
46
|
+
|
47
|
+
@xpath << hash.map{|k, v|
|
48
|
+
sk = k.to_s
|
49
|
+
sk = '_text' if sk == '.' or k == 46
|
50
|
+
k = '.' if k == 46 and RUBY_VERSION < '1.9.0'
|
51
|
+
@subs[sk] = v.to_s
|
52
|
+
"#{ '@' if k.to_s =~ xml_attribute_name }#{k} = $#{sk}"
|
53
|
+
}.join(' and ')
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_predicate(hash, options)
|
57
|
+
hash = { :id => hash } if hash.kind_of? Symbol
|
58
|
+
hash.merge! options
|
59
|
+
@xpath << '[ '
|
60
|
+
to_conditions(hash)
|
61
|
+
@xpath << ' ]'
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_xpath(path, id, options)
|
65
|
+
@xpath = path
|
66
|
+
@xpath = "descendant-or-self::#{ @xpath }" if @xpath.kind_of? Symbol
|
67
|
+
to_predicate(id, options) if id
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
# if node = @xdoc.find_first(path) ## for libxml
|
73
|
+
# def node.text
|
74
|
+
# find_first('text()').to_s
|
75
|
+
# end
|
76
|
+
|
77
|
+
def xpath(path, id = nil, options = {}, &block)
|
78
|
+
former_xdoc = @xdoc
|
79
|
+
apa = AssertXPathArguments.new(path, id, options)
|
80
|
+
node = REXML::XPath.first(@xdoc, apa.xpath, nil, apa.subs)
|
81
|
+
|
82
|
+
add_diagnostic :clear do
|
83
|
+
diagnostic = "xpath: #{ apa.xpath.inspect }\n"
|
84
|
+
diagnostic << "arguments: #{ apa.subs.pretty_inspect }\n" if apa.subs.any?
|
85
|
+
diagnostic + "xml context:\n" + indent_xml
|
86
|
+
end
|
87
|
+
|
88
|
+
if node
|
89
|
+
def node.[](symbol)
|
90
|
+
return attributes[symbol.to_s]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if block
|
95
|
+
assert_('this xpath cannot find a node', :keep_diagnostics => true){ node }
|
96
|
+
assert_ nil, :args => [@xdoc = node], :keep_diagnostics => true, &block # TODO need the _ ?
|
97
|
+
end
|
98
|
+
|
99
|
+
return node
|
100
|
+
# TODO raid http://thebogles.com/blog/an-hpricot-style-interface-to-libxml/
|
101
|
+
ensure
|
102
|
+
@xdoc = former_xdoc
|
103
|
+
end # TODO trap LibXML::XML::XPath::InvalidPath and explicate it's an XPath problem
|
104
|
+
|
105
|
+
def indent_xml(node = @xdoc)
|
106
|
+
bar = REXML::Formatters::Pretty.new
|
107
|
+
out = String.new
|
108
|
+
bar.write(node, out)
|
109
|
+
return out
|
110
|
+
end
|
111
|
+
|
112
|
+
end; end; end
|
113
|
+
|
114
|
+
|
115
|
+
if RUBY_VERSION <= '1.8.6'
|
116
|
+
|
117
|
+
module REXML
|
118
|
+
module Formatters
|
119
|
+
class Pretty
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
# see http://www.google.com/codesearch/p?hl=en#Ezb_-tQR858/test_libs/rexml_fix.rb
|
124
|
+
# for less info about this fix...
|
125
|
+
|
126
|
+
def wrap(string, width)
|
127
|
+
# Recursivly wrap string at width.
|
128
|
+
return string if string.length <= width
|
129
|
+
place = string.rindex(/\s+/, width) # Position in string with last ' ' before cutoff
|
130
|
+
return string if place.nil?
|
131
|
+
return string[0,place] + "\n" + wrap(string[place+1..-1], width)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class Element
|
138
|
+
# this patches http://www.germane-software.com/projects/rexml/ticket/128
|
139
|
+
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
|
140
|
+
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
|
141
|
+
formatter = if indent > -1
|
142
|
+
if transitive
|
143
|
+
require "rexml/formatters/transitive"
|
144
|
+
REXML::Formatters::Transitive.new( indent, ie_hack )
|
145
|
+
else
|
146
|
+
REXML::Formatters::Pretty.new( indent, ie_hack )
|
147
|
+
end
|
148
|
+
else
|
149
|
+
REXML::Formatters::Default.new( ie_hack )
|
150
|
+
end
|
151
|
+
formatter.write( self, output )
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
require '../../test/assert_xhtml_suite.rb' if $0 == __FILE__ and File.exist?('../../test/assert_xhtml_suite.rb')
|
metadata
CHANGED
@@ -1,55 +1,61 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
4
2
|
name: assert2
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.3.
|
7
|
-
date: 2008-05-24 00:00:00 -07:00
|
8
|
-
summary: An assertion that reflects its block, with all intermediate values
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: phlip2005@gmail.com
|
12
|
-
homepage: http://assert2.rubyforge.org/
|
13
|
-
rubyforge_project: assert2
|
14
|
-
description:
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: false
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: 0.3.3
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
6
|
authors:
|
30
7
|
- Phlip
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
test_files: []
|
35
|
-
|
36
|
-
rdoc_options: []
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
37
11
|
|
38
|
-
|
12
|
+
date: 2009-01-12 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
39
15
|
|
16
|
+
description:
|
17
|
+
email: phlip2005@gmail.com
|
40
18
|
executables: []
|
41
19
|
|
42
20
|
extensions: []
|
43
21
|
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/assert2
|
26
|
+
- lib/assert2/flunk.rb
|
27
|
+
- lib/assert2/null_reflector.rb
|
28
|
+
- lib/assert2/ripdoc.html.erb
|
29
|
+
- lib/assert2/ripdoc.rb
|
30
|
+
- lib/assert2/ripper_reflector.rb
|
31
|
+
- lib/assert2/rubynode_reflector.rb
|
32
|
+
- lib/assert2/xpath.rb
|
33
|
+
- lib/assert2.rb
|
34
|
+
has_rdoc: false
|
35
|
+
homepage: http://assert2.rubyforge.org/
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
44
53
|
requirements: []
|
45
54
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.0.0
|
55
|
-
version:
|
55
|
+
rubyforge_project: assert2
|
56
|
+
rubygems_version: 1.3.1
|
57
|
+
signing_key:
|
58
|
+
specification_version: 2
|
59
|
+
summary: An assertion that reflects its block, with all intermediate values
|
60
|
+
test_files: []
|
61
|
+
|