delano-tryouts 0.4.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/CHANGES.txt +6 -0
- data/LICENSE.txt +19 -0
- data/README.rdoc +122 -0
- data/Rakefile +80 -0
- data/bin/mockout +49 -0
- data/bin/tryouts +38 -0
- data/lib/tryouts/cli/run.rb +74 -0
- data/lib/tryouts/cli.rb +15 -0
- data/lib/tryouts/drill/response.rb +109 -0
- data/lib/tryouts/drill/sergeant/cli.rb +49 -0
- data/lib/tryouts/drill.rb +103 -0
- data/lib/tryouts/mixins/hash.rb +25 -0
- data/lib/tryouts/mixins.rb +2 -0
- data/lib/tryouts/tryout.rb +194 -0
- data/lib/tryouts.rb +334 -0
- data/tryouts/mockoutcli_dreams.rb +19 -0
- data/tryouts/mockoutcli_dreams.yaml +11 -0
- data/tryouts/mockoutcli_tryouts.rb +26 -0
- data/tryouts.gemspec +75 -0
- metadata +115 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
|
2
|
+
class Tryouts
|
3
|
+
|
4
|
+
# = Tryout
|
5
|
+
#
|
6
|
+
# A Tryout is a set of drills (each drill is a test).
|
7
|
+
#
|
8
|
+
class Tryout
|
9
|
+
|
10
|
+
# The name of this tryout
|
11
|
+
attr_reader :name
|
12
|
+
|
13
|
+
# A Hash of Dream objects for this Tryout. The keys are drill names.
|
14
|
+
attr_accessor :dreams
|
15
|
+
|
16
|
+
# An Array of Drill objects
|
17
|
+
attr_reader :drills
|
18
|
+
|
19
|
+
# A default value for Drill.dtype
|
20
|
+
attr_reader :dtype
|
21
|
+
|
22
|
+
# For drill type :cli, this is the name of the command to test. It
|
23
|
+
# should be a valid method available to a Rye::Box object.
|
24
|
+
# For drill type :api, this attribute is ignored.
|
25
|
+
attr_reader :command
|
26
|
+
|
27
|
+
# A block to executed one time before starting the drills
|
28
|
+
attr_reader :setup
|
29
|
+
|
30
|
+
# A block to executed one time before starting the drills
|
31
|
+
attr_reader :clean
|
32
|
+
|
33
|
+
@@valid_dtypes = [:cli, :api]
|
34
|
+
|
35
|
+
# All :api Drills are run within this context (not used for :cli).
|
36
|
+
# Each Drill is executed in a new instance of this class. That means
|
37
|
+
# instance variables are not carried through, but class variables are.
|
38
|
+
# The before and after blocks are also run in this context.
|
39
|
+
class DrillContext; end
|
40
|
+
|
41
|
+
def initialize(name, dtype, command=nil, *args)
|
42
|
+
raise "Must supply command for dtype :cli" if dtype == :cli && command.nil?
|
43
|
+
raise "#{dtype} is not a valid drill type" if !@@valid_dtypes.member?(dtype)
|
44
|
+
@name, @dtype, @command = name, dtype, command
|
45
|
+
@drills = []
|
46
|
+
@dreams = {}
|
47
|
+
end
|
48
|
+
|
49
|
+
## --------------------------------------- EXTERNAL API -----
|
50
|
+
|
51
|
+
# Populate this Tryout from a block. The block should contain calls to
|
52
|
+
# the external DSL methods: dream, drill, xdrill
|
53
|
+
def from_block(b, &inline)
|
54
|
+
instance_eval &b
|
55
|
+
end
|
56
|
+
|
57
|
+
# Execute all Drill objects
|
58
|
+
def run
|
59
|
+
update_drills! # Ensure all drills have all known dreams
|
60
|
+
DrillContext.new.instance_eval &setup if setup.is_a?(Proc)
|
61
|
+
puts Tryouts::TRYOUT_MSG % @name
|
62
|
+
@drills.each do |drill|
|
63
|
+
drill.run(DrillContext.new) # Returns true or false
|
64
|
+
end
|
65
|
+
DrillContext.new.instance_eval &clean if clean.is_a?(Proc)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Prints error output. If there are no errors, it prints nothing.
|
69
|
+
def report
|
70
|
+
if success?
|
71
|
+
puts $/, "All your dreams came true"
|
72
|
+
return
|
73
|
+
end
|
74
|
+
puts $/, "ERRORS:"
|
75
|
+
@drills.each do |drill|
|
76
|
+
next if drill.success?
|
77
|
+
puts Tryouts::DRILL_MSG % drill.name
|
78
|
+
if drill.reality.rcode < 0
|
79
|
+
puts '%24s' % drill.reality.emsg
|
80
|
+
next
|
81
|
+
end
|
82
|
+
|
83
|
+
if drill.dream
|
84
|
+
drill.discrepency.each do |d|
|
85
|
+
puts '%24s: %s' % ["dream #{d}", drill.dream.send(d).inspect]
|
86
|
+
puts '%24s: %s' % ["reality #{d}", drill.reality.send(d).inspect]
|
87
|
+
end
|
88
|
+
else
|
89
|
+
puts '%24s' % ["[nodream]"]
|
90
|
+
if drill.reality.rcode > 0
|
91
|
+
puts '%24s: %s' % ["rcode", drill.reality.rcode.inspect]
|
92
|
+
puts '%24s: %s' % ["msg", drill.reality.emsg.inspect]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if drill.reality.rcode > 0
|
97
|
+
puts '%24s: %s' % ["backtrace", drill.reality.backtrace.inspect]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Did every Tryout finish successfully?
|
103
|
+
def success?
|
104
|
+
# Returns true only when every Tryout result returns true
|
105
|
+
!(@drills.collect { |r| r.success? }.member?(false))
|
106
|
+
end
|
107
|
+
|
108
|
+
# Add a Drill object to the list for this Tryout. If there is a dream
|
109
|
+
# defined with the same name as the Drill, that dream will be given to
|
110
|
+
# the Drill before its added to the list.
|
111
|
+
def add_drill(d)
|
112
|
+
d.add_dream @dreams[d.name] if !@dreams.nil? && @dreams.has_key?(d.name)
|
113
|
+
drills << d if d.is_a?(Tryouts::Drill)
|
114
|
+
d
|
115
|
+
end
|
116
|
+
|
117
|
+
# Goes through the list of Drill objects (@drills) and gives each
|
118
|
+
# one its associated Dream object (if available).
|
119
|
+
#
|
120
|
+
# This method is called before Tryout#run, but is only necessary in
|
121
|
+
# the case where dreams where loaded after the drills were defined.
|
122
|
+
def update_drills!
|
123
|
+
return if @dreams.nil?
|
124
|
+
@drills.each do |drill|
|
125
|
+
next unless @dreams.has_key?(drill.name)
|
126
|
+
drill.add_dream @dreams[drill.name]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
## --------------------------------------- EXTERNAL DSL -----
|
131
|
+
|
132
|
+
# A block to executed one time _before_ starting the drills
|
133
|
+
def setup(&block)
|
134
|
+
return @setup unless block
|
135
|
+
@setup = block
|
136
|
+
end
|
137
|
+
|
138
|
+
# A block to executed one time _after_ the drills
|
139
|
+
def clean(&block)
|
140
|
+
return @clean unless block
|
141
|
+
@clean = block
|
142
|
+
end
|
143
|
+
|
144
|
+
# +name+ of the Drill associated to this Dream
|
145
|
+
# +output+ A String or Array of expected output. A Dream object will be created using this value (optional)
|
146
|
+
# +definition+ is a block which will be run on an instance of Dream
|
147
|
+
#
|
148
|
+
# NOTE: This method is DSL-only. It's not intended to be used in OO syntax.
|
149
|
+
def dream(name, output=nil, format=:string, rcode=0, emsg=nil, &definition)
|
150
|
+
if output.nil?
|
151
|
+
dobj = Tryouts::Drill::Dream.from_block definition
|
152
|
+
else
|
153
|
+
dobj = Tryouts::Drill::Dream.new(output)
|
154
|
+
dobj.format, dobj.rcode, dobj.emsg = format, rcode, emsg
|
155
|
+
end
|
156
|
+
@dreams[name] = dobj
|
157
|
+
|
158
|
+
dobj
|
159
|
+
end
|
160
|
+
|
161
|
+
# Create and add a Drill object to the list for this Tryout
|
162
|
+
# +name+ is the name of the drill.
|
163
|
+
# +args+ is sent directly to the Drill class. The values are specific on the Sergeant.
|
164
|
+
def drill(name, *args, &b)
|
165
|
+
args.unshift(@command) if @dtype == :cli
|
166
|
+
drill = Tryouts::Drill.new(name, @dtype, *args, &b)
|
167
|
+
add_drill drill
|
168
|
+
end
|
169
|
+
def xdrill(*args, &b); end # ignore calls to xdrill
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
# Convert every Hash of dream params into a Tryouts::Drill::Dream object.
|
177
|
+
# DEPRECATED: This is not used anymore since we have the dreams DSL syntax.
|
178
|
+
def parse_dreams!
|
179
|
+
if @dreams.kind_of?(Hash)
|
180
|
+
#raise BadDreams, 'Not deep enough' unless @@dreams.deepest_point == 2
|
181
|
+
@dreams.each_pair do |tname, drills|
|
182
|
+
drills.each_pair do |dname, dream_params|
|
183
|
+
next if dream_params.is_a?(Tryouts::Drill::Dream)
|
184
|
+
dream = Tryouts::Drill::Dream.new
|
185
|
+
dream_params.each_pair { |n,v| dream.send("#{n}=", v) }
|
186
|
+
@dreams[tname][dname] = dream
|
187
|
+
end
|
188
|
+
end
|
189
|
+
else
|
190
|
+
raise BadDreams, 'Not a kind of Hash'
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end; end
|
data/lib/tryouts.rb
ADDED
@@ -0,0 +1,334 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'rye'
|
5
|
+
require 'yaml'
|
6
|
+
begin; require 'json'; rescue LoadError; end # json may not be installed
|
7
|
+
|
8
|
+
GYMNASIUM_HOME = File.join(Dir.pwd, 'tryouts')
|
9
|
+
GYMNASIUM_GLOB = File.join(GYMNASIUM_HOME, '**', '*_tryouts.rb')
|
10
|
+
|
11
|
+
|
12
|
+
# = Tryouts
|
13
|
+
#
|
14
|
+
# This class has three purposes:
|
15
|
+
# * It represents the Tryouts object which is a group of Tryout objects.
|
16
|
+
# * The tryouts and dreams DSLs are executed within its namespace. In general the
|
17
|
+
# class methods are the handlers for the DSL syntax (some instance getter methods
|
18
|
+
# are modified to support DSL syntax by acting like setters when given arguments)
|
19
|
+
# * It stores all known instances of Tryouts objects in a class variable @@instances.
|
20
|
+
#
|
21
|
+
# ==== Are you ready to run some drills?
|
22
|
+
#
|
23
|
+
# May all your dreams come true!
|
24
|
+
#
|
25
|
+
class Tryouts
|
26
|
+
# = Exception
|
27
|
+
# A generic exception which all other Tryouts exceptions inherit from.
|
28
|
+
class Exception < RuntimeError; end
|
29
|
+
# = BadDreams
|
30
|
+
# Raised when there is a problem loading or parsing a Tryouts::Drill::Dream object
|
31
|
+
class BadDreams < Exception; end
|
32
|
+
|
33
|
+
VERSION = "0.4.0"
|
34
|
+
|
35
|
+
require 'tryouts/mixins'
|
36
|
+
require 'tryouts/tryout'
|
37
|
+
require 'tryouts/drill'
|
38
|
+
|
39
|
+
TRYOUT_MSG = "\n %s "
|
40
|
+
DRILL_MSG = ' %20s: '
|
41
|
+
|
42
|
+
# An Hash of Tryouts instances stored under the name of the Tryouts subclass.
|
43
|
+
@@instances = {}
|
44
|
+
# The most recent tryouts name specified in the DSL
|
45
|
+
@@instance_pointer = nil
|
46
|
+
|
47
|
+
# The name of this group of Tryout objects
|
48
|
+
attr_accessor :group
|
49
|
+
# An Array of Tryout objects
|
50
|
+
attr_accessor :tryouts
|
51
|
+
# A Hash of Tryout names pointing to index values of :tryouts
|
52
|
+
attr_accessor :map
|
53
|
+
# A Symbol representing the command taking part in the tryouts. For @dtype :cli only.
|
54
|
+
attr_accessor :command
|
55
|
+
# A Symbol representing the name of the library taking part in the tryouts. For @dtype :api only.
|
56
|
+
attr_accessor :library
|
57
|
+
# A Symbol representing the default drill type. One of: :cli, :api
|
58
|
+
attr_accessor :dtype
|
59
|
+
|
60
|
+
# A Hash of dreams for all tryouts in this class. The keys should
|
61
|
+
# match the names of each tryout. The values are hashes will drill
|
62
|
+
# names as keys and response
|
63
|
+
attr_accessor :dreams
|
64
|
+
# The name of the most recent dreams group (see self.dream)
|
65
|
+
attr_accessor :dream_pointer
|
66
|
+
|
67
|
+
# Returns +@@instances+
|
68
|
+
def self.instances; @@instances; end
|
69
|
+
|
70
|
+
def initialize(group=nil)
|
71
|
+
@group = group || "Default Group"
|
72
|
+
@tryouts = []
|
73
|
+
@map = {}
|
74
|
+
@command = nil
|
75
|
+
@dtype = :cli
|
76
|
+
@dreams = {}
|
77
|
+
@dream_pointer = nil
|
78
|
+
end
|
79
|
+
|
80
|
+
# Populate this Tryouts from a block. The block should contain calls to
|
81
|
+
# the external DSL methods: tryout, command, dreams
|
82
|
+
def from_block(b, &inline)
|
83
|
+
instance_eval &b
|
84
|
+
end
|
85
|
+
|
86
|
+
# Execute Tryout#report for each Tryout in +@tryouts+
|
87
|
+
def report; @tryouts.each { |to| to.report }; end
|
88
|
+
|
89
|
+
# Execute Tryout#run for each Tryout in +@tryouts+
|
90
|
+
def run; @tryouts.each { |to| to.run }; end
|
91
|
+
|
92
|
+
# Add a shell command to Rye::Cmd and save the command name
|
93
|
+
# in @@commands so it can be used as the default for drills
|
94
|
+
def command(name=nil, path=nil)
|
95
|
+
return @command if name.nil?
|
96
|
+
@command = name.to_sym
|
97
|
+
Rye::Cmd.module_eval do
|
98
|
+
define_method(name) do |*args|
|
99
|
+
cmd(path || name, *args)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
@command
|
103
|
+
end
|
104
|
+
# Calls Tryouts#command on the current instance of Tryouts
|
105
|
+
#
|
106
|
+
# NOTE: this is a standalone DSL-syntax method.
|
107
|
+
def self.command(*args)
|
108
|
+
@@instances[ @@instance_pointer ].command(*args)
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# Require +name+. If +path+ is supplied, it will "require path".
|
113
|
+
# * +name+ The name of the library in question (required). Stored as a Symbol to +@library+.
|
114
|
+
# * +path+ Add a path to the front of $LOAD_PATH (optional). Use this if you want to load
|
115
|
+
# a specific copy of the library. Otherwise, it loads from the system path.
|
116
|
+
def library(name=nil, path=nil)
|
117
|
+
return @library if name.nil?
|
118
|
+
@library = name.to_sym
|
119
|
+
$LOAD_PATH.unshift path unless path.nil?
|
120
|
+
require @library.to_s
|
121
|
+
end
|
122
|
+
# Calls Tryouts#library on the current instance of Tryouts
|
123
|
+
#
|
124
|
+
# NOTE: this is a standalone DSL-syntax method.
|
125
|
+
def self.library(*args)
|
126
|
+
@@instances[ @@instance_pointer ].library(*args)
|
127
|
+
end
|
128
|
+
|
129
|
+
def group(name=nil)
|
130
|
+
return @group if name.nil?
|
131
|
+
@group = name unless name.nil?
|
132
|
+
# Preload dreams if possible
|
133
|
+
dfile = self.class.find_dreams_file(GYMNASIUM_HOME, @group)
|
134
|
+
self.load_dreams_file(dfile) if dfile
|
135
|
+
@group
|
136
|
+
end
|
137
|
+
# Raises a Tryouts::Exception. +group+ is not support in the standalone syntax
|
138
|
+
# because the group name is take from the name of the class. See inherited.
|
139
|
+
#
|
140
|
+
# NOTE: this is a standalone DSL-syntax method.
|
141
|
+
def self.group(*args)
|
142
|
+
raise "Group is already set: #{@@instances[ @@instance_pointer ].group}"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Create a new Tryout object and add it to the list for this Tryouts class.
|
146
|
+
# * +name+ is the name of the Tryout
|
147
|
+
# * +type+ is the default drill type for the Tryout. One of: :cli, :api
|
148
|
+
# * +command+ when type is :cli, this is the name of the Rye::Box method that we're testing. Otherwise ignored.
|
149
|
+
# * +b+ is a block definition for the Tryout. See Tryout#from_block
|
150
|
+
#
|
151
|
+
# NOTE: This is a DSL-only method and is not intended for OO use.
|
152
|
+
def tryout(name, type=nil, command=nil, &block)
|
153
|
+
return if name.nil?
|
154
|
+
type ||= @dtype
|
155
|
+
command ||= @command if type == :cli
|
156
|
+
to = Tryouts::Tryout.new(name, type, command)
|
157
|
+
# Populate the dreams if they've already been loaded
|
158
|
+
to.dreams = @dreams[name] if @dreams.has_key?(name)
|
159
|
+
# Process the rest of the DSL
|
160
|
+
to.from_block block if block
|
161
|
+
@tryouts << to
|
162
|
+
@map[name] = @tryouts.size - 1
|
163
|
+
to
|
164
|
+
end
|
165
|
+
# Calls Tryouts#tryout on the current instance of Tryouts
|
166
|
+
#
|
167
|
+
# NOTE: this is a standalone DSL-syntax method.
|
168
|
+
def self.tryout(*args, &block)
|
169
|
+
@@instances[ @@instance_pointer ].tryout(*args, &block)
|
170
|
+
end
|
171
|
+
|
172
|
+
# This method does nothing. It provides a quick way to disable a tryout.
|
173
|
+
#
|
174
|
+
# NOTE: This is a DSL-only method and is not intended for OO use.
|
175
|
+
def xtryout(*args, &block); end
|
176
|
+
# This method does nothing. It provides a quick way to disable a tryout.
|
177
|
+
#
|
178
|
+
# NOTE: this is a standalone DSL-syntax method.
|
179
|
+
def self.xtryout(*args, &block); end
|
180
|
+
|
181
|
+
# Load dreams from a file, or Hash.
|
182
|
+
# Raises a Tryouts::BadDreams exception when something goes awry.
|
183
|
+
#
|
184
|
+
# This method is used in two ways:
|
185
|
+
# * In the dreams file DSL
|
186
|
+
# * As a getter method on a Tryout object
|
187
|
+
def dreams(tryout_name=nil, &definition)
|
188
|
+
return @dreams unless tryout_name
|
189
|
+
if File.exists?(tryout_name)
|
190
|
+
dfile = tryout_name
|
191
|
+
# If we're given a directory we'll build the filename using the class name
|
192
|
+
if File.directory?(tryout_name)
|
193
|
+
dfile = self.class.find_dreams_file(tryout_name, group)
|
194
|
+
end
|
195
|
+
raise BadDreams, "Cannot find dreams file (#{tryout_name})" unless dfile
|
196
|
+
@dreams = load_dreams_file dfile
|
197
|
+
elsif tryout_name.kind_of?(Hash)
|
198
|
+
@dreams = tryout_name
|
199
|
+
elsif tryout_name.kind_of?(String) && definition
|
200
|
+
@dream_pointer = tryout_name # Used in Tryouts.dream
|
201
|
+
@dreams[ @dream_pointer ] ||= {}
|
202
|
+
definition.call
|
203
|
+
else
|
204
|
+
raise BadDreams, tryout_name
|
205
|
+
end
|
206
|
+
@dreams
|
207
|
+
end
|
208
|
+
# Without arguments, returns a Hash of all known dreams.
|
209
|
+
# With arguments, it calls Tryouts#dreams on the current instance of Tryouts.
|
210
|
+
#
|
211
|
+
# NOTE: this is a standalone DSL-syntax method.
|
212
|
+
def self.dreams(*args, &block)
|
213
|
+
if args.empty? && block.nil?
|
214
|
+
dreams = {}
|
215
|
+
@@instances.each_pair do |name,inst|
|
216
|
+
dreams[name] = inst.dreams
|
217
|
+
end
|
218
|
+
return dreams
|
219
|
+
else
|
220
|
+
@@instances[ @@instance_pointer ].dreams(*args, &block)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# +name+ of the Drill associated to this Dream
|
225
|
+
# +output+ A String or Array of expected output. A Dream object will be created using this value (optional)
|
226
|
+
# +definition+ is a block which will be run on an instance of Dream
|
227
|
+
#
|
228
|
+
#
|
229
|
+
# NOTE: This method is DSL-only. It's not intended to be used in OO syntax.
|
230
|
+
def dream(name, output=nil, format=:string, rcode=0, emsg=nil, &definition)
|
231
|
+
if output.nil?
|
232
|
+
dobj = Tryouts::Drill::Dream.from_block definition
|
233
|
+
else
|
234
|
+
dobj = Tryouts::Drill::Dream.new(output)
|
235
|
+
dobj.format, dobj.rcode, dobj.emsg = format, rcode, emsg
|
236
|
+
end
|
237
|
+
@dreams[@dream_pointer][name] = dobj
|
238
|
+
end
|
239
|
+
# Calls Tryouts#dream on the current instance of Tryouts
|
240
|
+
#
|
241
|
+
# NOTE: this is a standalone DSL-syntax method.
|
242
|
+
def self.dream(*args, &block)
|
243
|
+
@@instances[ @@instance_pointer ].dream(*args, &block)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Populate @@dreams with the content of the file +dpath+.
|
247
|
+
#
|
248
|
+
# NOTE: this is an OO syntax method
|
249
|
+
def load_dreams_file(dpath)
|
250
|
+
type = File.extname dpath
|
251
|
+
if type == ".yaml" || type == ".yml"
|
252
|
+
@dreams = YAML.load_file dpath
|
253
|
+
elsif type == ".json" || type == ".js"
|
254
|
+
@dreams = JSON.load_file dpath
|
255
|
+
elsif type == ".rb"
|
256
|
+
@dreams = instance_eval File.read(dpath)
|
257
|
+
else
|
258
|
+
raise BadDreams, "Unknown kind of dream: #{dpath}"
|
259
|
+
end
|
260
|
+
@dreams
|
261
|
+
end
|
262
|
+
|
263
|
+
# Parse a +_tryouts.rb+ file. See Tryouts::CLI::Run for an example.
|
264
|
+
#
|
265
|
+
# NOTE: this is an OO syntax method
|
266
|
+
def self.parse_file(fpath)
|
267
|
+
raise "No such file: #{fpath}" unless File.exists?(fpath)
|
268
|
+
to = Tryouts.new
|
269
|
+
to.instance_eval(File.read(fpath), fpath)
|
270
|
+
@@instance_pointer = to.group
|
271
|
+
@@instances[ @@instance_pointer ] = to
|
272
|
+
end
|
273
|
+
|
274
|
+
# Run all Tryout objects in +@tryouts+
|
275
|
+
#
|
276
|
+
# NOTE: this is an OO syntax method
|
277
|
+
def self.run
|
278
|
+
@@instances.each_pair do |group, inst|
|
279
|
+
puts "-"*60
|
280
|
+
puts "Tryouts for #{group}"
|
281
|
+
inst.tryouts.each do |to|
|
282
|
+
to.run
|
283
|
+
to.report
|
284
|
+
STDOUT.flush
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Called when a new class inherits from Tryouts. This creates a new instance
|
290
|
+
# of Tryouts, sets group to the name of the new class, and adds the instance
|
291
|
+
# to +@@instances+.
|
292
|
+
#
|
293
|
+
# NOTE: this is a standalone DSL-syntax method.
|
294
|
+
def self.inherited(klass)
|
295
|
+
to = Tryouts.new
|
296
|
+
to.group = klass
|
297
|
+
@@instance_pointer = to.group
|
298
|
+
@@instances[ @@instance_pointer ] = to
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
##---
|
303
|
+
## Is this wacky syntax useful for anything?
|
304
|
+
## t2 :set .
|
305
|
+
## run = "poop"
|
306
|
+
## def self.t2(*args)
|
307
|
+
## OpenStruct.new
|
308
|
+
## end
|
309
|
+
##+++
|
310
|
+
|
311
|
+
# Find a dreams file in the directory +dir+ based on the current group name.
|
312
|
+
# The expected filename format is: groupname_dreams.ext where "groupname" is
|
313
|
+
# the lowercase name of the Tryouts group (spaces removed) and "ext" is one
|
314
|
+
# of: yaml, js, json, rb.
|
315
|
+
#
|
316
|
+
# e.g.
|
317
|
+
# Tryouts.find_dreams_file "dirpath" # => dirpath/tryouts_dreams.rb
|
318
|
+
#
|
319
|
+
def self.find_dreams_file(dir, group=nil)
|
320
|
+
dpath = nil
|
321
|
+
group ||= @@instance_pointer
|
322
|
+
group = group.to_s.downcase.tr(' ', '')
|
323
|
+
[:rb, :yaml].each do |ext|
|
324
|
+
tmp = File.join(dir, "#{group}_dreams.#{ext}")
|
325
|
+
if File.exists?(tmp)
|
326
|
+
dpath = tmp
|
327
|
+
break
|
328
|
+
end
|
329
|
+
end
|
330
|
+
dpath
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
dreams "Common Usage" do
|
3
|
+
dream "No args" do
|
4
|
+
output inline(%Q{
|
5
|
+
Date: 2009-02-16
|
6
|
+
Owners: greg, rupaul, telly, prince kinko
|
7
|
+
Players: d-bam, alberta, birds, condor man
|
8
|
+
})
|
9
|
+
end
|
10
|
+
dream "YAML Output" do
|
11
|
+
format :yaml
|
12
|
+
output ({
|
13
|
+
"Date" => "2009-02-16",
|
14
|
+
"Players" => ["d-bam", "alberta", "birds", "condor man"],
|
15
|
+
"Owners" => ["greg", "rupaul", "telly", "prince kinko"]
|
16
|
+
})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
TRYOUTS_HOME = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
3
|
+
MOCKOUT_PATH = File.join(TRYOUTS_HOME, "bin", "mockout")
|
4
|
+
|
5
|
+
group "mockout cli"
|
6
|
+
command :mockout, MOCKOUT_PATH
|
7
|
+
|
8
|
+
tryout "Common Usage" do
|
9
|
+
drill "No Command"
|
10
|
+
drill "No args", :info
|
11
|
+
drill "YAML Output", :f, "yaml", :info
|
12
|
+
drill "JSON Output", :f, "json", :info
|
13
|
+
end
|
14
|
+
|
15
|
+
tryout "inline dream that passes", :cli, :mockout do
|
16
|
+
output = ["we expect mockout to", "echo these lines back"]
|
17
|
+
|
18
|
+
# $ bin/mockout sergeant -e "we expect mockout to" "echo these lines back"
|
19
|
+
drill "echo arguments", :info, :e, output[0], output[1]
|
20
|
+
dream "echo arguments", output
|
21
|
+
end
|
22
|
+
|
23
|
+
tryout "inline dream that fails", :cli, :mockout do
|
24
|
+
dream "echo arguments", "The dream does"
|
25
|
+
drill "echo arguments", :info, :e, "not match reality"
|
26
|
+
end
|
data/tryouts.gemspec
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
@spec = Gem::Specification.new do |s|
|
2
|
+
s.name = "tryouts"
|
3
|
+
s.rubyforge_project = "tryouts"
|
4
|
+
s.version = "0.4.0"
|
5
|
+
s.summary = "Tryouts are high-level tests for your Ruby code. May all your dreams come true!"
|
6
|
+
s.description = s.summary
|
7
|
+
s.author = "Delano Mandelbaum"
|
8
|
+
s.email = "tryouts@solutious.com"
|
9
|
+
s.homepage = "http://github.com/delano/tryouts"
|
10
|
+
|
11
|
+
# = EXECUTABLES =
|
12
|
+
# The list of executables in your project (if any). Don't include the path,
|
13
|
+
# just the base filename.
|
14
|
+
s.executables = %w[tryouts]
|
15
|
+
|
16
|
+
# Directories to extract rdocs from
|
17
|
+
s.require_paths = %w[lib]
|
18
|
+
|
19
|
+
# Specific files to include rdocs from
|
20
|
+
s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
|
21
|
+
|
22
|
+
# Update --main to reflect the default page to display
|
23
|
+
s.rdoc_options = ["--line-numbers", "--title", "Tryouts: #{s.summary}", "--main", "README.rdoc"]
|
24
|
+
|
25
|
+
# = DEPENDENCIES =
|
26
|
+
# Add all gem dependencies
|
27
|
+
s.add_dependency 'drydock', '>= 0.6.5'
|
28
|
+
s.add_dependency 'rye', '>= 0.6.6'
|
29
|
+
s.add_dependency 'sysinfo', '>= 0.5.1'
|
30
|
+
|
31
|
+
# = MANIFEST =
|
32
|
+
# The complete list of files to be included in the release. When GitHub packages your gem,
|
33
|
+
# it doesn't allow you to run any command that accesses the filesystem. You will get an
|
34
|
+
# error. You can ask your VCS for the list of versioned files:
|
35
|
+
# git ls-files
|
36
|
+
# svn list -R
|
37
|
+
s.files = %w(
|
38
|
+
CHANGES.txt
|
39
|
+
LICENSE.txt
|
40
|
+
README.rdoc
|
41
|
+
Rakefile
|
42
|
+
bin/mockout
|
43
|
+
bin/tryouts
|
44
|
+
lib/tryouts.rb
|
45
|
+
lib/tryouts/cli.rb
|
46
|
+
lib/tryouts/cli/run.rb
|
47
|
+
lib/tryouts/drill.rb
|
48
|
+
lib/tryouts/drill/response.rb
|
49
|
+
lib/tryouts/drill/sergeant/cli.rb
|
50
|
+
lib/tryouts/mixins.rb
|
51
|
+
lib/tryouts/mixins/hash.rb
|
52
|
+
lib/tryouts/tryout.rb
|
53
|
+
tryouts.gemspec
|
54
|
+
tryouts/mockoutcli_dreams.rb
|
55
|
+
tryouts/mockoutcli_dreams.yaml
|
56
|
+
tryouts/mockoutcli_tryouts.rb
|
57
|
+
)
|
58
|
+
|
59
|
+
s.has_rdoc = true
|
60
|
+
s.rubygems_version = '1.3.0'
|
61
|
+
|
62
|
+
if s.respond_to? :specification_version then
|
63
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
64
|
+
s.specification_version = 2
|
65
|
+
|
66
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
67
|
+
s.add_runtime_dependency(%q<RedCloth>, [">= 4.0.4"])
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
70
|
+
end
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|