rr 1.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +25 -0
  3. data/Gemfile +1 -8
  4. data/README.md +8 -13
  5. data/Rakefile +16 -6
  6. data/lib/rr/class_instance_method_defined.rb +1 -1
  7. data/lib/rr/double.rb +28 -10
  8. data/lib/rr/double_definitions/double_definition.rb +39 -16
  9. data/lib/rr/double_definitions/double_definition_create.rb +5 -5
  10. data/lib/rr/double_definitions/double_definition_create_blank_slate.rb +10 -4
  11. data/lib/rr/double_definitions/strategies/strategy.rb +27 -8
  12. data/lib/rr/double_definitions/strategies/verification/mock.rb +8 -2
  13. data/lib/rr/double_matches.rb +4 -3
  14. data/lib/rr/expectations/any_argument_expectation.rb +4 -4
  15. data/lib/rr/expectations/argument_equality_expectation.rb +43 -5
  16. data/lib/rr/injections/double_injection.rb +65 -18
  17. data/lib/rr/injections/method_missing_injection.rb +36 -9
  18. data/lib/rr/keyword_arguments.rb +15 -0
  19. data/lib/rr/method_dispatches/base_method_dispatch.rb +22 -5
  20. data/lib/rr/method_dispatches/method_dispatch.rb +21 -10
  21. data/lib/rr/method_dispatches/method_missing_dispatch.rb +14 -5
  22. data/lib/rr/recorded_call.rb +9 -3
  23. data/lib/rr/recorded_calls.rb +17 -7
  24. data/lib/rr/space.rb +15 -5
  25. data/lib/rr/version.rb +1 -1
  26. data/lib/rr/without_autohook.rb +2 -1
  27. data/rr.gemspec +5 -0
  28. data/spec/suites.yml +1 -15
  29. data/spec/suites/rspec_2/unit/double_definitions/double_definition_create_spec.rb +18 -18
  30. data/spec/suites/rspec_2/unit/expectations/any_argument_expectation_spec.rb +9 -9
  31. data/spec/suites/rspec_2/unit/expectations/argument_equality_expectation_spec.rb +21 -21
  32. data/spec/suites/rspec_2/unit/expectations/boolean_argument_equality_expectation_spec.rb +4 -4
  33. data/spec/suites/rspec_2/unit/expectations/hash_including_argument_equality_expectation_spec.rb +31 -21
  34. data/spec/suites/rspec_2/unit/space_spec.rb +4 -3
  35. metadata +61 -10
  36. data/lib/rr/proc_from_block.rb +0 -11
  37. data/spec/suites/rspec_2/unit/proc_from_block_spec.rb +0 -14
  38. data/spec/suites/rspec_2_rails_4/integration/astc_rails_4_spec.rb +0 -142
  39. data/spec/suites/rspec_2_rails_4/integration/minitest_4_rails_4_spec.rb +0 -149
  40. data/spec/suites/rspec_2_rails_4/spec_helper.rb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 35d55fd0d14916ec412865fa0093c5c3ecf6af07
4
- data.tar.gz: e5dd7d9dbddb7c2dfe272de8a0fb9e3c18ffbf9b
2
+ SHA256:
3
+ metadata.gz: a67997dc1e6efa65e6b99101306915242163d3d6b65f73cec7a1ba2e3dbb3229
4
+ data.tar.gz: 34ed2995cdf97291cb5f1334737d8fc93dbd9078a420197635a307414d61255c
5
5
  SHA512:
6
- metadata.gz: 3013497ba6d79be17044b1da4efa0806f8c608840d46603fc05ec255aebdc701946cd097d9032a017f88ff2e672c5a065d0a4a4a14431bb5d0b0c6c431a3c9d3
7
- data.tar.gz: 066dc64081fc2b385185e25bd4f56612b90f14c9788ab8ca78fb17b5593542fb601b33108703ce637770d28c2a90a4dd00edac809447b59f09755e7bbe73588f
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
- gem 'rake', '~> 10.0'
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.png)](http://badge.fury.io/rb/rr) [![Build Status](https://travis-ci.org/rr/rr.png?branch=master)](https://travis-ci.org/rr/rr) [![Code Climate GPA](https://codeclimate.com/github/rr/rr.png)](https://codeclimate.com/github/rr/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.1
151
- * 2.2
152
- * 2.3
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](http://github.com/rr/rr/issues) and I'll respond as soon as I can.
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 Ruby 2.0.0-p195 installed (this is the primary Ruby
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
- rescue LoadError
24
+ default_tasks << 'appraisal:install'
22
25
  end
23
26
 
24
- # spec
25
- require File.expand_path('../spec/defines_spec_suite_tasks', __FILE__)
26
- DefinesSpecSuiteTasks.call
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 => ['appraisal:install', :spec, :test]
43
+ task :default => default_tasks
@@ -6,4 +6,4 @@ module RR
6
6
  klass.private_instance_methods(include_super).detect {|method_name| method_name.to_sym == instance_method.to_sym}
7
7
  end
8
8
  end
9
- end
9
+ end
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
- formatted_errors = args.collect {|arg| arg.inspect}.join(', ')
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
- "- #{formatted_name(double.method_name, double.expected_arguments)}"
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?(*arguments)
36
- definition.exact_match?(*arguments)
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?(*arguments)
42
- definition.wildcard_match?(*arguments)
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, expected_arguments)
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
- # Double#with sets the expectation that the Double will receive
40
- # the passed in arguments.
41
- #
42
- # Passing in a block sets the return value.
43
- #
44
- # mock(subject).method_name.with(1, 2) {:return_value}
45
- def with(*args, &return_value_block)
46
- @argument_expectation = Expectations::ArgumentEqualityExpectation.new(*args)
47
- install_method_callback return_value_block
48
- self
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 = Expectations::ArgumentEqualityExpectation.new()
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?(*arguments)
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?(*arguments)
316
+ @argument_expectation.exact_match?(arguments, keyword_arguments)
306
317
  end
307
318
 
308
- def wildcard_match?(*arguments)
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?(*arguments)
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
- argument_expectation ? argument_expectation.expected_arguments : []
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, *args, &handler)
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
- def method_missing(method_name, *args, &block)
18
- @double_definition_create.call(method_name, *args, &block)
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, :definition, :method_name, :args, :handler
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, @method_name, @args, @handler = definition, method_name, args, handler
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
- def permissive_argument
27
- if args.empty?
28
- definition.with_any_args
29
- else
30
- definition.with(*args)
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
- def do_call
36
- definition.with(*args).once
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