minitest 1.3.0 → 6.0.6

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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +2 -0
  3. data/History.rdoc +1860 -0
  4. data/Manifest.txt +38 -8
  5. data/README.rdoc +763 -0
  6. data/Rakefile +70 -56
  7. data/bin/minitest +5 -0
  8. data/design_rationale.rb +54 -0
  9. data/lib/hoe/minitest.rb +30 -0
  10. data/lib/minitest/assertions.rb +821 -0
  11. data/lib/minitest/autorun.rb +5 -0
  12. data/lib/minitest/benchmark.rb +452 -0
  13. data/lib/minitest/bisect.rb +304 -0
  14. data/lib/minitest/complete.rb +56 -0
  15. data/lib/minitest/compress.rb +94 -0
  16. data/lib/minitest/error_on_warning.rb +11 -0
  17. data/lib/minitest/expectations.rb +321 -0
  18. data/lib/minitest/find_minimal_combination.rb +127 -0
  19. data/lib/minitest/hell.rb +11 -0
  20. data/lib/minitest/manual_plugins.rb +4 -0
  21. data/lib/minitest/parallel.rb +72 -0
  22. data/lib/minitest/path_expander.rb +432 -0
  23. data/lib/minitest/pride.rb +4 -0
  24. data/lib/minitest/pride_plugin.rb +135 -0
  25. data/lib/minitest/server.rb +49 -0
  26. data/lib/minitest/server_plugin.rb +88 -0
  27. data/lib/minitest/spec.rb +306 -64
  28. data/lib/minitest/sprint.rb +105 -0
  29. data/lib/minitest/sprint_plugin.rb +39 -0
  30. data/lib/minitest/test.rb +232 -0
  31. data/lib/minitest/test_task.rb +331 -0
  32. data/lib/minitest.rb +1232 -0
  33. data/test/minitest/metametameta.rb +150 -0
  34. data/test/minitest/test_bisect.rb +249 -0
  35. data/test/minitest/test_find_minimal_combination.rb +138 -0
  36. data/test/minitest/test_minitest_assertions.rb +1729 -0
  37. data/test/minitest/test_minitest_benchmark.rb +151 -0
  38. data/test/minitest/test_minitest_reporter.rb +437 -0
  39. data/test/minitest/test_minitest_spec.rb +1095 -0
  40. data/test/minitest/test_minitest_test.rb +1295 -0
  41. data/test/minitest/test_minitest_test_task.rb +57 -0
  42. data/test/minitest/test_path_expander.rb +229 -0
  43. data/test/minitest/test_server.rb +146 -0
  44. data.tar.gz.sig +1 -0
  45. metadata +235 -62
  46. metadata.gz.sig +0 -0
  47. data/.autotest +0 -15
  48. data/History.txt +0 -114
  49. data/README.txt +0 -56
  50. data/lib/minitest/mock.rb +0 -31
  51. data/lib/minitest/unit.rb +0 -482
  52. data/test/test_mini_mock.rb +0 -77
  53. data/test/test_mini_spec.rb +0 -149
  54. data/test/test_mini_test.rb +0 -829
data/lib/minitest/spec.rb CHANGED
@@ -1,82 +1,324 @@
1
- #!/usr/bin/ruby -w
2
-
3
- require 'minitest/unit'
4
-
5
- class Module
6
- def infect_with_assertions pos_prefix, neg_prefix, skip_re, map = {}
7
- MiniTest::Assertions.public_instance_methods(false).each do |meth|
8
- meth = meth.to_s
9
-
10
- new_name = case meth
11
- when /^assert/ then
12
- meth.sub(/^assert/, pos_prefix.to_s)
13
- when /^refute/ then
14
- meth.sub(/^refute/, neg_prefix.to_s)
15
- end
16
- next unless new_name
17
- next if new_name =~ skip_re
18
-
19
- regexp, replacement = map.find { |re, _| new_name =~ re }
20
- new_name.sub! regexp, replacement if replacement
21
-
22
- # warn "%-22p -> %p %p" % [meth, new_name, regexp]
23
- self.class_eval <<-EOM
24
- def #{new_name} *args, &block
25
- return MiniTest::Spec.current.#{meth}(*args, &self) if Proc === self
26
- return MiniTest::Spec.current.#{meth}(args.first, self) if args.size == 1
27
- return MiniTest::Spec.current.#{meth}(self, *args)
1
+ require_relative "test"
2
+
3
+ class Module # :nodoc:
4
+ def infect_an_assertion meth, new_name, dont_flip = false # :nodoc:
5
+ block = dont_flip == :block
6
+ dont_flip = false if block
7
+
8
+ # https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
9
+ # Drop this when we can drop ruby 2.6 (aka after rails 6.1 EOL, ~2024-06)
10
+ kw_extra = "ruby2_keywords %p" % [new_name] if respond_to? :ruby2_keywords, true
11
+
12
+ self.class_eval <<-EOM, __FILE__, __LINE__ + 1
13
+ def #{new_name} *args
14
+ raise "Calling ##{new_name} outside of test." unless ctx
15
+ case
16
+ when #{!!dont_flip} then
17
+ ctx.#{meth}(target, *args)
18
+ when #{block} && Proc === target then
19
+ ctx.#{meth}(*args, &target)
20
+ else
21
+ ctx.#{meth}(args.first, target, *args[1..-1])
28
22
  end
