Class: Minitest::Runnable

Inherits:
Object show all
Defined in:
lib/minitest.rb

Overview

Represents anything “runnable”, like Test, Spec, Benchmark, or whatever you can dream up.

Subclasses of this are automatically registered and available in Runnable.runnables.

Direct Known Subclasses

Test

Defined Under Namespace

Classes: ExitAfterFirstFail

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Runnable

:nodoc:



463
464
465
466
467
# File 'lib/minitest.rb', line 463

def initialize name # :nodoc:
  self.name       = name
  self.failures   = []
  self.assertions = 0
end

Instance Attribute Details

#assertionsObject

Number of assertions executed in this run.



286
287
288
# File 'lib/minitest.rb', line 286

def assertions
  @assertions
end

#failuresObject

An assertion raised during the run, if any.



291
292
293
# File 'lib/minitest.rb', line 291

def failures
  @failures
end

Class Method Details

.check_failures(result, reporter) ⇒ Object



327
328
329
330
331
332
333
334
335
# File 'lib/minitest.rb', line 327

def self.check_failures result, reporter
  if !result.failures.empty?
    begin
      reporter.reporters.each { |r| r.report }
    ensure
      raise ExitAfterFirstFail
    end
  end
end

.inherited(klass) ⇒ Object

:nodoc:



307
308
309
310
# File 'lib/minitest.rb', line 307

def self.inherited klass # :nodoc:
  self.runnables << klass
  super
end

.methods_matching(re) ⇒ Object

Returns all instance methods matching the pattern re.



315
316
317
# File 'lib/minitest.rb', line 315

def self.methods_matching re
  public_instance_methods(true).grep(re).map(&:to_s)
end

.on_signal(name, action) ⇒ Object

:nodoc:



423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/minitest.rb', line 423

def self.on_signal name, action # :nodoc:
  supported = Signal.list[name]

  old_trap = trap name do
    old_trap.call if old_trap.respond_to? :call
    action.call
  end if supported

  yield
ensure
  trap name, old_trap if supported
end

.resetObject

:nodoc:



319
320
321
# File 'lib/minitest.rb', line 319

def self.reset # :nodoc:
  @@runnables = []
end

.run(reporter, options = {}) ⇒ Object

Responsible for running all runnable methods in a given class, each in its own instance. Each instance is passed to the reporter to record.



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/minitest.rb', line 342

def self.run reporter, options = {}
  io = options.fetch :io, $stdout
  filter = options[:filter] || '/./'
  filter = Regexp.new $1 if filter =~ /\/(.*)\//

  filtered_methods = self.runnable_methods.find_all { |m|
    filter === m || filter === "#{self}##{m}"
  }

  begin
    # before_first
    method1 = self.new(filtered_methods.first)
    # run method and capture exceptions.
    method1.capture_exceptions do
      method1.before_first_method
    end
    # save exceptions to reporter and check for failures
    with_info_handler reporter do
      # only record if failures not empty, otherwise
      # the count (runs) are messed up. each call to .record
      # increases count by one.
      if !method1.failures.empty?
        reporter.record method1
        check_failures method1, reporter
      end

      # run the other methods
      filtered_methods.each do |method_name|
        method = self.new(method_name)
        matched_name = method_name.match /test_(\d+)_/
        if matched_name
          test_number = matched_name[1].to_i
          test_name = method_name.split(/_\d+_/).last
          file_path, line_number = method.method(method_name).source_location
          # /5/4/3/2/1/test.rb => 2/1/test.rb
          file_path = file_path.split(File::SEPARATOR).reject(&:empty?)
          file_path = (file_path.length >= 3 ? file_path[-3..-1] :
              file_path).join(File::SEPARATOR)
          # 36 = cyan, 0 = clear
          test_output_title = "\e[36m#{test_name} | #{test_number} |" +
              "#{file_path}:#{line_number}\e[0m"
          io.puts test_output_title
        end
        result = method.run
        raise "#{self}#run _must_ return self" unless self === result
        reporter.record result
        check_failures result, reporter
      end
    end
  ensure # ensure after last runs
    # after_last
    # init method1 again
    method1 = self.new(filtered_methods.first)
    method1.capture_exceptions do
      method1.after_last_method
    end
    with_info_handler reporter do
      if !method1.failures.empty?
        reporter.record method1
        check_failures method1, reporter
      end
    end
  end
end

.runnable_methodsObject

Each subclass of Runnable is responsible for overriding this method to return all runnable methods. See #methods_matching.

Raises:

  • (NotImplementedError)


440
441
442
# File 'lib/minitest.rb', line 440

def self.runnable_methods
  raise NotImplementedError, "subclass responsibility"
end

.runnablesObject

Returns all subclasses of Runnable.



447
448
449
# File 'lib/minitest.rb', line 447

def self.runnables
  @@runnables
end

.with_info_handler(reporter, &block) ⇒ Object

:nodoc:



410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/minitest.rb', line 410

def self.with_info_handler reporter, &block # :nodoc:
  handler = lambda do
    unless reporter.passed? then
      warn "Current results:"
      warn ""
      warn reporter.reporters.first
      warn ""
    end
  end

  on_signal "INFO", handler, &block
end

Instance Method Details

#after_last_methodObject



408
# File 'lib/minitest.rb', line 408

def after_last_method; end

#before_first_methodObject



407
# File 'lib/minitest.rb', line 407

def before_first_method; end

#failureObject

:nodoc:



459
460
461
# File 'lib/minitest.rb', line 459

def failure # :nodoc:
  self.failures.first
end

#marshal_dumpObject

:nodoc:



451
452
453
# File 'lib/minitest.rb', line 451

def marshal_dump # :nodoc:
  [self.name, self.failures, self.assertions]
end

#marshal_load(ary) ⇒ Object

:nodoc:



455
456
457
# File 'lib/minitest.rb', line 455

def marshal_load ary # :nodoc:
  self.name, self.failures, self.assertions = ary
end

#nameObject

Name of the run.



296
297
298
# File 'lib/minitest.rb', line 296

def name
  @NAME
end

#name=(o) ⇒ Object

Set the name of the run.



303
304
305
# File 'lib/minitest.rb', line 303

def name= o
  @NAME = o
end

#passed?Boolean

Did this run pass?

Note: skipped runs are not considered passing, but they don’t cause the process to exit non-zero.

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


482
483
484
# File 'lib/minitest.rb', line 482

def passed?
  raise NotImplementedError, "subclass responsibility"
end

#result_codeObject

Returns a single character string to print based on the result of the run. Eg “.”, “F”, or “E”.

Raises:

  • (NotImplementedError)


490
491
492
# File 'lib/minitest.rb', line 490

def result_code
  raise NotImplementedError, "subclass responsibility"
end

#runObject

Runs a single method. Needs to return self.

Raises:

  • (NotImplementedError)


472
473
474
# File 'lib/minitest.rb', line 472

def run
  raise NotImplementedError, "subclass responsibility"
end

#skipped?Boolean

Was this run skipped? See #passed? for more information.

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


497
498
499
# File 'lib/minitest.rb', line 497

def skipped?
  raise NotImplementedError, "subclass responsibility"
end