delano-tryouts 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,11 @@
1
+ common usage:
2
+ yaml output:
3
+ :format: :yaml
4
+ :rcode: 0
5
+ no args:
6
+ :format: :string
7
+ :rcode: 0
8
+ :output:
9
+ - " Date: 2009-02-16\n"
10
+ - " Players: d-bam, alberta, birds, condor man\n"
11
+ - " Coaches: greg|rupaul|telly|prince kinko\n"
@@ -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