29
- EOM
30
- end
23
+ end
24
+ #{kw_extra}
25
+ EOM
31
26
  end
32
27
  end
33
28
 
34
- Object.infect_with_assertions(:must, :wont,
35
- /^(must|wont)$|wont_(throw)|
36
- must_(block|not?_|nothing|raise$)/x,
37
- /(must_throw)s/ => '\1',
38
- /(?!not)_same/ => '_be_same_as',
39
- /_in_/ => '_be_within_',
40
- /_operator/ => '_be',
41
- /_includes/ => '_include',
42
- /(must|wont)_(.*_of|nil|empty)/ => '\1_be_\2',
43
- /must_raises/ => 'must_raise')
44
-
45
- class Object
46
- alias :must_be_close_to :must_be_within_delta
47
- alias :wont_be_close_to :wont_be_within_delta
29
+ # :stopdoc:
30
+ module Minitest # fucking hell rdoc...
31
+ Expectation = Struct.new :target, :ctx
48
32
  end
33
+ # :startdoc:
34
+
35
+ ##
36
+ # Kernel extensions for minitest
49
37
 
50
38
  module Kernel
51
- def describe desc, &block
52
- cls = Class.new(MiniTest::Spec)
53
- Object.const_set desc.to_s.split(/\W+/).map { |s| s.capitalize }.join, cls
39
+ ##
40
+ # Describe a series of expectations for a given target +desc+.
41
+ #
42
+ # Defines a test class subclassing from either Minitest::Spec or
43
+ # from the surrounding describe's class. The surrounding class may
44
+ # subclass Minitest::Spec manually in order to easily share code:
45
+ #
46
+ # class MySpec < Minitest::Spec
47
+ # # ... shared code ...
48
+ # end
49
+ #
50
+ # class TestStuff < MySpec
51
+ # it "does stuff" do
52
+ # # shared code available here
53
+ # end
54
+ # describe "inner stuff" do
55
+ # it "still does stuff" do
56
+ # # ...and here
57
+ # end
58
+ # end
59
+ # end
60
+ #
61
+ # For more information on getting started with writing specs, see:
62
+ #
63
+ # http://www.rubyinside.com/a-minitestspec-tutorial-elegant-spec-style-testing-that-comes-with-ruby-5354.html
64
+ #
65
+ # For some suggestions on how to improve your specs, try:
66
+ #
67
+ # https://betterspecs.org
68
+ #
69
+ # but do note that several items there are debatable or specific to
70
+ # rspec.
71
+ #
72
+ # For more information about expectations, see Minitest::Expectations.
54
73
 
74
+ def describe desc, *additional_desc, &block # :doc:
75
+ stack = Minitest::Spec.describe_stack
76
+ is_spec_class = Class === self && kind_of?(Minitest::Spec::DSL)
77
+ name = [stack.last, desc, *additional_desc]
78
+ name.prepend self if stack.empty? && is_spec_class
79
+ sclas =
80
+ stack.last \
81
+ || (is_spec_class && self) \
82
+ || Minitest::Spec.spec_type(desc, *additional_desc)
83
+
84
+ cls = sclas.create name.compact.join("::"), desc
85
+
86
+ stack.push cls
55
87
  cls.class_eval(&block)
88
+ stack.pop
89
+ cls
56
90
  end
