Module: Minitest::Retry

Defined in:
lib/minitest/retry.rb,
lib/minitest/retry/version.rb

Defined Under Namespace

Modules: ClassMethods, TestWithRetry

Constant Summary collapse

VERSION =
"0.3.1"

Class Method Summary collapse

Class Method Details

.classes_to_retryObject



48
49
50
# File 'lib/minitest/retry.rb', line 48

def classes_to_retry
  @classes_to_retry
end

.consistent_failure_callbackObject



56
57
58
# File 'lib/minitest/retry.rb', line 56

def consistent_failure_callback
  @consistent_failure_callback
end

.exceptions_to_retryObject



40
41
42
# File 'lib/minitest/retry.rb', line 40

def exceptions_to_retry
  @exceptions_to_retry
end

.exceptions_to_skipObject



68
69
70
# File 'lib/minitest/retry.rb', line 68

def exceptions_to_skip
  @exceptions_to_skip
end

.failure_callbackObject



52
53
54
# File 'lib/minitest/retry.rb', line 52

def failure_callback
  @failure_callback
end

.failure_to_retry?(failures = [], klass_method_name, klass) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/minitest/retry.rb', line 72

def failure_to_retry?(failures = [], klass_method_name, klass)
  return false if failures.empty?

  if methods_to_retry.any?
    return methods_to_retry.include?(klass_method_name)
  end

  if exceptions_to_retry.any?
    errors = failures.map(&:error).map(&:class)
    return (errors & exceptions_to_retry).any?
  end

  if methods_to_skip.any?
    return !methods_to_skip.include?(klass_method_name)
  end

  if exceptions_to_skip.any?
    errors = failures.map(&:error).map(&:class)
    return !(errors & exceptions_to_skip).any?
  end

  return true if classes_to_retry.empty?
  ancestors = klass.ancestors.map(&:to_s)
  return classes_to_retry.any? { |class_to_retry| ancestors.include?(class_to_retry) }
end

.ioObject



32
33
34
# File 'lib/minitest/retry.rb', line 32

def io
  @io
end

.methods_to_retryObject



44
45
46
# File 'lib/minitest/retry.rb', line 44

def methods_to_retry
  @methods_to_retry
end

.methods_to_skipObject



64
65
66
# File 'lib/minitest/retry.rb', line 64

def methods_to_skip
  @methods_to_skip
end

.on_consistent_failure(&block) ⇒ Object



18
19
20
21
# File 'lib/minitest/retry.rb', line 18

def on_consistent_failure(&block)
  return unless block_given?
  @consistent_failure_callback = block
end

.on_failure(&block) ⇒ Object



13
14
15
16
# File 'lib/minitest/retry.rb', line 13

def on_failure(&block)
  return unless block_given?
  @failure_callback = block
end

.on_retry(&block) ⇒ Object



23
24
25
26
# File 'lib/minitest/retry.rb', line 23

def on_retry(&block)
  return unless block_given?
  @retry_callback = block
end

.prepended(base) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/minitest/retry.rb', line 148

def self.prepended(base)
  unless Minitest::VERSION > "6"
    class << base
      prepend ClassMethods
    end
  end
end

.retry_callbackObject



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

def retry_callback
  @retry_callback
end

.retry_countObject



28
29
30
# File 'lib/minitest/retry.rb', line 28

def retry_count
  @retry_count
end

.run_with_retry(klass_or_instance, method_name) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/minitest/retry.rb', line 98

def run_with_retry(klass_or_instance, method_name)
  klass = klass_or_instance.instance_of?(Class) ? klass_or_instance : klass_or_instance.class
  klass_method_name = "#{klass.name}##{method_name}"
  result = yield

  return result unless failure_to_retry?(result.failures, klass_method_name, klass)
  return result if result.skipped?

  failure_callback&.call(klass, method_name, result)

  retry_count.times do |count|
    retry_callback&.call(klass, method_name, count + 1, result)

    if verbose && io
      msg = "[MinitestRetry] retry '%s' count: %s,  msg: %s\n" %
        [method_name, count + 1, result.failures.map(&:message).join(",")]
      io.puts(msg)
    end

    # NOTE: Only keep the last result when executed multiple times.
    klass_or_instance.failures.clear if klass_or_instance.respond_to?(:failures)
    result = yield
    break if result.failures.empty?
  end

  if consistent_failure_callback && !result.failures.empty?
    consistent_failure_callback.call(klass, method_name, result)
  end

  result
end

.use!(retry_count: 3, io: $stdout, verbose: true, exceptions_to_retry: [], methods_to_retry: [], classes_to_retry: [], methods_to_skip: [], exceptions_to_skip: []) ⇒ Object



6
7
8
9
10
11
# File 'lib/minitest/retry.rb', line 6

def use!(retry_count: 3, io: $stdout, verbose: true, exceptions_to_retry: [], methods_to_retry: [], classes_to_retry: [], methods_to_skip: [], exceptions_to_skip: [])
  @retry_count, @io, @verbose, @exceptions_to_retry, @methods_to_retry, @classes_to_retry, @methods_to_skip, @exceptions_to_skip = retry_count, io, verbose, exceptions_to_retry, methods_to_retry, classes_to_retry, methods_to_skip, exceptions_to_skip
  @failure_callback, @consistent_failure_callback, @retry_callback = nil, nil, nil
  Minitest.prepend(self)
  Minitest::Test.prepend(TestWithRetry) if Minitest::VERSION > "6"
end

.verboseObject



36
37
38
# File 'lib/minitest/retry.rb', line 36

def verbose
  @verbose
end