rubytest 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,70 +1,80 @@
1
1
  module Test
2
2
 
3
+ # Configure test run via a block then will be passed a `Config` instance.
3
4
  #
4
- def self.run(name=nil, &block)
5
- name = name ? name : 'default'
6
-
7
- @config ||= {}
8
- @config[name.to_s] = block
5
+ # @return [Config]
6
+ def self.configure(&block)
7
+ if reconfigure?
8
+ configuration.apply(&block)
9
+ else
10
+ @config = Config.new(&block)
11
+ end
9
12
  end
10
13
 
14
+ # Reconfigure test run via a block then will be passed the {Config} instance.
15
+ # Unlike `configure` this does not create a new Config instance, but instead
16
+ # augments the current configuration.
11
17
  #
12
- def self.config
13
- @config ||= {}
18
+ # @return [Config]
19
+ def self.reconfigure?
20
+ @reconfigure
14
21
  end
15
22
 
16
- # Handle test run configruation.
23
+ # Get the current configuration.
17
24
  #
18
- # @todo Why not use the instace level for `Test.config` ?
25
+ # @return [Config]
26
+ def self.configuration(reconfigurable=false)
27
+ @reconfigure = true if reconfigurable
28
+ @config ||= Config.new
29
+ end
30
+
31
+ ##
32
+ # Encapsulates test run configruation.
19
33
  #
20
34
  class Config
21
35
 
22
- # Tradional test configuration file glob. This glob looks for a `Testfile`
23
- # or a `.test` file, either of which can have an optional `.rb` extension.
24
- # Also `config/rubytest.rb` is permissable.
25
- GLOB_RC = '{testfile.rb,testfile,.test.rb,.test,config/rubytest.rb,.config/rubytest.rb}'
36
+ # Default report is in the old "dot-progress" format.
37
+ DEFAULT_FORMAT = 'dotprogress'
26
38
 
27
39
  # Glob used to find project root directory.
28
- GLOB_ROOT = '{.ruby,.git,.hg,_darcs,lib/}'
40
+ GLOB_ROOT = '{.index,.gemspec,.git,.hg,_darcs,lib/}'
29
41
 
42
+ # RubyTest configuration file can be in '.test.rb`, `etc/test.rb`
43
+ # or `config/test.rb`, `.test`, in that order of precedence.
30
44
  #
31
- # Load configuration. This will first look for a root level `Testfile.rb`
32
- # or `.test.rb` file. Failing that it will look for `task/*.rubytest` files.
33
- # An example entry into any of these look like:
34
- #
35
- # Test.run :name do |run|
36
- # run.files << 'test/case_*.rb'
37
- # end
45
+ # @deprecated Use manual -c/--config option instead.
46
+ GLOB_CONFIG = '{.test.rb,etc/test.rb,config/test.rb,.test}'
47
+
38
48
  #
39
- # Use `default` for name for non-specific profile and `common` for code that
40
- # should apply to all configurations.
49
+ def self.assertionless
50
+ @assertionless
51
+ end
52
+
41
53
  #
42
- # Failing any traditional configuration files, the Confection system will
43
- # be used. An example entry in a projects `Config.rb` is:
54
+ def self.assertionless=(boolean)
55
+ @assertionaless = !!boolean
56
+ end
57
+
58
+ # Load configuration file. An example file might look like:
44
59
  #
45
- # config 'rubytest', profile: 'name' do |run|
60
+ # Test.configure do |run|
46
61
  # run.files << 'test/case_*.rb'
47
62
  # end
48
63
  #
49
- # You can leave the `:name` parameter out for `:default`.
50
- #
51
- def self.load
52
- if rc_file
53
- super(rc_file)
54
- #else
55
- # if config = Test.rc_config
56
- # config.each do |c|
57
- # Test.run(c.profile, &c)
58
- # end
59
- # end
64
+ # @deprecated Planned for deprecation in April 2013.
65
+ def self.load_config
66
+ if config_file
67
+ file = config_file.sub(Dir.pwd+'/','')
68
+ $stderr.puts "Automatic #{file} loading has been deprecated.\nUse -c option for future version."
69
+ load config_file
60
70
  end
