module Minitest::Allow

Constants

VERSION

Attributes

allow[RW]
allow_save[RW]
allow_seen[RW]

Public Instance Methods

allow_results() click to toggle source
# File lib/minitest/allow_plugin.rb, line 53
def allow_results
  self.reporters
    .grep(Minitest::StatisticsReporter)
    .map(&:results)
end
filter_allow() click to toggle source

Test runs call record, we put everything ran in allow_seen. This means allow_seen has everything RAN, regardless of pass/fail We use this intersected with the allowed file to determine what to report on… if it wasn’t seen, we don’t say add/remove at all.

‘allow` is all the stuff from the allow file. Test names and regexps that excuse failures.

‘allow_results` is an array of arrays of results: [[result, …], …]

When the run is done, we want to tell the user what tests to remove or add from the allowed list:

  • If a test passed that is in the allowed list, it should be removed.

  • If a test failed that is NOT in the allowed list, it should be added.

  • If a test failed that is matched by a regexp, it’s NAME should be removed if it is listed.

# File lib/minitest/allow_plugin.rb, line 87
def filter_allow
  # 1. split allow into strings and regexps
  allowed_REs, allowed_names = allow.partition { |a| Regexp === a }

  allowed_names = allowed_names.map { |x| [x, x] }.to_h

  # 2. remove items from allow_results whose full_name matches the strings
  # 3. remove items from allow_results whose message matches the regexps
  # 4. remove items from allow_results whose full_name matches the regexps?

  hit = {}
  allow_results = self.allow_results
  allow_results.each do |results|
    results.delete_if { |r|
      name = r.full_name

      by_name = allowed_names[name]
      by_regx = allowed_REs.find { |re| r.failure.message =~ re || name =~ re }

      # this will add the name as bad unless hit by regexp as well
      # if hit by regex, then we want to report it as "good" so
      # the name gets removed from the allow list:

      # the same goes for when the test is listed as bad but is now skipped:

      hit[name] = true if by_name && !by_regx && !r.skipped?

      by_name || by_regx
    }
  end

  # 5. remove string and regexps that matched any of the above from allow
  self.allow -= hit.keys

  errored, failed = allow_results
    .flatten
    .reject(&:skipped?)
    .partition { |t| Minitest::UnexpectedError === t.failure }

  failed = failed.map(&:full_name)
  errors = Hash.new { |h,k| h[k] = [] }

  errored.each do |t|
    msg = t.failure.message.lines.first.chomp.gsub(/0x\h+/, "0xHHHH")

    errors[Regexp.new(Regexp.escape(msg))] << t.full_name
  end

  extra_bad = failed.uniq
  extra_bad << errors.transform_values(&:uniq) unless errors.empty?

  # 6. report new failures including regular expressions for errors

  unless extra_bad.empty? then
    io.puts
    io.puts "Bad tests that are NOT allowed:"
    Psych.dump extra_bad, io, line_width:-1
    io.puts
  end
end
passed?() click to toggle source
Calls superclass method
# File lib/minitest/allow_plugin.rb, line 159
def passed?
  write_allow        if allow_save
  filter_allow       if allow
  report_extra_allow if allow

  super # CompositeReporter#passed?
end
record(result) click to toggle source
Calls superclass method
# File lib/minitest/allow_plugin.rb, line 48
def record result
  allow_seen << result.full_name
  super
end
report_extra_allow() click to toggle source
# File lib/minitest/allow_plugin.rb, line 148
def report_extra_allow
  good = allow & allow_seen

  unless good.empty? then
    io.puts
    io.puts "Excluded tests that now pass:"
    Psych.dump good, io, line_width:-1
    io.puts
  end
end
write_allow() click to toggle source
# File lib/minitest/allow_plugin.rb, line 59
def write_allow
  data = allow_results
    .flatten
    .map(&:full_name)
    .uniq
    .sort

  File.write allow_save, Psych.dump(data, line_width:-1)
end