minispec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.pryrc +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +2140 -0
- data/Rakefile +11 -0
- data/bin/minispec +4 -0
- data/lib/minispec.rb +175 -0
- data/lib/minispec/api.rb +2 -0
- data/lib/minispec/api/class.rb +195 -0
- data/lib/minispec/api/class/after.rb +49 -0
- data/lib/minispec/api/class/around.rb +54 -0
- data/lib/minispec/api/class/before.rb +101 -0
- data/lib/minispec/api/class/helpers.rb +116 -0
- data/lib/minispec/api/class/let.rb +44 -0
- data/lib/minispec/api/class/tests.rb +33 -0
- data/lib/minispec/api/instance.rb +158 -0
- data/lib/minispec/api/instance/mocks/doubles.rb +36 -0
- data/lib/minispec/api/instance/mocks/mocks.rb +319 -0
- data/lib/minispec/api/instance/mocks/spies.rb +17 -0
- data/lib/minispec/api/instance/mocks/stubs.rb +105 -0
- data/lib/minispec/helpers.rb +1 -0
- data/lib/minispec/helpers/array.rb +56 -0
- data/lib/minispec/helpers/booleans.rb +108 -0
- data/lib/minispec/helpers/generic.rb +24 -0
- data/lib/minispec/helpers/mocks/expectations.rb +29 -0
- data/lib/minispec/helpers/mocks/spies.rb +36 -0
- data/lib/minispec/helpers/raise.rb +44 -0
- data/lib/minispec/helpers/throw.rb +29 -0
- data/lib/minispec/mocks.rb +11 -0
- data/lib/minispec/mocks/expectations.rb +77 -0
- data/lib/minispec/mocks/stubs.rb +178 -0
- data/lib/minispec/mocks/validations.rb +80 -0
- data/lib/minispec/mocks/validations/amount.rb +63 -0
- data/lib/minispec/mocks/validations/arguments.rb +161 -0
- data/lib/minispec/mocks/validations/caller.rb +43 -0
- data/lib/minispec/mocks/validations/order.rb +47 -0
- data/lib/minispec/mocks/validations/raise.rb +111 -0
- data/lib/minispec/mocks/validations/return.rb +74 -0
- data/lib/minispec/mocks/validations/throw.rb +91 -0
- data/lib/minispec/mocks/validations/yield.rb +141 -0
- data/lib/minispec/proxy.rb +201 -0
- data/lib/minispec/reporter.rb +185 -0
- data/lib/minispec/utils.rb +139 -0
- data/lib/minispec/utils/differ.rb +325 -0
- data/lib/minispec/utils/pretty_print.rb +51 -0
- data/lib/minispec/utils/raise.rb +123 -0
- data/lib/minispec/utils/throw.rb +140 -0
- data/minispec.gemspec +27 -0
- data/test/mocks/expectations/amount.rb +67 -0
- data/test/mocks/expectations/arguments.rb +126 -0
- data/test/mocks/expectations/caller.rb +55 -0
- data/test/mocks/expectations/generic.rb +35 -0
- data/test/mocks/expectations/order.rb +46 -0
- data/test/mocks/expectations/raise.rb +166 -0
- data/test/mocks/expectations/return.rb +71 -0
- data/test/mocks/expectations/throw.rb +113 -0
- data/test/mocks/expectations/yield.rb +109 -0
- data/test/mocks/spies/amount.rb +68 -0
- data/test/mocks/spies/arguments.rb +57 -0
- data/test/mocks/spies/generic.rb +61 -0
- data/test/mocks/spies/order.rb +38 -0
- data/test/mocks/spies/raise.rb +158 -0
- data/test/mocks/spies/return.rb +71 -0
- data/test/mocks/spies/throw.rb +113 -0
- data/test/mocks/spies/yield.rb +101 -0
- data/test/mocks/test__doubles.rb +98 -0
- data/test/mocks/test__expectations.rb +27 -0
- data/test/mocks/test__mocks.rb +197 -0
- data/test/mocks/test__proxies.rb +61 -0
- data/test/mocks/test__spies.rb +43 -0
- data/test/mocks/test__stubs.rb +427 -0
- data/test/proxified_asserts.rb +34 -0
- data/test/setup.rb +53 -0
- data/test/test__around.rb +58 -0
- data/test/test__assert.rb +510 -0
- data/test/test__before_and_after.rb +117 -0
- data/test/test__before_and_after_all.rb +71 -0
- data/test/test__helpers.rb +197 -0
- data/test/test__raise.rb +104 -0
- data/test/test__skip.rb +41 -0
- data/test/test__throw.rb +103 -0
- metadata +196 -0
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
root = File.expand_path('..', __FILE__)
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.ruby_opts << '-r "%s/test/setup" -I "%s/lib"' % [root, root]
|
8
|
+
t.pattern = 'test/**/test__*.rb'
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
task default: :test
|
data/bin/minispec
ADDED
data/lib/minispec.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'pp'
|
3
|
+
require 'coderay'
|
4
|
+
require 'diff/lcs'
|
5
|
+
require 'diff/lcs/hunk'
|
6
|
+
|
7
|
+
# private module.
|
8
|
+
# for internal use only.
|
9
|
+
module MiniSpec
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# files loading pattern. relative to `Dir.pwd`
|
13
|
+
DEFAULT_PATTERN = "{spec,test}/**/{*_spec.rb,*_test.rb,test_*.rb}".freeze
|
14
|
+
|
15
|
+
SPEC_WRAPPERS = %w[
|
16
|
+
describe
|
17
|
+
context
|
18
|
+
section
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
TEST_WRAPPERS = %w[
|
22
|
+
test
|
23
|
+
testing
|
24
|
+
example
|
25
|
+
should
|
26
|
+
it
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
IMPORTABLES = %w[
|
30
|
+
tests
|
31
|
+
helpers
|
32
|
+
before
|
33
|
+
after
|
34
|
+
around
|
35
|
+
vars
|
36
|
+
continue_on_failures
|
37
|
+
].map(&:to_sym).freeze
|
38
|
+
|
39
|
+
AFFIRMATIONS = %w[
|
40
|
+
is is?
|
41
|
+
are are?
|
42
|
+
was was?
|
43
|
+
does does?
|
44
|
+
did did?
|
45
|
+
have have?
|
46
|
+
has has?
|
47
|
+
assert
|
48
|
+
affirm
|
49
|
+
assume
|
50
|
+
assure
|
51
|
+
expect
|
52
|
+
verify
|
53
|
+
check
|
54
|
+
prove
|
55
|
+
would
|
56
|
+
will
|
57
|
+
].freeze
|
58
|
+
|
59
|
+
NEGATIONS = %w[
|
60
|
+
refute
|
61
|
+
negate
|
62
|
+
fail_if
|
63
|
+
not_expected
|
64
|
+
assert_not
|
65
|
+
].freeze
|
66
|
+
|
67
|
+
|
68
|
+
def source_location_cache file
|
69
|
+
return unless File.file?(file) && File.readable?(file)
|
70
|
+
(@source_location_cache ||= {})[file] ||= File.readlines(file)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
MiniSpec::SPEC_WRAPPERS.each do |meth|
|
75
|
+
# top-level methods that allows to define specs using Minispec's DSL
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
#
|
79
|
+
# describe SomeSpec do
|
80
|
+
# # some tests
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# describe SomeAnotherSpec do
|
84
|
+
# # some another tests
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
define_method meth do |subject, &proc|
|
88
|
+
spec_name = subject.to_s.freeze
|
89
|
+
spec = Class.new do
|
90
|
+
include Minispec
|
91
|
+
define_method(:subject) { subject }
|
92
|
+
# set spec name before executing the proc
|
93
|
+
# otherwise wrong spec name will be reported
|
94
|
+
define_singleton_method(:spec_name) { spec_name }
|
95
|
+
define_singleton_method(:spec_fullname) { spec_name }
|
96
|
+
define_singleton_method(:spec_proc) { proc }
|
97
|
+
define_singleton_method(:indent) { 0 }
|
98
|
+
end
|
99
|
+
spec.class_exec(&proc)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
require 'minispec/utils'
|
104
|
+
require 'minispec/mocks'
|
105
|
+
require 'minispec/proxy'
|
106
|
+
require 'minispec/reporter'
|
107
|
+
require 'minispec/api'
|
108
|
+
|
109
|
+
# public module.
|
110
|
+
# to be used for inclusions by end users.
|
111
|
+
module Minispec
|
112
|
+
# extending Minispec module with MiniSpec::ClassAPI
|
113
|
+
# to be able to define global shared resources
|
114
|
+
#
|
115
|
+
# @example
|
116
|
+
# module Minispec
|
117
|
+
# around do
|
118
|
+
# # all specs includes Minispec module
|
119
|
+
# # so all tests will run inside this block
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# def some_utility_method
|
123
|
+
# # all specs will have this method
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# # etc
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
extend MiniSpec::ClassAPI
|
130
|
+
|
131
|
+
class << self
|
132
|
+
attr_accessor :specs, :tests, :assertions
|
133
|
+
|
134
|
+
def included base
|
135
|
+
base.extend(MiniSpec::ClassAPI)
|
136
|
+
base.send(:include, MiniSpec::InstanceAPI)
|
137
|
+
|
138
|
+
# inserting global shared resources defined inside Minispec module
|
139
|
+
MiniSpec::IMPORTABLES.each do |importable|
|
140
|
+
base.send('import_%s' % importable, self)
|
141
|
+
end
|
142
|
+
|
143
|
+
specs.push(base) unless specs.include?(base)
|
144
|
+
end
|
145
|
+
|
146
|
+
def run opts = {}
|
147
|
+
files = opts[:files] || opts[:file]
|
148
|
+
files ||= File.basename($0) == 'minispec' && $*.any? && $*
|
149
|
+
files ||= Dir[File.join(Dir.pwd, opts[:pattern] || MiniSpec::DEFAULT_PATTERN)]
|
150
|
+
files = [files] unless files.is_a?(Array)
|
151
|
+
|
152
|
+
$:.include?(Dir.pwd) || $:.unshift(Dir.pwd)
|
153
|
+
lib = File.join(Dir.pwd, 'lib')
|
154
|
+
!$:.include?(lib) && File.directory?(lib) && $:.unshift(lib)
|
155
|
+
|
156
|
+
pwd = /\A#{Regexp.escape(Dir.pwd)}\//.freeze
|
157
|
+
files.each do |f|
|
158
|
+
path = File.expand_path(File.dirname(f), Dir.pwd).sub(pwd, '')
|
159
|
+
path = File.join(Dir.pwd, path.split('/').first)
|
160
|
+
$:.include?(path) || $:.unshift(path)
|
161
|
+
require(f)
|
162
|
+
end
|
163
|
+
reporter = opts[:reporter] || MiniSpec::Reporter.new
|
164
|
+
specs.each {|s| s.run(reporter)}
|
165
|
+
reporter.summary
|
166
|
+
exit(1) if reporter.failures?
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
Minispec.specs = []
|
172
|
+
Minispec.tests = 0
|
173
|
+
Minispec.assertions = 0
|
174
|
+
|
175
|
+
require 'minispec/helpers'
|
data/lib/minispec/api.rb
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
module MiniSpec
|
2
|
+
module ClassAPI
|
3
|
+
|
4
|
+
# @example
|
5
|
+
# module CPUTests
|
6
|
+
# include Minispec
|
7
|
+
#
|
8
|
+
# # CPU related tests
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# module RAMTests
|
12
|
+
# include Minispec
|
13
|
+
#
|
14
|
+
# # RAM related tests
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# describe :MacBook do
|
18
|
+
# include CPUTests
|
19
|
+
# include RAMTests
|
20
|
+
#
|
21
|
+
# # will run CPU and RAM tests + any tests defined here
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
def included base
|
25
|
+
base.send(:include, Minispec)
|
26
|
+
MiniSpec::IMPORTABLES.each do |importable|
|
27
|
+
base.send('import_%s' % importable, self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @example
|
32
|
+
# module CPUTests
|
33
|
+
# include Minispec
|
34
|
+
#
|
35
|
+
# # CPU related tests
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# module RAMTests
|
39
|
+
# include Minispec
|
40
|
+
#
|
41
|
+
# # RAM related tests
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# describe :MacBook do
|
45
|
+
# include CPUTests
|
46
|
+
# include RAMTests
|
47
|
+
#
|
48
|
+
# # we do not need :around hook nor included variables
|
49
|
+
# reset :around, :vars
|
50
|
+
#
|
51
|
+
# # will run CPU and RAM tests + any tests defined here
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
def reset *importables
|
55
|
+
importables.each do |importable|
|
56
|
+
MiniSpec::IMPORTABLES.include?(inheritable.to_sym) || raise(ArgumentError,
|
57
|
+
'Do not know how to reset %s. Use one of %s' % [inheritable.inspect, MiniSpec::IMPORTABLES*', '])
|
58
|
+
self.send('reset_%s' % inheritable)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# by default MiniSpec will stop evaluating a test on first failed assertion.
|
63
|
+
# `continue_on_failures true` will make MiniSpec continue evaluating regardless failures.
|
64
|
+
#
|
65
|
+
# @example set globally
|
66
|
+
#
|
67
|
+
# MiniSpec.setup do
|
68
|
+
# continue_on_failures true
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# @example set per spec
|
72
|
+
#
|
73
|
+
# describe SomeTest do
|
74
|
+
# continue_on_failures true
|
75
|
+
#
|
76
|
+
# # ...
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
def continue_on_failures status
|
80
|
+
@continue_on_failures = status
|
81
|
+
end
|
82
|
+
def continue_on_failures?
|
83
|
+
@continue_on_failures
|
84
|
+
end
|
85
|
+
|
86
|
+
def import_continue_on_failures base
|
87
|
+
import_instance_variable(:continue_on_failures, base)
|
88
|
+
end
|
89
|
+
alias import_continue_on_failures_from import_continue_on_failures
|
90
|
+
|
91
|
+
def reset_continue_on_failures
|
92
|
+
remove_instance_variable(:@continue_on_failures)
|
93
|
+
end
|
94
|
+
|
95
|
+
def hooks_filter callbacks, filter
|
96
|
+
return callbacks unless filter
|
97
|
+
callbacks.map do |(matchers,proc)|
|
98
|
+
MiniSpec::Utils.any_match?(filter, matchers) ? [filter, matchers, proc] : nil
|
99
|
+
end.compact
|
100
|
+
end
|
101
|
+
|
102
|
+
def import_instance_variable var, base
|
103
|
+
return unless base.instance_variable_defined?('@%s' % var)
|
104
|
+
val = base.instance_variable_get('@%s' % var)
|
105
|
+
val.is_a?(Proc) ? send(var, &val) : send(var, val)
|
106
|
+
end
|
107
|
+
|
108
|
+
MiniSpec::SPEC_WRAPPERS.each do |meth|
|
109
|
+
# used to define nested specs
|
110
|
+
#
|
111
|
+
# inner specs will not share any of its stuff with parent spec
|
112
|
+
# nor will affect parent's state in any way,
|
113
|
+
# i.e. wont override any variables, setups nor tests etc.
|
114
|
+
# that's it, a inner spec is a isolated closure.
|
115
|
+
#
|
116
|
+
# @note if these methods used inside a class that included Minispec,
|
117
|
+
# the created spec will use parent spec as superclass.
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# describe :Math do
|
121
|
+
#
|
122
|
+
# # Math tests
|
123
|
+
#
|
124
|
+
# describe :PI do
|
125
|
+
# # PI tests
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
define_method meth do |subject, opts = {}, &proc|
|
130
|
+
spec_name = subject.to_s.freeze
|
131
|
+
spec_fullname = [self.spec_fullname, spec_name].join(' / ').freeze
|
132
|
+
indent = self.indent + 2
|
133
|
+
args = self.is_a?(Class) && self.include?(Minispec) ? [self] : []
|
134
|
+
spec = Class.new *args do
|
135
|
+
include Minispec
|
136
|
+
define_method(:subject) { subject }
|
137
|
+
# set spec name before executing the proc
|
138
|
+
# otherwise wrong spec name will be reported in failures
|
139
|
+
define_singleton_method(:spec_name) { spec_name }
|
140
|
+
define_singleton_method(:spec_fullname) { spec_fullname }
|
141
|
+
define_singleton_method(:spec_proc) { proc }
|
142
|
+
define_singleton_method(:indent) { indent }
|
143
|
+
end
|
144
|
+
MiniSpec::IMPORTABLES.reject {|i| i == :tests}.each do |importable|
|
145
|
+
spec.send('import_%s' % importable, self)
|
146
|
+
end
|
147
|
+
spec.class_exec(&proc)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def spec_name; self.name end
|
152
|
+
alias :spec_fullname :spec_name
|
153
|
+
def spec_proc; nil end
|
154
|
+
def indent; 0 end
|
155
|
+
|
156
|
+
def run reporter
|
157
|
+
reporter.puts(spec_name, indent: indent)
|
158
|
+
instance = self.allocate
|
159
|
+
runner = proc do
|
160
|
+
instance.__ms__boot
|
161
|
+
tests.each_pair do |label,(verb,proc)|
|
162
|
+
reporter.print('%s %s ' % [verb, label], indent: indent + 2)
|
163
|
+
|
164
|
+
failures = instance.__ms__run_test(label)
|
165
|
+
|
166
|
+
if skipped = instance.__ms__skipped?
|
167
|
+
reporter.mark_as_skipped(spec_name, label, skipped)
|
168
|
+
next
|
169
|
+
end
|
170
|
+
|
171
|
+
if failures.empty?
|
172
|
+
reporter.mark_as_passed(spec_name, label)
|
173
|
+
next
|
174
|
+
end
|
175
|
+
|
176
|
+
reporter.mark_as_failed(spec_fullname, label, verb, proc, failures)
|
177
|
+
end
|
178
|
+
instance.__ms__halt
|
179
|
+
end
|
180
|
+
if around_all = around_all?
|
181
|
+
instance.instance_exec(runner, &around_all)
|
182
|
+
else
|
183
|
+
runner.call
|
184
|
+
end
|
185
|
+
reporter
|
186
|
+
rescue Exception => e
|
187
|
+
# catch exceptions raised inside :before_all/:after_all/:around_all hooks.
|
188
|
+
# exceptions raised inside tests are caught by instance#__ms__run_test
|
189
|
+
reporter.failed_specs << [spec_name, spec_proc, e]
|
190
|
+
reporter
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
Dir[File.expand_path('../class/**/*.rb', __FILE__)].each {|f| require(f)}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module MiniSpec
|
2
|
+
module ClassAPI
|
3
|
+
|
4
|
+
# same as `before` except it will run after matched tests.
|
5
|
+
# @note `after` hooks will run even on failed tests.
|
6
|
+
# however it wont run if some exception arise inside test.
|
7
|
+
def after *matchers, &proc
|
8
|
+
proc || raise(ArgumentError, 'block is missing')
|
9
|
+
matchers.flatten!
|
10
|
+
matchers = [:*] if matchers.empty?
|
11
|
+
return if after?.find {|x| x[0] == matchers && x[1].source_location == proc.source_location}
|
12
|
+
after?.push([matchers, proc])
|
13
|
+
end
|
14
|
+
|
15
|
+
def after? filter = nil
|
16
|
+
hooks_filter(@after ||= [], filter)
|
17
|
+
end
|
18
|
+
|
19
|
+
def reset_after
|
20
|
+
@after = []
|
21
|
+
end
|
22
|
+
|
23
|
+
# import `:after` and `:after_all` hooks from base
|
24
|
+
def import_after base
|
25
|
+
import_instance_variable(:after_all, base)
|
26
|
+
base.after?.each {|(m,p)| self.after(m, &p)}
|
27
|
+
end
|
28
|
+
alias import_after_from import_after
|
29
|
+
|
30
|
+
# code to run once after all tests finished.
|
31
|
+
# this callback will run only once.
|
32
|
+
# for callbacks that runs after any test @see #after
|
33
|
+
#
|
34
|
+
# @note this callback will run even if there are failed tests.
|
35
|
+
def after_all &proc
|
36
|
+
proc || raise(ArgumentError, 'block is missing')
|
37
|
+
@after_all = proc
|
38
|
+
end
|
39
|
+
alias after! after_all
|
40
|
+
|
41
|
+
def after_all?
|
42
|
+
@after_all
|
43
|
+
end
|
44
|
+
|
45
|
+
def reset_after_all
|
46
|
+
remove_instance_variable(:@after_all)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MiniSpec
|
2
|
+
module ClassAPI
|
3
|
+
|
4
|
+
# a block to wrap each test evaluation
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# describe SomeClass do
|
8
|
+
#
|
9
|
+
# around do |test|
|
10
|
+
# DB.connect
|
11
|
+
# test.run
|
12
|
+
# DB.disconnect
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
def around *matchers, &proc
|
17
|
+
proc || raise(ArgumentError, 'block is missing')
|
18
|
+
matchers.flatten!
|
19
|
+
matchers = [:*] if matchers.empty?
|
20
|
+
return if around?.find {|x| x[0] == matchers && x[1].source_location == proc.source_location}
|
21
|
+
around?.push([matchers, proc])
|
22
|
+
end
|
23
|
+
|
24
|
+
def around? filter = nil
|
25
|
+
hooks_filter(@around ||= [], filter)
|
26
|
+
end
|
27
|
+
|
28
|
+
def reset_around
|
29
|
+
@around = []
|
30
|
+
end
|
31
|
+
|
32
|
+
# import `:around` and `:around_all` from base
|
33
|
+
def import_around base
|
34
|
+
import_instance_variable(:around_all, base)
|
35
|
+
base.around?.each {|(m,p)| self.around(m, &p)}
|
36
|
+
end
|
37
|
+
alias import_around_from import_around
|
38
|
+
|
39
|
+
# a block to wrap all tests evaluation
|
40
|
+
def around_all &proc
|
41
|
+
proc || raise(ArgumentError, 'block is missing')
|
42
|
+
@around_all = proc
|
43
|
+
end
|
44
|
+
alias around! around_all
|
45
|
+
|
46
|
+
def around_all?
|
47
|
+
@around_all
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset_around_all
|
51
|
+
remove_instance_variable(:@around_all)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|