delano-tryouts 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|