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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9adac2fb9c8647d2f74cd27918f4ec7a2cab0aa3
4
- data.tar.gz: d1a89dc5cf285ae1a86b149165107a936ce9fc97
3
+ metadata.gz: 1a4278ce46b890ca708d751a055af4476ebc5b74
4
+ data.tar.gz: 6df4a43793f809f124cc9b97b769e77697d28c53
5
5
  SHA512:
6
- metadata.gz: 7de74d0b5c42d79bd268032380f01aec93f381bcd34bc5687dde7d7160bcb0a6785f69282019e2614f136d1a435892871f4ced552e32ba40151aa08ae0af9039
7
- data.tar.gz: b5029ff013d9fa78b9f319db78805f6ccad749f957a2ab956464cca62ee63c265d5180d65a09d0cea884345850d3bf8e6ec76bc0b3f9b38408c66e75d876492b
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
- # callback = proc { |message| expect(message).to eq 'message' }
24
- # MockProxy.update_proxy(model_proxy, receive_email: callback)
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.update_proxy(generator_proxy, decorate: proc { |*args| method_call(type, *args) })
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
- get_callback(proxy, key_path)
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: Reuse existing stub but modify a proc
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 = get_callback(proxy, key_path)
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 = get_callback(proxy, key_path)
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
- callback = key_paths.reduce(existing_callback_hash) do |callback_hash, key|
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
- 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}"
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
@@ -1,4 +1,4 @@
1
1
  class MockProxy
2
2
  # The version number
3
- VERSION = '0.1.3'
3
+ VERSION = '0.2.0'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mock_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - matrinox