qed 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ module QED
2
+ module Reporter
3
+
4
+ require 'facets/string'
5
+ require 'ansi/code'
6
+
7
+ # = Reporter BaseClass
8
+ #
9
+ # Serves as the base class for all other specification
10
+ # output formats.
11
+ #
12
+ class BaseClass
13
+
14
+ ANSICode = ANSI::Code
15
+
16
+ attr :io
17
+ attr :steps
18
+ attr :pass
19
+ attr :fail
20
+ attr :error
21
+
22
+ def initialize(io=STDOUT)
23
+ @io = io
24
+ @specs = 0
25
+ @steps = 0
26
+ @pass = []
27
+ @fail = []
28
+ @error = []
29
+ end
30
+
31
+ # Before running any specifications.
32
+ def report_intro
33
+ end
34
+
35
+ # Beginning of a specification.
36
+ def report_start(spec)
37
+ @specs += 1
38
+ end
39
+
40
+ # Report a header.
41
+ def report_header(step)
42
+ end
43
+
44
+ # Report a comment.
45
+ def report_comment(step)
46
+ end
47
+
48
+ # Er... what was this for?
49
+ #def report_mode(step)
50
+ # report_literal(step)
51
+ #end
52
+
53
+ # Before running a step.
54
+ def report_step(step)
55
+ @steps += 1
56
+ end
57
+
58
+ # Report step passed.
59
+ def report_pass(step)
60
+ @pass << step
61
+ end
62
+
63
+ # Report step failed.
64
+ def report_fail(step, assertion)
65
+ @fail << [step, assertion]
66
+ end
67
+
68
+ # Report step raised an error.
69
+ def report_error(step, exception)
70
+ raise exception if $RESPECT_DEBUG
71
+ @error << [step, exception]
72
+ end
73
+
74
+ # Since regular macro step does not pass or fail,
75
+ # this method is used instead.
76
+ #
77
+ # TODO: Rename to #report_nominal (?)
78
+ def report_macro(step)
79
+ end
80
+
81
+ # Report on omitted step.
82
+ def report_omit(step)
83
+ end
84
+
85
+ # After running a step.
86
+ def report_step_end(step)
87
+ end
88
+
89
+ # End of a specification.
90
+ def report_end(spec)
91
+ end
92
+
93
+ # After running all specifications.
94
+ def report_summary
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+ end
101
+
@@ -0,0 +1,63 @@
1
+ module QED
2
+ module Reporter #:nodoc:
3
+
4
+ require 'qed/reporter/base'
5
+
6
+ # = DotProgress Reporter
7
+ #
8
+ class DotProgress < BaseClass
9
+
10
+ #
11
+ def report_intro
12
+ @start_time = Time.now
13
+ io.puts "Started"
14
+ end
15
+
16
+ #
17
+ def report_step(step)
18
+ super
19
+ #if step.code
20
+ io.print "."
21
+ #str = "(%s) %s" % [count.join('.'), str.tab(6).strip]
22
+ #puts "* #{step.text.tab(2).strip}"
23
+ #puts "\n#{step.code}\n" if $VERBOSE
24
+ #else
25
+ #puts "\n#{step.text}"
26
+ #end
27
+ end
28
+
29
+ #def report(str)
30
+ # count[-1] += 1 unless count.empty?
31
+ # str = str.chomp('.') + '.'
32
+ # str = count.join('.') + ' ' + str
33
+ # puts str.strip
34
+ #end
35
+
36
+ def report_summary
37
+ io.puts "\nFinished in #{Time.now - @start_time} seconds.\n\n"
38
+
39
+ @error.each do |step, exception|
40
+ io.puts ANSICode.red("***** ERROR *****")
41
+ io.puts "#{exception}"
42
+ io.puts ":#{exception.backtrace[0]}:"
43
+ #io.puts ":#{exception.backtrace[1]}:"
44
+ #io.puts exception.backtrace[1..-1] if $VERBOSE
45
+ io.puts
46
+ end
47
+
48
+ @fail.each do |step, assertion|
49
+ io.puts ANSICode.red("***** FAIL *****")
50
+ io.puts ANSICode.bold("#{assertion}")
51
+ io.puts ":#{assertion.backtrace[2]}:"
52
+ #io.puts assertion if $VERBOSE
53
+ io.puts
54
+ end
55
+
56
+ io.puts "%s specs, %s steps, %s failures, %s errors" % [@specs, @steps, @fail.size, @error.size] #, @pass.size ]
57
+ end
58
+
59
+ end#class DotProgress
60
+
61
+ end#module Reporter
62
+ end#module QED
63
+
@@ -0,0 +1,67 @@
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.tabto(2)
18
+ txt[0,1] = "*"
19
+ io.puts txt
20
+ end
21
+
22
+ def report_macro(step)
23
+ txt = step.to_s.tabto(2)
24
+ txt[0,1] = "*"
25
+ io.puts txt
26
+ #io.puts
27
+ #io.puts ANSICode.magenta("#{step}")
28
+ end
29
+
30
+ def report_pass(step)
31
+ #io.puts ANSICode.green("#{step}")
32
+ end
33
+
34
+ def report_fail(step, assertion)
35
+ msg = ''
36
+ msg << " ##### FAIL #####\n"
37
+ msg << " # " + assertion.to_s
38
+ msg = ANSICode.magenta(msg)
39
+ io.puts msg
40
+ #io.puts
41
+ io.puts ANSICode.red("#{step}")
42
+ end
43
+
44
+ def report_error(step, exception)
45
+ raise exception if $DEBUG
46
+ msg = ''
47
+ msg << " ##### ERROR #####\n"
48
+ msg << " # " + exception.to_s + "\n"
49
+ msg << " # " + exception.backtrace[0]
50
+ msg = ANSICode.magenta(msg)
51
+ io.puts msg
52
+ #io.puts
53
+ io.puts ANSICode.red("#{step}")
54
+ end
55
+
56
+ #def report(str)
57
+ # count[-1] += 1 unless count.empty?
58
+ # str = str.chomp('.') + '.'
59
+ # str = count.join('.') + ' ' + str
60
+ # io.puts str.strip
61
+ #end
62
+
63
+ end #class Summary
64
+
65
+ end#module Reporter
66
+ end#module QED
67
+
@@ -0,0 +1,90 @@
1
+ module QED
2
+ module Reporter #:nodoc:
3
+
4
+ require 'qed/reporter/base'
5
+
6
+ # = Verbatim Reporter
7
+ #
8
+ class Verbatim < BaseClass
9
+
10
+ #def report_step(step)
11
+ # super
12
+ # if step.code
13
+ # #str = "(%s) %s" % [count.join('.'), str.tab(6).strip]
14
+ # #io.puts "* #{step.to_s.tab(2).strip}"
15
+ # #io.puts
16
+ # #io.puts step.to_s
17
+ # #io.puts
18
+ # else
19
+ # #io.puts "#{step}\n" # TODO: This never happens.
20
+ # end
21
+ #end
22
+
23
+ def report_header(step)
24
+ io.puts ANSICode.bold("#{step}")
25
+ #io.puts
26
+ end
27
+
28
+ def report_comment(step)
29
+ io.puts step
30
+ #io.puts
31
+ end
32
+
33
+ #
34
+ def report_macro(step)
35
+ #io.puts
36
+ #io.puts step.text
37
+ io.puts ANSICode.magenta("#{step}")
38
+ #io.puts
39
+ end
40
+
41
+ #
42
+ def report_pass(step)
43
+ io.puts ANSICode.green("#{step}")
44
+ #io.puts
45
+ end
46
+
47
+ def report_fail(step, error)
48
+ tab = step.to_s.index(/\S/) #step.tab
49
+ io.puts ANSICode.red("#{step}")
50
+ #puts
51
+ msg = []
52
+ msg << ANSICode.bold(ANSICode.red("FAIL: ")) + error.to_str
53
+ msg << ANSICode.bold(error.backtrace[0].chomp(":in \`_binding'"))
54
+ io.puts msg.join("\n").tabto(tab||2)
55
+ io.puts
56
+ end
57
+
58
+ def report_error(step, error)
59
+ raise error if $DEBUG
60
+ tab = step.to_s.index(/\S/) #step.tab
61
+ io.puts ANSICode.red("#{step}")
62
+ #io.puts
63
+ msg = []
64
+ msg << ANSICode.bold(ANSICode.red("ERROR: ")) + error.to_str.sub(/for QED::Context.*?$/,'')
65
+ msg << ANSICode.bold(error.backtrace[0].chomp(":in \`_binding'"))
66
+ #msg = ANSICode.red(msg)
67
+ io.puts msg.join("\n").tabto(tab||2)
68
+ io.puts
69
+ end
70
+
71
+ def report_step_end(step)
72
+ io.puts
73
+ end
74
+
75
+ #def report(str)
76
+ # count[-1] += 1 unless count.empty?
77
+ # str = str.chomp('.') + '.'
78
+ # str = count.join('.') + ' ' + str
79
+ # puts str.strip
80
+ #end
81
+
82
+ #def report_table(set)
83
+ # puts ANSICode.magenta(set.to_yaml.tabto(2))
84
+ #end
85
+
86
+ end
87
+
88
+ end #module
89
+ end #module QED
90
+
@@ -0,0 +1,148 @@
1
+ #require 'quarry/behave'
2
+ #require 'quarry/runner/context'
3
+
4
+ module QED
5
+
6
+ require 'qed/script'
7
+
8
+ # = Specificaton Runner
9
+ #
10
+ # The Runner class loops through a set of specifications
11
+ # and executes each one in turn.
12
+ #
13
+ # The current working directory is changed to that of the
14
+ # specification script's. So any relative file references
15
+ # within a spec must take that into account.
16
+ #
17
+ class Runner
18
+
19
+ # QED::Spec::Runner.configure do
20
+ # def setup(spec)
21
+ # ...
22
+ # end
23
+ # def teardown(spec)
24
+ # ...
25
+ # end
26
+ # end
27
+ #def self.configure(plugin=nil, &block)
28
+ # if block_given?
29
+ # m = Module.new(&block)
30
+ # m.extend m
31
+ # @config << m
32
+ # end
33
+ # if plugin
34
+ # @config << plugin
35
+ # end
36
+ #end
37
+
38
+ attr :specs
39
+ attr :output
40
+
41
+ #attr :context
42
+ #attr :count
43
+
44
+ #attr_accessor :before
45
+ #attr_accessor :after
46
+
47
+ # New Specification
48
+ def initialize(specs, output=nil)
49
+ @specs = [specs].flatten
50
+ @output = output || Reporter::DotProgress.new #(self)
51
+ end
52
+
53
+ #
54
+ def check
55
+ output.report_intro
56
+ # loop through each specification and run it
57
+ specs.each do |spec|
58
+ # create a run context for the spec
59
+ #@context = Context.new(spec)
60
+ # run the specification
61
+ run_spec(spec)
62
+ end
63
+ output.report_summary
64
+ end
65
+
66
+ # Run a specification.
67
+ #
68
+ def run_spec(spec)
69
+ #report(spec.description)
70
+
71
+ #script = Script.load(spec, output)
72
+ script = Script.new(spec, output)
73
+
74
+ # pretty sure this is the thing to do
75
+ Dir.chdir(File.dirname(spec)) do
76
+
77
+ output.report_start(spec)
78
+
79
+ # TODO <-- plugin in here start (how to set?)
80
+ #context.instance_eval(&spec.given) if spec.given
81
+
82
+ script.run
83
+
84
+ #spec.steps.each do |step|
85
+ #output.report_step(self)
86
+ #step.run(self, spec, context, output)
87
+ #output.report_step_end(self)
88
+ #end
89
+
90
+ # TODO <-- plugin in here end
91
+ #context.instance_eval(&spec.complete) if spec.complete
92
+
93
+ output.report_end(spec)
94
+ end
95
+ end
96
+
97
+ =begin
98
+ # Run a specification step.
99
+ #
100
+ def run_step(spec, step)
101
+ output.report_step(step)
102
+ # TODO: Would spec.before + spec.code be better?
103
+ context.instance_eval(@before, spec.file) if @before
104
+ begin
105
+ context.instance_eval(step.code, spec.file, step.lineno)
106
+ output.report_pass(step)
107
+ rescue Assertion => error
108
+ output.report_fail(step, error)
109
+ rescue Exception => error
110
+ output.report_error(step, error)
111
+ ensure
112
+ context.instance_eval(@after, spec.file) if @after
113
+ end
114
+ end
115
+
116
+ # Run a specification tabular step.
117
+ #
118
+ # TODO: Table reporting needs to be improved. Big time!
119
+ def run_table(spec, step)
120
+ table = YAML.load(File.new(step.file)) # yaml or csv ?
121
+
122
+ vars = *table[0]
123
+ rows = table[1..-1]
124
+
125
+ output.report_step(step)
126
+ context.instance_eval(@before, spec.file) if @before
127
+ rows.each do |row|
128
+ set = vars.zip(row).map{ |a| "#{a[0]}=#{a[1].inspect}" }.join(';')
129
+ code = set + "\n" + step.code
130
+ begin
131
+ context.instance_eval(code, spec.file, step.lineno)
132
+ #output.report_literal(set)
133
+ output.report_pass(step)
134
+ rescue Assertion => error
135
+ output.report_fail(step, error)
136
+ rescue Exception => error
137
+ output.report_error(step, error)
138
+ ensure
139
+ context.instance_eval(@after, spec.file) if @after
140
+ end
141
+ end
142
+ end
143
+ =end
144
+
145
+ end#class Runner
146
+
147
+ end#module Quarry
148
+