Module: Minitest

Defined in:
lib/minitest.rb,
lib/minitest/mock.rb,
lib/minitest/test.rb,
lib/minitest/unit.rb,
lib/minitest/benchmark.rb,
lib/minitest/benchmark.rb,
lib/minitest/assertions.rb,
lib/minitest/pride_plugin.rb,
lib/minitest/parallel_each.rb

Overview

:nodoc:

Defined Under Namespace

Modules: Assertions, Expectations, Guard Classes: AbstractReporter, Assertion, BacktraceFilter, BenchSpec, Benchmark, CompositeReporter, Mock, ParallelEach, PrideIO, PrideLOL, ProgressReporter, Reporter, Runnable, Skip, Spec, StatisticsReporter, SummaryReporter, Test, UnexpectedError, Unit

Constant Summary collapse

VERSION =

:nodoc:

'5.0.17'
DATE =

:nodoc:

'2013-08-12'
@@after_run =
[]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.__run(reporter, options) ⇒ Object

Runs all the suites for a given type. Runs suites declaring a test_order of :parallel in parallel, and everything else serial.



128
129
130
131
132
# File 'lib/minitest.rb', line 128

def self.__run reporter, options
  Runnable.runnables.each do |runnable|
    runnable.run reporter, options
  end
end

.after_run(&block) ⇒ Object

A simple hook allowing you to run a block of code after everything is done running. Eg:

Minitest.after_run { p $debugging_info }


59
60
61
# File 'lib/minitest.rb', line 59

def self.after_run &block
  @@after_run << block
end

.autorunObject

Registers Minitest to run at process exit



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/minitest.rb', line 37

def self.autorun
  at_exit {
    next if $! and not $!.kind_of? SystemExit

    exit_code = nil

    at_exit {
      @@after_run.reverse_each(&:call)
      exit exit_code || false
    }

    exit_code = Minitest.run ARGV
  } unless @@installed_at_exit
  @@installed_at_exit = true
end

.filter_backtrace(bt) ⇒ Object

:nodoc:



271
272
273
# File 'lib/minitest.rb', line 271

def self.filter_backtrace bt # :nodoc:
  backtrace_filter.filter bt
end

.init_plugins(options) ⇒ Object

:nodoc:



63
64
65
66
67
68
# File 'lib/minitest.rb', line 63

def self.init_plugins options # :nodoc:
  self.extensions.each do |name|
    msg = "plugin_#{name}_init"
    send msg, options if self.respond_to? msg
  end
end

.load_pluginsObject

:nodoc:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/minitest.rb', line 70

def self.load_plugins # :nodoc:
  return unless self.extensions.empty?

  seen = {}

  Gem.find_files("minitest/*_plugin.rb").each do |plugin_path|
    name = File.basename plugin_path, "_plugin.rb"

    next if seen[name]
    seen[name] = true

    require plugin_path
    self.extensions << name
  end
end

.plugin_pride_init(options) ⇒ Object

:nodoc:



10
11
12
13
14
15
16
17
18
19
# File 'lib/minitest/pride_plugin.rb', line 10

def self.plugin_pride_init options # :nodoc:
  if PrideIO.pride? then
    klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO
    io    = klass.new options[:io]

    self.reporter.reporters.grep(Minitest::Reporter).each do |rep|
      rep.io = io
    end
  end
end

.plugin_pride_options(opts, options) ⇒ Object

:nodoc:



4
5
6
7
8
# File 'lib/minitest/pride_plugin.rb', line 4

def self.plugin_pride_options opts, options # :nodoc:
  opts.on "-p", "--pride", "Pride. Show your testing pride!" do
    PrideIO.pride!
  end
end

.process_args(args = []) ⇒ Object

:nodoc:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/minitest.rb', line 208

