qed 1.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.
@@ -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
+