delano-tryouts 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +13 -0
- data/README.rdoc +12 -7
- data/bin/sergeant +4 -2
- data/lib/tryouts/cli/run.rb +52 -10
- data/lib/tryouts/drill/response.rb +112 -21
- data/lib/tryouts/drill/sergeant/api.rb +1 -1
- data/lib/tryouts/drill/sergeant/cli.rb +2 -2
- data/lib/tryouts/drill.rb +15 -5
- data/lib/tryouts/mixins/hash.rb +6 -0
- data/lib/tryouts/tryout.rb +60 -24
- data/lib/tryouts.rb +41 -10
- data/tryouts.gemspec +5 -5
- metadata +5 -15
data/CHANGES.txt
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
TRYOUTS, CHANGES
|
2
2
|
|
3
3
|
|
4
|
+
#### 0.6.3 (2009-06-25) ###############################
|
5
|
+
|
6
|
+
NOTE: command testing (:cli) is still disabled.
|
7
|
+
|
8
|
+
* FIXED: Now correctly append to existing Tryouts object
|
9
|
+
* CHANGE: Renamed :regex format to :match
|
10
|
+
* ADDED: Hella better runtime error handling
|
11
|
+
* ADDED: Better support for quiet (-q)
|
12
|
+
* ADDED: Verbose output now displays each dream vs reality
|
13
|
+
* ADDED: Skipped drills now appear in the report
|
14
|
+
* ADDED: new dream format: :ne (!=)
|
15
|
+
|
16
|
+
|
4
17
|
#### 0.6.2 (2009-06-24) ###############################
|
5
18
|
|
6
19
|
NOTE: command testing (:cli) is still disabled.
|
data/README.rdoc
CHANGED
@@ -4,19 +4,21 @@ Tryouts is a high-level testing library for your command-line applications and R
|
|
4
4
|
|
5
5
|
NOTE: The DSL syntax has changed significantly from 0.5 and command-line app tests are currently disabled.
|
6
6
|
|
7
|
-
==
|
7
|
+
== Syntax
|
8
8
|
|
9
9
|
Tryouts is a bit different than other testing libraries. Test definitions are organized in a similar way as Shoulda tests (although the keywords in the syntax are different).
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
*
|
11
|
+
=== Terminology
|
12
|
+
|
13
|
+
* Tryout: a set of drills (just like basketball tryouts is a set of drills)
|
14
|
+
* Drill: a single test.
|
15
|
+
* Dream: the expected outcome of a drill. There's always one or more dream per drill.
|
14
16
|
|
15
17
|
== Testing Ruby codes (an API)
|
16
18
|
|
17
19
|
Tryouts employs the same approach for testing Ruby codes. The return value of the drill block is compared to the expectation defined by the dream. Here is an example of including dreams inside the tryout definition.
|
18
20
|
|
19
|
-
library :caesars,
|
21
|
+
library :caesars, "../path/to/caesars/lib"
|
20
22
|
|
21
23
|
tryout "Common Usage" do
|
22
24
|
dream 3
|
@@ -24,17 +26,20 @@ Tryouts employs the same approach for testing Ruby codes. The return value of th
|
|
24
26
|
12 / 4
|
25
27
|
end
|
26
28
|
|
27
|
-
dream :
|
29
|
+
dream :Proc, :class
|
28
30
|
drill "Check the return value class" do
|
29
31
|
Proc.new do
|
30
32
|
:anything
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
|
-
dream :exception
|
36
|
+
dream NameError, :exception
|
35
37
|
drill "A test can pass based on the exception" do
|
36
38
|
raise NameError
|
37
39
|
end
|
40
|
+
|
41
|
+
dream /\w\d\w \d\w\d/, :match
|
42
|
+
drill "Knows where Santa Claus lives", 'H0H 0H0'
|
38
43
|
end
|
39
44
|
|
40
45
|
|
data/bin/sergeant
CHANGED
@@ -4,8 +4,8 @@ TRYOUTS_HOME = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
4
4
|
|
5
5
|
$:.unshift File.join(TRYOUTS_HOME, 'lib')
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
local_libs = %w{tryouts net-scp amazon-ec2 aws-s3 caesars drydock rye storable sysinfo annoy}
|
8
|
+
local_libs.each { |dir| $:.unshift File.join(TRYOUTS_HOME, '..', dir, 'lib') }
|
9
9
|
|
10
10
|
require 'drydock'
|
11
11
|
require 'tryouts'
|
@@ -58,3 +58,5 @@ module TryoutsCLI
|
|
58
58
|
command :list => Tryouts::CLI::Run
|
59
59
|
|
60
60
|
end
|
61
|
+
|
62
|
+
Drydock.run!(ARGV, STDIN) if Drydock.run?
|
data/lib/tryouts/cli/run.rb
CHANGED
@@ -32,41 +32,83 @@ class Run < Drydock::Command
|
|
32
32
|
# $ sergeant run [path/2/tryouts]
|
33
33
|
# Executes all tryouts that can be found from the current working directory.
|
34
34
|
def run
|
35
|
+
start = Time.now
|
35
36
|
|
36
37
|
Tryouts.enable_debug if Drydock.debug?
|
37
|
-
Tryouts.verbose = @global.verbose
|
38
|
-
|
39
|
-
|
38
|
+
Tryouts.verbose = @global.quiet ? -1 : @global.verbose
|
39
|
+
|
40
|
+
if Tryouts.verbose > 0
|
41
|
+
print "Tryouts #{Tryouts::VERSION} -- "
|
42
|
+
print "#{Tryouts.sysinfo.to_s} (#{RUBY_VERSION}) -- "
|
43
|
+
puts "#{start.strftime("%Y-%m-%d %H:%M:%S")}"
|
44
|
+
end
|
40
45
|
|
41
46
|
load_available_tryouts_files
|
42
|
-
|
47
|
+
|
43
48
|
passed, failed = 0, 0
|
44
49
|
Tryouts.instances.each_pair do |group,tryouts_inst|
|
45
|
-
puts '', ' %-60s'.att(:reverse) % group
|
50
|
+
puts '', ' %-60s'.att(:reverse) % group unless Tryouts.verbose < 0
|
46
51
|
puts " #{tryouts_inst.paths.join("\n ")}" if Tryouts.verbose > 0
|
47
52
|
tryouts_inst.tryouts.each_pair do |name,to|
|
48
|
-
|
49
|
-
|
53
|
+
begin
|
54
|
+
to.run
|
55
|
+
to.report
|
56
|
+
rescue SyntaxError, LoadError, Exception,
|
57
|
+
RuntimeError, NoMethodError, NameError => ex
|
58
|
+
tryouts_inst.errors << ex
|
59
|
+
end
|
50
60
|
STDOUT.flush
|
51
61
|
passed += to.passed
|
52
62
|
failed += to.failed
|
53
63
|
end
|
64
|
+
|
65
|
+
unless tryouts_inst.errors.empty?
|
66
|
+
title = '%-61s' % " RUNTIME ERRORS !?"
|
67
|
+
puts $/, title.color(:red).att(:reverse).bright
|
68
|
+
tryouts_inst.errors.each do |ex|
|
69
|
+
trace = Tryouts.verbose > 0 ? ex.backtrace : [ex.backtrace.first]
|
70
|
+
puts '%12s: %s (%s)' % ["error", ex.message.inspect, ex.class]
|
71
|
+
puts '%12s: %s' % ["trace", trace.join($/ + ' '*14)]
|
72
|
+
puts
|
73
|
+
end
|
74
|
+
end
|
54
75
|
end
|
55
|
-
|
76
|
+
|
77
|
+
if Tryouts.verbose < 0
|
78
|
+
if (passed == 0 && failed == 0)
|
79
|
+
exit -1
|
80
|
+
elsif failed == 0 && !Tryouts.failed?
|
81
|
+
puts "PASS"
|
82
|
+
exit 0
|
83
|
+
else
|
84
|
+
puts "FAIL"
|
85
|
+
exit 1
|
86
|
+
end
|
87
|
+
else
|
88
|
+
if Tryouts.verbose > 0
|
89
|
+
elapsed = Time.now - start
|
90
|
+
puts $/, " Elapsed: %.3f seconds" % elapsed.to_f #if elapsed > 0.01
|
91
|
+
end
|
56
92
|
if (passed == 0 && failed == 0)
|
57
93
|
puts DEV if Tryouts.verbose > 4
|
58
94
|
msg = " You didn't even try to acheive your dreams :[ "
|
59
|
-
|
95
|
+
puts $/, msg.att(:reverse)
|
96
|
+
exit -1
|
97
|
+
elsif failed == 0 && !Tryouts.failed?
|
60
98
|
puts PUG if Tryouts.verbose > 4
|
61
99
|
msg = passed > 1 ? "All %s dreams" : "Your only dream"
|
62
100
|
msg = (" #{msg} came true " % [passed+failed]).color(:green)
|
101
|
+
puts $/, msg.att(:reverse)
|
102
|
+
exit 0
|
63
103
|
else
|
64
104
|
puts BUG if Tryouts.verbose > 4
|
65
105
|
score = (passed.to_f / (passed.to_f+failed.to_f)) * 100
|
66
106
|
msg = " %s of %s dreams came true (%d%%) ".color(:red)
|
67
107
|
msg = msg % [passed, passed+failed, score.to_i]
|
108
|
+
puts $/, msg.att(:reverse)
|
109
|
+
exit 1
|
68
110
|
end
|
69
|
-
|
111
|
+
|
70
112
|
end
|
71
113
|
end
|
72
114
|
|
@@ -19,29 +19,85 @@ class Tryouts::Drill
|
|
19
19
|
## I don't think this check is necessary or useful
|
20
20
|
##return false unless reality.error.nil? && reality.trace.nil?
|
21
21
|
return true if reality.output == true and dream.nil?
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
22
|
+
|
23
|
+
begin
|
24
|
+
case dream.format
|
25
|
+
when :exception
|
26
|
+
reality.etype == dream.output
|
27
|
+
when :match
|
28
|
+
reality.output.respond_to?(:match) &&
|
29
|
+
!reality.output.match(dream.output).nil?
|
30
|
+
when :gt
|
31
|
+
reality.output > dream.output
|
32
|
+
when :gte
|
33
|
+
reality.output >= dream.output
|
34
|
+
when :lt
|
35
|
+
reality.output < dream.output
|
36
|
+
when :lte
|
37
|
+
reality.output <= dream.output
|
38
|
+
when :ne
|
39
|
+
reality.output != dream.output
|
40
|
+
when :respond_to?, :kind_of?, :is_a?
|
41
|
+
reality.output.send(dream.format, dream.output)
|
42
|
+
else
|
43
|
+
|
44
|
+
if dream.format.nil?
|
45
|
+
reality.output == dream.output
|
46
|
+
elsif reality.output.respond_to?(dream.format)
|
47
|
+
reality.output.send(dream.format) == dream.output
|
48
|
+
else
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
rescue => ex
|
54
|
+
puts ex.message, ex.backtrace if Tryouts.debug?
|
55
|
+
reality.error, reality.trace, reality.etype = ex.message, ex.backtrace, ex.class
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def Response.compare_string(dream, reality)
|
61
|
+
return "[noreality]" if reality.nil?
|
62
|
+
|
63
|
+
if reality.output == true and dream.nil?
|
64
|
+
return "#{reality.output.inspect} == true"
|
42
65
|
end
|
43
66
|
|
67
|
+
begin
|
68
|
+
case dream.format
|
69
|
+
when :exception
|
70
|
+
"#{reality.etype} == #{dream.output}"
|
71
|
+
when :match
|
72
|
+
"#{reality.output.inspect}.match(#{dream.output.inspect})"
|
73
|
+
when :gt, :gte, :lt, :lte, :ne
|
74
|
+
op = {:gt=>'>',:gte=>'>=', :lt=>'<', :lte => '<=', :ne => '!='}.find { |i| i[0] == dream.format }
|
75
|
+
"#{reality.output.inspect} #{op[1]} #{dream.output.inspect}"
|
76
|
+
when :respond_to?
|
77
|
+
"#{reality.output.class}.respond_to? #{dream.output.inspect}"
|
78
|
+
when :kind_of?
|
79
|
+
"#{reality.output.class}.kind_of? #{dream.output.inspect}"
|
80
|
+
when :is_a?
|
81
|
+
"#{reality.output.class}.is_a? #{dream.output.inspect}"
|
82
|
+
else
|
83
|
+
|
84
|
+
if dream.format.nil?
|
85
|
+
"#{reality.output.inspect} == #{dream.output.inspect}"
|
86
|
+
elsif reality.output.respond_to?(dream.format)
|
87
|
+
"#{reality.output.inspect}.#{dream.format} == #{dream.output.inspect}"
|
88
|
+
else
|
89
|
+
"#{reality.output.inspect}.respond_to?(#{dream.format.inspect}) == false"
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
rescue => ex
|
94
|
+
puts ex.message, ex.backtrace if Tryouts.debug?
|
95
|
+
reality.error, reality.trace, reality.etype = ex.message, ex.backtrace, ex.class
|
96
|
+
return ""
|
97
|
+
end
|
98
|
+
|
44
99
|
end
|
100
|
+
|
45
101
|
end
|
46
102
|
|
47
103
|
|
@@ -71,7 +127,23 @@ class Tryouts::Drill
|
|
71
127
|
end
|
72
128
|
|
73
129
|
def ==(reality)
|
74
|
-
|
130
|
+
return @answer unless @answer.nil?
|
131
|
+
@answer = Response.compare(self, reality)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_to_string(reality)
|
135
|
+
return @test_string unless @test_string.nil?
|
136
|
+
@test_string = Response.compare_string(self, reality)
|
137
|
+
end
|
138
|
+
|
139
|
+
def comparison_value
|
140
|
+
return @ret unless @ret.nil?
|
141
|
+
@ret = case @format
|
142
|
+
when :respond_to?, :is_a?, :kind_of?
|
143
|
+
true
|
144
|
+
else
|
145
|
+
@output
|
146
|
+
end
|
75
147
|
end
|
76
148
|
end
|
77
149
|
|
@@ -93,6 +165,25 @@ class Tryouts::Drill
|
|
93
165
|
def ==(dream)
|
94
166
|
Response.compare(dream, self)
|
95
167
|
end
|
168
|
+
|
169
|
+
def comparison_value(dream)
|
170
|
+
case dream.format
|
171
|
+
when :exception
|
172
|
+
@etype
|
173
|
+
when :respond_to?, :is_a?, :kind_of?
|
174
|
+
@output.send(dream.format, dream.output)
|
175
|
+
when nil
|
176
|
+
@output
|
177
|
+
else
|
178
|
+
if @output.nil?
|
179
|
+
@output
|
180
|
+
elsif @output.respond_to?(dream.format)
|
181
|
+
@output.send(dream.format)
|
182
|
+
else
|
183
|
+
@output
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
96
187
|
end
|
97
188
|
|
98
189
|
end
|
@@ -29,7 +29,7 @@ class Tryouts; class Drill; module Sergeant
|
|
29
29
|
begin
|
30
30
|
response.output = context.instance_eval &runtime
|
31
31
|
rescue => e
|
32
|
-
puts e.message, e.backtrace if Tryouts.
|
32
|
+
puts e.message, e.backtrace if Tryouts.verbose > 2
|
33
33
|
response.etype = e.class
|
34
34
|
response.error = e.message
|
35
35
|
response.trace = e.backtrace
|
@@ -38,13 +38,13 @@ class Tryouts; class Drill; module Sergeant
|
|
38
38
|
end
|
39
39
|
response.error = ret.stderr unless ret.stderr.empty?
|
40
40
|
rescue Rye::CommandNotFound => ex
|
41
|
-
puts ex.message, ex.backtrace if Tryouts.
|
41
|
+
puts ex.message, ex.backtrace if Tryouts.verbose > 2
|
42
42
|
response.etype = ex.class
|
43
43
|
response.ecode = ex.exit_code
|
44
44
|
response.error = "[#{@rbox.host}] Command not found: #{ex.message}"
|
45
45
|
response.trace = ex.backtrace
|
46
46
|
rescue Rye::CommandError => ex
|
47
|
-
puts ex.message, ex.backtrace if Tryouts.
|
47
|
+
puts ex.message, ex.backtrace if Tryouts.verbose > 2
|
48
48
|
response.etype = ex.class
|
49
49
|
response.ecode = ex.exit_code
|
50
50
|
response.output = ex.stdout
|
data/lib/tryouts/drill.rb
CHANGED
@@ -14,7 +14,8 @@ class Tryouts
|
|
14
14
|
require 'tryouts/drill/sergeant/api'
|
15
15
|
|
16
16
|
class NoSergeant < Tryouts::Exception; end
|
17
|
-
|
17
|
+
class UnknownFormat < Tryouts::Exception; end
|
18
|
+
|
18
19
|
# A symbol specifying the drill type. One of: :cli, :api
|
19
20
|
attr_reader :dtype
|
20
21
|
# The name of the drill. This should match the name used in the dreams file.
|
@@ -30,7 +31,7 @@ class Tryouts
|
|
30
31
|
attr_reader :reality
|
31
32
|
|
32
33
|
def initialize(name, dtype, *args, &drill)
|
33
|
-
@name, @dtype, @drill = name, dtype, drill
|
34
|
+
@name, @dtype, @drill, @skip = name, dtype, drill, false
|
34
35
|
@dreams = []
|
35
36
|
if @dtype == :cli
|
36
37
|
@sergeant = Tryouts::Drill::Sergeant::CLI.new *args
|
@@ -38,6 +39,8 @@ class Tryouts
|
|
38
39
|
default_output = drill.nil? ? args.shift : nil
|
39
40
|
@sergeant = Tryouts::Drill::Sergeant::API.new default_output
|
40
41
|
@dreams << Tryouts::Drill::Dream.new(*args) unless args.empty?
|
42
|
+
elsif @dtype == :skip
|
43
|
+
@skip = true
|
41
44
|
else
|
42
45
|
raise NoSergeant, "Weird drill sergeant: #{@dtype}"
|
43
46
|
end
|
@@ -46,10 +49,11 @@ class Tryouts
|
|
46
49
|
drill_args = [] if dtype == :cli && drill.is_a?(Proc)
|
47
50
|
@reality = Tryouts::Drill::Reality.new
|
48
51
|
end
|
49
|
-
|
52
|
+
|
53
|
+
def skip?; @skip; end
|
54
|
+
|
50
55
|
def run(context=nil)
|
51
56
|
begin
|
52
|
-
print Tryouts::DRILL_MSG % @name
|
53
57
|
@reality = @sergeant.run @drill, context
|
54
58
|
# Store the stash from the drill block
|
55
59
|
@reality.stash = context.stash if context.respond_to? :stash
|
@@ -66,7 +70,13 @@ class Tryouts
|
|
66
70
|
end
|
67
71
|
|
68
72
|
def success?
|
69
|
-
|
73
|
+
return false if @dreams.empty? && @reality.output != true
|
74
|
+
begin
|
75
|
+
@dreams.each { |d| return false unless d == @reality }
|
76
|
+
rescue => ex
|
77
|
+
puts ex.message, ex.backtrace if Tryouts.debug?
|
78
|
+
return false
|
79
|
+
end
|
70
80
|
true
|
71
81
|
end
|
72
82
|
|
data/lib/tryouts/mixins/hash.rb
CHANGED
@@ -22,6 +22,12 @@ class Hash
|
|
22
22
|
end
|
23
23
|
|
24
24
|
unless method_defined?(:last)
|
25
|
+
# Ruby 1.9 doesn't have a Hash#last (but Tryouts::OrderedHash does).
|
26
|
+
# It's used in Tryouts to return the most recently added instance of
|
27
|
+
# Tryouts to @@instances.
|
28
|
+
#
|
29
|
+
# NOTE: This method is defined only when Hash.method_defined?(:last)
|
30
|
+
# returns false.
|
25
31
|
def last
|
26
32
|
self[ self.keys.last ]
|
27
33
|
end
|
data/lib/tryouts/tryout.rb
CHANGED
@@ -21,6 +21,8 @@ class Tryouts
|
|
21
21
|
attr_reader :passed
|
22
22
|
# The number of dreams that did not come true (failed drills)
|
23
23
|
attr_reader :failed
|
24
|
+
# The number of skipped drills
|
25
|
+
attr_reader :skipped
|
24
26
|
# For drill type :cli, this is the name of the command to test. It
|
25
27
|
# should be a valid method available to a Rye::Box object.
|
26
28
|
# For drill type :api, this attribute is ignored.
|
@@ -35,7 +37,7 @@ class Tryouts
|
|
35
37
|
raise "#{dtype} is not a valid drill type" if !@@valid_dtypes.member?(dtype)
|
36
38
|
@name, @dtype, @command = name, dtype, command
|
37
39
|
@drills, @dream_catcher = [], []
|
38
|
-
@passed, @failed = 0, 0
|
40
|
+
@passed, @failed, @skipped = 0, 0, 0
|
39
41
|
end
|
40
42
|
|
41
43
|
## --------------------------------------- EXTERNAL API -----
|
@@ -44,54 +46,85 @@ class Tryouts
|
|
44
46
|
# the external DSL methods: dream, drill, xdrill
|
45
47
|
def from_block(b=nil, &inline)
|
46
48
|
runtime = b.nil? ? inline : b
|
47
|
-
|
49
|
+
begin
|
50
|
+
instance_eval &runtime
|
51
|
+
rescue => ex
|
52
|
+
raise ex
|
53
|
+
end
|
48
54
|
end
|
49
55
|
|
50
56
|
# Execute all Drill objects
|
51
57
|
def run
|
52
58
|
DrillContext.module_eval &setup if setup.is_a?(Proc)
|
53
|
-
puts Tryouts::TRYOUT_MSG.bright % @name
|
59
|
+
puts Tryouts::TRYOUT_MSG.bright % @name unless Tryouts.verbose < 0
|
54
60
|
@drills.each do |drill|
|
61
|
+
print Tryouts::DRILL_MSG % drill.name unless Tryouts.verbose < 0
|
62
|
+
if drill.skip?
|
63
|
+
puts "SKIP" if Tryouts.verbose >= 0
|
64
|
+
puts if Tryouts.verbose > 0
|
65
|
+
@skipped += 1
|
66
|
+
next
|
67
|
+
end
|
55
68
|
drill.run DrillContext.new
|
69
|
+
drill.success? ? @passed += 1 : @failed += 1
|
70
|
+
next if Tryouts.verbose < 0
|
56
71
|
note = drill.dreams.empty? ? '[nodream]' : ''
|
57
|
-
|
58
|
-
puts
|
72
|
+
c = drill.success? ? :green : :red
|
73
|
+
puts drill.success? ? "PASS".color(c).bright : "FAIL #{note}".color(c).bright
|
59
74
|
if Tryouts.verbose > 1
|
60
|
-
drill.
|
61
|
-
puts '%
|
75
|
+
if drill.dreams.empty?
|
76
|
+
puts '%6s%s'.color(c) % ['', drill.reality.output.inspect]
|
77
|
+
else
|
78
|
+
drill.dreams.each do |dream|
|
79
|
+
if dream != drill.reality
|
80
|
+
puts '%6s%s'.color(c) % ['', drill.reality.output.inspect]
|
81
|
+
else
|
82
|
+
puts '%6s%s'.color(:green) % ["", dream.test_to_string(drill.reality)]
|
83
|
+
end
|
84
|
+
end
|
62
85
|
end
|
86
|
+
elsif Tryouts.verbose > 0
|
87
|
+
puts '%6s%s'.color(c) % ['', drill.reality.output.inspect]
|
63
88
|
end
|
64
|
-
drill.success? ? @passed += 1 : @failed += 1
|
65
89
|
end
|
66
90
|
DrillContext.module_eval &clean if clean.is_a?(Proc)
|
67
91
|
end
|
68
92
|
|
69
93
|
# Prints error output. If there are no errors, it prints nothing.
|
70
94
|
def report
|
95
|
+
return if Tryouts.verbose < 0
|
71
96
|
return true if success?
|
72
|
-
failed = @drills.select { |d| !d.success? }
|
97
|
+
failed = @drills.select { |d| !d.skip? && !d.success? }
|
73
98
|
failed.each_with_index do |drill,index|
|
74
99
|
dreams, reality = drill.dreams, drill.reality
|
75
|
-
title = ' %-59s' % %Q{ERROR #{index+1}/#{failed.size} "#{drill.name}"}
|
76
|
-
puts $/, ' ' << title.color(:red).att(:reverse)
|
77
100
|
|
78
|
-
|
79
|
-
|
80
|
-
puts '
|
81
|
-
|
82
|
-
|
83
|
-
puts '%
|
84
|
-
end
|
85
|
-
puts '%12s: %s' % ["returned", reality.output.inspect]
|
86
|
-
unless reality.error.nil?
|
87
|
-
puts '%12s: %s' % ["error", reality.error.inspect]
|
101
|
+
unless dreams.empty?
|
102
|
+
title = ' %-51s %2d/%-2d ' % [drill.name, index+1, failed.size]
|
103
|
+
puts $/, ' ' << title.color(:red).att(:reverse)
|
104
|
+
|
105
|
+
drill.reality.stash.each_pair do |n,v|
|
106
|
+
puts '%14s: %s' % [n,v.inspect]
|
88
107
|
end
|
89
|
-
|
90
|
-
|
108
|
+
|
109
|
+
dreams.each do |dream|
|
110
|
+
next if dream == reality #? :normal : :red
|
111
|
+
puts '%12s: %s'.color(:red) % ["test", dream.test_to_string(drill.reality)]
|
112
|
+
puts '%12s: %s' % ["returned", reality.comparison_value(dream).inspect]
|
113
|
+
puts '%12s: %s' % ["expected", dream.comparison_value.inspect]
|
91
114
|
puts
|
92
115
|
end
|
93
116
|
|
94
117
|
end
|
118
|
+
|
119
|
+
unless reality.error.nil?
|
120
|
+
puts '%12s: %s (%s)' % ["error", reality.error.inspect, reality.etype]
|
121
|
+
end
|
122
|
+
unless reality.trace.nil?
|
123
|
+
trace = Tryouts.verbose > 1 ? reality.trace : [reality.trace.first]
|
124
|
+
puts '%12s: %s' % ["trace", trace.join($/ + ' '*14)]
|
125
|
+
puts
|
126
|
+
end
|
127
|
+
|
95
128
|
end
|
96
129
|
false
|
97
130
|
end
|
@@ -137,7 +170,10 @@ class Tryouts
|
|
137
170
|
self.add_drill drill
|
138
171
|
end
|
139
172
|
# A quick way to comment out a drill
|
140
|
-
def xdrill(*args, &b)
|
173
|
+
def xdrill(dname, *args, &b)
|
174
|
+
@dream_catcher.clear # Otherwise the next drill will get them...
|
175
|
+
self.add_drill Tryouts::Drill.new(dname, :skip)
|
176
|
+
end
|
141
177
|
|
142
178
|
|
143
179
|
#
|
data/lib/tryouts.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
|
2
|
+
require 'time'
|
2
3
|
require 'sysinfo'
|
4
|
+
require 'digest/sha1'
|
3
5
|
require 'ostruct'
|
4
6
|
require 'yaml'
|
7
|
+
|
5
8
|
begin; require 'json'; rescue LoadError; end # json may not be installed
|
6
9
|
|
7
|
-
GYMNASIUM_HOME = File.join(Dir.pwd, 'tryouts') ## also check try (for rye)
|
10
|
+
GYMNASIUM_HOME = File.join(Dir.pwd, '{tryouts,try}') ## also check try (for rye)
|
8
11
|
GYMNASIUM_GLOB = File.join(GYMNASIUM_HOME, '**', '*_tryouts.rb')
|
9
12
|
|
10
13
|
|
@@ -29,7 +32,7 @@ class Tryouts
|
|
29
32
|
# Raised when there is a problem loading or parsing a Tryouts::Drill::Dream object
|
30
33
|
class BadDreams < Exception; end
|
31
34
|
|
32
|
-
VERSION = "0.6.
|
35
|
+
VERSION = "0.6.3"
|
33
36
|
|
34
37
|
require 'tryouts/mixins'
|
35
38
|
require 'tryouts/tryout'
|
@@ -51,6 +54,8 @@ class Tryouts
|
|
51
54
|
|
52
55
|
@@debug = false
|
53
56
|
@@verbose = 0
|
57
|
+
# This will be true if any error occurred during any of the drills or parsing.
|
58
|
+
@@failed = false
|
54
59
|
|
55
60
|
def self.debug?; @@debug; end
|
56
61
|
def self.enable_debug; @@debug = true; end
|
@@ -59,6 +64,8 @@ class Tryouts
|
|
59
64
|
def self.verbose; @@verbose; end
|
60
65
|
def self.verbose=(v); @@verbose = (v == true) ? 1 : v; end
|
61
66
|
|
67
|
+
def self.failed?; @@failed; end
|
68
|
+
def self.failed=(v); @@failed = v; end
|
62
69
|
|
63
70
|
# Returns +@@instances+
|
64
71
|
def self.instances; @@instances; end
|
@@ -77,11 +84,13 @@ class Tryouts
|
|
77
84
|
attr_accessor :command
|
78
85
|
# A Symbol representing the name of the library taking part in the tryouts. For @dtype :api only.
|
79
86
|
attr_accessor :library
|
80
|
-
|
87
|
+
# An Array of exceptions that were raised during the tryouts that were not captured by a drill.
|
88
|
+
attr_reader :errors
|
89
|
+
|
81
90
|
def initialize(group=nil)
|
82
91
|
@group = group || "Default Group"
|
83
92
|
@tryouts = HASH_TYPE.new
|
84
|
-
@paths = []
|
93
|
+
@paths, @errors = [], []
|
85
94
|
@command = nil
|
86
95
|
end
|
87
96
|
|
@@ -131,7 +140,13 @@ class Tryouts
|
|
131
140
|
@library = name.to_sym
|
132
141
|
@dtype = :api
|
133
142
|
$LOAD_PATH.unshift path unless path.nil?
|
134
|
-
|
143
|
+
begin
|
144
|
+
require @library.to_s
|
145
|
+
rescue SyntaxError, LoadError, Exception,
|
146
|
+
RuntimeError, NoMethodError, NameError => ex
|
147
|
+
@errors << ex
|
148
|
+
Tryouts.failed = true
|
149
|
+
end
|
135
150
|
end
|
136
151
|
# Calls Tryouts#library on the current instance of Tryouts
|
137
152
|
#
|
@@ -174,7 +189,13 @@ class Tryouts
|
|
174
189
|
end
|
175
190
|
|
176
191
|
# Process the rest of the DSL
|
177
|
-
|
192
|
+
begin
|
193
|
+
to.from_block block if block
|
194
|
+
rescue SyntaxError, LoadError, Exception,
|
195
|
+
RuntimeError, NoMethodError, NameError => ex
|
196
|
+
@errors << ex
|
197
|
+
Tryouts.failed = true
|
198
|
+
end
|
178
199
|
to
|
179
200
|
end
|
180
201
|
# Calls Tryouts#tryout on the current instance of Tryouts
|
@@ -221,13 +242,23 @@ class Tryouts
|
|
221
242
|
raise "No such file: #{fpath}" unless File.exists?(fpath)
|
222
243
|
file_content = File.read(fpath)
|
223
244
|
to = Tryouts.new
|
224
|
-
|
225
|
-
if @@instances.has_key? to.group
|
226
|
-
to = @@instances[to.group]
|
245
|
+
begin
|
227
246
|
to.instance_eval file_content, fpath
|
247
|
+
# After parsing the DSL, we'll know the group name.
|
248
|
+
# If a Tryouts object already exists for that group
|
249
|
+
# we'll use that instead and re-parse the DSL.
|
250
|
+
if @@instances.has_key? to.group
|
251
|
+
to = @@instances[to.group]
|
252
|
+
to.instance_eval file_content, fpath
|
253
|
+
end
|
254
|
+
to.paths << fpath
|
255
|
+
rescue SyntaxError, LoadError, Exception,
|
256
|
+
RuntimeError, NoMethodError, NameError => ex
|
257
|
+
to.errors << ex
|
258
|
+
Tryouts.failed = true
|
228
259
|
end
|
229
|
-
to.paths << fpath
|
230
260
|
@@instances[to.group] = to
|
261
|
+
to
|
231
262
|
end
|
232
263
|
|
233
264
|
# Run all Tryout objects in +@tryouts+
|
data/tryouts.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "tryouts"
|
3
3
|
s.rubyforge_project = "tryouts"
|
4
|
-
s.version = "0.6.
|
4
|
+
s.version = "0.6.3"
|
5
5
|
s.summary = "Tryouts are high-level tests for your Ruby code. May all your dreams come true!"
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
@@ -24,8 +24,8 @@
|
|
24
24
|
|
25
25
|
# = DEPENDENCIES =
|
26
26
|
# Add all gem dependencies
|
27
|
-
s.add_dependency 'drydock', '>= 0.6.5'
|
28
27
|
s.add_dependency 'rye', '>= 0.8.2'
|
28
|
+
s.add_dependency 'drydock', '>= 0.6.6'
|
29
29
|
s.add_dependency 'sysinfo', '>= 0.5.1'
|
30
30
|
|
31
31
|
# = MANIFEST =
|
@@ -64,12 +64,12 @@
|
|
64
64
|
s.specification_version = 2
|
65
65
|
|
66
66
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
67
|
-
s.add_runtime_dependency(%q<RedCloth>, [">= 4.0.4"])
|
67
|
+
#s.add_runtime_dependency(%q<RedCloth>, [">= 4.0.4"])
|
68
68
|
else
|
69
|
-
s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
69
|
+
#s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
70
70
|
end
|
71
71
|
else
|
72
|
-
s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
72
|
+
#s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
73
73
|
end
|
74
74
|
|
75
75
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delano-tryouts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -12,16 +12,6 @@ cert_chain: []
|
|
12
12
|
date: 2009-05-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: drydock
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.6.5
|
24
|
-
version:
|
25
15
|
- !ruby/object:Gem::Dependency
|
26
16
|
name: rye
|
27
17
|
type: :runtime
|
@@ -33,24 +23,24 @@ dependencies:
|
|
33
23
|
version: 0.8.2
|
34
24
|
version:
|
35
25
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
26
|
+
name: drydock
|
37
27
|
type: :runtime
|
38
28
|
version_requirement:
|
39
29
|
version_requirements: !ruby/object:Gem::Requirement
|
40
30
|
requirements:
|
41
31
|
- - ">="
|
42
32
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
33
|
+
version: 0.6.6
|
44
34
|
version:
|
45
35
|
- !ruby/object:Gem::Dependency
|
46
|
-
name:
|
36
|
+
name: sysinfo
|
47
37
|
type: :runtime
|
48
38
|
version_requirement:
|
49
39
|
version_requirements: !ruby/object:Gem::Requirement
|
50
40
|
requirements:
|
51
41
|
- - ">="
|
52
42
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
43
|
+
version: 0.5.1
|
54
44
|
version:
|
55
45
|
description: Tryouts are high-level tests for your Ruby code. May all your dreams come true!
|
56
46
|
email: tryouts@solutious.com
|