qed 2.3.0 → 2.4.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.
Files changed (50) hide show
  1. data/History.rdoc +15 -0
  2. data/eg/hello_world.rdoc +15 -0
  3. data/eg/view_error.rdoc +21 -0
  4. data/eg/website.rdoc +12 -0
  5. data/lib/qed/advice.rb +4 -3
  6. data/lib/qed/command.rb +2 -3
  7. data/lib/qed/core_ext/instance_exec.rb +36 -0
  8. data/lib/qed/demo.rb +0 -1
  9. data/lib/qed/evaluator.rb +75 -36
  10. data/lib/qed/extensions/filefixtures.rb +27 -0
  11. data/lib/qed/extensions/shell_session.rb +2 -0
  12. data/lib/qed/meta/data.rb +29 -0
  13. data/lib/qed/meta/gemfile +10 -0
  14. data/{PROFILE → lib/qed/meta/profile} +0 -0
  15. data/lib/qed/parser.rb +148 -74
  16. data/lib/qed/reporter/abstract.rb +175 -25
  17. data/lib/qed/reporter/bullet.rb +14 -10
  18. data/lib/qed/reporter/dotprogress.rb +26 -9
  19. data/lib/qed/reporter/verbatim.rb +36 -15
  20. data/lib/qed/scope.rb +18 -8
  21. data/lib/qed/session.rb +2 -2
  22. data/meta/data.rb +29 -0
  23. data/meta/gemfile +10 -0
  24. data/{lib/qed/profile.yml → meta/profile} +0 -0
  25. data/{demo → qed}/01_demos.rdoc +7 -13
  26. data/{demo → qed}/02_advice.rdoc +7 -7
  27. data/{demo → qed}/03_helpers.rdoc +2 -2
  28. data/{demo → qed}/04_samples.rdoc +0 -0
  29. data/{demo → qed}/05_quote.rdoc +0 -0
  30. data/{demo → qed}/07_toplevel.rdoc +0 -0
  31. data/{demo → qed}/08_cross_script.rdoc +0 -2
  32. data/{demo → qed}/09_cross_script.rdoc +5 -3
  33. data/{demo → qed}/10_constant_lookup.rdoc +0 -0
  34. data/{demo → qed}/applique/constant.rb +0 -0
  35. data/{demo → qed}/applique/env.rb +0 -0
  36. data/{demo → qed}/applique/fileutils.rb +0 -0
  37. data/{demo → qed}/applique/markup.rb +0 -0
  38. data/{demo → qed}/applique/quote.rb +0 -0
  39. data/{demo → qed}/applique/toplevel.rb +0 -0
  40. data/{demo → qed}/helpers/advice.rb +0 -0
  41. data/{demo → qed}/helpers/sample.rb +0 -0
  42. data/{demo → qed}/helpers/toplevel.rb +0 -0
  43. data/{demo → qed}/samples/data.txt +0 -0
  44. data/{demo → qed}/samples/table.yml +0 -0
  45. metadata +43 -38
  46. data/REQUIRE +0 -7
  47. data/VERSION +0 -5
  48. data/lib/qed/package.yml +0 -5
  49. data/script/qedoc +0 -2
  50. data/script/test +0 -4
@@ -7,28 +7,40 @@ module Reporter
7
7
  # = Reporter Absract Base Class
8
8
  #
9
9
  # Serves as the base class for all other output formats.
10
- #
11
10
  class Abstract
12
11
 
13
12
  attr :io
14
- attr :steps
15
- attr :omit
13
+ attr :record
16
14
 
17
15
  def initialize(options={})
18
16
  @io = options[:io] || STDOUT
19
17
  @trace = options[:trace]
20
18
 
21
- @demos = 0
22
- @steps = 0
23
- @omit = []
24
- @pass = []
25
- @fail = []
26
- @error = []
19
+ @record = {
20
+ :demo => [],
21
+ :step => [],
22
+ :omit => [],
23
+ :pass => [],
24
+ :fail => [],
25
+ :error => []
26
+ }
27
+
28
+ #@demos = 0
29
+ #@steps = 0
30
+ #@omit = []
31
+ #@pass = []
32
+ #@fail = []
33
+ #@error = []
34
+
35
+ @source = {}
27
36
  end
28
37
 
29
- def passes ; @pass ; end
30
- def errors ; @error ; end
31
- def failures ; @fail ; end
38
+ def demos ; @record[:demo] ; end
39
+ def steps ; @record[:step] ; end
40
+ def omits ; @record[:omit] ; end
41
+ def passes ; @record[:pass] ; end
42
+ def errors ; @record[:error] ; end
43
+ def fails ; @record[:fail] ; end
32
44
 
