rr 1.2.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Gem Version](https://badge.fury.io/rb/rr.
|
1
|
+
# RR [![Gem Version](https://badge.fury.io/rb/rr.svg)](https://badge.fury.io/rb/rr) [![Build Status](https://travis-ci.org/rr/rr.svg?branch=master)](https://travis-ci.org/rr/rr) [![Code Climate GPA](https://codeclimate.com/github/rr/rr.svg)](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
|