61
71
  end
62
72
 
63
- # Find traditional rc file.
64
- def self.rc_file
65
- @rc_file ||= (
66
- Dir.glob(File.join(root, GLOB_RC), File::FNM_CASEFOLD).first
67
- )
73
+ # Find traditional configuration file.
74
+ #
75
+ # @deprecated
76
+ def self.config_file
77
+ @config_file ||= Dir.glob(File.join(root, GLOB_CONFIG)).first
68
78
  end
69
79
 
70
80
  # Find and cache project root directory.
@@ -84,13 +94,14 @@ module Test
84
94
  )
85
95
  end
86
96
 
87
- # Load and cache a project's `.index` file.
97
+ # Load and cache a project's `.index` file, if it has one.
88
98
  #
89
- # @return [Hash] Project's loaded `.index` file, if it has one.
99
+ # @return [Hash] YAML loaded `.index` file, or empty hash.
90
100
  def self.dotindex
91
101
  @dotindex ||= (
92
102
  file = File.join(root, '.index')
93
103
  if File.exist?(file)
104
+ require 'yaml'
94
105
  YAML.load_file(file) rescue {}
95
106
  else
96
107
  {}
@@ -98,10 +109,11 @@ module Test
98
109
  )
99
110
  end
100
111
 
101
- # Setup $LOAD_PATH based on .index file.
112
+ # Setup $LOAD_PATH based on project's `.index` file, if an
113
+ # index file is not found, then default to `lib/` if it exists.
102
114
  #
103
115
  def self.load_path_setup
104
- if load_paths = (dotindex['paths'] || {})['load']
116
+ if load_paths = (dotindex['paths'] || {})['lib']
105
117
  load_paths.each do |path|
106
118
  $LOAD_PATH.unshift(File.join(root, path))
107
119
  end
@@ -113,6 +125,329 @@ module Test
113
125
  end
114
126
  end
115
127
 