91
+ private :describe
57
92
  end
58
93
 
59
- class MiniTest::Spec < MiniTest::Unit::TestCase
60
- def self.current
61
- @@current_spec
62
- end
94
+ ##
95
+ # Minitest::Spec -- The faster, better, less-magical spec framework!
96
+ #
97
+ # For a list of expectations, see Minitest::Expectations.
63
98
 
64
- def initialize name
65
- super
66
- @@current_spec = self
67
- end
99
+ class Minitest::Spec < Minitest::Test
68
100
 
69
- def self.before(type = :each, &block)
70
- raise "unsupported before type: #{type}" unless type == :each
71
- define_method :setup, &block
72
- end
101
+ ##
102
+ # Oh look! A Minitest::Spec::DSL module! Eat your heart out DHH.
73
103
 
74
- def self.after(type = :each, &block)
75
- raise "unsupported after type: #{type}" unless type == :each
76
- define_method :teardown, &block
77
- end
104
+ module DSL
105
+ ##
106
+ # Contains pairs of matchers and Spec classes to be used to
107
+ # calculate the superclass of a top-level describe. This allows for
108
+ # automatically customizable spec types.
109
+ #
110
+ # See: register_spec_type and spec_type
111
+
112
+ TYPES = [[//, Minitest::Spec]]
113
+
114
+ ##
115
+ # Register a new type of spec that matches the spec's description.
116
+ # This method can take either a Regexp and a spec class or a spec
117
+ # class and a block that takes the description and returns true if
118
+ # it matches.
119
+ #
120
+ # Eg:
121
+ #
122
+ # register_spec_type(/Controller$/, Minitest::Spec::Rails)
123
+ #
124
+ # or:
125
+ #
126
+ # register_spec_type(Minitest::Spec::RailsModel) do |desc|
127
+ # desc.superclass == ActiveRecord::Base
128
+ # end
129
+
130
+ def register_spec_type *args, &block
131
+ if block then
132
+ matcher, klass = block, args.first
133
+ else
134
+ matcher, klass = *args
135
+ end
136
+ TYPES.unshift [matcher, klass]
137
+ end
138
+
139
+ ##
140
+ # Figure out the spec class to use based on a spec's description. Eg:
141
+ #
142
+ # spec_type("BlahController") # => Minitest::Spec::Rails
143
+
144
+ def spec_type desc, *additional
145
+ TYPES.find { |matcher, _klass|
146
+ if matcher.respond_to? :call then
147
+ matcher.call desc, *additional
148
+ else
149
+ matcher === desc.to_s
150
+ end
151
+ }.last
152
+ end
153
+
154
+ def describe_stack # :nodoc:
155
+ Thread.current[:describe_stack] ||= []
156
+ end
157
+
158
+ def children # :nodoc:
159
+ @children ||= []
160
+ end
161
+
162
+ def nuke_test_methods! # :nodoc:
163
+ self.public_instance_methods.grep(/^test_/).each do |name|
164
+ self.send :undef_method, name
165
+ end
166
+ end
167
+
168
+ ##
169
+ # Define a 'before' action. Inherits the way normal methods should.
170
+ #
171
+ # NOTE: +type+ is ignored and is only there to make porting easier.
172
+ #
173
+ # Equivalent to Minitest::Test#setup.
174
+
175
+ def before _type = nil, &block
176
+ define_method :setup do
177
+ super()
178
+ self.instance_eval(&block)
179
+ end
180
+ end
181
+
182
+ ##
183
+ # Define an 'after' action. Inherits the way normal methods should.
184
+ #
185
+ # NOTE: +type+ is ignored and is only there to make porting easier.
186
+ #
187
+ # Equivalent to Minitest::Test#teardown.
188
+
189
+ def after _type = nil, &block
190
+ define_method :teardown do
191
+ self.instance_eval(&block)
192
+ super()
193
+ end
194
+ end
195
+
196
+ ##
197
+ # Define an expectation with name +desc+. Name gets morphed to a
198
+ # proper test method name. For some freakish reason, people who
199
+ # write specs don't like class inheritance, so this goes way out of
200
+ # its way to make sure that expectations aren't inherited.
201
+ #
202
+ # This is also aliased to #specify and doesn't require a +desc+ arg.
203
+ #
204
+ # Hint: If you _do_ want inheritance, use minitest/test. You can mix
205
+ # and match between assertions and expectations as much as you want.
206
+
207
+ def it desc = "anonymous", &block
208
+ block ||= proc { skip "(no tests defined)" }
209
+
210
+ @specs ||= 0
211
+ @specs += 1
78
212
 
79
- def self.it desc, &block
80
- define_method "test_#{desc.gsub(/\W+/, '_').downcase}", &block
213
+ name = "test_%04d_%s" % [ @specs, desc ]
214
+
215
+ undef_klasses = self.children.reject { |c| c.public_method_defined? name }
216
+
217
+ define_method name, &block
218
+
219
+ undef_klasses.each do |undef_klass|
220
+ undef_klass.send :undef_method, name
221
+ end
222
+
223
+ name
224
+ end
225
+
226
+ ##
227
+ # Essentially, define an accessor for +name+ with +block+.
228
+ #
229
+ # Why use let instead of def? I honestly don't know.
230
+
231
+ def let name, &block
232
+ name = name.to_s
233
+ pre, post = "let '#{name}' cannot ", ". Please use another name."
234
+ methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject]
235
+ raise ArgumentError, "#{pre}begin with 'test'#{post}" if
236
+ name.start_with? "test"
237
+ raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if
238
+ methods.include? name
239
+
240
+ define_method name do
241
+ @_memoized ||= {}
242
+ @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) }
243
+ end
244
+ end
245
+
246
+ ##
247
+ # Another lazy man's accessor generator. Made even more lazy by
248
+ # setting the name for you to +subject+.
249
+
250
+ def subject &block
251
+ let :subject, &block
252
+ end
253
+
254
+ def create name, desc # :nodoc:
255
+ cls = Class.new self do
256
+ @name = name
257
+ @desc = desc
258
+
259
+ nuke_test_methods!
260
+ end
261
+
262
+ children << cls
263
+
264
+ cls
265
+ end
266
+
267
+ def name # :nodoc:
268
+ defined?(@name) ? @name : super
269
+ end
270
+
271
+ alias to_s name
272
+ alias inspect name
273
+
274
+ attr_reader :desc # :nodoc:
275
+ alias specify it
276
+
277
+ ##
278
+ # Rdoc... why are you so dumb?
279
+
280
+ module InstanceMethods
281
+ ##
282
+ # Takes a value or a block and returns a value monad that has
283
+ # all of Expectations methods available to it.
284
+ #
285
+ # _(1 + 1).must_equal 2
286
+ #
287
+ # And for blocks:
288
+ #
289
+ # _ { 1 + "1" }.must_raise TypeError
290
+ #
291
+ # This method of expectation-based testing is preferable to
292
+ # straight-expectation methods (on Object) because it stores its
293
+ # test context, bypassing our hacky use of thread-local variables.
294
+ #
295
+ # It is also aliased to #value and #expect for your aesthetic
296
+ # pleasure:
297
+ #
298
+ # _(1 + 1).must_equal 2
299
+ # value(1 + 1).must_equal 2
300
+ # expect(1 + 1).must_equal 2
301
+
302
+ def _ value = nil, &block
303
+ Minitest::Expectation.new block || value, self
304
+ end
305
+
306
+ alias value _
307
+ alias expect _
308
+ end
309
+
310
+ def self.extended obj # :nodoc:
311
+ obj.send :include, InstanceMethods
312
+ end
81
313
  end
