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.
- data/HISTORY +15 -0
- data/LICENSE +344 -0
- data/MANIFEST +56 -0
- data/README.rdoc +97 -0
- data/bin/qed +150 -0
- data/bin/qedoc +52 -0
- data/demo/01_spec.qed +143 -0
- data/demo/01_spec.yaml +4 -0
- data/demo/qed_helper.rb +1 -0
- data/doc/qedoc/index.html +355 -0
- data/doc/qedoc/jquery.js +19 -0
- data/lib/qed.rb +5 -0
- data/lib/qed/assertion.rb +23 -0
- data/lib/qed/document.rb +188 -0
- data/lib/qed/document/jquery.js +19 -0
- data/lib/qed/document/markup.rb +53 -0
- data/lib/qed/document/template.rhtml +190 -0
- data/lib/qed/doubles/mock.rb +94 -0
- data/lib/qed/doubles/spy.rb +191 -0
- data/lib/qed/doubles/stub.rb +94 -0
- data/lib/qed/expectation.rb +60 -0
- data/lib/qed/grammar/assert.rb +104 -0
- data/lib/qed/grammar/expect.rb +121 -0
- data/lib/qed/grammar/legacy/assert.rb +291 -0
- data/lib/qed/grammar/should.rb +52 -0
- data/lib/qed/reporter/base.rb +101 -0
- data/lib/qed/reporter/dotprogress.rb +63 -0
- data/lib/qed/reporter/summary.rb +67 -0
- data/lib/qed/reporter/verbatim.rb +90 -0
- data/lib/qed/runner.rb +148 -0
- data/lib/qed/script.rb +179 -0
- data/lib/qed/utilities/extract.rb +137 -0
- data/lib/qed/utilities/monitor.rb +23 -0
- data/meta/authors +1 -0
- data/meta/created +1 -0
- data/meta/description +2 -0
- data/meta/homepage +1 -0
- data/meta/package +1 -0
- data/meta/project +1 -0
- data/meta/requires +1 -0
- data/meta/ruby +2 -0
- data/meta/summary +1 -0
- data/meta/title +1 -0
- data/meta/version +1 -0
- metadata +115 -0
@@ -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
|
+
|
data/lib/qed/runner.rb
ADDED
@@ -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
|
+
|