33
45
  #
34
46
  def trace?
@@ -37,10 +49,10 @@ module Reporter
37
49
 
38
50
  #
39
51
  def update(type, *args)
52
+ __send__("count_#{type}", *args) if respond_to?("count_#{type}")
40
53
  __send__("#{type}", *args)
41
54
  end
42
55
 
43
-
44
56
  def self.When(type, &block)
45
57
  #raise ArgumentError unless %w{session demo demonstration step}.include?(type.to_s)
46
58
  #type = :demonstration if type.to_s == 'demo'
@@ -71,13 +83,39 @@ module Reporter
71
83
  # __send__("after_#{type}", target, *args)
72
84
  #end
73
85
 
86
+ def count_demo(demo)
87
+ @record[:demo] << demo
88
+ end
89
+
90
+ def count_desc(step)
91
+ @record[:step] << step
92
+ end
93
+
94
+ def count_code(step)
95
+ @record[:step] << step
96
+ end
97
+
98
+ def count_pass(step)
99
+ @record[:pass] << step
100
+ end
101
+
102
+ def count_fail(step, exception)
103
+ @record[:fail] << [step, exception]
104
+ end
105
+
106
+ def count_error(step, exception)
107
+ @record[:error] << [step, exception]
108
+ end
109
+
110
+
74
111
  # At the start of a session, before running any demonstrations.
75
112
  def before_session(session)
113
+ @start_time = Time.now
76
114
  end
77
115
 
78
116
  # Beginning of a demonstration.
79
117
  def before_demo(demo) #demo(demo)
80
- @demos += 1
118
+ #demos << demo
81
119
  end
82
120
 
83
121
  #
@@ -91,42 +129,88 @@ module Reporter
91
129
  #def comment(elem)
92
130
  #end
93
131
 
132
+ #
133
+ def before_step(step)
134
+ #@steps += 1
135
+ end
136
+
137
+ #
138
+ def before_head(step)
139
+ end
140
+
141
+ #
142
+ def before_desc(step)
143
+ #steps << step
144
+ end
145
+
146
+ #
147
+ def before_data(step)
148
+ end
149
+
94
150
  # Before running a step that is omitted.
95
- #def omit_step(step)
151
+ #def before_omit(step)
96
152
  # @omit << step
97
153
  #end
98
154
 
99
155
  #
100
- def before_step(step, file)
101
- @steps += 1
156
+ def before_code(step)
157
+ #steps << step
102
158
  end
103
159
 
104
- # Right before running code.
105
- def code(section)
160
+ # Reight before demo.
161
+ def demo(demo)
162
+ end
163
+
164
+ # Right before header.
165
+ def head(step)
106
166
  end
107
167
 
108
168
  # Right before text section.
109
- def text(section)
169
+ def desc(step) #text ?
170
+ end
171
+
172
+ # Right before date section.
173
+ def data(step)
174
+ end
175
+
176
+ # Right before running code.
177
+ def code(step)
110
178
  end
111
179
 
112
180
  # After running a step that passed.
113
181
  def pass(step)
114
- @pass << step
182
+ #@pass << step
115
183
  end
116
184
 
117
185
  # After running a step that failed.
118
186
  def fail(step, assertion)
119
- @fail << [step, assertion]
187
+ #@fail << [step, assertion]
120
188
  end
121
189
 
122
190
  # After running a step that raised an error.
123
191
  def error(step, exception)
124
192
  raise exception if $DEBUG
125
- @error << [step, exception]
193
+ #@error << [step, exception]
126
194
  end
127
195
 
128
196
  #
129
- def after_step(step, file)
197
+ def after_data(step)
198
+ end
199
+
200
+ #
201
+ def after_code(step)
202
+ end
203
+
204
+ #
205
+ def after_desc(step)
206
+ end
207
+
208
+ #
209
+ def after_head(step)
210
+ end
211
+
212
+ #
213
+ def after_step(step)
130
214
  end
131
215
 
132
216
  #
@@ -142,17 +226,83 @@ module Reporter
142
226
  def after_session(session)
143
227
  end
144
228
 
145
- #
229
+ # TODO: should we rename b/c of keyword?
146
230
  def when(*args)
147
231
  end
148
232
 
149
233
  private
150
234
 
