qed 1.3 → 2.0.0

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