qed 1.3 → 2.0.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.
@@ -1,68 +0,0 @@
1
- module QED
2
- module Reporter #:nodoc:
3
-
4
- require 'qed/reporter/base'
5
-
6
- # = Summary Reporter
7
- #
8
- # Similar to the Verbatim reporter, but does
9
- # not display test code for passing tests.
10
- class Summary < BaseClass
11
-
12
- def report_header(step)
13
- io.puts ANSICode.bold("#{step}")
14
- end
15
-
16
- def report_comment(step)
17
- txt = step.to_s.strip.tabto(2)
18
- txt[0,1] = "*"
19
- io.puts txt
20
- io.puts
21
- end
22
-
23
- def report_macro(step)
24
- txt = step.to_s.tabto(2)
25
- txt[0,1] = "*"
26
- io.puts txt
27
- #io.puts
28
- #io.puts ANSICode.magenta("#{step}")
29
- end
30
-
31
- def report_pass(step)
32
- #io.puts ANSICode.green("#{step}")
33
- end
34
-
35
- def report_fail(step, assertion)
36
- msg = ''
37
- msg << " ##### FAIL #####\n"
38
- msg << " # " + assertion.to_s
39
- msg = ANSICode.magenta(msg)
40
- io.puts msg
41
- #io.puts
42
- io.puts ANSICode.red("#{step}")
43
- end
44
-
45
- def report_error(step, exception)
46
- raise exception if $DEBUG
47
- msg = ''
48
- msg << " ##### ERROR #####\n"
49
- msg << " # " + exception.to_s + "\n"
50
- msg << " # " + exception.backtrace[0]
51
- msg = ANSICode.magenta(msg)
52
- io.puts msg
53
- #io.puts
54
- io.puts ANSICode.red("#{step}")
55
- end
56
-
57
- #def report(str)
58
- # count[-1] += 1 unless count.empty?
59
- # str = str.chomp('.') + '.'
60
- # str = count.join('.') + ' ' + str
61
- # io.puts str.strip
62
- #end
63
-
64
- end #class Summary
65
-
66
- end#module Reporter
67
- end#module QED
68
-
data/lib/qed/runner.rb DELETED
@@ -1,198 +0,0 @@
1
- module QED
2
-
3
- require 'qed/script'
4
-
5
- # = Specificaton Runner
6
- #
7
- # The Runner class loops through a set of specifications
8
- # and executes each one in turn.
9
- #
10
- # The current working directory is changed to that of the
11
- # specification script's. So any relative file references
12
- # within a spec must take that into account.
13
- #
14
- class Runner
15
-
16
- # QED::Runner.configure do
17
- # def setup(spec)
18
- # ...
19
- # end
20
- # def teardown(spec)
21
- # ...
22
- # end
23
- # end
24
- #def self.configure(plugin=nil, &block)
25
- # if block_given?
26
- # m = Module.new(&block)
27
- # m.extend m
28
- # @config << m
29
- # end
30
- # if plugin
31
- # @config << plugin
32
- # end
33
- #end
34
-
35
- def self.configure(&block)
36
- class_eval(&block)
37
- end
38
-
39
- def self.start(&block)
40
- define_method(:start, &block)
41
- end
42
-
43
- def self.finish(&block)
44
- define_method(:finish, &block)
45
- end
46
-
47
- #
48
- attr :specs
49
-
50
- #
51
- attr_accessor :format
52
-
53
- #
54
- attr_accessor :trace
55
-
56
- #attr :context
57
- #attr :count
58
-
59
- #attr_accessor :before
60
- #attr_accessor :after
61
-
62
- # New Specification
63
- def initialize(specs, options={})
64
- @specs = [specs].flatten
65
-
66
- @format = :dotprogress
67
- @trace = false
68
-
69
- options.each do |k,v|
70
- __send__("#{k}=", v) if v
71
- end
72
- end
73
-
74
- # Instance of selected Reporter subclass.
75
- def reporter
76
- case format
77
- when :dotprogress
78
- Reporter::DotProgress.new(reporter_options)
79
- when :verbatim
80
- Reporter::Verbatim.new(reporter_options)
81
- when :summary
82
- Reporter::Summary.new(reporter_options)
83
- when :script #ditto ?
84
- # TODO
85
- else
86
- Reporter::DotProgress.new(reporter_options)
87
- end
88
- end
89
-
90
- # Report options.
91
- #--
92
- # TODO: rename :verbose to :trace
93
- #++
94
- def reporter_options
95
- { :verbose => @trace }
96
- end
97
-
98
- #
99
- def output
100
- @output ||= reporter
101
- end
102
-
103
- #
104
- def check
105
- start
106
- output.report_intro
107
- specs.each do |spec| # loop through each specification and run it
108
- run_spec(spec) # run the specification
109
- end
110
- output.report_summary
111
- finish
112
- end
113
-
114
- # Run a specification.
115
- def run_spec(spec)
116
- script = Script.new(spec, output)
117
-
118
- # pretty sure this is the thing to do
119
- Dir.chdir(File.dirname(spec)) do
120
-
121
- output.report_start(spec)
122
-
123
- # TODO <-- plugin in here start (how to set?)
124
- #context.instance_eval(&spec.given) if spec.given
125
-
126
- script.run
127
-
128
- #spec.steps.each do |step|
129
- #output.report_step(self)
130
- #step.run(self, spec, context, output)
131
- #output.report_step_end(self)
132
- #end
133
-
134
- # TODO <-- plugin in here end
135
- #context.instance_eval(&spec.complete) if spec.complete
136
-
137
- output.report_end(spec)
138
- end
139
- end
140
-
141
- =begin
142
- # Run a specification step.
143
- #
144
- def run_step(spec, step)
145
- output.report_step(step)
146
- # TODO: Would spec.before + spec.code be better?
147
- context.instance_eval(@before, spec.file) if @before
148
- begin
149
- context.instance_eval(step.code, spec.file, step.lineno)
150
- output.report_pass(step)
151
- rescue Assertion => error
152
- output.report_fail(step, error)
153
- rescue Exception => error
154
- output.report_error(step, error)
155
- ensure
156
- context.instance_eval(@after, spec.file) if @after
157
- end
158
- end
159
-
160
- # Run a specification tabular step.
161
- #
162
- # TODO: Table reporting needs to be improved. Big time!
163
- def run_table(spec, step)
164
- table = YAML.load(File.new(step.file)) # yaml or csv ?
165
-
166
- vars = *table[0]
167
- rows = table[1..-1]
168
-
169
- output.report_step(step)
170
- context.instance_eval(@before, spec.file) if @before
171
- rows.each do |row|
172
- set = vars.zip(row).map{ |a| "#{a[0]}=#{a[1].inspect}" }.join(';')
173
- code = set + "\n" + step.code
174
- begin
175
- context.instance_eval(code, spec.file, step.lineno)
176
- #output.report_literal(set)
177
- output.report_pass(step)
178
- rescue Assertion => error
179
- output.report_fail(step, error)
180
- rescue Exception => error
181
- output.report_error(step, error)
182
- ensure
183
- context.instance_eval(@after, spec.file) if @after
184
- end
185
- end
186
- end
187
- =end
188
-
189
- def start
190
- end
191
-
192
- def finish
193
- end
194
-
195
- end#class Runner
196
-
197
- end#module QED
198
-
data/lib/qed/script1.rb DELETED
@@ -1,495 +0,0 @@
1
- module QED
2
- require 'yaml'
3
- require 'facets/dir/ascend'
4
-
5
- require 'ae'
6
-
7
- require 'qed/reporter/dotprogress'
8
- require 'qed/reporter/summary'
9
- require 'qed/reporter/verbatim'
10
-
11
- #Assertion = AE::Assertion
12
- Expectation = Assertor
13
-
14
- # Global Before
15
- def self.Before(&procedure)
16
- @_before = procedure if procedure
17
- @_before
18
- end
19
-
20
- # Global After
21
- def self.After(&procedure)
22
- @_after = procedure if procedure
23
- @_after
24
- end
25
-
26
- # New Specification
27
- #def initialize(specs, output=nil)
28
- # @specs = [specs].flatten
29
- #end
30
-
31
- # = Script
32
- #
33
- class Script
34
-
35
- #def self.load(file, output=nil)
36
- # new(File.read(file), output)
37
- #end
38
-
39
- # Path of demonstration script.
40
- attr :file
41
-
42
- # Reporter object to issue output calls.
43
- attr :output
44
-
45
- # List of helper scripts to require.
46
- attr :helpers
47
-
48
- # New Script
49
- def initialize(file, output=nil)
50
- @file = file
51
- @output = output || Reporter::Verbatim.new #(self)
52
- parse #_document(file)
53
- end
54
-
55
- # File basename less extension.
56
- def name
57
- @name ||= File.basename(file).chomp(File.extname(file))
58
- end
59
-
60
- #
61
- def directory
62
- @directory ||= Dir.pwd #File.dirname(File.expand_path(file))
63
- end
64
-
65
- #def convert
66
- # @source.gsub(/^\w/, '# \1')
67
- #end
68
-
69
- # Run the script.
70
- def run
71
- @lineno = 0
72
-
73
- $LOAD_PATH.unshift(directory)
74
-
75
- import_helpers
76
-
77
- steps.each do |step|
78
- output.report_step(step)
79
- case step
80
- when /^[=#]/
81
- output.report_header(step)
82
- when /^\S/
83
- output.report_comment(step)
84
- context.When.each do |(regex, proc)|
85
- if md = regex.match(step)
86
- proc.call(*md[1..-1])
87
- end
88
- end
89
- else
90
- #if context.table
91
- # run_table(step)
92
- #else
93
- run_step(step)
94
- #end
95
- end
96
- @lineno += step.count("\n")
97
- end
98
-
99
- $LOAD_PATH.index(directory){ |i| $LOAD_PATH.delete_at(i) }
100
- end
101
-
102
- #--
103
- # NOTE: The Around code is in place should we decide
104
- # to use it. I'm not sure yet if it's really neccessary,
105
- # since we have Before and After.
106
- #++
107
- def run_step(step=nil, &blk)
108
- QED.Before.call if QED.Before
109
- context.Before.call if context.Before
110
- begin
111
- if blk # TODO: Is this still used?
112
- blk.call #eval(step, context._binding)
113
- else
114
- #if context.Around
115
- # context.Around.call do
116
- # eval(step, context._binding, @file, @lineno+1)
117
- # end
118
- #else
119
- eval(step, context._binding, @file, @lineno+1)
120
- #end
121
- end
122
- output.report_pass(step) if step
123
- rescue Assertion => error
124
- output.report_fail(step, error)
125
- rescue Exception => error
126
- output.report_error(step, error)
127
- ensure
128
- context.After.call if context.After
129
- QED.After.call if QED.After
130
- end
131
- end
132
-
133
- =begin
134
- #
135
- def run_table(step)
136
- file = context.table
137
- Dir.ascend(Dir.pwd) do |path|
138
- f1 = File.join(path, file)
139
- f2 = File.join(path, 'fixtures', file)
140
- fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
141
- (file = fr; break) if fr
142
- end
143
- output.report_pass(step) #step)
144
-
145
- tbl = YAML.load(File.new(file))
146
- key = tbl.shift
147
- tbl.each do |set|
148
- assign = key.zip(set).map{ |k, v| "#{k}=#{v.inspect};" }.join
149
- run_table_step(assign + step, set)
150
- #run_step(set.inspect.tabto(4)){ blk.call(set) }
151
- #@_script.run_step(set.to_yaml.tabto(2)){ blk.call(set) }
152
- #@_script.output.report_table(set)
153
- end
154
- #output.report_pass(step) #step)
155
- context.table = nil
156
- end
157
-
158
- #
159
- #def run_table_step(step, set)
160
- def run_table_step(set, &blk)
161
- context.before.call if context.before
162
- begin
163
- #eval(step, context._binding, @file) # TODO: would be nice to know file and lineno here
164
- blk.call(*set)
165
- output.report_pass(' ' + set.inspect) #step)
166
- rescue Assertion => error
167
- output.report_fail(set.inspect, error)
168
- rescue Exception => error
169
- output.report_error(set.inspect, error)
170
- ensure
171
- context.after.call if context.after
172
- end
173
- end
174
- =end
175
-
176
- # Cut-up script into steps.
177
- def steps
178
- @steps ||= (
179
- code = false
180
- str = ''
181
- steps = []
182
- @source.each_line do |line|
183
- if /^\s*$/.match line
184
- str << line
185
- elsif /^[=]/.match line
186
- steps << str #.chomp("\n")
187
- steps << line #.chomp("\n")
188
- str = ''
189
- #str << line
190
- code = false
191
- elsif /^\S/.match line
192
- if code
193
- steps << str #.chomp("\n")
194
- str = ''
195
- str << line
196
- code = false
197
- else
198
- str << line
199
- end
200
- else
201
- if code
202
- str << line
203
- else
204
- steps << str
205
- str = ''
206
- str << line
207
- code = true
208
- end
209
- end
210
- end
211
- steps << str
212
- #steps.map{ |s| s.chomp("\n") }
213
- steps
214
- )
215
- end
216
-
217
- #
218
- def to_html
219
- require 'tilt'
220
- Tilt.new(file).render
221
- end
222
-
223
- #
224
- def parse
225
- steps = []
226
- require 'nokogiri'
227
- doc = Nokogiri::HTML(to_html)
228
- doc.root.traverse do |elem|
229
- case elem.name
230
- when /h*/
231
- steps << Head.new(elem.text)
232
- when "p"
233
- steps << Text.new(elem.text)
234
- when 'pre'
235
- steps << Code.new(elem.text)
236
- end
237
- end
238
- steps
239
- end
240
-
241
- class Head
242
- attr :text
243
- def initialize(text)
244
- @text = text
245
- end
246
- end
247
-
248
- class Code
249
- attr :text
250
- def initialize(text)
251
- @text = text
252
- end
253
- end
254
-
255
- class Text
256
- attr :text
257
- def initialize(text)
258
- @text = text
259
- end
260
- end
261
-
262
- # The run context.
263
- def context
264
- @context ||= Context.new(self)
265
- end
266
-
267
- #
268
- def import(helper)
269
- code = File.read(helper)
270
- eval(code, context._binding)
271
- end
272
-
273
- private
274
-
275
- # Splits the document into main source and footer
276
- # and extract the helper document references from
277
- # the footer.
278
- #
279
- def parse_document(file)
280
- text = File.read(file)
281
- index = text.rindex('---') || text.size
282
- source = text[0...index]
283
- footer = text[index+3..-1].to_s.strip
284
- #helpers = parse_helpers(footer)
285
- @source = source
286
- @footer = footer
287
- end
288
-
289
- #
290
- def parse_helpers(footer)
291
- helpers = []
292
- footer.split("\n").each do |line|
293
- next if line.strip == ''
294
- case line
295
- when /\[(.*?)\]\((.*?)\)/
296
- helpers << $2
297
- when /(.*?)\[(.*?)\]/
298
- helpers << $2
299
- end
300
- end
301
- helpers
302
- end
303
-
304
- =begin
305
- # Looks for a master +helper.rb+ file and a special
306
- # helpers/<name>.rb file. Both of these, when found, will
307
- # be imported when this script is run.
308
-
309
- def collect_helpers
310
- dir = File.dirname(file)
311
- list = []
312
- list << "helper.rb" if File.exist?(File.join(dir, "helper.rb"))
313
- list << "helpers/#{name}.rb" if File.exist?(File.join(dir, "helpers/#{name}.rb"))
314
- list
315
- end
316
- =end
317
-
318
- # TODO: How to determine where to find the env.rb file?
319
- #def require_environment
320
- # dir = File.dirname(file)
321
- # dir = File.expand_path(dir)
322
- # env = loop do
323
- # file = File.join(dir, 'env.rb')
324
- # break file if File.exist?(file)
325
- # break nil if ['demo', 'demos', 'doc', 'docs', 'test', 'tests'].include? File.basename(dir)
326
- # break nil if dir == Dir.pwd
327
- # dir = File.dirname(dir)
328
- # end
329
- # require(env) if env
330
- #end
331
-
332
- # FIXME: where to stop looking for helpers.
333
- def import_helpers
334
- hlp = []
335
- dir = Dir.pwd #File.expand_path(dir)
336
- env = loop do
337
- helpers.each do |helper|
338
- file = File.join(dir, 'helpers', helper)
339
- if File.exist?(file)
340
- hlp << file
341
- end
342
- end
343
- break if ['qed', 'demo', 'demos', 'doc', 'docs', 'test', 'tests'].include? File.basename(dir)
344
- dir = File.dirname(dir)
345
- end
346
- hlp.each{ |helper| import(helper) }
347
- end
348
-
349
- end
350
-
351
- #
352
- class Context < Module
353
-
354
- TABLE = /^TABLE\[(.*?)\]/i
355
-
356
- def initialize(script)
357
- @_script = script
358
- @_when = []
359
- @_tables = []
360
- end
361
-
362
- def _binding
363
- @_binding ||= binding
364
- end
365
-
366
- # Before each step.
367
- def Before(&procedure)
368
- @_before = procedure if procedure
369
- @_before
370
- end
371
-
372
- # After each step.
373
- def After(&procedure)
374
- @_after = procedure if procedure
375
- @_after
376
- end
377
-
378
- # Run code around each step.
379
- #
380
- # Around procedures must take a block, in which the step is run.
381
- #
382
- # Around do |&step|
383
- # ... do something here ...
384
- # step.call
385
- # ... do stiff stuff ...
386
- # end
387
- #
388
- #def Around(&procedure)
389
- # @_around = procedure if procedure
390
- # @_around
391
- #end
392
-
393
- # Comment match procedure.
394
- #
395
- # This is useful for creating unobtrusive setup and (albeit more
396
- # limited) teardown code. A pattern is matched against each comment
397
- # as it is processed. If there is match, the code procedure is
398
- # triggered, passing in any mathcing expression arguments.
399
- #
400
- def When(pattern=nil, &procedure)
401
- return @_when unless procedure
402
- raise ArgumentError unless pattern
403
- unless Regexp === pattern
404
- pattern = __when_string_to_regexp(pattern)
405
- end
406
- @_when << [pattern, procedure]
407
- end
408
-
409
- # Code match-and-transform procedure.
410
- #
411
- # This is useful to transform human readable code examples
412
- # into proper exectuable code. For example, say you want to
413
- # run shell code, but want to make if look like typical
414
- # shelle examples:
415
- #
416
- # $ cp fixture/a.rb fixture/b.rb
417
- #
418
- # You can use a transform to convert lines starting with '$'
419
- # into executable Ruby using #system.
420
- #
421
- # system('cp fixture/a.rb fixture/b.rb')
422
- #
423
- #def Transform(pattern=nil, &procedure)
424
- #
425
- #end
426
-
427
- # Table-based steps.
428
- def Table(file=nil, &blk)
429
- file = file || @_tables.last
430
- tbl = YAML.load(File.new(file))
431
- tbl.each do |set|
432
- blk.call(*set)
433
- end
434
- @_tables << file
435
- end
436
-
437
- # Read/Write a fixture.
438
- def Data(file, &content)
439
- raise if File.directory?(file)
440
- if content
441
- FileUtils.mkdir_p(File.dirname(fname))
442
- case File.extname(file)
443
- when '.yml', '.yaml'
444
- File.open(file, 'w'){ |f| f << content.call.to_yaml }
445
- else
446
- File.open(file, 'w'){ |f| f << content.call }
447
- end
448
- else
449
- #raise LoadError, "no such fixture file -- #{fname}" unless File.exist?(fname)
450
- case File.extname(file)
451
- when '.yml', '.yaml'
452
- YAML.load(File.new(file))
453
- else
454
- File.read(file)
455
- end
456
- end
457
- end
458
-
459
- private
460
-
461
- def __when_string_to_regexp(str)
462
- str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
463
- x =~ /\A\(\((.*)\)\)\z/ ? $1 : Regexp.escape(x)
464
- }.join
465
- str = str.gsub(/(\\\ )+/, '\s+')
466
- Regexp.new(str, Regexp::IGNORECASE)
467
-
468
- #rexps = []
469
- #str = str.gsub(/\(\((.*?)\)\)/) do |m|
470
- # rexps << '(' + $1 + ')'
471
- # "\0"
472
- #end
473
- #str = Regexp.escape(str)
474
- #rexps.each do |r|
475
- # str = str.sub("\0", r)
476
- #end
477
- #str = str.gsub(/(\\\ )+/, '\s+')
478
- #Regexp.new(str, Regexp::IGNORECASE)
479
- end
480
-
481
- #
482
- # check only local and maybe start paths
483
- #def __locate_file(file)
484
- # Dir.ascend(Dir.pwd) do |path|
485
- # f1 = File.join(path, file)
486
- # f2 = File.join(path, 'fixtures', file)
487
- # fr = File.file?(f1) ? f1 : File.exist?(f2) ? f2 : nil
488
- # (file = fr; break) if fr
489
- # end
490
- #end
491
-
492
- end
493
-
494
- end
495
-