def self.process_args args = [] # :nodoc:
  options = { :io => $stdout }
  orig_args = args.dup

  OptionParser.new do |opts|
    opts.banner  = "minitest options:"
    opts.version = Minitest::VERSION

    opts.on "-h", "--help", "Display this help." do
      puts opts
      exit
    end

    opts.on "-s", "--seed SEED", Integer, "Sets random seed" do |m|
      options[:seed] = m.to_i
    end

    opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
      options[:verbose] = true
    end

    opts.on "-n", "--name PATTERN","Filter run on /pattern/ or string." do |a|
      options[:filter] = a
    end

    unless extensions.empty?
      opts.separator ""
      opts.separator "Known extensions: #{extensions.join(', ')}"

      extensions.each do |meth|
        msg = "plugin_#{meth}_options"
        send msg, opts, options if self.respond_to?(msg)
      end
    end

    begin
      opts.parse! args
    rescue OptionParser::InvalidOption => e
      puts
      puts e
      puts
      puts opts
      exit 1
    end

    orig_args -= args
  end

  unless options[:seed] then
    srand
    options[:seed] = srand % 0xFFFF
    orig_args << "--seed" << options[:seed].to_s
  end

  srand options[:seed]

  options[:args] = orig_args.map { |s|
    s =~ /[\s|&<>$()]/ ? s.inspect : s
  }.join " "

  options
end

.run(args = []) ⇒ Object

This is the top-level run method. Everything starts from here. It tells each Runnable sub-class to run, and each of those are responsible for doing whatever they do.

The overall structure of a run looks like this:

Minitest.autorun
  Minitest.run(args)
    __run(reporter, options)
      Runnable.runnables.each
        runnable.run(reporter, options)
          self.runnable_methods.each
            self.new(runnable_method).run


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/minitest.rb', line 101

def self.run args = []
  self.load_plugins

  options = process_args args

  reporter = CompositeReporter.new
  reporter << ProgressReporter.new(options[:io], options)
  reporter << SummaryReporter.new(options[:io], options)

  self.reporter = reporter # this makes it available to plugins
  self.init_plugins options
  self.reporter = nil # runnables shouldn't depend on the reporter, ever

  reporter.start
  __run reporter, options
  reporter.report

  reporter.passed?
end

.run_specs(spec_opts = {}) ⇒ Object

Run specs. Does not print dots (ProgressReporter)

spec_opts

Parameters:

  • :io (Array<String>)

    defaults to $stdout

  • :trace (Array<String>)

    files to trace



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/minitest.rb', line 183

def self.run_specs spec_opts={}
  options = { :io => spec_opts.fetch(:io, $stdout) }
  reporter = Minitest::CompositeReporter.new
  reporter << Minitest::SummaryReporter.new(options[:io], options)
  reporter.start

  trace_specs spec_opts

  begin
    Minitest.__run reporter, options
    reporter.reporters.each { |r| r.report }
  rescue Minitest::Runnable::ExitAfterFirstFail
    # Minitest calls .report on exception
  end

  # handle exit. code from self.autorun
  at_exit {
    next if $! and not $!.kind_of? SystemExit
    at_exit {
      @@after_run.reverse_each(&:call)
      exit reporter.passed? || false
    }
  }
end

.trace_specs(spec_opts) ⇒ Object

Trace file source to :io (default $stdout)

spec_opts = {}

Parameters:

  • :trace (Array<String>)

    the files to trace

  • :io (IO)

    io to print to



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/minitest.rb', line 141

def self.trace_specs spec_opts
  targets = []
  files = {}
  last_file = ''
  last_line = -1

  files_to_trace = spec_opts.fetch(:trace, []);
  io = spec_opts.fetch(:io, $stdout)
  color = spec_opts.fetch(:color, "\e[32m") # ANSI.green default
  # target only existing readable files
  files_to_trace.each { |f| targets.push(f) if File.exists?(f) && File
  .readable?(f) }
  return if targets.empty?

  set_trace_func(lambda do |event, file, line, id, binding, classname|
    return unless targets.include? file

    # never repeat a line
    return if file == last_file && line == last_line

    file_sym = file.intern
    files[file_sym] = IO.readlines(file) if files[file_sym].nil?
    lines = files[file_sym]

    # arrays are 0 indexed and line numbers start at one.
    io.print color if color # ANSI code
    io.puts lines[ line - 1]
    io.print "\e[0m" if color # ANSI.clear

    last_file = file
    last_line = line

  end)
end

Instance Method Details

#attr_accessorObject

Names of known extension plugins.



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

mc.send :attr_accessor, :backtrace_filter