rubytest 0.5.4 → 0.6.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.
@@ -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