mock_proxy 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mock_proxy.rb +52 -17
- data/lib/mock_proxy/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a4278ce46b890ca708d751a055af4476ebc5b74
|
4
|
+
data.tar.gz: 6df4a43793f809f124cc9b97b769e77697d28c53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d31c8ec5f6fc2a9e081879216422b2389267f6afa401bd3d561e1bc0fefd80459254ef9a93d5b2a8a3e1cf4d1494801dae2617f314f735a08752ac477d0d4c9
|
7
|
+
data.tar.gz: a638bcaafc83134d4788885c41122d4fee841f73af4cba6033dd52e1731557736cd699b4dd2c236354c7af8bee3b662939ffc7c6a62305f835b209d9e5d0190d
|
data/lib/mock_proxy.rb
CHANGED
@@ -15,13 +15,14 @@ require "mock_proxy/version"
|
|
15
15
|
# you did not define all the method calls (it won't automatically return itself for methods not defined in the hash)
|
16
16
|
#
|
17
17
|
# Example use:
|
18
|
-
# let(:model_proxy) { MockProxy.new(generate_email: { validate!: { send: proc { |to| email } } }) }
|
18
|
+
# let(:model_proxy) { MockProxy.new(receive_email: proc {}, generate_email: { validate!: { send: proc { |to| email } } }) }
|
19
19
|
# before { allow(Model).to receive(:new).and_return model_proxy }
|
20
20
|
# # ...
|
21
21
|
# describe 'Model' do
|
22
22
|
# it 'model also receives email' do
|
23
|
-
#
|
24
|
-
#
|
23
|
+
# MockProxy.observe(model_proxy, :receive_email) do |message|
|
24
|
+
# expect(message).to eq 'message'
|
25
|
+
# end
|
25
26
|
# run_system_under_test
|
26
27
|
# end
|
27
28
|
# end
|
@@ -32,7 +33,7 @@ require "mock_proxy/version"
|
|
32
33
|
# Example:
|
33
34
|
# let(:model_proxy) do
|
34
35
|
# callback = proc do |type|
|
35
|
-
# MockProxy.
|
36
|
+
# MockProxy.merge(generator_proxy, decorate: proc { |*args| method_call(type, *args) })
|
36
37
|
# generator_proxy
|
37
38
|
# end
|
38
39
|
# MockProxy.new(generate_email: callback)
|
@@ -55,7 +56,7 @@ class MockProxy
|
|
55
56
|
# dot delimited key path or an array of method names as strings or symbols
|
56
57
|
# @return [Block]
|
57
58
|
def self.get(proxy, key_path)
|
58
|
-
|
59
|
+
get_and_validate_callback(proxy, key_path)
|
59
60
|
end
|
60
61
|
|
61
62
|
# Deep merges the callback tree, replacing existing values with new values.
|
@@ -76,9 +77,11 @@ class MockProxy
|
|
76
77
|
proxy
|
77
78
|
end
|
78
79
|
|
79
|
-
# Replaces the proc at the specified key path
|
80
|
+
# Replaces the proc at the specified key path, but only if there was one there before.
|
81
|
+
# Without creating new paths comes validation, including checking that this replaces an
|
82
|
+
# existing proc, sort of like mkdir (without the -p option)
|
80
83
|
#
|
81
|
-
# Use case:
|
84
|
+
# Use case: Replace existing stub with a new proc without creating new method chains
|
82
85
|
#
|
83
86
|
# @param [MockProxy] proxy existing proxy
|
84
87
|
# @param [String, Symbol, #to_s, Array<String, Symbol, #to_s>] key_path the chain of methods or key path. Can be a
|
@@ -89,6 +92,21 @@ class MockProxy
|
|
89
92
|
proxy
|
90
93
|
end
|
91
94
|
|
95
|
+
# Sets the proc at the specified key path, regardless if there was a proc there before.
|
96
|
+
# No validation comes with automatic path creation, meaning the key path will be defined
|
97
|
+
# it it hasn't already, sort of like mkdir -p
|
98
|
+
#
|
99
|
+
# Use case: Sets a new stub at specified key path while creating new method chains
|
100
|
+
#
|
101
|
+
# @param [MockProxy] proxy existing proxy
|
102
|
+
# @param [String, Symbol, #to_s, Array<String, Symbol, #to_s>] key_path the chain of methods or key path. Can be a
|
103
|
+
# dot delimited key path or an array of method names as strings or symbols
|
104
|
+
# @return [MockProxy] the original proxy object
|
105
|
+
def self.set_at(proxy, key_path, &block)
|
106
|
+
set_callback(proxy, key_path, block, false)
|
107
|
+
proxy
|
108
|
+
end
|
109
|
+
|
92
110
|
# Add an observer to an existing proxy
|
93
111
|
#
|
94
112
|
# Use case: Observe method call without changing the existing callback's stubbed return value
|
@@ -100,7 +118,7 @@ class MockProxy
|
|
100
118
|
# @yieldreturn [optional]
|
101
119
|
# @return [MockProxy] the original proxy object
|
102
120
|
def self.observe(proxy, key_path, &block)
|
103
|
-
callback =
|
121
|
+
callback = get_and_validate_callback(proxy, key_path)
|
104
122
|
# Wrap existing callback, calling the provided block before it
|
105
123
|
# Multiple calls to .observe will create a pyramid of callbacks, calling the observers before
|
106
124
|
# eventually calling the existing callback
|
@@ -123,7 +141,7 @@ class MockProxy
|
|
123
141
|
# @yieldreturn [optional]
|
124
142
|
# @return [MockProxy] the original proxy object
|
125
143
|
def self.wrap(proxy, key_path, &block)
|
126
|
-
callback =
|
144
|
+
callback = get_and_validate_callback(proxy, key_path)
|
127
145
|
# Wrap existing callback, calling the provided block before it
|
128
146
|
# Multiple calls to .observe will create a pyramid of callbacks, calling the observers before
|
129
147
|
# eventually calling the existing callback
|
@@ -143,34 +161,51 @@ class MockProxy
|
|
143
161
|
def self.get_callback(proxy, key_path)
|
144
162
|
key_paths = key_path.is_a?(Array) ? key_path.map(&:to_s) : key_path.split('.')
|
145
163
|
existing_callback_hash = proxy.instance_variable_get('@callback_hash')
|
146
|
-
|
164
|
+
key_paths.reduce(existing_callback_hash) do |callback_hash, key|
|
147
165
|
if callback_hash && callback_hash[key]
|
148
166
|
callback_hash[key]
|
149
167
|
else
|
150
168
|
fail ArgumentError, "The existing callback tree does not contain the full key path you provided. We stopped at #{key} and the callback tree looks like this: #{existing_callback_hash}"
|
151
169
|
end
|
152
170
|
end
|
153
|
-
if callback.is_a?(Proc)
|
154
|
-
callback
|
155
|
-
else
|
156
|
-
fail ArgumentError, "The existing callback tree contains the full key path you provided but continues going. If you want to shorten the callback tree, use MockProxy.update. The callback tree looks like this: #{existing_callback_hash}"
|
157
|
-
end
|
158
171
|
end
|
159
172
|
private_class_method :get_callback
|
160
173
|
|
174
|
+
# @private
|
175
|
+
# @param [MockProxy] proxy existing proxy
|
176
|
+
# @param [String, Symbol, #to_s, Array<String, Symbol, #to_s>] key_path the chain of methods or key path. Can be a
|
177
|
+
# dot delimited key path or an array of method names as strings or symbols
|
178
|
+
# @return [Proc] if proc found at key path
|
179
|
+
# @raise [ArgumentError] if proc not found or hash found at key path
|
180
|
+
def self.get_and_validate_callback(proxy, key_path)
|
181
|
+
callback = get_callback(proxy, key_path)
|
182
|
+
return callback if callback.is_a?(Proc)
|
183
|
+
fail ArgumentError, "The existing callback tree contains the full key path you provided but continues going (i.e. no proc at exact key path). If you want to shorten the callback tree, use MockProxy.set_at. The callback tree looks like this: #{proxy.instance_variable_get('@callback_hash')}"
|
184
|
+
end
|
185
|
+
private_class_method :get_and_validate_callback
|
186
|
+
|
161
187
|
# @private
|
162
188
|
# @param [MockProxy] proxy existing proxy
|
163
189
|
# @param [String, Symbol, #to_s, Array<String, Symbol, #to_s>] key_path the chain of methods or key path. Can be a
|
164
190
|
# dot delimited key path or an array of method names as strings or symbols
|
165
191
|
# @param [Proc] proc the new proc to replace the existing proc
|
192
|
+
# @param [Bool] validate true will throw error if nil at any part of key path, false to
|
193
|
+
# create key path if missing (mkdir vs mkdir -p) (Defaults: true)
|
166
194
|
# @return [MockProxy] if proc existed at key path
|
167
195
|
# @raise [ArgumentError] if proc not found or hash found at key path
|
168
|
-
def self.set_callback(proxy, key_path, proc)
|
196
|
+
def self.set_callback(proxy, key_path, proc, validate = true)
|
197
|
+
# Validate by checking if proc exists at key path
|
198
|
+
get_and_validate_callback(proxy, key_path) if validate
|
199
|
+
# Set callback at key path, validating if set
|
169
200
|
key_paths = key_path.is_a?(Array) ? key_path.map(&:to_s) : key_path.to_s.split('.')
|
170
201
|
copied_callback_hash = proxy.instance_variable_get('@callback_hash').clone
|
171
202
|
key_paths.reduce(copied_callback_hash) do |callback_hash, key|
|
172
203
|
if !callback_hash || !callback_hash[key]
|
173
|
-
|
204
|
+
if validate
|
205
|
+
fail ArgumentError, "The existing callback tree does not contain the full key path you provided. We stopped at #{key} and the callback tree looks like this: #{copied_callback_hash}"
|
206
|
+
else
|
207
|
+
callback_hash[key] = {}
|
208
|
+
end
|
174
209
|
end
|
175
210
|
if callback_hash[key].is_a?(Proc)
|
176
211
|
callback_hash[key] = proc
|
data/lib/mock_proxy/version.rb
CHANGED