├── .ci.gemfile
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── CHANGELOG
├── Gemfile
├── MIT-LICENSE
├── README.rdoc
├── Rakefile
├── lib
└── minitest
│ ├── hooks.rb
│ └── hooks
│ ├── default.rb
│ └── test.rb
├── minitest-hooks.gemspec
└── spec
├── all.rb
├── errors
└── example.rb
├── helper.rb
├── minitest_hooks_all_name_spec.rb
├── minitest_hooks_direct_spec.rb
├── minitest_hooks_errors_spec.rb
├── minitest_hooks_spec.rb
├── minitest_hooks_test.rb
└── simplecov_helper.rb
/.ci.gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | minitest_version = case RUBY_VERSION
4 | when /\A1.8/
5 | '< 5.12'
6 | when /\A1.9/
7 | '< 5.4'
8 | when /\A2.0/
9 | '< 5.6'
10 | when /\A2.1/
11 | '< 5.8'
12 | when /\A2.2/
13 | '< 5.9'
14 | when /\A2.3/
15 | '< 5.10'
16 | when /\A2.4/
17 | '< 5.11'
18 | else
19 | '> 0'
20 | end
21 | gem 'minitest', minitest_version
22 | gem 'minitest-global_expectations', '>=1.0.1'
23 |
24 | if RUBY_VERSION >= '3.3'
25 | # Until minitest is updated to not require mutex_m
26 | gem 'mutex_m'
27 | end
28 |
29 | if RUBY_VERSION < '2.0'
30 | gem 'sequel', '< 5.70'
31 | else
32 | gem 'sequel'
33 | end
34 |
35 | if RUBY_VERSION < '2'
36 | gem 'rake', '<10.0.0'
37 | else
38 | gem 'rake'
39 | end
40 |
41 | if defined?(JRUBY_VERSION)
42 | gem 'jdbc-sqlite3'
43 | elsif RUBY_VERSION < '1.9.3'
44 | gem 'sqlite3', '<1.4'
45 | elsif RUBY_VERSION < '2.5'
46 | gem 'sqlite3', '< 1.5'
47 | else
48 | gem 'sqlite3'
49 | end
50 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | permissions:
10 | contents: read
11 |
12 | jobs:
13 | tests:
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | os: [ubuntu-latest]
18 | ruby: [ "2.0.0", 2.1, 2.3, 2.4, 2.5, 2.6, 2.7, "3.0", 3.1, 3.2, 3.3, 3.4, jruby-9.3, jruby-9.4, jruby-10.0 ]
19 | include:
20 | - { os: ubuntu-22.04, ruby: "1.9.3" }
21 | - { os: ubuntu-22.04, ruby: jruby-9.2 }
22 | runs-on: ${{ matrix.os }}
23 | name: ${{ matrix.ruby }}
24 | env:
25 | BUNDLE_GEMFILE: .ci.gemfile
26 | steps:
27 | - uses: actions/checkout@v4
28 | - run: sudo apt-get -yqq install libsqlite3-dev
29 | - uses: ruby/setup-ruby@v1
30 | with:
31 | ruby-version: ${{ matrix.ruby }}
32 | bundler-cache: true
33 | - run: bundle exec rake
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /rdoc
2 | /minitest-hooks-*.gem
3 | /Gemfile.lock
4 | /.bundle
5 | /coverage
6 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | === 1.5.2 (2024-08-14)
2 |
3 | * Fix use with minitest 5.25+ (paracycle) (#27, #28)
4 |
5 | === 1.5.1 (2023-07-27)
6 |
7 | * Do not include specs or Rakefile in the gem (jeremyevans)
8 |
9 | * Fix use with minitest 5.19+ by using Minitest instead of MiniTest as the constant (jeremyevans)
10 |
11 | === 1.5.0 (2018-05-21)
12 |
13 | * Fix use with minitest 5.11+ by using Minitest::Result in such cases (GUI) (#15)
14 |
15 | === 1.4.2 (2017-09-12)
16 |
17 | * Don't modify test instance name if before_all/after_all cause an error (jeremyevans) (#14)
18 |
19 | * Set around_all test instance name to strings so that exceptions in {before,after,around}_all don't break reporters (jeremyevans) (#14)
20 |
21 | * Set time to 0 for around_all test instance so that exceptions in {before,after,around}_all don't break reporters (jeremyevans) (#13, #14)
22 |
23 | === 1.4.1 (2017-07-31)
24 |
25 | * Set test/spec name correctly when running before(:all)/after(:all)/around(:all) hooks (rcrogers, jeremyevans) (#12)
26 |
27 | === 1.4.0 (2015-11-17)
28 |
29 | * Handle errors in before(:all)/after(:all)/around(:all) hooks (jeremyevans)
30 |
31 | === 1.3.0 (2015-08-17)
32 |
33 | * Don't run before_all/after_all/around_all hooks for classes with no tests/specs when using minitest >= 5.8.0 (jeremyevans) (#7)
34 |
35 | === 1.2.0 (2015-07-02)
36 |
37 | * Add minitest/hooks/test file, which doesn't require minitest/spec (janko-m) (#9, #10)
38 |
39 | === 1.1.0 (2015-05-11)
40 |
41 | * Remove unnecessary module inclusion (jeremyevans)
42 |
43 | * Add block-based around and around(:all) support (jeremyevans)
44 |
45 | === 1.0.1 (2015-04-26)
46 |
47 | * Fix homepage in gemspec (jeremyevans)
48 |
49 | === 1.0.0 (2015-04-26)
50 |
51 | * Initial Public Release
52 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gemspec
4 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2023 Jeremy Evans
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to
5 | deal in the Software without restriction, including without limitation the
6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 | sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/README.rdoc:
--------------------------------------------------------------------------------
1 | = minitest-hooks
2 |
3 | minitest-hooks adds around and before_all/after_all/around_all hooks for Minitest.
4 | This allows you do things like run each suite of specs inside a database transaction,
5 | running each spec inside its own savepoint inside that transaction, which can
6 | significantly speed up testing for specs that share expensive database setup code.
7 |
8 | = Installation
9 |
10 | gem install minitest-hooks
11 |
12 | = Source Code
13 |
14 | Source code is available on GitHub at https://github.com/jeremyevans/minitest-hooks
15 |
16 | = Usage
17 |
18 | == In Specs (Minitest::Spec)
19 |
20 | === For all specs
21 |
22 | require 'minitest/hooks/default'
23 |
24 | === For some specs
25 |
26 | First, you need to require the library.
27 |
28 | require 'minitest/hooks'
29 |
30 | You can set the default for some specs to be Minitest::HooksSpec:
31 |
32 | Minitest::Spec.register_spec_type(/something/, Minitest::HooksSpec)
33 |
34 | Alternatively, you can include Minitest::Hooks in a specific spec class:
35 |
36 | describe 'something' do
37 | include Minitest::Hooks
38 | end
39 |
40 | === before_all Hooks
41 |
42 | To run code before any specs in the suite are executed, pass +:all+ to +before+:
43 |
44 | describe 'something' do
45 | before(:all) do
46 | DB[:table].insert(:column=>1)
47 | end
48 | end
49 |
50 | === after_all Hooks
51 |
52 | To run code after all specs in the suite are executed, pass +:all+ to +after+:
53 |
54 | describe 'something' do
55 | after(:all) do
56 | DB[:table].delete
57 | end
58 | end
59 |
60 | === around Hooks
61 |
62 | To run code around each spec in a suite, call +around+ with a block, and have the block
63 | call +super+:
64 |
65 | describe 'something' do
66 | around do |&block|
67 | DB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true) do
68 | super(&block)
69 | end
70 | end
71 | end
72 |
73 | === around_all Hooks
74 |
75 | To run code around all specs in a suite, call around(:all) with a block,
76 | and have the block call +super+:
77 |
78 | describe 'something' do
79 | around(:all) do |&block|
80 | DB.transaction(:rollback=>:always) do
81 | super(&block)
82 | end
83 | end
84 | end
85 |
86 | === In Tests (Minitest::Test)
87 |
88 | Create a subclass of Minitest::Test and include Minitest::Hooks,
89 | and have your test classes subclass from that subclass:
90 |
91 | require 'minitest/hooks/test'
92 | class MyTest < Minitest::Test
93 | include Minitest::Hooks
94 | end
95 |
96 | class TestSuite1 < MyTest
97 | end
98 |
99 | You can just define the +before_all+, +after_all+, +around+, and +around_all+ methods,
100 | instead of using the spec DSL. Make sure to call super when overriding the methods.
101 |
102 | class TestSuite1 < MyTest
103 | def before_all
104 | super
105 | DB[:table].insert(:column=>1)
106 | end
107 |
108 | def after_all
109 | DB[:table].delete
110 | super
111 | end
112 |
113 | def around
114 | DB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true) do
115 | super
116 | end
117 | end
118 |
119 | def around_all
120 | DB.transaction(:rollback=>:always) do
121 | super
122 | end
123 | end
124 | end
125 |
126 | = Behavior
127 |
128 | == Hooks Just Define Methods
129 |
130 | Just like the before/after hooks supported by minitest, all hooks supported by minitest-hooks
131 | just define methods on the spec class, there is no magic ("It's just ruby"). This has a
132 | couple of effects:
133 |
134 | 1. You cannot define multiple hooks of the same type in the same class. This is because
135 | you cannot have multiple methods with the same name in the same class. If you define
136 | a second hook of the same type in the same class, it will overwrite the previous hook,
137 | just like ruby's behavior if you define a method twice in the same class.
138 |
139 | 2. For around and around(:all) hooks, you should always call super. If you want a subclass
140 | around hook to run inside a superclass around hook, you need to call super in the
141 | subclass hook and run the code inside the block you pass to super, then call block.call
142 | somewhere inside the super block:
143 |
144 | describe "superclass" do
145 | around do |&block|
146 | some_outer_method do
147 | super(&block)
148 | end
149 | end
150 |
151 | describe "subclass" do
152 | around do |&block|
153 | super do
154 | some_inner_method do
155 | block.call
156 | end
157 | end
158 | end
159 | end
160 | end
161 |
162 | You do not need to call super for before(:all) or after(:all) hooks. Both before(:all) and
163 | after(:all) implicitly call super for you in the method they define, mirroring minitest's
164 | behavior for before and after hooks.
165 |
166 | 3. All hooks share state/instance variables. So any instance variables you set in before(:all),
167 | around(:all), or around are shared with the examples. Note that after(:all) will only see
168 | instance variables set in before(:all) or around(:all), it will not see instance variables
169 | set inside examples.
170 |
171 | == All Spec Classes are Independent
172 |
173 | The way minitest works, all spec classes are indepedent of other spec classes in terms
174 | of how and when they are executed, even spec classes that are subclasses of other spec
175 | classes. This means that for every spec class, the before(:all), after(:all), and
176 | around(:all) hooks for that class will be executed, even if they were defined in the
177 | spec's superclass and not in the spec class itself.
178 |
179 | So if you have a spec superclass that uses before(:all), and a spec subclass for that
180 | superclass, the before(:all) in the spec superclass will be run twice, once in the context
181 | of an instance of the superclass, before executing the superclass's specs, and once in the
182 | context of an instance of the subclass, before executing the subclass's specs.
183 |
184 | == Order of Operations
185 |
186 | For each spec class, the around(:all) hooks are run first. Both before(:all) and after(:all)
187 | run inside around(:all). For each spec inside the spec class, around will be called,
188 | and before and after for each spec will be run inside around.
189 |
190 | = License
191 |
192 | MIT
193 |
194 | = Author
195 |
196 | Jeremy Evans
197 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "rake"
2 | require "rake/clean"
3 |
4 | CLEAN.include ["minitest-hooks-*.gem", "rdoc", "coverage"]
5 |
6 | desc "Build minitest-hooks gem"
7 | task :package=>[:clean] do |p|
8 | sh %{#{FileUtils::RUBY} -S gem build minitest-hooks.gemspec}
9 | end
10 |
11 | ### Specs
12 |
13 | desc "Run specs"
14 | task :spec do
15 | sh %{#{FileUtils::RUBY} #{"-w" if RUBY_VERSION >= '3'} #{'-W:strict_unused_block' if RUBY_VERSION >= '3.4'} spec/all.rb}
16 | end
17 |
18 | desc "Run specs with coverage"
19 | task :spec_cov do
20 | ENV['COVERAGE'] = '1'
21 | sh %{#{FileUtils::RUBY} spec/all.rb}
22 | end
23 |
24 | task :default=>:spec
25 |
26 | ### RDoc
27 |
28 | desc "Generate rdoc"
29 | task :rdoc do
30 | rdoc_dir = "rdoc"
31 | rdoc_opts = ["--line-numbers", "--inline-source", '--title', 'minitest-hooks: around and before_all/after_all/around_all hooks for Minitest']
32 |
33 | begin
34 | gem 'hanna'
35 | rdoc_opts.concat(['-f', 'hanna'])
36 | rescue Gem::LoadError
37 | end
38 |
39 | rdoc_opts.concat(['--main', 'README.rdoc', "-o", rdoc_dir] +
40 | %w"README.rdoc CHANGELOG MIT-LICENSE" +
41 | Dir["lib/**/*.rb"]
42 | )
43 |
44 | FileUtils.rm_rf(rdoc_dir)
45 |
46 | require "rdoc"
47 | RDoc::RDoc.new.document(rdoc_opts)
48 | end
49 |
--------------------------------------------------------------------------------
/lib/minitest/hooks.rb:
--------------------------------------------------------------------------------
1 | require 'minitest/hooks/test'
2 | require 'minitest/spec'
3 |
4 | # Spec subclass that includes the hook methods.
5 | class Minitest::HooksSpec < Minitest::Spec
6 | include Minitest::Hooks
7 | end
8 |
--------------------------------------------------------------------------------
/lib/minitest/hooks/default.rb:
--------------------------------------------------------------------------------
1 | require 'minitest/hooks'
2 |
3 | Minitest::Spec.register_spec_type(//, Minitest::HooksSpec)
4 |
--------------------------------------------------------------------------------
/lib/minitest/hooks/test.rb:
--------------------------------------------------------------------------------
1 | require 'minitest'
2 |
3 | # Add support for around and before_all/after_all/around_all hooks to
4 | # minitest spec classes.
5 | module Minitest::Hooks
6 | # Add the class methods to the class. Also, include an additional
7 | # module in the class that before(:all) and after(:all) methods
8 | # work on a class that directly includes this module.
9 | def self.included(mod)
10 | super
11 | mod.instance_exec do
12 | extend(Minitest::Hooks::ClassMethods)
13 | end
14 | end
15 |
16 | # Empty method, necessary so that super calls in spec subclasses work.
17 | def before_all
18 | end
19 |
20 | # Empty method, necessary so that super calls in spec subclasses work.
21 | def after_all
22 | end
23 |
24 | # Method that just yields, so that super calls in spec subclasses work.
25 | def around_all
26 | yield
27 | end
28 |
29 | # Method that just yields, so that super calls in spec subclasses work.
30 | def around
31 | yield
32 | end
33 |
34 | # Run around hook inside, since time_it is run around every spec.
35 | def time_it
36 | super do
37 | around do
38 | yield
39 | end
40 | end
41 | end
42 | end
43 |
44 | module Minitest::Hooks::ClassMethods
45 | # Object used to get an empty new instance, as new by default will return
46 | # a dup of the singleton instance.
47 | NEW = Object.new.freeze
48 |
49 | # Unless name is NEW, return a dup singleton instance.
50 | def new(name)
51 | if name.equal?(NEW)
52 | return super('around_all')
53 | end
54 |
55 | instance = @instance.dup
56 | instance.name = name
57 | instance.failures = []
58 | instance
59 | end
60 |
61 | # When running the specs in the class, first create a singleton instance, the singleton is
62 | # used to implement around_all/before_all/after_all hooks, and each spec will run as a
63 | # dup of the singleton instance.
64 | def with_info_handler(*args, &block)
65 | @instance = new(NEW)
66 | @instance.time = 0
67 | @instance.name = "around_all"
68 |
69 | reporter = args[0]
70 |
71 | begin
72 | @instance.around_all do
73 | begin
74 | @instance.capture_exceptions do
75 | @instance.name = "before_all"
76 | @instance.before_all
77 | end
78 |
79 | if @instance.failure
80 | failed = true
81 | _record_minitest_hooks_error(reporter, @instance)
82 | else
83 | super
84 | end
85 | ensure
86 | @instance.capture_exceptions do
87 | @instance.name = "after_all" unless failed
88 | @instance.after_all
89 | end
90 | if @instance.failure && !failed
91 | failed = true
92 | _record_minitest_hooks_error(reporter, @instance)
93 | end
94 | @instance.name = "around_all" unless failed
95 | end
96 | end
97 | rescue => e
98 | @instance.capture_exceptions do
99 | raise e
100 | end
101 | _record_minitest_hooks_error(reporter, @instance)
102 | end
103 | end
104 |
105 | # If type is :all, set the around_all hook, otherwise set the around hook.
106 | def around(type=nil, &block)
107 | meth = type == :all ? :around_all : :around
108 | define_method(meth, &block)
109 | end
110 |
111 | # If type is :all, set the before_all hook instead of the before hook.
112 | def before(type=nil, &block)
113 | if type == :all
114 | define_method(:before_all) do
115 | super()
116 | instance_exec(&block)
117 | end
118 | nil
119 | else
120 | super
121 | end
122 | end
123 |
124 | # If type is :all, set the after_all hook instead of the after hook.
125 | def after(type=nil, &block)
126 | if type == :all
127 | define_method(:after_all) do
128 | instance_exec(&block)
129 | super()
130 | end
131 | nil
132 | else
133 | super
134 | end
135 | end
136 |
137 | private
138 |
139 | def _record_minitest_hooks_error(reporter, instance)
140 | # In Minitest 5.11+, use Minitest::Result for wrapping the object to send
141 | # to the reporter.
142 | if(defined?(Minitest::Result))
143 | result = Minitest::Result.from(instance)
144 | # :nocov:
145 | else
146 | result = instance
147 | # :nocov:
148 | end
149 | reporter.record result
150 | end
151 | end
152 |
--------------------------------------------------------------------------------
/minitest-hooks.gemspec:
--------------------------------------------------------------------------------
1 | Gem::Specification.new do |s|
2 | s.name = 'minitest-hooks'
3 | s.version = '1.5.2'
4 | s.platform = Gem::Platform::RUBY
5 | s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "MIT-LICENSE"]
6 | s.rdoc_options += ["--quiet", "--line-numbers", "--inline-source", '--title', 'minitest-hooks: around and before_all/after_all/around_all hooks for Minitest', '--main', 'README.rdoc']
7 | s.license = "MIT"
8 | s.summary = "Around and before_all/after_all/around_all hooks for Minitest"
9 | s.author = "Jeremy Evans"
10 | s.email = "code@jeremyevans.net"
11 | s.homepage = "http://github.com/jeremyevans/minitest-hooks"
12 | s.files = %w(MIT-LICENSE CHANGELOG README.rdoc) + Dir["lib/**/*.rb"]
13 | s.description = <5.3"
21 | s.add_development_dependency "sequel", '>4'
22 | s.add_development_dependency "sqlite3"
23 | s.add_development_dependency "rake"
24 | s.add_development_dependency "minitest-global_expectations"
25 | end
26 |
--------------------------------------------------------------------------------
/spec/all.rb:
--------------------------------------------------------------------------------
1 | require 'rbconfig'
2 | ENV['RUBY'] ||= ENV["RUBY"] || File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]).sub(/.*\s.*/m, '"\&"')
3 | ENV['RUBYLIB'] = "lib:#{ENV['RUBYLIB']}"
4 | Dir['./spec/*_{spec,test}.rb'].each{|f| require f}
5 |
--------------------------------------------------------------------------------
/spec/errors/example.rb:
--------------------------------------------------------------------------------
1 | require './spec/helper'
2 | require 'minitest/hooks/default'
3 |
4 | error = ENV['MINITEST_HOOKS_ERRORS']
5 |
6 | module Minitest
7 | def self.plugin_result_inspector_reporter_init(options)
8 | self.reporter << ResultInspectorReporter.new(options[:io], options)
9 | end
10 |
11 | class ResultInspectorReporter < SummaryReporter
12 | def report
13 | results.each do |result|
14 | io.puts "result to_s: #{result.to_s.inspect}"
15 | # For Minitest 5.11+, we expect Minitest::Result objects.
16 | if defined?(Minitest::Result)
17 | io.puts "result source_location: #{result.source_location.inspect}"
18 | else
19 | # For older versions of Minitest, extract source_location in a
20 | # similar fashion to how some third party reporters expected to be
21 | # able to:
22 | # https://github.com/circleci/minitest-ci/blob/8b72b0f32f154d91b53d63d1d0a8a8fb3b01d726/lib/minitest/ci_plugin.rb#L139
23 | io.puts "result source_location: #{result.method(result.name).source_location.inspect}"
24 | end
25 | end
26 | end
27 | end
28 | end
29 |
30 | Minitest.extensions << "result_inspector_reporter"
31 |
32 | describe 'Minitest::Hooks error handling' do
33 | before(:all) do
34 | raise if error == 'before-all'
35 | end
36 | before do
37 | raise if error == 'before'
38 | end
39 | after do
40 | raise if error == 'after'
41 | end
42 | after(:all) do
43 | raise if error == 'after-all'
44 | end
45 | around do |&block|
46 | raise if error == 'around-before'
47 | super(&block)
48 | raise if error == 'around-after'
49 | end
50 | around(:all) do |&block|
51 | raise if error == 'around-all-before'
52 | super(&block)
53 | case error
54 | when 'before-all'
55 | name.must_equal 'before_all'
56 | when 'after-all'
57 | name.must_equal 'after_all'
58 | else
59 | name.must_equal 'around_all'
60 | end
61 | raise if error == 'around-all-after'
62 | end
63 |
64 | 3.times do |i|
65 | it "should work try #{i}" do
66 | end
67 | end
68 | end
69 |
--------------------------------------------------------------------------------
/spec/helper.rb:
--------------------------------------------------------------------------------
1 | $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../lib/"))
2 | require 'rubygems'
3 | require 'sequel'
4 |
5 | if ENV.delete('COVERAGE')
6 | require_relative 'simplecov_helper'
7 | end
8 |
9 | ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
10 | gem 'minitest'
11 | require 'minitest/global_expectations/autorun'
12 | DATABASE_URL = ENV['DATABASE_URL'] || (defined?(JRUBY_VERSION) ? 'jdbc:sqlite::memory:' : 'sqlite:/')
13 |
--------------------------------------------------------------------------------
/spec/minitest_hooks_all_name_spec.rb:
--------------------------------------------------------------------------------
1 | require './spec/helper'
2 | require 'minitest/hooks/default'
3 |
4 | describe 'Minitest::Hooks error handling' do
5 | before(:all) do
6 | name.must_equal 'before_all'
7 | end
8 | after(:all) do
9 | name.must_equal 'after_all'
10 | end
11 | around(:all) do |&block|
12 | name.must_equal 'around_all'
13 | super(&block)
14 | name.must_equal 'around_all'
15 | end
16 |
17 | 3.times do |i|
18 | it "should work try #{i}" do
19 | end
20 | end
21 | end
22 |
23 | class MinitestHooksNameTest < Minitest::Test
24 | include Minitest::Hooks
25 |
26 | def before_all
27 | assert_equal 'before_all', name
28 | end
29 | def after_all
30 | assert_equal 'after_all', name
31 | end
32 | def around_all
33 | assert_equal 'around_all', name
34 | super
35 | assert_equal 'around_all', name
36 | end
37 |
38 | 3.times do |i|
39 | define_method "test_should_work_try_#{i}" do
40 | end
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/spec/minitest_hooks_direct_spec.rb:
--------------------------------------------------------------------------------
1 | require './spec/helper'
2 | require 'minitest/hooks'
3 |
4 | NDB = Sequel.connect(DATABASE_URL)
5 |
6 | Minitest::Spec.register_spec_type(/no_default/, Minitest::Spec)
7 |
8 | describe 'Minitest::Hooks with transactions/savepoints no_default' do
9 | include Minitest::Hooks
10 |
11 | before(:all) do
12 | @ds_ba = @ds_aa
13 | @ds_ba.count.must_equal 1 + @i
14 | end
15 | before do
16 | @ds_be = @ds_ae
17 | @ds_be.count.must_equal 2 + @i * 2
18 | end
19 | after do
20 | @ds_be.count.must_equal 2 + @i * 2
21 | end
22 | after(:all) do
23 | @ds_ba.count.must_equal 1 + @i
24 | end
25 | around do |&block|
26 | @ds_aa.count.must_equal 1 + @i
27 | NDB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true) do
28 | @ds_ae = @ds_aa
29 | @ds_ae.insert(1)
30 | super(&block)
31 | end
32 | @ds_aa.count.must_equal 1 + @i
33 | end
34 | around(:all) do |&block|
35 | @i ||= 0
36 | NDB.transaction(:rollback=>:always) do
37 | NDB.create_table(:a){Integer :a}
38 | @ds_aa = NDB[:a]
39 | @ds_aa.count.must_equal 0
40 | @ds_aa.insert(1)
41 | super(&block)
42 | end
43 | NDB.table_exists?(:a).must_equal false
44 | end
45 |
46 | 3.times do |i|
47 | it "should work try #{i}" do
48 | @ds_aa.count.must_equal 2
49 | @ds_ae.count.must_equal 2
50 | @ds_ba.count.must_equal 2
51 | @ds_be.count.must_equal 2
52 | end
53 | end
54 |
55 | describe "in nested describe" do
56 | before(:all) do
57 | @ds_ba3 = @ds_ba
58 | @ds_ba2 = @ds_aa2
59 | @ds_ba2.count.must_equal 2
60 | end
61 | before do
62 | @ds_be3 = @ds_be
63 | @ds_be2 = @ds_ae2
64 | @ds_be2.count.must_equal 4
65 | end
66 | after do
67 | @ds_be2.count.must_equal 4
68 | end
69 | after(:all) do
70 | @ds_ba2.count.must_equal 2
71 | end
72 | around do |&block|
73 | @ds_aa.count.must_equal 2
74 | super() do
75 | @ds_aa.count.must_equal 3
76 | @ds_ae3 = @ds_ae
77 | @ds_ae2 = @ds_aa2
78 | @ds_ae2.insert(1)
79 | block.call
80 | @ds_aa.count.must_equal 4
81 | end
82 | @ds_aa.count.must_equal 2
83 | end
84 | around(:all) do |&block|
85 | @i ||= 1
86 | super() do
87 | @ds_aa.count.must_equal 1
88 | @ds_aa2 = @ds_aa
89 | @ds_aa2.insert(1)
90 | block.call
91 | @ds_aa.count.must_equal 2
92 | end
93 | NDB.table_exists?(:a).must_equal false
94 | end
95 |
96 | 3.times do |i|
97 | it "should work try #{i}" do
98 | @ds_aa.count.must_equal 4
99 | @ds_ae.count.must_equal 4
100 | @ds_ba.count.must_equal 4
101 | @ds_be.count.must_equal 4
102 | @ds_aa2.count.must_equal 4
103 | @ds_ae2.count.must_equal 4
104 | @ds_ba2.count.must_equal 4
105 | @ds_be2.count.must_equal 4
106 | @ds_ae3.count.must_equal 4
107 | @ds_ba3.count.must_equal 4
108 | @ds_be3.count.must_equal 4
109 | end
110 | end
111 | end
112 | end
113 |
114 |
--------------------------------------------------------------------------------
/spec/minitest_hooks_errors_spec.rb:
--------------------------------------------------------------------------------
1 | require './spec/helper'
2 | require 'minitest/hooks/default'
3 | require 'open3'
4 |
5 | RUBY = ENV['RUBY'] || 'ruby'
6 |
7 | describe 'Minitest::Hooks error handling' do
8 | def self.run_test(desc, runs, errors)
9 | it "should handle errors in #{desc}" do
10 | ENV['MINITEST_HOOKS_ERRORS'] = desc
11 | Open3.popen3(RUBY, "spec/errors/example.rb", "-v") do |_, o, e, w|
12 | output = o.read
13 | output.must_match(/#{runs} runs, 0 assertions, 0 failures, #{errors} errors, 0 skips/)
14 | output.must_match(/result to_s: ".*?Minitest::Hooks error handling#\w+.*?spec\/errors\/example\.rb:\d+/)
15 | output.must_match(/result source_location: \["(unknown|.+?\.rb)", -?\d+/)
16 | output = e.read
17 | output.gsub!(/Picked up _JAVA_OPTIONS: [^\n]+\n/, '')
18 | output.must_equal ''
19 | w.value.exitstatus.wont_equal 0 if w
20 | end
21 | end
22 | end
23 |
24 | run_test "before-all", 1, 1
25 | run_test "before", 3, 3
26 | run_test "after", 3, 3
27 | run_test "after-all", 4, 1
28 | run_test "around-before", 1, 1
29 | run_test "around-after", 1, 1
30 | run_test "around-all-before", 1, 1
31 | run_test "around-all-after", 4, 1
32 | end
33 |
--------------------------------------------------------------------------------
/spec/minitest_hooks_spec.rb:
--------------------------------------------------------------------------------
1 | require './spec/helper'
2 | require 'minitest/hooks/default'
3 |
4 | DB = Sequel.connect(DATABASE_URL)
5 |
6 | describe 'Minitest::Hooks with transactions/savepoints' do
7 | before(:all) do
8 | @ds_ba = @ds_aa
9 | @ds_ba.count.must_equal 1 + @i
10 | end
11 | before do
12 | @ds_be = @ds_ae
13 | @ds_be.count.must_equal 2 + @i * 2
14 | end
15 | after do
16 | @ds_be.count.must_equal 2 + @i * 2
17 | end
18 | after(:all) do
19 | @ds_ba.count.must_equal 1 + @i
20 | end
21 | around do |&block|
22 | @ds_aa.count.must_equal 1 + @i
23 | DB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true) do
24 | @ds_ae = @ds_aa
25 | @ds_ae.insert(1)
26 | super(&block)
27 | end
28 | @ds_aa.count.must_equal 1 + @i
29 | end
30 | around(:all) do |&block|
31 | @i ||= 0
32 | DB.transaction(:rollback=>:always) do
33 | DB.create_table(:a){Integer :a}
34 | @ds_aa = DB[:a]
35 | @ds_aa.count.must_equal 0
36 | @ds_aa.insert(1)
37 | super(&block)
38 | end
39 | DB.table_exists?(:a).must_equal false
40 | end
41 |
42 | 3.times do |i|
43 | it "should work try #{i}" do
44 | @ds_aa.count.must_equal 2
45 | @ds_ae.count.must_equal 2
46 | @ds_ba.count.must_equal 2
47 | @ds_be.count.must_equal 2
48 | end
49 | end
50 |
51 | describe "in nested describe" do
52 | before(:all) do
53 | @ds_ba3 = @ds_ba
54 | @ds_ba2 = @ds_aa2
55 | @ds_ba2.count.must_equal 2
56 | end
57 | before do
58 | @ds_be3 = @ds_be
59 | @ds_be2 = @ds_ae2
60 | @ds_be2.count.must_equal 4
61 | end
62 | after do
63 | @ds_be2.count.must_equal 4
64 | end
65 | after(:all) do
66 | @ds_ba2.count.must_equal 2
67 | end
68 | around do |&block|
69 | @ds_aa.count.must_equal 2
70 | super() do
71 | @ds_aa.count.must_equal 3
72 | @ds_ae3 = @ds_ae
73 | @ds_ae2 = @ds_aa2
74 | @ds_ae2.insert(1)
75 | block.call
76 | @ds_aa.count.must_equal 4
77 | end
78 | @ds_aa.count.must_equal 2
79 | end
80 | around(:all) do |&block|
81 | @i ||= 1
82 | super() do
83 | @ds_aa.count.must_equal 1
84 | @ds_aa2 = @ds_aa
85 | @ds_aa2.insert(1)
86 | block.call
87 | @ds_aa.count.must_equal 2
88 | end
89 | DB.table_exists?(:a).must_equal false
90 | end
91 |
92 | 3.times do |i|
93 | it "should work try #{i}" do
94 | @ds_aa.count.must_equal 4
95 | @ds_ae.count.must_equal 4
96 | @ds_ba.count.must_equal 4
97 | @ds_be.count.must_equal 4
98 | @ds_aa2.count.must_equal 4
99 | @ds_ae2.count.must_equal 4
100 | @ds_ba2.count.must_equal 4
101 | @ds_be2.count.must_equal 4
102 | @ds_ae3.count.must_equal 4
103 | @ds_ba3.count.must_equal 4
104 | @ds_be3.count.must_equal 4
105 | end
106 | end
107 | end
108 | end
109 |
--------------------------------------------------------------------------------
/spec/minitest_hooks_test.rb:
--------------------------------------------------------------------------------
1 | require './spec/helper'
2 | require 'minitest/hooks/test'
3 |
4 | class MyTest < Minitest::Test
5 | include Minitest::Hooks
6 | end
7 |
8 | class TestMinitestHooks < MyTest
9 | DB = Sequel.connect(DATABASE_URL)
10 |
11 | def before_all
12 | super
13 | @ds_ba = @ds_aa
14 | assert_equal @ds_ba.count, 1 + @i
15 | end
16 | def setup
17 | super
18 | @ds_be = @ds_ae
19 | assert_equal @ds_be.count, 2 + @i * 2
20 | end
21 | def teardown
22 | assert_equal @ds_be.count, 2 + @i * 2
23 | super
24 | end
25 | def after_all
26 | assert_equal @ds_ba.count, 1 + @i
27 | super
28 | end
29 | def around
30 | assert_equal @ds_aa.count, 1 + @i
31 | DB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true) do
32 | @ds_ae = @ds_aa
33 | @ds_ae.insert(1)
34 | super
35 | end
36 | assert_equal @ds_aa.count, 1 + @i
37 | end
38 | def around_all
39 | @i ||= 0
40 | DB.transaction(:rollback=>:always) do
41 | DB.create_table(:a){Integer :a}
42 | @ds_aa = DB[:a]
43 | assert_equal @ds_aa.count, 0
44 | @ds_aa.insert(1)
45 | super
46 | end
47 | assert_equal DB.table_exists?(:a), false
48 | end
49 |
50 | 3.times do |i|
51 | define_method(:"test_should_work_#{i}") do
52 | assert_equal @ds_aa.count, 2
53 | assert_equal @ds_ae.count, 2
54 | assert_equal @ds_ba.count, 2
55 | assert_equal @ds_be.count, 2
56 | end
57 | end
58 |
59 | class TestMinitestHooks2 < self
60 | def before_all
61 | super
62 | @ds_ba3 = @ds_ba
63 | @ds_ba2 = @ds_aa2
64 | assert_equal @ds_ba2.count, 2
65 | end
66 | def setup
67 | super
68 | @ds_be3 = @ds_be
69 | @ds_be2 = @ds_ae2
70 | assert_equal @ds_be2.count, 4
71 | end
72 | def teardown
73 | assert_equal @ds_be2.count, 4
74 | super
75 | end
76 | def after_all
77 | assert_equal @ds_ba2.count, 2
78 | super
79 | end
80 | def around
81 | assert_equal @ds_aa.count, 2
82 | super do
83 | assert_equal @ds_aa.count, 3
84 | @ds_ae3 = @ds_ae
85 | @ds_ae2 = @ds_aa2
86 | @ds_ae2.insert(1)
87 | yield
88 | assert_equal @ds_aa.count, 4
89 | end
90 | assert_equal @ds_aa.count, 2
91 | end
92 | def around_all
93 | @i ||= 1
94 | super do
95 | assert_equal @ds_aa.count, 1
96 | @ds_aa2 = @ds_aa
97 | @ds_aa2.insert(1)
98 | yield
99 | assert_equal @ds_aa.count, 2
100 | end
101 | assert_equal DB.table_exists?(:a), false
102 | end
103 |
104 | 3.times do |i|
105 | define_method(:"test_should_work_#{i}") do
106 | assert_equal @ds_aa.count, 4
107 | assert_equal @ds_ae.count, 4
108 | assert_equal @ds_ba.count, 4
109 | assert_equal @ds_be.count, 4
110 | assert_equal @ds_aa2.count, 4
111 | assert_equal @ds_ae2.count, 4
112 | assert_equal @ds_ba2.count, 4
113 | assert_equal @ds_be2.count, 4
114 | assert_equal @ds_ae3.count, 4
115 | assert_equal @ds_ba3.count, 4
116 | assert_equal @ds_be3.count, 4
117 | end
118 | end
119 | end
120 | end
121 |
--------------------------------------------------------------------------------
/spec/simplecov_helper.rb:
--------------------------------------------------------------------------------
1 | require 'simplecov'
2 |
3 | SimpleCov.instance_exec do
4 | enable_coverage :branch
5 | add_filter "/spec/"
6 | add_group('Missing'){|src| src.covered_percent < 100}
7 | add_group('Covered'){|src| src.covered_percent == 100}
8 | enable_for_subprocesses true
9 |
10 | at_fork do |pid|
11 | command_name "#{SimpleCov.command_name} (subprocess: #{pid})"
12 | self.print_error_status = false
13 | formatter SimpleCov::Formatter::SimpleFormatter
14 | minimum_coverage 0
15 | start
16 | end
17 |
18 | if ENV['COVERAGE'] == 'subprocess'
19 | ENV.delete('COVERAGE')
20 | command_name 'spawn'
21 | at_fork.call(Process.pid)
22 | else
23 | ENV['COVERAGE'] = 'subprocess'
24 | ENV['RUBYOPT'] = "#{ENV['RUBYOPT']} -r ./spec/simplecov_helper"
25 | start
26 | end
27 | end
28 |
--------------------------------------------------------------------------------