314
+
315
+ extend DSL
316
+
317
+ TYPES = DSL::TYPES # :nodoc:
318
+ end
319
+
320
+ require_relative "expectations"
321
+
322
+ class Minitest::Expectation
323
+ include Minitest::Expectations
82
324
  end
@@ -0,0 +1,105 @@
1
+ $LOAD_PATH.unshift "test", "lib"
2
+
3
+ require "simplecov" if ENV["MT_COV"] || ARGV.delete("--simplecov")
4
+ require_relative "autorun"
5
+ require_relative "path_expander"
6
+
7
+ module Minitest
8
+
9
+ ##
10
+ # Runs (Get it? It's fast!) your tests and makes it easier to rerun
11
+ # individual failures.
12
+
13
+ class Sprint
14
+ # extracted version = "1.5.0"
15
+
16
+ ##
17
+ # Process and run minitest cmdline.
18
+
19
+ def self.run args = ARGV
20
+ if args.delete("--bisect") or args.delete("-b") then
21
+ require_relative "bisect"
22
+
23
+ return Minitest::Bisect.run ARGV
24
+ end
25
+
26
+ Minitest::PathExpander.new(args).process { |f|
27
+ require "./#{f}" if File.file? f
28
+ }
29
+ end
30
+
31
+ ##
32
+ # An extra minitest reporter to output how to rerun failures in
33
+ # various styles.
34
+
35
+ class SprintReporter < AbstractReporter
36
+ ##
37
+ # The style to report, either lines or regexp. Defaults to lines.
38
+ attr_accessor :style
39
+ attr_accessor :results # :nodoc:
40
+
41
+ def initialize style = :regexp # :nodoc:
42
+ self.results = []
43
+ self.style = style
44
+ end
45
+
46
+ def record result # :nodoc:
47
+ results << result unless result.passed? or result.skipped?
48
+ end
49
+
50
+ def report # :nodoc:
51
+ return if results.empty?
52
+
53
+ puts
54
+ puts "Happy Happy Sprint List:"
55
+ puts
56
+ print_list
57
+ puts
58
+ end
59
+
60
+ def print_list # :nodoc:
61
+ case style
62
+ when :regexp
63
+ results.each do |result|
64
+ puts " minitest -n #{result.class_name}##{result.name}"
65
+ end
66
+ when :lines
67
+ files = Hash.new { |h,k| h[k] = [] }
68
+ results.each do |result|
69
+ path, line = result.source_location
70
+ path = path.delete_prefix "#{Dir.pwd}/"
71
+ files[path] << line
72
+ end
73
+
74
+ files.sort.each do |path, lines|
75
+ puts " minitest %s:%s" % [path, lines.sort.join(",")]
76
+ end
77
+ else
78
+ raise "unsupported style: %p" % [style]
79
+ end
80
+ end
81
+ end
82
+
83
+ ##
84
+ # An extra minitest reporter to output how to rerun failures using
85
+ # rake.
86
+
87
+ class RakeReporter < SprintReporter
88
+ ##
89
+ # The name of the rake task to rerun. Defaults to nil.
90
+
91
+ attr_accessor :name
92
+
93
+ def initialize name = nil # :nodoc:
94
+ super()
95
+ self.name = name
96
+ end
97
+
98
+ def print_list # :nodoc:
99
+ results.each do |result|
100
+ puts [" rake", name, "N=#{result.class_name}##{result.name}"].compact.join(" ")
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "../minitest"
2
+
3
+ # :stopdoc:
4
+ class OptionParser # unofficial embedded gem "makeoptparseworkwell"
5
+ def hidden(...) = define(...).tap { |sw| def sw.summarize(*) = nil }
6
+ def deprecate(from, to) = hidden(from) { abort "#{from} is deprecated. Use #{to}." }
7
+ def topdict(name) = name.length > 1 ? top.long : top.short
8
+ def alias(from, to) = (dict = topdict(from) and dict[to] = dict[from])
9
+ end unless OptionParser.method_defined? :hidden
10
+ # :startdoc:
11
+
12
+ module Minitest # :nodoc:
13
+ def self.plugin_sprint_options opts, options # :nodoc:
14
+ opts.on "--rake [TASK]", "Report how to re-run failures with rake." do |task|
15
+ options[:sprint] = :rake
16
+ options[:rake_task] = task
17
+ end
18
+
19
+ opts.deprecate "--binstub", "--rerun"
20
+
21
+ sprint_styles = %w[rake lines names binstub]
22
+
23
+ opts.on "-r", "--rerun [STYLE]", sprint_styles, "Report how to re-run failures using STYLE (names, lines)." do |style|
24
+ options[:sprint] = (style || :lines).to_sym
25
+ end
26
+ end
27
+
28
+ def self.plugin_sprint_init options
29
+ require_relative "sprint"
30
+ case options[:sprint]
31
+ when :rake then
32
+ self.reporter << Minitest::Sprint::RakeReporter.new(options[:rake_task])
33
+ when :binstub, :names then
34
+ self.reporter << Minitest::Sprint::SprintReporter.new
35
+ when :lines then
36
+ self.reporter << Minitest::Sprint::SprintReporter.new(:lines)
37
+ end
38
+ end
39
+ end