qed 2.5.1 → 2.6.0
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/HISTORY.rdoc +259 -0
- data/LICENSE.rdoc +35 -0
- data/README.rdoc +20 -28
- data/bin/qedoc +2 -2
- data/lib/{qedoc/command.rb → qed/cli/qedoc.rb} +9 -26
- data/lib/qed/demo.rb +16 -4
- data/lib/{qedoc → qed}/document.rb +82 -36
- data/lib/{qedoc → qed}/document/jquery.js +0 -0
- data/lib/{qedoc → qed}/document/markup.rb +0 -0
- data/lib/{qedoc → qed}/document/template.rhtml +3 -8
- data/lib/qed/evaluator.rb +1 -1
- data/lib/qed/parser.rb +7 -0
- data/lib/qed/reporter/abstract.rb +136 -18
- data/lib/qed/reporter/bullet.rb +29 -17
- data/lib/qed/reporter/dotprogress.rb +14 -11
- data/lib/qed/reporter/dtrace.rb +67 -0
- data/lib/qed/reporter/tapy.rb +224 -0
- data/lib/qed/reporter/verbatim.rb +2 -2
- data/lib/qed/scope.rb +46 -31
- data/lib/qed/session.rb +28 -7
- metadata +12 -33
- data/LICENSE +0 -204
data/lib/qed/reporter/bullet.rb
CHANGED
@@ -3,10 +3,9 @@ module Reporter #:nodoc:
|
|
3
3
|
|
4
4
|
require 'qed/reporter/abstract'
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# Similar to the Verbose reporter, but does
|
6
|
+
# Bullet Point Reporter - similar to the Verbose reporter, but does
|
9
7
|
# not display test code for passing tests.
|
8
|
+
#
|
10
9
|
class BulletPoint < Abstract
|
11
10
|
|
12
11
|
#
|
@@ -26,23 +25,37 @@ module Reporter #:nodoc:
|
|
26
25
|
end
|
27
26
|
|
28
27
|
def fail(step, assertion)
|
29
|
-
|
30
|
-
|
31
|
-
msg
|
32
|
-
msg
|
33
|
-
|
34
|
-
|
28
|
+
backtrace = sane_backtrace(assertion)
|
29
|
+
|
30
|
+
msg = []
|
31
|
+
msg << " " + "FAIL".ansi(:red)
|
32
|
+
msg << ""
|
33
|
+
msg << assertion.to_s.gsub(/^/, ' ')
|
34
|
+
msg << ""
|
35
|
+
backtrace.each do |bt|
|
36
|
+
msg << " " + relative_file(bt)
|
37
|
+
end
|
38
|
+
io.puts msg.join("\n")
|
39
|
+
io.puts
|
40
|
+
io.print step.text.tabto(4)
|
35
41
|
end
|
36
42
|
|
37
43
|
def error(step, exception)
|
38
44
|
raise exception if $DEBUG
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
msg
|
43
|
-
msg
|
44
|
-
|
45
|
-
|
45
|
+
|
46
|
+
backtrace = sane_backtrace(exception)
|
47
|
+
|
48
|
+
msg = []
|
49
|
+
msg << " " + "ERROR".ansi(:red)
|
50
|
+
msg << ""
|
51
|
+
msg << " " + exception.to_s
|
52
|
+
msg << ""
|
53
|
+
backtrace.each do |bt|
|
54
|
+
msg << " " + relative_file(bt)
|
55
|
+
end
|
56
|
+
io.puts msg.join("\n")
|
57
|
+
io.puts
|
58
|
+
io.print step.text.tabto(4)
|
46
59
|
end
|
47
60
|
|
48
61
|
#def report(str)
|
@@ -76,4 +89,3 @@ module Reporter #:nodoc:
|
|
76
89
|
|
77
90
|
end#module Reporter
|
78
91
|
end#module QED
|
79
|
-
|
@@ -43,23 +43,26 @@ module Reporter #:nodoc:
|
|
43
43
|
print_time
|
44
44
|
|
45
45
|
errors.each do |step, exception|
|
46
|
-
backtrace =
|
46
|
+
backtrace = sane_backtrace(exception)
|
47
|
+
|
47
48
|
io.puts "***** ERROR *****".ansi(:red)
|
48
49
|
io.puts "#{exception}"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
backtrace.each do |bt|
|
51
|
+
io.puts bt
|
52
|
+
io.puts code_snippet(bt)
|
53
|
+
end
|
53
54
|
io.puts
|
54
55
|
end
|
55
56
|
|
56
57
|
fails.each do |step, assertion|
|
57
|
-
backtrace =
|
58
|
-
|
59
|
-
io.puts "
|
60
|
-
io.puts "
|
61
|
-
|
62
|
-
|
58
|
+
backtrace = sane_backtrace(assertion)
|
59
|
+
|
60
|
+
io.puts "***** FAIL *****".ansi(:red, :bold)
|
61
|
+
io.puts "#{assertion}"
|
62
|
+
backtrace.each do |bt|
|
63
|
+
io.puts bt
|
64
|
+
io.puts code_snippet(bt)
|
65
|
+
end
|
63
66
|
io.puts
|
64
67
|
end
|
65
68
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module QED
|
2
|
+
module Reporter #:nodoc:
|
3
|
+
|
4
|
+
require 'qed/reporter/abstract'
|
5
|
+
|
6
|
+
# Deep trace reporter
|
7
|
+
#
|
8
|
+
class DTrace < Abstract
|
9
|
+
|
10
|
+
#
|
11
|
+
def before_session(session)
|
12
|
+
@start_time = Time.now
|
13
|
+
io.puts "Started"
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
#def before_step(step)
|
18
|
+
# super(step)
|
19
|
+
# io.print "."
|
20
|
+
# io.flush
|
21
|
+
#end
|
22
|
+
|
23
|
+
def pass(step)
|
24
|
+
super(step)
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
def fail(step, assertion)
|
29
|
+
super(step, assertion)
|
30
|
+
|
31
|
+
io.puts "#{assertion}".ansi(:red)
|
32
|
+
|
33
|
+
backtrace = sane_backtrace(assertion)
|
34
|
+
backtrace.each do |bt|
|
35
|
+
io.puts bt
|
36
|
+
io.puts code_snippet(bt)
|
37
|
+
end
|
38
|
+
|
39
|
+
io.puts
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def error(step, exception)
|
44
|
+
super(step, exception)
|
45
|
+
|
46
|
+
io.puts "#{exception}".ansi(:red)
|
47
|
+
|
48
|
+
backtrace = sane_backtrace(exception)
|
49
|
+
backtrace.each do |bt|
|
50
|
+
io.puts bt
|
51
|
+
io.puts code_snippet(bt)
|
52
|
+
end
|
53
|
+
|
54
|
+
io.puts
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
#
|
59
|
+
def after_session(session)
|
60
|
+
print_time
|
61
|
+
print_tally
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end#module Reporter
|
67
|
+
end#module QED
|
@@ -0,0 +1,224 @@
|
|
1
|
+
module QED
|
2
|
+
module Reporter #:nodoc:
|
3
|
+
|
4
|
+
require 'qed/reporter/abstract'
|
5
|
+
|
6
|
+
# TAP-Y Reporter
|
7
|
+
#
|
8
|
+
# NOTE: I suppose techincally that each TAP-Y test should be an assertion,
|
9
|
+
# but that's a whole other ball of wax, and would require AE to remember
|
10
|
+
# every assertion made. It also would have no means of providing an upfront
|
11
|
+
# count.
|
12
|
+
#
|
13
|
+
class TapY < Abstract
|
14
|
+
|
15
|
+
#
|
16
|
+
def head(step)
|
17
|
+
data = {
|
18
|
+
'type' => 'header',
|
19
|
+
'start' => Time.now.strftime('%Y-%m-%d %H:%M:%S'),
|
20
|
+
'count' => session.total_step_count
|
21
|
+
}
|
22
|
+
io.puts data.to_yaml
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
def desc(step)
|
27
|
+
#data = {
|
28
|
+
# 'type' => 'note',
|
29
|
+
# 'description' => step.to_s.strip
|
30
|
+
#}
|
31
|
+
#io.puts data.to_yaml
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# @todo How to get the line number so we can do proper snippets?
|
36
|
+
def pass(step)
|
37
|
+
super(step)
|
38
|
+
|
39
|
+
lines = step.text.split("\n")
|
40
|
+
#snip, l = [], step.line
|
41
|
+
#lines.map do |line|
|
42
|
+
# snip << { (l += 1) => line }
|
43
|
+
#end
|
44
|
+
|
45
|
+
if step.header?
|
46
|
+
data = {
|
47
|
+
'type' => 'note',
|
48
|
+
'description' => step.text, #.strip,
|
49
|
+
}
|
50
|
+
elsif step.code?
|
51
|
+
data = {
|
52
|
+
'type' => 'test',
|
53
|
+
'status' => 'pass',
|
54
|
+
'description' => step.text.strip,
|
55
|
+
#'file' => step.file,
|
56
|
+
#'line' => step.line,
|
57
|
+
#'returned' => nil,
|
58
|
+
#'expected' => nil,
|
59
|
+
'source' => lines.first,
|
60
|
+
'snippet' => step.text.strip,
|
61
|
+
'time' => time_since_start
|
62
|
+
}
|
63
|
+
else
|
64
|
+
data = {
|
65
|
+
'type' => 'test',
|
66
|
+
'status' => 'pass',
|
67
|
+
'description' => step.text.strip,
|
68
|
+
#'file' => step.file,
|
69
|
+
#'line' => step.line,
|
70
|
+
#'returned' => nil,
|
71
|
+
#'expected' => nil,
|
72
|
+
'source' => lines.first,
|
73
|
+
'snippet' => step.text.strip,
|
74
|
+
'time' => time_since_start
|
75
|
+
}
|
76
|
+
end
|
77
|
+
io.puts data.to_yaml
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
def fail(step, assertion)
|
82
|
+
super(step, assertion)
|
83
|
+
|
84
|
+
backtrace = sane_backtrace(assertion)
|
85
|
+
|
86
|
+
file, line = file_line(backtrace)
|
87
|
+
|
88
|
+
snippet = structured_code_snippet(assertion, bredth=3)
|
89
|
+
source = snippet.map{ |h| h.values.first }[snippet.size / 2].strip
|
90
|
+
|
91
|
+
data = {
|
92
|
+
'type' => 'test',
|
93
|
+
'status' => 'fail',
|
94
|
+
'description' => step.text.strip,
|
95
|
+
'file' => file,
|
96
|
+
'line' => line,
|
97
|
+
'message' => assertion.to_s.unansi,
|
98
|
+
#'returned' => nil,
|
99
|
+
#'expected' => nil,
|
100
|
+
'source' => source,
|
101
|
+
'snippet' => snippet,
|
102
|
+
'time' => time_since_start
|
103
|
+
}
|
104
|
+
|
105
|
+
io.puts data.to_yaml
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
def error(step, exception)
|
110
|
+
super(step, exception)
|
111
|
+
|
112
|
+
backtrace = sane_backtrace(exception)
|
113
|
+
|
114
|
+
file, line = file_line(backtrace)
|
115
|
+
|
116
|
+
snippet = structured_code_snippet(exception, bredth=3)
|
117
|
+
source = snippet.map{ |h| h.values.first }[snippet.size / 2].strip
|
118
|
+
|
119
|
+
data = {
|
120
|
+
'type' => 'test',
|
121
|
+
'status' => 'error',
|
122
|
+
'description' => step.text.strip,
|
123
|
+
'file' => file,
|
124
|
+
'line' => line,
|
125
|
+
'message' => exception.to_s.unansi,
|
126
|
+
#'returned' => nil,
|
127
|
+
#'expected' => nil,
|
128
|
+
'backtrace' => backtrace,
|
129
|
+
'source' => source,
|
130
|
+
'snippet' => snippet,
|
131
|
+
'time' => time_since_start
|
132
|
+
}
|
133
|
+
|
134
|
+
io.puts data.to_yaml
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
=begin
|
139
|
+
def fail(step, assertion)
|
140
|
+
backtrace = sane_backtrace(assertion)
|
141
|
+
|
142
|
+
msg = []
|
143
|
+
msg << " " + "FAIL".ansi(:red)
|
144
|
+
msg << ""
|
145
|
+
msg << assertion.to_s.gsub(/^/, ' ')
|
146
|
+
msg << ""
|
147
|
+
backtrace.each do |bt|
|
148
|
+
msg << " " + relative_file(bt)
|
149
|
+
end
|
150
|
+
io.puts msg.join("\n")
|
151
|
+
io.puts
|
152
|
+
io.print step.text.tabto(4)
|
153
|
+
end
|
154
|
+
|
155
|
+
def error(step, exception)
|
156
|
+
raise exception if $DEBUG
|
157
|
+
|
158
|
+
backtrace = sane_backtrace(exception)
|
159
|
+
|
160
|
+
msg = []
|
161
|
+
msg << " " + "ERROR".ansi(:red)
|
162
|
+
msg << ""
|
163
|
+
msg << " " + exception.to_s
|
164
|
+
msg << ""
|
165
|
+
backtrace.each do |bt|
|
166
|
+
msg << " " + relative_file(bt)
|
167
|
+
end
|
168
|
+
io.puts msg.join("\n")
|
169
|
+
io.puts
|
170
|
+
io.print step.text.tabto(4)
|
171
|
+
end
|
172
|
+
=end
|
173
|
+
|
174
|
+
#def report(str)
|
175
|
+
# count[-1] += 1 unless count.empty?
|
176
|
+
# str = str.chomp('.') + '.'
|
177
|
+
# str = count.join('.') + ' ' + str
|
178
|
+
# io.puts str.strip
|
179
|
+
#end
|
180
|
+
|
181
|
+
#def report_comment(step)
|
182
|
+
# txt = step.to_s.strip.tabto(2)
|
183
|
+
# txt[0,1] = "*"
|
184
|
+
# io.puts txt
|
185
|
+
# io.puts
|
186
|
+
#end
|
187
|
+
|
188
|
+
#def report_macro(step)
|
189
|
+
# txt = step.to_s.tabto(2)
|
190
|
+
# txt[0,1] = "*"
|
191
|
+
# io.puts txt
|
192
|
+
# #io.puts
|
193
|
+
# #io.puts "#{step}".ansi(:magenta)
|
194
|
+
#end
|
195
|
+
|
196
|
+
def after_session(session)
|
197
|
+
pass_size = steps.size - (fails.size + errors.size + omits.size)
|
198
|
+
|
199
|
+
data = {
|
200
|
+
'type' => 'footer',
|
201
|
+
'tally' => {
|
202
|
+
'pass' => pass_size,
|
203
|
+
'fail' => fails.size,
|
204
|
+
'error' => errors.size,
|
205
|
+
'omit' => omits.size,
|
206
|
+
'pending' => 0
|
207
|
+
},
|
208
|
+
'time' => time_since_start
|
209
|
+
}
|
210
|
+
|
211
|
+
io.puts data.to_yaml
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
#
|
217
|
+
def time_since_start
|
218
|
+
Time.now - @start_time
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
end#module Reporter
|
224
|
+
end#module QED
|
@@ -51,7 +51,7 @@ module Reporter #:nodoc:
|
|
51
51
|
#msg << ANSI::Code.bold(ANSI::Code.red("FAIL: ")) + error.message
|
52
52
|
#msg << ANSI::Code.bold(clean_backtrace(error.backtrace[0]))
|
53
53
|
msg << "FAIL: ".ansi(:bold, :red) + error.message.to_s #to_str
|
54
|
-
msg <<
|
54
|
+
msg << sane_backtrace(error).first.ansi(:bold)
|
55
55
|
io.puts msg.join("\n").tabto(tab||2)
|
56
56
|
io.puts
|
57
57
|
end
|
@@ -65,7 +65,7 @@ module Reporter #:nodoc:
|
|
65
65
|
io.print "#{txt}\n\n".ansi(:red)
|
66
66
|
msg = []
|
67
67
|
msg << "ERROR: #{error.class} ".ansi(:bold,:red) + error.message #.sub(/for QED::Context.*?$/,'')
|
68
|
-
msg <<
|
68
|
+
msg << sane_backtrace(error).first.ansi(:bold)
|
69
69
|
#msg = msg.ansi(:red)
|
70
70
|
io.puts msg.join("\n").tabto(tab||2)
|
71
71
|
io.puts
|
data/lib/qed/scope.rb
CHANGED
@@ -29,7 +29,7 @@ module QED
|
|
29
29
|
#@loadlist = []
|
30
30
|
|
31
31
|
include *applique
|
32
|
-
extend self
|
32
|
+
#extend self
|
33
33
|
#extend applique # TODO: extend or include applique or none ?
|
34
34
|
#extend DSLi
|
35
35
|
|
@@ -112,15 +112,23 @@ module QED
|
|
112
112
|
@_applique.first.After(type, &procedure)
|
113
113
|
end
|
114
114
|
|
115
|
+
# Directory of current document.
|
116
|
+
def __DIR__(file=nil)
|
117
|
+
if file
|
118
|
+
Dir.glob(File.join(File.dirname(@_file), file)).first || file
|
119
|
+
else
|
120
|
+
File.dirname(@_file)
|
121
|
+
end
|
122
|
+
end
|
115
123
|
|
116
124
|
# TODO: Should Table and Data be extensions that can be loaded if desired?
|
117
125
|
|
118
|
-
# Use sample table to run steps. The table file
|
119
|
-
#
|
120
|
-
#
|
126
|
+
# Use sample table to run steps. The table file is located relative to
|
127
|
+
# the demo, failing that it will be looked for relative to the working
|
128
|
+
# directory.
|
121
129
|
#
|
122
130
|
# TODO: Cache data for speed ?
|
123
|
-
def Table(file=nil) #:yield:
|
131
|
+
def Table(file=nil, options={}) #:yield:
|
124
132
|
if file
|
125
133
|
file = Dir.glob(File.join(File.dirname(@_file), file)).first || file
|
126
134
|
else
|
@@ -128,40 +136,47 @@ module QED
|
|
128
136
|
end
|
129
137
|
@_last_table = file
|
130
138
|
|
131
|
-
|
132
|
-
|
133
|
-
|
139
|
+
file_handle = File.new(file)
|
140
|
+
|
141
|
+
if options[:stream]
|
142
|
+
if block_given?
|
143
|
+
YAML.load_documents(file_handle) do |data|
|
144
|
+
yield data
|
145
|
+
end
|
146
|
+
else
|
147
|
+
YAML.load_stream(file_handle)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
if block_given?
|
151
|
+
tbl = YAML.load(file_handle)
|
152
|
+
tbl.each do |data|
|
153
|
+
yield(*data)
|
154
|
+
end
|
155
|
+
else
|
156
|
+
YAML.load(file_handle)
|
157
|
+
end
|
134
158
|
end
|
135
159
|
end
|
136
160
|
|
137
|
-
# Read a static data
|
161
|
+
# Read a static data file and yield contents to block if given.
|
138
162
|
#
|
163
|
+
# This method no longer automatically uses YAML.load.
|
164
|
+
#--
|
139
165
|
# TODO: Cache data for speed ?
|
166
|
+
#++
|
140
167
|
def Data(file) #:yield:
|
141
|
-
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
# when '.yml', '.yaml'
|
146
|
-
# File.open(file, 'w'){ |f| f << content.call.to_yaml }
|
147
|
-
# else
|
148
|
-
# File.open(file, 'w'){ |f| f << content.call }
|
149
|
-
# end
|
168
|
+
file = Dir.glob(File.join(File.dirname(@_file), file)).first || file
|
169
|
+
#case File.extname(file)
|
170
|
+
#when '.yml', '.yaml'
|
171
|
+
# data = YAML.load(File.new(file))
|
150
172
|
#else
|
151
|
-
|
152
|
-
file = Dir.glob(File.join(File.dirname(@_file), file)).first || file
|
153
|
-
case File.extname(file)
|
154
|
-
when '.yml', '.yaml'
|
155
|
-
data = YAML.load(File.new(file))
|
156
|
-
else
|
157
|
-
data = File.read(file)
|
158
|
-
end
|
159
|
-
if block_given?
|
160
|
-
yield(data)
|
161
|
-
else
|
162
|
-
data
|
163
|
-
end
|
173
|
+
data = File.read(file)
|
164
174
|
#end
|
175
|
+
if block_given?
|
176
|
+
yield(data)
|
177
|
+
else
|
178
|
+
data
|
179
|
+
end
|
165
180
|
end
|
166
181
|
|
167
182
|
# Clear temporary work directory.
|