minitest-stub_on_roids 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aaef4c0cb77c912a56a222ad9bd287d5bf9f39f386917bea4a7c2ee0ff343498
4
- data.tar.gz: 3dc69f5af5f646e6a3497ac3a4481f7d32651ae5e35a6db74cb832733724b378
3
+ metadata.gz: 23aadaec28be102d543682e9b3e23a7dbae2ee9572b3d60ad8e8ddb714b949e3
4
+ data.tar.gz: c4fdad4c83ac66b6cb2d4786c6aa97a4ea8a313f9144dd95054e24f935b6bdd2
5
5
  SHA512:
6
- metadata.gz: 743ed77b28fc873a00364634899354aae4cb686a5eee54317130885b27b2ff6899285d978c8dcf6b2e2b0ab72cffa1dd110efa87a58748866fb145a2319e4e5b
7
- data.tar.gz: 11ae76fcc9956d9278f484910527d242f348c548020f44d5ff094bbd1368b82489eea606028c651396392c57a0a96669cb76546cbe80303ad3b4280a6e046ad3
6
+ metadata.gz: ed323c5833b8cbecc2dc2862de817e83e4571961a4c28c8d8a8bce0c92194806052ecb14384f2262fd83fe2e5e5fdb74744a296d979dd192a1d18fc9b9c20e88
7
+ data.tar.gz: d87659d4b7a347c6e2c6bc159c7c6e66957b76643c5edc0d0c3f99c217e054f85635b118f4cdba02e8d31791b1c67e4754282af127c8c6389cd1d8851381e900
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
- gemspec
5
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,17 +1,33 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- minitest-stub_on_roids (0.0.1)
4
+ minitest-stub_on_roids (0.0.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ ast (2.4.0)
10
+ jaro_winkler (1.5.3)
11
+ parallel (1.17.0)
12
+ parser (2.6.4.0)
13
+ ast (~> 2.4.0)
14
+ rainbow (3.0.0)
15
+ rubocop (0.74.0)
16
+ jaro_winkler (~> 1.5.1)
17
+ parallel (~> 1.10)
18
+ parser (>= 2.6)
19
+ rainbow (>= 2.2.2, < 4.0)
20
+ ruby-progressbar (~> 1.7)
21
+ unicode-display_width (>= 1.4.0, < 1.7)
22
+ ruby-progressbar (1.10.1)
23
+ unicode-display_width (1.6.0)
9
24
 
10
25
  PLATFORMS
11
26
  ruby
12
27
 
13
28
  DEPENDENCIES
14
29
  minitest-stub_on_roids!
30
+ rubocop (= 0.74.0)
15
31
 
16
32
  BUNDLED WITH
17
33
  2.0.1
data/README.md CHANGED
@@ -4,11 +4,11 @@ Provides a set of helper methods around Minitest's `Object#stub` method.
4
4
 
5
5
  The following methods are available:
6
6
 
7
- * `#stub_with_args`
7
+ * `.stub_with_args`
8
8
  1. Stubs a class method for the duration of the block.
9
9
  2. *If* the method is called, asserts that it is called with the expected arguments.
10
10
  3. Doesn't mind how many times the method is called, if at all.
11
- * `#stub_and_expect`
11
+ * `.stub_and_expect`
12
12
  1. Stubs a class method for the duration of the block.
13
13
  2. Asserts that the method is called the exact amount of times as expected, and with the expected arguments.
14
14
 
@@ -43,9 +43,9 @@ Banana.extend Minitest::StubOnRoids
43
43
 
44
44
  This will add the following methods to the class:
45
45
 
46
- ### `#stub_with_args`
46
+ ### `.stub_with_args`
47
47
 
48
- Use `#stub_with_args` to stub a class method as you normally would but also assert that if it is called - it is called with the expected arguments:
48
+ Use `.stub_with_args` to stub a class method as you normally would but also assert that if it is called - it is called with the expected arguments:
49
49
 
50
50
  ```ruby
51
51
  Banana.stub_with_args(:new, banana_mock, [3.0, "Yellow"]) do
@@ -63,11 +63,11 @@ end
63
63
 
64
64
  Just like with Minitest's `Object#stub` method, there is no expectation on the amount of times the stubbed method is called in the block.
65
65
 
66
- ### `#stub_and_expect`
66
+ ### `.stub_and_expect`
67
67
 
68
- Use `#stub_and_expect` to stub a class method as you normally would but also set expectations on it, similarly to using `Minitest::Mock#expect`.
68
+ Use `.stub_and_expect` to stub a class method as you normally would but also set expectations on it, similarly to using `Minitest::Mock#expect`.
69
69
 
70
- This means that a `MockExpectationError` will be thrown if inside the block:
70
+ This means that a `MockExpectationError` will be raised if within the block...
71
71
  * The method is called with a different set of arguments than expected.
72
72
  * The method is called more or less the amount of times it was expected to be called.
73
73
 
@@ -88,7 +88,8 @@ end
88
88
  # => MockExpectationError raised
89
89
  ```
90
90
 
91
- Use the `times` keyword argument to expect a method to be called a specific amount of times within the block (default is 1):
91
+ #### Multiple calls
92
+ Use the `times` keyword argument to expect a method to be called multiple times within the block (default is 1):
92
93
 
93
94
  ```ruby
94
95
  Banana.stub_and_expect(:new, banana_mock, [3.0, "Yellow"], times: 2) do
@@ -99,9 +100,54 @@ end
99
100
  # => Works
100
101
  ```
101
102
 
102
- ### Limitations
103
+ #### Multiple calls with different arguments
104
+
105
+ Use the `expectations` keyword argument to expect a method to be called a multiple times within the block with different arguments and return values (order must be respected).
106
+
107
+ Given the following expectations array:
108
+
109
+ ```ruby
110
+ expectations = [
111
+ {
112
+ expected_args: [3.0, "Yellow"],
113
+ return_value: banana_mock
114
+ },
115
+ {
116
+ expected_args: [5.0, "Green"],
117
+ return_value: banana_mock2
118
+ },
119
+ {
120
+ expected_args: [15.0, "Red"],
121
+ return_value: banana_mock3
122
+ }
123
+ ]
124
+ ```
125
+
126
+ Calling `Banana.new` multiple times exactly as expected works:
127
+
128
+ ```ruby
129
+ Banana.stub_and_expect(:new, expectations: expectations) do
130
+ Banana.new(3.0, "Yellow")
131
+ Banana.new(5.0, "Green")
132
+ Banana.new(15.0, "Red")
133
+ end
134
+
135
+ # => Works
136
+ ```
137
+
138
+ Calling `Banana.new` with the wrong arguments fails:
139
+
140
+ ```ruby
141
+ Banana.stub_and_expect(:new, expectations: expectations) do
142
+ Banana.new(3.0, "Yellow")
143
+ Banana.new(15.0, "Red")
144
+ end
145
+
146
+ # => MockExpectationError raised
147
+ ```
148
+
149
+ ### Notes
103
150
 
104
- * Nesting blocks is not supported, meaning you can't expect methods to be called with more than one set of arguments at a time.
105
151
  * This gem might work with instance methods as well, but its intent is (and it's only tested for) using it on class methods.
106
152
 
107
153
  ## Contributing
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/testtask'
2
4
 
3
5
  Rake::TestTask.new do |t|
@@ -5,4 +7,4 @@ Rake::TestTask.new do |t|
5
7
  end
6
8
 
7
9
  desc "Run tests"
8
- task :default => :test
10
+ task default: :test
@@ -1,34 +1,48 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "minitest/autorun"
2
4
 
3
- class StubbedMethodArgsError < StandardError; end
4
- class MethodAlreadyStubbedError < StandardError; end
5
+ class StubbedMethodArgsError < StandardError
6
+ def initialize(method_name, klass, actual_args)
7
+ super "Stubbed method :#{method_name} called on #{klass} with " \
8
+ "unexpected arguments #{actual_args}"
9
+ end
10
+ end
11
+
12
+ class MethodAlreadyStubbedError < StandardError
13
+ def initialize(name)
14
+ super "Method :#{name} already stubbed"
15
+ end
16
+ end
5
17
 
6
18
  module Minitest
7
19
  module StubOnRoids
8
- def stub_with_args(name, val_or_callable, expected_args, &block)
9
- raise MethodAlreadyStubbedError, "Method :#{name} already stubbed" if self.respond_to? "__minitest_stub__#{name}"
20
+ def stub_with_args(method_name, retval, expected_args = [])
21
+ raise_if_already_stubbed(method_name)
10
22
 
11
- asserted_callable = lambda do |*actual_args|
23
+ retval_with_args_assertion = lambda do |*actual_args|
12
24
  expected_args.zip(actual_args).each do |expected_arg, actual_arg|
13
25
  next if expected_arg == actual_arg
14
- raise StubbedMethodArgsError, "stubbed method :#{name} called on #{self} with unexpected arguments #{actual_args}"
26
+
27
+ raise StubbedMethodArgsError.new(method_name, self, actual_args)
15
28
  end
16
-
17
- val_or_callable
29
+
30
+ retval
18
31
  end
19
32
 
20
- stub(name, asserted_callable) do
33
+ stub(method_name, retval_with_args_assertion) do
21
34
  yield
22
35
  end
23
36
  end
24
37
 
25
- def stub_and_expect(name, val_or_callable = nil, expected_args = [], times: 1)
26
- raise MethodAlreadyStubbedError, "Method :#{name} already stubbed" if self.respond_to? "__minitest_stub__#{name}"
27
-
28
- mock = Minitest::Mock.new
29
- times.times { mock.expect :call, val_or_callable, expected_args }
38
+ def stub_and_expect(method_name, retval = nil, expected_args = [],
39
+ times: 1, expectations: [])
40
+ raise_if_bad_args(retval, expected_args, expectations)
41
+ raise_if_already_stubbed(method_name)
30
42
 
31
- stub(name, mock) do
43
+ mock = build_mock(retval, expected_args, times, expectations)
44
+
45
+ stub(method_name, mock) do
32
46
  yield
33
47
  end
34
48
 
@@ -37,5 +51,46 @@ module Minitest
37
51
  # Monkeypatching the error message for better readability
38
52
  raise e.class, e.message.gsub(":call", ":#{name}")
39
53
  end
54
+
55
+ private
56
+
57
+ def build_mock(retval, expected_args, times, expectations)
58
+ mock = Minitest::Mock.new
59
+
60
+ if expectations.size.zero?
61
+ times.times { mock.expect :call, retval, expected_args }
62
+ else
63
+ expectations.each do |expectation|
64
+ validate_expectation(expectation)
65
+ expectation_times = expectation[:times] || 1
66
+
67
+ expectation_times.times do
68
+ mock.expect :call, expectation[:return_value], expectation[:expected_args]
69
+ end
70
+ end
71
+ end
72
+
73
+ mock
74
+ end
75
+
76
+ def raise_if_already_stubbed(method_name)
77
+ return unless respond_to? "__minitest_stub__#{method_name}"
78
+
79
+ raise MethodAlreadyStubbedError, method_name
80
+ end
81
+
82
+ def raise_if_bad_args(retval, expected_args, expectations)
83
+ if (!retval.nil? || expected_args.size.positive?) &&
84
+ expectations.size.positive?
85
+ raise ArgumentError,
86
+ "`retval` and `expected_args` arguments cannot be passed along with `expectations`"
87
+ end
88
+ end
89
+
90
+ def validate_expectation(expectation)
91
+ %i[expected_args return_value].each do |k|
92
+ raise ArgumentError, "Missing key #{k} in expectation definition" if expectation[k].nil?
93
+ end
94
+ end
40
95
  end
41
96
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest-stub_on_roids
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Nizov
@@ -9,7 +9,21 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-08-05 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.74.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.74.0
13
27
  description: A set of helper methods based around Minitest's Object#stub method.
14
28
  email: simon.nizov@gmail.com
15
29
  executables: []