rr 1.2.1 → 3.0.0
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.
- checksums.yaml +5 -5
- data/CHANGES.md +25 -0
- data/Gemfile +1 -8
- data/README.md +8 -13
- data/Rakefile +16 -6
- data/lib/rr/class_instance_method_defined.rb +1 -1
- data/lib/rr/double.rb +28 -10
- data/lib/rr/double_definitions/double_definition.rb +39 -16
- data/lib/rr/double_definitions/double_definition_create.rb +5 -5
- data/lib/rr/double_definitions/double_definition_create_blank_slate.rb +10 -4
- data/lib/rr/double_definitions/strategies/strategy.rb +27 -8
- data/lib/rr/double_definitions/strategies/verification/mock.rb +8 -2
- data/lib/rr/double_matches.rb +4 -3
- data/lib/rr/expectations/any_argument_expectation.rb +4 -4
- data/lib/rr/expectations/argument_equality_expectation.rb +43 -5
- data/lib/rr/injections/double_injection.rb +65 -18
- data/lib/rr/injections/method_missing_injection.rb +36 -9
- data/lib/rr/keyword_arguments.rb +15 -0
- data/lib/rr/method_dispatches/base_method_dispatch.rb +22 -5
- data/lib/rr/method_dispatches/method_dispatch.rb +21 -10
- data/lib/rr/method_dispatches/method_missing_dispatch.rb +14 -5
- data/lib/rr/recorded_call.rb +9 -3
- data/lib/rr/recorded_calls.rb +17 -7
- data/lib/rr/space.rb +15 -5
- data/lib/rr/version.rb +1 -1
- data/lib/rr/without_autohook.rb +2 -1
- data/rr.gemspec +5 -0
- data/spec/suites.yml +1 -15
- data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_spec.rb +18 -18
- data/spec/suites/rspec_2/unit/expectations/any_argument_expectation_spec.rb +9 -9
- data/spec/suites/rspec_2/unit/expectations/argument_equality_expectation_spec.rb +21 -21
- data/spec/suites/rspec_2/unit/expectations/boolean_argument_equality_expectation_spec.rb +4 -4
- data/spec/suites/rspec_2/unit/expectations/hash_including_argument_equality_expectation_spec.rb +31 -21
- data/spec/suites/rspec_2/unit/space_spec.rb +4 -3
- metadata +61 -10
- data/lib/rr/proc_from_block.rb +0 -11
- data/spec/suites/rspec_2/unit/proc_from_block_spec.rb +0 -14
- data/spec/suites/rspec_2_rails_4/integration/astc_rails_4_spec.rb +0 -142
- data/spec/suites/rspec_2_rails_4/integration/minitest_4_rails_4_spec.rb +0 -149
- data/spec/suites/rspec_2_rails_4/spec_helper.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a67997dc1e6efa65e6b99101306915242163d3d6b65f73cec7a1ba2e3dbb3229
|
4
|
+
data.tar.gz: 34ed2995cdf97291cb5f1334737d8fc93dbd9078a420197635a307414d61255c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bb271fe1108d5b1fc1b35c8c14d1d38bcf2254e9863a7cc48d8e20ca67aabc3ee6d02e8cb9bcd30875c285a3b5c14e3386faa31b7907f04be501678025a5278
|
7
|
+
data.tar.gz: 85641d68043365de3f062ef34164492ba69c5be725b14a12eef75f06895df73a05dbea3d53d196e6f3402d1f4ce108bcc2bdc2b8c65e2bfb015d2f7d7f6bff7c
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.0.0 - 2021-03-31
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* Added support for Ruby 3.0's keyword arguments.
|
8
|
+
[GitHub#17][Reported by Takuro Ashie]
|
9
|
+
|
10
|
+
### Fixes
|
11
|
+
|
12
|
+
* Fixed a bug that `any_instance_of` doesn't work with class
|
13
|
+
hierarchies. [GitHub#12][Reported by Étienne Barrié]
|
14
|
+
|
15
|
+
### Thanks
|
16
|
+
|
17
|
+
* Étienne Barrié
|
18
|
+
|
19
|
+
* Takuro Ashie
|
20
|
+
|
21
|
+
## 1.2.1 - 2017-06-22
|
22
|
+
|
23
|
+
### Fixes
|
24
|
+
|
25
|
+
* Fixed a bug that `RR.reset` resets newly created methods.
|
26
|
+
[GitHub#8]
|
27
|
+
|
3
28
|
## 1.2.0 - 2016-05-30
|
4
29
|
|
5
30
|
### Improvements
|
data/Gemfile
CHANGED
@@ -1,10 +1,3 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
gem 'simplecov', '~> 0.7'
|
5
|
-
gem 'appraisal', '~> 0.5'
|
6
|
-
gem 'posix-spawn', :platforms => :mri
|
7
|
-
gem 'open4', :platforms => :mri
|
8
|
-
gem 'test-unit'
|
9
|
-
gem 'test-unit-rr'
|
10
|
-
gem 'rspec', '~> 2.14'
|
3
|
+
gemspec
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# RR [](https://badge.fury.io/rb/rr) [](https://travis-ci.org/rr/rr) [](https://codeclimate.com/github/rr/rr)
|
2
2
|
|
3
3
|
RR is a test double framework for Ruby that features a rich selection of double
|
4
4
|
techniques and a terse syntax.
|
@@ -147,35 +147,30 @@ require 'rr'
|
|
147
147
|
|
148
148
|
RR is designed and tested to work against the following Ruby versions:
|
149
149
|
|
150
|
-
* 2.
|
151
|
-
* 2.
|
152
|
-
* 2.
|
150
|
+
* 2.4
|
151
|
+
* 2.5
|
152
|
+
* 2.6
|
153
|
+
* 2.7
|
153
154
|
* JRuby 1.7.4
|
154
155
|
|
155
156
|
as well as the following test frameworks:
|
156
157
|
|
157
|
-
* RSpec 2
|
158
158
|
* Test::Unit via [test-unit-rr](https://test-unit.github.io/#test-unit-rr)
|
159
|
+
* RSpec 2
|
159
160
|
* MiniTest 4
|
160
161
|
* Minitest 5
|
161
162
|
|
162
|
-
and the following Rails versions:
|
163
|
-
|
164
|
-
* Rails 4
|
165
|
-
|
166
|
-
|
167
163
|
## Help!
|
168
164
|
|
169
165
|
If you have a question or are having trouble, simply [post it as an
|
170
|
-
issue](
|
166
|
+
issue](https://github.com/rr/rr/issues) and I'll respond as soon as I can.
|
171
167
|
|
172
168
|
|
173
169
|
## Contributing
|
174
170
|
|
175
171
|
Want to contribute a bug fix or new feature to RR? Great! Follow these steps:
|
176
172
|
|
177
|
-
1. Make sure you have
|
178
|
-
version that RR targets).
|
173
|
+
1. Make sure you have a recent Ruby (check the compatibility table above).
|
179
174
|
2. Clone the repo (you probably knew that already).
|
180
175
|
3. Make a new branch off of `master` with a descriptive name.
|
181
176
|
4. Work on your patch.
|
data/Rakefile
CHANGED
@@ -7,10 +7,13 @@ require 'pp'
|
|
7
7
|
# build, install, release
|
8
8
|
require 'bundler/gem_tasks'
|
9
9
|
|
10
|
+
default_tasks = []
|
11
|
+
|
10
12
|
begin
|
11
13
|
# appraisal
|
12
14
|
require 'appraisal'
|
13
|
-
|
15
|
+
rescue LoadError
|
16
|
+
else
|
14
17
|
# appraisals
|
15
18
|
Appraisal::File.each do |appraisal|
|
16
19
|
desc "Resolve and install dependencies for the #{appraisal.name} appraisal"
|
@@ -18,16 +21,23 @@ begin
|
|
18
21
|
appraisal.install
|
19
22
|
end
|
20
23
|
end
|
21
|
-
|
24
|
+
default_tasks << 'appraisal:install'
|
22
25
|
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
+
begin
|
28
|
+
# spec
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
rescue LoadError
|
31
|
+
else
|
32
|
+
require File.expand_path('../spec/defines_spec_suite_tasks', __FILE__)
|
33
|
+
DefinesSpecSuiteTasks.call
|
34
|
+
default_tasks << :spec
|
35
|
+
end
|
27
36
|
|
28
37
|
desc "Run tests"
|
29
38
|
task :test do
|
30
39
|
ruby("test/run-test.rb")
|
31
40
|
end
|
41
|
+
default_tasks << :test
|
32
42
|
|
33
|
-
task :default =>
|
43
|
+
task :default => default_tasks
|
data/lib/rr/double.rb
CHANGED
@@ -4,14 +4,20 @@ module RR
|
|
4
4
|
# and the implementation.
|
5
5
|
class Double
|
6
6
|
extend(Module.new do
|
7
|
-
def formatted_name(method_name, args)
|
8
|
-
|
7
|
+
def formatted_name(method_name, args, kwargs)
|
8
|
+
formatted_arguments =
|
9
|
+
args.collect {|arg| arg.inspect} +
|
10
|
+
kwargs.collect {|keyword, value| "#{keyword}: #{value.inspect}"}
|
11
|
+
formatted_errors = formatted_arguments.join(', ')
|
9
12
|
"#{method_name}(#{formatted_errors})"
|
10
13
|
end
|
11
14
|
|
12
15
|
def list_message_part(doubles)
|
13
16
|
doubles.collect do |double|
|
14
|
-
|
17
|
+
name = formatted_name(double.method_name,
|
18
|
+
double.expected_arguments,
|
19
|
+
double.expected_keyword_arguments)
|
20
|
+
"- #{name}"
|
15
21
|
end.join("\n")
|
16
22
|
end
|
17
23
|
end)
|
@@ -32,14 +38,14 @@ module RR
|
|
32
38
|
|
33
39
|
# Double#exact_match? returns true when the passed in arguments
|
34
40
|
# exactly match the ArgumentEqualityExpectation arguments.
|
35
|
-
def exact_match?(
|
36
|
-
definition.exact_match?(
|
41
|
+
def exact_match?(arguments, keyword_arguments)
|
42
|
+
definition.exact_match?(arguments, keyword_arguments)
|
37
43
|
end
|
38
44
|
|
39
45
|
# Double#wildcard_match? returns true when the passed in arguments
|
40
46
|
# wildcard match the ArgumentEqualityExpectation arguments.
|
41
|
-
def wildcard_match?(
|
42
|
-
definition.wildcard_match?(
|
47
|
+
def wildcard_match?(arguments, keyword_arguments)
|
48
|
+
definition.wildcard_match?(arguments, keyword_arguments)
|
43
49
|
end
|
44
50
|
|
45
51
|
# Double#attempt? returns true when the
|
@@ -74,18 +80,26 @@ module RR
|
|
74
80
|
argument_expectation.expected_arguments
|
75
81
|
end
|
76
82
|
|
83
|
+
# The keyword arguments that this Double expects
|
84
|
+
def expected_keyword_arguments
|
85
|
+
verify_argument_expectation_is_set
|
86
|
+
argument_expectation.expected_keyword_arguments
|
87
|
+
end
|
88
|
+
|
77
89
|
# The TimesCalledMatcher for the TimesCalledExpectation
|
78
90
|
def times_matcher
|
79
91
|
definition.times_matcher
|
80
92
|
end
|
81
93
|
|
82
94
|
def formatted_name
|
83
|
-
self.class.formatted_name(method_name,
|
95
|
+
self.class.formatted_name(method_name,
|
96
|
+
expected_arguments,
|
97
|
+
expected_keyword_arguments)
|
84
98
|
end
|
85
99
|
|
86
|
-
def method_call(args)
|
100
|
+
def method_call(args, kwargs)
|
87
101
|
if verbose?
|
88
|
-
puts Double.formatted_name(method_name, args)
|
102
|
+
puts Double.formatted_name(method_name, args, kwargs)
|
89
103
|
end
|
90
104
|
times_called_expectation.attempt if definition.times_matcher
|
91
105
|
space.verify_ordered_double(self) if ordered?
|
@@ -148,6 +162,10 @@ module RR
|
|
148
162
|
definition.argument_expectation.expected_arguments
|
149
163
|
end
|
150
164
|
|
165
|
+
def kwargs
|
166
|
+
definition.argument_expectation.expected_keyword_arguments
|
167
|
+
end
|
168
|
+
|
151
169
|
def argument_expectation
|
152
170
|
definition.argument_expectation
|
153
171
|
end
|
@@ -36,16 +36,26 @@ module RR
|
|
36
36
|
end
|
37
37
|
|
38
38
|
module ArgumentDefinitionConstructionMethods
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
39
|
+
if KeywordArguments.fully_supported?
|
40
|
+
# Double#with sets the expectation that the Double will receive
|
41
|
+
# the passed in arguments.
|
42
|
+
#
|
43
|
+
# Passing in a block sets the return value.
|
44
|
+
#
|
45
|
+
# mock(subject).method_name.with(1, 2) {:return_value}
|
46
|
+
def with(*args, **kwargs, &return_value_block)
|
47
|
+
@argument_expectation =
|
48
|
+
Expectations::ArgumentEqualityExpectation.new(args, kwargs)
|
49
|
+
install_method_callback return_value_block
|
50
|
+
self
|
51
|
+
end
|
52
|
+
else
|
53
|
+
def with(*args, &return_value_block)
|
54
|
+
@argument_expectation =
|
55
|
+
Expectations::ArgumentEqualityExpectation.new(args, {})
|
56
|
+
install_method_callback return_value_block
|
57
|
+
self
|
58
|
+
end
|
49
59
|
end
|
50
60
|
|
51
61
|
# Double#with_any_args sets the expectation that the Double can receive
|
@@ -67,7 +77,8 @@ module RR
|
|
67
77
|
#
|
68
78
|
# mock(subject).method_name.with_no_args {:return_value}
|
69
79
|
def with_no_args(&return_value_block)
|
70
|
-
@argument_expectation =
|
80
|
+
@argument_expectation =
|
81
|
+
Expectations::ArgumentEqualityExpectation.new([], {})
|
71
82
|
install_method_callback return_value_block
|
72
83
|
self
|
73
84
|
end
|
@@ -298,18 +309,18 @@ module RR
|
|
298
309
|
@verbose ? true : false
|
299
310
|
end
|
300
311
|
|
301
|
-
def exact_match?(
|
312
|
+
def exact_match?(arguments, keyword_arguments)
|
302
313
|
unless @argument_expectation
|
303
314
|
raise RR::Errors.build_error(:DoubleDefinitionError, "#argument_expectation must be defined on #{inspect}")
|
304
315
|
end
|
305
|
-
@argument_expectation.exact_match?(
|
316
|
+
@argument_expectation.exact_match?(arguments, keyword_arguments)
|
306
317
|
end
|
307
318
|
|
308
|
-
def wildcard_match?(
|
319
|
+
def wildcard_match?(arguments, keyword_arguments)
|
309
320
|
unless @argument_expectation
|
310
321
|
raise RR::Errors.build_error(:DoubleDefinitionError, "#argument_expectation must be defined on #{inspect}")
|
311
322
|
end
|
312
|
-
@argument_expectation.wildcard_match?(
|
323
|
+
@argument_expectation.wildcard_match?(arguments, keyword_arguments)
|
313
324
|
end
|
314
325
|
|
315
326
|
def terminal?
|
@@ -320,7 +331,19 @@ module RR
|
|
320
331
|
end
|
321
332
|
|
322
333
|
def expected_arguments
|
323
|
-
|
334
|
+
if argument_expectation
|
335
|
+
argument_expectation.expected_arguments
|
336
|
+
else
|
337
|
+
[]
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def expected_keyword_arguments
|
342
|
+
if argument_expectation
|
343
|
+
argument_expectation.expected_keyword_arguments
|
344
|
+
else
|
345
|
+
{}
|
346
|
+
end
|
324
347
|
end
|
325
348
|
|
326
349
|
def implementation_is_original_method?
|
@@ -30,11 +30,11 @@ module RR
|
|
30
30
|
@double_injection_strategy = self.class.default_double_injection_strategy.call(self)
|
31
31
|
end
|
32
32
|
|
33
|
-
def call(method_name,
|
33
|
+
def call(method_name, args, kwargs, &handler)
|
34
34
|
definition = DoubleDefinition.new(self)
|
35
|
-
verification_strategy.call(definition, method_name, args, handler)
|
36
|
-
implementation_strategy.call(definition, method_name, args, handler)
|
37
|
-
double_injection_strategy.call(definition, method_name, args, handler)
|
35
|
+
verification_strategy.call(definition, method_name, args, kwargs, handler)
|
36
|
+
implementation_strategy.call(definition, method_name, args, kwargs, handler)
|
37
|
+
double_injection_strategy.call(definition, method_name, args, kwargs, handler)
|
38
38
|
definition
|
39
39
|
end
|
40
40
|
|
@@ -81,7 +81,7 @@ module RR
|
|
81
81
|
self
|
82
82
|
elsif method_name
|
83
83
|
# TODO: Pass in arguments.
|
84
|
-
call(method_name)
|
84
|
+
call(method_name, [], {})
|
85
85
|
else
|
86
86
|
DoubleDefinitionCreateBlankSlate.new(self, &definition_eval_block)
|
87
87
|
end
|
@@ -14,13 +14,19 @@ module RR
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
if KeywordArguments.fully_supported?
|
18
|
+
def method_missing(method_name, *args, **kwargs, &block)
|
19
|
+
@double_definition_create.call(method_name, args, kwargs, &block)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
def method_missing(method_name, *args, &block)
|
23
|
+
@double_definition_create.call(method_name, args, {}, &block)
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
def __double_definition_create__
|
22
28
|
@double_definition_create
|
23
29
|
end
|
24
|
-
end
|
30
|
+
end
|
25
31
|
end
|
26
|
-
end
|
32
|
+
end
|
@@ -2,7 +2,12 @@ module RR
|
|
2
2
|
module DoubleDefinitions
|
3
3
|
module Strategies
|
4
4
|
class Strategy
|
5
|
-
attr_reader :double_definition_create
|
5
|
+
attr_reader :double_definition_create
|
6
|
+
attr_reader :definition
|
7
|
+
attr_reader :method_name
|
8
|
+
attr_reader :args
|
9
|
+
attr_reader :kwargs
|
10
|
+
attr_reader :handler
|
6
11
|
|
7
12
|
include Space::Reader
|
8
13
|
|
@@ -10,8 +15,12 @@ module RR
|
|
10
15
|
@double_definition_create = double_definition_create
|
11
16
|
end
|
12
17
|
|
13
|
-
def call(definition, method_name, args, handler)
|
14
|
-
@definition
|
18
|
+
def call(definition, method_name, args, kwargs, handler)
|
19
|
+
@definition = definition
|
20
|
+
@method_name = method_name
|
21
|
+
@args = args
|
22
|
+
@kwargs = kwargs
|
23
|
+
@handler = handler
|
15
24
|
do_call
|
16
25
|
end
|
17
26
|
|
@@ -23,11 +32,21 @@ module RR
|
|
23
32
|
raise NotImplementedError
|
24
33
|
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
35
|
+
if KeywordArguments.fully_supported?
|
36
|
+
def permissive_argument
|
37
|
+
if args.empty? and kwargs.empty?
|
38
|
+
definition.with_any_args
|
39
|
+
else
|
40
|
+
definition.with(*args, **kwargs)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
def permissive_argument
|
45
|
+
if args.empty?
|
46
|
+
definition.with_any_args
|
47
|
+
else
|
48
|
+
definition.with(*args)
|
49
|
+
end
|
31
50
|
end
|
32
51
|
end
|
33
52
|
|
@@ -32,8 +32,14 @@ module RR
|
|
32
32
|
# end
|
33
33
|
class Mock < VerificationStrategy
|
34
34
|
protected
|
35
|
-
|
36
|
-
|
35
|
+
if KeywordArguments.fully_supported?
|
36
|
+
def do_call
|
37
|
+
definition.with(*args, **kwargs).once
|
38
|
+
end
|
39
|
+
else
|
40
|
+
def do_call
|
41
|
+
definition.with(*args).once
|
42
|
+
end
|
37
43
|
end
|
38
44
|
end
|
39
45
|
end
|