128
+ # Initialize new Config instance.
129
+ def initialize(settings={}, &block)
130
+ @format = nil
131
+ @autopath = nil
132
+ @chdir = nil
133
+ @files = []
134
+ @tags = []
135
+ @match = []
136
+ @units = []
137
+ @requires = []
138
+ @loadpath = []
139
+
140
+ #apply_environment
141
+
142
+ settings.each do |k,v|
143
+ send("#{k}=", v)
144
+ end
145
+
146
+ self.class.load_config # deprecated!!!
147
+
148
+ apply(&block)
149
+ end
150
+
151
+ # Evaluate configuration block.
152
+ #
153
+ # @return nothing
154
+ def apply(&block)
155
+ block.call(self) if block
156
+ end
157
+
158
+ # Default test suite ($TEST_SUITE).
159
+ #
160
+ # @return [Array]
161
+ def suite
162
+ @suite ||= $TEST_SUITE
163
+ end
164
+
165
+ # This is not really for general, but it is useful for Ruby Test's
166
+ # own tests, to isolate tests.
167
+ def suite=(test_objects)
168
+ @suite = Array(test_objects)
169
+ end
170
+
171
+ # List of test files to run.
172
+ #
173
+ # @return [Array<String>]
174
+ def files
175
+ @files
176
+ end
177
+ alias test_files files
178
+
179
+ # Set the list of test files to run. Entries can be file glob patterns.
180
+ #
181
+ # @return [Array<String>]
182
+ def files=(list)
183
+ @files = makelist(list)
184
+ end
185
+ alias test_files= files=
186
+
187
+ # Automatically modify the `$LOAD_PATH`?
188
+ #
189
+ # @return [Boolean]
190
+ def autopath?
191
+ @autopath
192
+ end
193
+
194
+ # Automatically modify the `$LOAD_PATH`?
195
+ #
196
+ # @return [Boolean]
197
+ def autopath=(boolean)
198
+ @autopath = !! boolean
199
+ end
200
+
201
+ # Paths to add to $LOAD_PATH.
202
+ #
203
+ # @return [Array<String>]
204
+ attr :loadpath
205
+
206
+ # Set paths to add to $LOAD_PATH.
207
+ #
208
+ # @return [Array<String>]
209
+ def loadpath=(list)
210
+ @loadpath = makelist(list)
211
+ end
212
+
213
+ # Scripts to require prior to tests.
214
+ #
215
+ # @return [Array<String>]
216
+ attr :requires
217
+
218
+ # Set the features that need to be required before the
219
+ # test files.
220
+ #
221
+ # @return [Array<String>]
222
+ def requires=(list)
223
+ @requires = makelist(list)
224
+ end
225
+
226
+ # Name of test report format, by default it is `dotprogress`.
227
+ #
228
+ # @return [String] format
229
+ def format
230
+ @format || DEFAULT_FORMAT
231
+ end
232
+
233
+ # Set test report format.
234
+ #
235
+ # @return [String] format
236
+ def format=(format)
237
+ @format = format.to_s
238
+ end
239
+
240
+ # Provide extra details in reports?
241
+ #
242
+ # @return [Boolean]
243
+ def verbose?
244
+ @verbose
245
+ end
246
+
247
+ # Set verbose mode.
248
+ #
249
+ # @return [Boolean]
250
+ def verbose=(boolean)
251
+ @verbose = !! boolean
252
+ end
253
+
254
+ # Selection of tags for filtering tests.
255
+ #
256
+ # @return [Array<String>]
257
+ def tags
258
+ @tags
259
+ end
260
+
261
+ # Set the list of tags for filtering tests.
262
+ #
263
+ # @return [Array<String>]
264
+ def tags=(list)
265
+ @tags = makelist(list)
266
+ end
267
+
268
+ # Description match for filtering tests.
269
+ #
270
+ # @return [Array<String>]
271
+ def match
272
+ @match
273
+ end
274
+
275
+ # Set the description matches for filtering tests.
276
+ #
277
+ # @return [Array<String>]
278
+ def match=(list)
279
+ @match = makelist(list)
280
+ end
281
+
282
+ # List of units with which to filter tests. It is an array of strings
283
+ # which are matched against module, class and method names.
284
+ #
285
+ # @return [Array<String>]
286
+ def units
287
+ @units
288
+ end
289
+
290
+ # Set the list of units with which to filter tests. It is an array of
291
+ # strings which are matched against module, class and method names.
292
+ #
293
+ # @return [Array<String>]
294
+ def units=(list)
295
+ @units = makelist(list)
296
+ end
297
+
298
+ # Hard is a synonym for assertionless.
299
+ #
300
+ # @return [Boolean]
301
+ def hard?
302
+ @hard || self.class.assertionless
303
+ end
304
+
305
+ # Hard is a synonym for assertionless.
306
+ #
307
+ # @return [Boolean]
308
+ def hard=(boolean)
309
+ @hard = !! boolean
310
+ end
311
+
312
+ # Change to this directory before running tests.
313
+ #
314
+ # @return [String]
315
+ def chdir
316
+ @chdir
317
+ end
318
+
319
+ # Set directory to change to before running tests.
320
+ #
321
+ # @return [String]
322
+ def chdir=(dir)
323
+ @chdir = dir.to_s
324
+ end
325
+
326
+ # The mode is only useful for specialied purposes, such as how
327
+ # to run tests via the Rake task. It has no general purpose
328
+ # and can be ignored in most cases.
329
+ #
330
+ # @return [String]
331
+ def mode
332
+ @mode
333
+ end
334
+
335
+ # The mode is only useful for specialied purposes, such as how
336
+ # to run tests via the Rake task. It has no general purpose
337
+ # and can be ignored in most cases.
338
+ #
339
+ # @return [String]
340
+ def mode=(type)
341
+ @mode = type.to_s
342
+ end
343
+
344
+ # Convert configuration to shell options, compatible with the
345
+ # rubytest command line.
346
+ #
347
+ # @return [Array<String>]
348
+ def to_shellwords
349
+ argv = []
350
+ argv << %[--autopath] if autopath?
351
+ argv << %[--verbose] if verbose?
352
+ argv << %[--format="#{format}"] if format
353
+ argv << %[--chdir="#{chdir}"] if chdir
354
+ argv << %[--tags="#{tags.join(';')}"] unless tags.empty?
355
+ argv << %[--match="#{match.join(';')}"] unless match.empty?
356
+ argv << %[--units="#{units.join(';')}"] unless units.empty?
357
+ argv << %[--loadpath="#{loadpath.join(';')}"] unless loadpath.empty?
358
+ argv << %[--requires="#{requires.join(';')}"] unless requires.empty?
359
+ argv << files.join(' ') unless files.empty?
360
+ argv
361
+ end
362
+
363
+ # Apply environment, overriding any previous configuration settings.
364
+ #
365
+ # @todo Better name for this method?
366
+ # @return nothing
367
+ def apply_environment_overrides
368
+ @format = env(:format, @format)
369
+ @autopath = env(:autopath, @autopath)
370
+ @files = env(:files, @files)
371
+ @match = env(:match, @match)
372
+ @tags = env(:tags, @tags)
373
+ @units = env(:units, @units)
374
+ @requires = env(:requires, @requires)
375
+ @loadpath = env(:loadpath, @loadpath)
376
+ end
377
+
378
+ # Apply environment as underlying defaults for unset configuration
379
+ # settings.
380
+ #
381
+ # @return nothing
382
+ def apply_environment_defaults
383
+ @format = env(:format, @format) if @format.nil?
384
+ @autopath = env(:autopath, @autopath) if @autopath.nil?
385
+ @files = env(:files, @files) if @files.empty?
386
+ @match = env(:match, @match) if @match.empty?
387
+ @tags = env(:tags, @tags) if @tags.empty?
388
+ @units = env(:units, @units) if @units.empty?
389
+ @requires = env(:requires, @requires) if @requires.empty?
390
+ @loadpath = env(:loadpath, @loadpath) if @loadpath.empty?
391
+ end
392
+
393
+ # Load configuration file.
394
+ #
395
+ # @return [Boolean] true if file was required
396
+ def load_config(file)
397
+ try_paths = ['etc', 'config']
398
+ try_paths.concat loadpath
399
+ try_paths << '.'
400
+ try_paths = try_paths.uniq
401
+
402
+ if chdir
403
+ try_paths = try_paths.map{ |path| File.join(chdir, path) }
404
+ end
405
+
406
+ hold_path = $LOAD_PATH.dup
407
+ $LOAD_PATH.replace(try_paths)
408
+ begin
409
+ success = require file
410
+ ensure
411
+ $LOAD_PATH.replace(hold_path)
412
+ end
413
+ success
414
+ end
415
+
416
+ private
417
+
418
+ # Lookup environment variable with name `rubytest_{name}`,
419
+ # and transform in according to the type of the given
420
+ # default. If the environment variable is not set then
421
+ # returns the default.
422
+ #
423
+ # @return [Object]
424
+ def env(name, default=nil)
425
+ value = ENV["rubytest_#{name}".downcase]
426
+
427
+ case default
428
+ when Array
429
+ return makelist(value) if value
430
+ else
431
+ return value if value
432
+ end
433
+ default
434
+ end
435
+
436
+ # If given a String then split up at `:` and `;` markers.
437
+ # Otherwise ensure the list is an Array and the entries are
438
+ # all strings and not empty.
439
+ #
440
+ # @return [Array<String>]
441
+ def makelist(list)
442
+ case list
443
+ when String
444
+ list = list.split(/[:;]/)
445
+ else
446
+ list = Array(list).map{ |path| path.to_s }
447
+ end
448
+ list.reject{ |path| path.strip.empty? }
449
+ end
450
+
116
451
  end
117
452
 
118
453
  end