235
+ def print_time
236
+ io.puts "\nFinished in %.5f seconds.\n\n" % [Time.now - @start_time]
237
+ end
238
+
239
+ def print_tally
240
+ mask = "%s demos, %s steps: %s failures, %s errors (%s/%s assertions)"
241
+ vars = [demos.size, steps.size, fails.size, errors.size, $assertions-$failures, $assertions] #, @pass.size ]
242
+
243
+ io.puts mask % vars
244
+ end
245
+
151
246
  #
152
247
  def clean_backtrace(btrace)
153
248
  btrace.chomp(":in \`__binding__'")
154
249
  end
155
250
 
251
+ #
252
+ INTERNALS = /(lib|bin)[\\\/]qed/
253
+
254
+ =begin
255
+ # Clean the backtrace of any reference to ko/ paths and code.
256
+ def clean_backtrace(backtrace)
257
+ trace = backtrace.reject{ |bt| bt =~ INTERNALS }
258
+ trace.map do |bt|
259
+ if i = bt.index(':in')
260
+ bt[0...i]
261
+ else
262
+ bt
263
+ end
264
+ end
265
+ end
266
+ =end
267
+
268
+ #
269
+ def code_snippet(exception, bredth=3)
270
+ backtrace = exception.backtrace.reject{ |bt| bt =~ INTERNALS }
271
+ backtrace.first =~ /(.+?):(\d+(?=:|\z))/ or return ""
272
+ source_file, source_line = $1, $2.to_i
273
+
274
+ source = source(source_file)
275
+
276
+ radius = bredth # number of surrounding lines to show
277
+ region = [source_line - radius, 1].max ..
278
+ [source_line + radius, source.length].min
279
+
280
+ # ensure proper alignment by zero-padding line numbers
281
+ format = " %2s %0#{region.last.to_s.length}d %s"
282
+
283
+ pretty = region.map do |n|
284
+ format % [('=>' if n == source_line), n, source[n-1].chomp]
285
+ end #.unshift "[#{region.inspect}] in #{source_file}"
286
+
287
+ pretty
288
+ end
289
+
290
+ #
291
+ def source(file)
292
+ @source[file] ||= (
293
+ File.readlines(file)
294
+ )
295
+ end
296
+
297
+ # TODO: Show more of the file name than just the basename.
298
+ def file_and_line(exception)
299
+ line = exception.backtrace[0]
300
+ return "" unless line
301
+ i = line.rindex(':in')
302
+ line = i ? line[0...i] : line
303
+ File.basename(line)
304
+ end
305
+
156
306
  end
157
307
 
158
308
  end
@@ -10,16 +10,15 @@ module Reporter #:nodoc:
10
10
  class BulletPoint < Abstract
11
11
 
12
12
  #
13
- def text(step)
14
- case step.commentary
15
- when /^\=/
16
- io.print "#{step.commentary}".ansi(:bold)
17
- else
18
- txt = step.commentary.to_s.strip.tabto(2)
19
- txt[0,1] = "*"
20
- io.puts txt
21
- io.puts
22
- end
13
+ def head(step)
14
+ io.print "#{step}".ansi(:bold)
15
+ end
16
+
17
+ def desc(step)
18
+ txt = step.to_s.strip.tabto(2)
19
+ txt[0,1] = "*"
20
+ io.puts txt
21
+ io.puts
23
22
  end
24
23
 
25
24
  def pass(step)
@@ -68,6 +67,11 @@ module Reporter #:nodoc:
68
67
  # #io.puts "#{step}".ansi(:magenta)
69
68
  #end
70
69
 
70
+ def after_session(session)
71
+ print_time
72
+ print_tally
73
+ end
74
+
71
75
  end #class Summary
72
76
 
73
77
  end#module Reporter
@@ -14,39 +14,56 @@ module Reporter #:nodoc:
14
14
  end
15
15
 
16
16
  #
17
- def before_step(step, file)
18
- super(step, file)
17
+ #def before_step(step)
18
+ # super(step)
19
+ # io.print "."
20
+ # io.flush
21
+ #end
22
+
23
+ def pass(step)
19
24
  io.print "."
20
25
  io.flush
26
+ super(step)
27
+ end
28
+
29
+ def fail(step, assertion)
30
+ io.print "F"
31
+ io.flush
32
+ super(step, assertion)
33
+ end
34
+
35
+ def error(step, exception)
36
+ io.print "E"
37
+ io.flush
38
+ super(step, exception)
21
39
  end
22
40
 
