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.
@@ -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