23
41
  #
24
42
  def after_session(session)
25
- io.puts "\nFinished in #{Time.now - @start_time} seconds.\n\n"
43
+ print_time
26
44
 
27
- @error.each do |step, exception|
45
+ errors.each do |step, exception|
28
46
  backtrace = clean_backtrace(exception.backtrace[0])
29
47
  io.puts "***** ERROR *****".ansi(:red)
30
48
  io.puts "#{exception}"
31
49
  io.puts ":#{backtrace}:"
32
50
  #io.puts ":#{exception.backtrace[1]}:"
33
51
  #io.puts exception.backtrace[1..-1] if $VERBOSE
52
+ io.puts code_snippet(exception)
34
53
  io.puts
35
54
  end
36
55
 
37
- @fail.each do |step, assertion|
56
+ fails.each do |step, assertion|
38
57
  backtrace = clean_backtrace(assertion.backtrace[0])
39
58
  io.puts "***** FAIL *****".ansi(:red)
40
59
  io.puts "#{assertion}".ansi(:bold)
41
60
  io.puts ":#{backtrace}:"
42
61
  # -- io.puts assertion if $VERBOSE
62
+ io.puts code_snippet(assertion)
43
63
  io.puts
44
64
  end
45
65
 
46
- mask = "%s demos, %s steps: %s failures, %s errors (%s/%s assertions)"
47
- vars = [@demos, @steps, @fail.size, @error.size, $assertions-$failures, $assertions] #, @pass.size ]
48
-
49
- io.puts mask % vars
66
+ print_tally
50
67
  end
51
68
 
52
69
  end#class DotProgress
@@ -8,28 +8,42 @@ module Reporter #:nodoc:
8
8
  class Verbatim < Abstract
9
9
 
10
10
  #
11
- def text(section)
12
- text = section.commentary
13
- text = text.gsub(/^([=#].*?)$/, '\1'.ansi(:bold))
14
- io.print text
15
- if section.continuation?
16
- io.puts(section.clean_example.ansi(:blue))
17
- io.puts
18
- end
11
+ def before_session(session)
12
+ @start_time = Time.now
13
+ end
14
+
15
+ #
16
+ def head(step)
17
+ io.print step.text.ansi(:bold)
18
+ end
19
+
20
+ #
21
+ def desc(step)
19
22
  end
20
23
 
21
- # headers ?
24
+ #
25
+ def data(step)
26
+ io.puts step.clean_text.ansi(:blue)
27
+ io.puts
28
+ end
22
29
 
23
30
  #
24
31
  def pass(step)
25
- txt = step.example #.rstrip.sub("\n",'')
26
- io.print "#{txt}".ansi(:green)
32
+ super(step)
33
+ if step.code?
34
+ io.print "#{step.text}".ansi(:green)
35
+ elsif step.header?
36
+ io.print "#{step.text}".ansi(:bold)
37
+ else
38
+ io.print "#{step.text}"
39
+ end
27
40
  end
28
41
 
29
42
  #
30
43
  def fail(step, error)
31
- txt = step.example.rstrip #.sub("\n",'')
32
- tab = step.example.index(/\S/)
44
+ super(step, error)
45
+ txt = step.text.rstrip #.sub("\n",'')
46
+ tab = step.text.index(/\S/)
33
47
  io.print "#{txt}\n\n".ansi(:red)
34
48
  msg = []
35
49
  #msg << ANSI::Code.bold(ANSI::Code.red("FAIL: ")) + error.to_str
@@ -42,9 +56,10 @@ module Reporter #:nodoc:
42
56
 
43
57
  #
44
58
  def error(step, error)
59
+ super(step, error)
45
60
  raise error if $DEBUG
46
- txt = step.example.rstrip #.sub("\n",'')
47
- tab = step.example.index(/\S/)
61
+ txt = step.text.rstrip #.sub("\n",'')
62
+ tab = step.text.index(/\S/)
48
63
  io.print "#{txt}\n\n".ansi(:red)
49
64
  msg = []
50
65
  msg << "ERROR: #{error.class} ".ansi(:bold,:red) + error.to_str #.sub(/for QED::Context.*?$/,'')
@@ -73,6 +88,12 @@ module Reporter #:nodoc:
73
88
  # #io.puts
74
89
  #end
75
90
 
91
+ #
92
+ def after_session(session)
93
+ print_time
94
+ print_tally
95
+ end
96
+
76
97
  end
77
98
 
78
99
  end #module Reporter