much-stub 0.1.4 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21883570fda48199a217f7489b6c45f6d3c2e1d1cb5aa872847e154033754771
4
- data.tar.gz: bf63e826137aa1d315d48823c7a11787a09be559b16abc600a168edc19ff9068
3
+ metadata.gz: c37bcf3b2a355483515be9eabd74c93bd93ccf5f503180409f86d18a183f6f8a
4
+ data.tar.gz: 20cab69d294b44212ccd23eb068ae17e2458576153e817c30dac08206c294c47
5
5
  SHA512:
6
- metadata.gz: 7f6c8c294b7f7d006b3c88a3890d24e3ff913110caa11b70642d7ba246449dd3dcb20de0df46e939d90a9b917f0c509144c260fdbfc689f6a89be1f9fb5b942f
7
- data.tar.gz: 6a7c16b6b19625ad5b84df6d5413119a921f81425278f5f3b8c0b579895c9a22e8de58da349e56684412d93a74f450ba6e7ed2b53f06ad9185f9cf8ee31ec1a5
6
+ metadata.gz: 929d09b4df2e8b85496b4a47fe67a23dde700ee751b7fa3d1b074a09db185f01ad3ff54e16a7935cd1db75fc4af58fdb9ff3482fe81d40fcfcca421ae515e265
7
+ data.tar.gz: dfbfd75bc0edc084c45eee9c62926c7c2baaec32cb28f40d670a6296e1b21c7348ee4f1d6926d02b03a63223e1369b2d0907735c2b8849805862404afffd256f
data/.l.yml ADDED
@@ -0,0 +1,8 @@
1
+ # https://github.com/redding/l.rb
2
+
3
+ linters:
4
+ - name: "Rubocop"
5
+ cmd: "bundle exec rubocop"
6
+ extensions:
7
+ - ".rb"
8
+ cli_abbrev: "u"
data/.rubocop.yml ADDED
@@ -0,0 +1,3 @@
1
+ inherit_gem:
2
+ much-style-guide:
3
+ - "lib/much-style-guide/rubocop.yml"
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.2
data/.t.yml ADDED
@@ -0,0 +1,6 @@
1
+ # https://github.com/redding/t.rb
2
+
3
+ default_cmd: bundle exec assert
4
+ test_dir: test
5
+ test_file_suffixes:
6
+ - "_tests.rb"
data/Gemfile CHANGED
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
5
+ ruby ">= 2.5"
6
+
3
7
  gemspec
4
8
 
5
- gem "pry", "~> 0.12.2"
9
+ gem "pry"
data/README.md CHANGED
@@ -16,15 +16,16 @@ Note: this was originally implemented in and extracted from [Assert](https://git
16
16
  ```ruby
17
17
  # Given this object/API
18
18
 
19
- my_class = Class.new do
20
- def my_method
21
- "my-method"
19
+ my_class =
20
+ Class.new do
21
+ def my_method
22
+ "my-method"
23
+ end
24
+
25
+ def my_value(value)
26
+ value
27
+ end
22
28
  end
23
-
24
- def my_value(value)
25
- value
26
- end
27
- end
28
29
  my_object = my_class.new
29
30
 
30
31
  my_object.my_method
@@ -95,15 +96,16 @@ my_object.my_value(456)
95
96
  ```ruby
96
97
  # Given this object/API
97
98
 
98
- my_class = Class.new do
99
- def basic_method(value)
100
- value
101
- end
99
+ my_class =
100
+ Class.new do
101
+ def basic_method(value)
102
+ value
103
+ end
102
104
 
103
- def iterator_method(items, &block)
104
- items.each(&block)
105
+ def iterator_method(items, &block)
106
+ items.each(&block)
107
+ end
105
108
  end
106
- end
107
109
  my_object = my_class.new
108
110
 
109
111
  # Store method call arguments/blocks for spying.
@@ -189,11 +191,12 @@ basic_method_calls.first.args
189
191
  ```ruby
190
192
  # Given this object/API ...
191
193
 
192
- my_class = Class.new do
193
- def build_thing(thing_value);
194
- Thing.new(value)
194
+ my_class =
195
+ Class.new do
196
+ def build_thing(thing_value);
197
+ Thing.new(value)
198
+ end
195
199
  end
196
- end
197
200
  my_object = my_class.new
198
201
 
199
202
  # ... and this Test Double.
@@ -223,11 +226,12 @@ Use the `.tap` method to spy on method calls while preserving the original metho
223
226
  ```ruby
224
227
  # Given this object/API
225
228
 
226
- my_class = Class.new do
227
- def basic_method(value)
228
- value.to_s
229
+ my_class =
230
+ Class.new do
231
+ def basic_method(value)
232
+ value.to_s
233
+ end
229
234
  end
230
- end
231
235
  my_object = my_class.new
232
236
 
233
237
  # Normal stubs override the original behavior and return value...
@@ -275,11 +279,12 @@ class Thing
275
279
  end
276
280
  end
277
281
 
278
- my_class = Class.new do
279
- def thing(value)
280
- Thing.new(value)
282
+ my_class =
283
+ Class.new do
284
+ def thing(value)
285
+ Thing.new(value)
286
+ end
281
287
  end
282
- end
283
288
  my_object = my_class.new
284
289
 
285
290
  # Use `MuchStub.tap` to stub any thing instances created by `my_object.thing`
@@ -306,16 +311,16 @@ Use the `.spy` method to spy on method calls. This is especially helpful for spy
306
311
  ```ruby
307
312
  # Given this object/API
308
313
 
309
- myclass = Class.new do
310
- def one; self; end
311
- def two(val); self; end
312
- def three; self; end
313
- def ready?; false; end
314
- end
314
+ myclass =
315
+ Class.new do
316
+ def one; self; end
317
+ def two(val); self; end
318
+ def three; self; end
319
+ def ready?; false; end
320
+ end
315
321
  myobj = myclass.new
316
322
 
317
- spy =
318
- MuchStub.spy(myobj :one, :two, :three, ready?: true)
323
+ spy = MuchStub.spy(myobj :one, :two, :three, ready?: true)
319
324
 
320
325
  assert_equal spy, myobj.one
321
326
  assert_equal spy, myobj.two("a")
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MuchStub
2
4
  class Call
3
5
  attr_reader :pargs, :kargs, :block
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "much-stub/call"
2
4
 
3
5
  module MuchStub
4
6
  class CallSpy < ::BasicObject
5
7
  METHOD_NAME_REPLACEMENTS = {
6
8
  "!" => "_bang",
7
- "?" => "_predicate"
9
+ "?" => "_predicate",
8
10
  }.freeze
9
11
 
10
12
  def initialize(**return_values)
11
- @call_spy_return_values = return_values.transform_keys{ |key| key.to_s }
12
- @call_spy_method_calls = ::Hash.new { |hash, key| hash[key] = [] }
13
+ @call_spy_return_values = return_values.transform_keys(&:to_s)
14
+ @call_spy_method_calls = ::Hash.new{ |hash, key| hash[key] = [] }
13
15
  @call_spy_method_return_values =
14
- ::Hash.new { |hash, key| hash[key] = call_spy_return_value_proc(key) }
16
+ ::Hash.new{ |hash, key| hash[key] = call_spy_return_value_proc(key) }
15
17
  end
16
18
 
17
19
  def call_spy_tap
@@ -20,23 +22,23 @@ module MuchStub
20
22
  end
21
23
 
22
24
  def ==(other)
23
- self.equal?(other)
25
+ equal?(other)
24
26
  end
25
27
 
26
28
  def ===(other)
27
- self.equal?(other)
29
+ equal?(other)
28
30
  end
29
31
 
30
32
  def eql?(other)
31
- self.equal?(other)
33
+ equal?(other)
32
34
  end
33
35
 
34
36
  def equal?(other)
35
- self.__id__ == other.__id__
37
+ __id__ == other.__id__
36
38
  end
37
39
 
38
40
  def hash
39
- self.__id__
41
+ __id__
40
42
  end
41
43
 
42
44
  def respond_to?(*)
@@ -44,7 +46,7 @@ module MuchStub
44
46
  end
45
47
 
46
48
  def inspect
47
- "#<MuchStub::CallSpy:#{"0x0%x" % (self.__id__ << 1)}>"
49
+ "#<MuchStub::CallSpy:#{"0x0%x" % (__id__ << 1)}>"
48
50
  end
49
51
 
50
52
  private
@@ -54,16 +56,14 @@ module MuchStub
54
56
  end
55
57
 
56
58
  def call_spy_return_value_proc(method_name)
57
- value = @call_spy_return_values[method_name]
58
- return value if value.respond_to?(:call)
59
-
60
- ::Proc.new { value.nil? ? self : value }
59
+ value = @call_spy_return_values.fetch(method_name, ::Proc.new{ self })
60
+ value.respond_to?(:call) ? value : ::Proc.new{ value }
61
61
  end
62
62
 
63
63
  def call_spy_normalize_method_name(name)
64
- METHOD_NAME_REPLACEMENTS.reduce(name.to_s) { |acc, (source, replacement)|
64
+ METHOD_NAME_REPLACEMENTS.reduce(name.to_s) do |acc, (source, replacement)|
65
65
  acc.gsub(source, replacement)
66
- }
66
+ end
67
67
  end
68
68
 
69
69
  def call_spy_define_spied_method(name)
@@ -79,7 +79,9 @@ module MuchStub
79
79
  spied_method_name = query_method_match[1]
80
80
  query_method_suffix = query_method_match[2]
81
81
  method_name = call_spy_normalize_method_name(spied_method_name)
82
- call_spy_define_metaclass_method("#{method_name}#{query_method_suffix}") do
82
+ call_spy_define_metaclass_method(
83
+ "#{method_name}#{query_method_suffix}",
84
+ ) do
83
85
  yield(method_name) if ::Kernel.block_given?
84
86
  end
85
87
  end
@@ -89,36 +91,35 @@ module MuchStub
89
91
  metaclass.define_method(name, &block)
90
92
  end
91
93
 
94
+ def respond_to_missing?(_name, *_args)
95
+ false
96
+ end
97
+
92
98
  def method_missing(name, *args, &block)
93
99
  if (match = name.match(/(\w+)(_calls)\z/))
94
100
  call_spy_define_query_method(match) do |method_name|
95
101
  @call_spy_method_calls[method_name]
96
102
  end
97
- self.__send__(name, *args, &block)
98
103
  elsif (match = name.match(/(\w+)(_last_called_with)\z/))
99
104
  call_spy_define_query_method(match) do |method_name|
100
- self.__send__("#{method_name}_calls").last
105
+ __send__("#{method_name}_calls").last
101
106
  end
102
- self.__send__(name, *args, &block)
103
107
  elsif (match = name.match(/(\w+)(_called_with)\z/))
104
108
  call_spy_define_query_method(match) do |method_name|
105
- self.__send__("#{method_name}_last_called_with")
109
+ __send__("#{method_name}_last_called_with")
106
110
  end
107
- self.__send__(name, *args, &block)
108
111
  elsif (match = name.match(/(\w+)(_call_count)\z/))
109
112
  call_spy_define_query_method(match) do |method_name|
110
- self.__send__("#{method_name}_calls").size
113
+ __send__("#{method_name}_calls").size
111
114
  end
112
- self.__send__(name, *args, &block)
113
115
  elsif (match = name.match(/(\w+)(_called\?)\z/))
114
116
  call_spy_define_query_method(match) do |method_name|
115
- self.__send__("#{method_name}_call_count") > 0
117
+ __send__("#{method_name}_call_count") > 0
116
118
  end
117
- self.__send__(name, *args, &block)
118
119
  else
119
120
  call_spy_define_spied_method(name)
120
- self.__send__(name, *args, &block)
121
121
  end
122
+ __send__(name, *args, &block)
122
123
  end
123
124
  end
124
125
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MuchStub
2
- VERSION = "0.1.4"
4
+ VERSION = "0.1.8"
3
5
  end
data/lib/much-stub.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "much-stub/version"
2
4
 
3
5
  require "much-stub/call"
@@ -13,66 +15,70 @@ module MuchStub
13
15
  end
14
16
 
15
17
  def self.arity_matches?(method, args)
16
- return true if method.arity == args.size # mandatory args
17
- return true if method.arity < 0 && args.size >= (method.arity+1).abs # variable args
18
- return false
18
+ # mandatory args
19
+ return true if method.arity == args.size
20
+ # variable args
21
+ return true if method.arity < 0 && args.size >= (method.arity + 1).abs
22
+
23
+ false
19
24
  end
20
25
 
21
26
  def self.stub(obj, meth, &block)
22
- key = self.stub_key(obj, meth)
23
- self.stubs[key] ||= MuchStub::Stub.new(obj, meth, caller_locations)
24
- self.stubs[key].tap{ |s| s.do = block }
27
+ key = stub_key(obj, meth)
28
+ stubs[key] ||= MuchStub::Stub.new(obj, meth, caller_locations)
29
+ stubs[key].tap{ |s| s.do = block }
25
30
  end
26
31
 
27
32
  def self.call(*args, &block)
28
- self.stub(*args, &block)
33
+ stub(*args, &block)
29
34
  end
30
35
 
31
36
  def self.stub_on_call(*args, &on_call_block)
32
- self.stub(*args).on_call(&on_call_block)
37
+ stub(*args).on_call(&on_call_block)
33
38
  end
34
39
 
35
40
  def self.on_call(*args, &on_call_block)
36
- self.stub_on_call(*args, &on_call_block)
41
+ stub_on_call(*args, &on_call_block)
37
42
  end
38
43
 
39
44
  def self.unstub(obj, meth)
40
- key = self.stub_key(obj, meth)
41
- (self.stubs.delete(key) || MuchStub::NullStub.new).teardown
45
+ key = stub_key(obj, meth)
46
+ (stubs.delete(key) || MuchStub::NullStub.new).teardown
42
47
  end
43
48
 
44
49
  def self.unstub!
45
- self.stubs.keys.each{ |key| self.stubs.delete(key).teardown }
50
+ stubs.keys.each{ |key| stubs.delete(key).teardown }
46
51
  end
47
52
 
48
53
  def self.stub_send(obj, meth, *args, &block)
49
54
  orig_caller = caller_locations
50
- stub = self.stubs.fetch(MuchStub::Stub.key(obj, meth)) do
51
- raise NotStubbedError, "`#{meth}` not stubbed.", orig_caller.map(&:to_s)
52
- end
55
+ stub =
56
+ stubs.fetch(MuchStub::Stub.key(obj, meth)) do
57
+ raise NotStubbedError, "`#{meth}` not stubbed.", orig_caller.map(&:to_s)
58
+ end
53
59
  stub.call_method(args, &block)
54
60
  end
55
61
 
56
62
  def self.tap(obj, meth, &tap_block)
57
- self.stub(obj, meth) { |*args, &block|
58
- self.stub_send(obj, meth, *args, &block).tap { |value|
59
- tap_block.call(value, *args, &block) if tap_block
60
- }
61
- }
63
+ stub(obj, meth) do |*args, &block|
64
+ stub_send(obj, meth, *args, &block).tap do |value|
65
+ tap_block&.call(value, *args, &block)
66
+ end
67
+ end
62
68
  end
63
69
 
64
70
  def self.tap_on_call(obj, meth, &on_call_block)
65
- self.tap(obj, meth) { |value, *args, &block|
66
- on_call_block.call(value, MuchStub::Call.new(*args, &block)) if on_call_block
67
- }
71
+ tap(obj, meth) do |value, *args, &block|
72
+ on_call_block&.call(value, MuchStub::Call.new(*args, &block))
73
+ end
68
74
  end
69
75
 
70
76
  def self.spy(obj, *meths, **return_values)
71
77
  MuchStub::CallSpy.new(**return_values).call_spy_tap do |spy|
72
78
  meths.each do |meth|
73
- self.stub(obj, meth) { |*args, &block|
79
+ stub(obj, meth) do |*args, &block|
74
80
  spy.__send__(meth, *args, &block)
75
- }
81
+ end
76
82
  end
77
83
  end
78
84
  end
@@ -114,7 +120,9 @@ module MuchStub
114
120
  @method,
115
121
  args,
116
122
  method_name: @method_name,
117
- backtrace: orig_caller))
123
+ backtrace: orig_caller,
124
+ ),
125
+ )
118
126
  end
119
127
  lookup(args, orig_caller).call(*args, &block)
120
128
  rescue NotStubbedError
@@ -130,7 +138,9 @@ module MuchStub
130
138
  @method,
131
139
  args,
132
140
  method_name: @method_name,
133
- backtrace: orig_caller))
141
+ backtrace: orig_caller,
142
+ ),
143
+ )
134
144
  end
135
145
  @lookup[args] = block
136
146
  self
@@ -138,12 +148,12 @@ module MuchStub
138
148
 
139
149
  def on_call(&on_call_block)
140
150
  stub_block =
141
- ->(*args, &block) {
142
- on_call_block.call(MuchStub::Call.new(*args, &block)) if on_call_block
151
+ ->(*args, &block){
152
+ on_call_block&.call(MuchStub::Call.new(*args, &block))
143
153
  }
144
154
  if @lookup.empty?
145
155
  @do = stub_block
146
- elsif @lookup.has_value?(nil)
156
+ elsif @lookup.value?(nil)
147
157
  @lookup.transform_values!{ |value| value.nil? ? stub_block : value }
148
158
  end
149
159
  self
@@ -157,7 +167,7 @@ module MuchStub
157
167
  end
158
168
 
159
169
  def inspect
160
- "#<#{self.class}:#{"0x0%x" % (object_id << 1)}" \
170
+ "#<#{self.class}:#{format("0x0%x", (object_id << 1))}" \
161
171
  " @method_name=#{@method_name.inspect}" \
162
172
  ">"
163
173
  end
@@ -169,7 +179,7 @@ module MuchStub
169
179
  msg = "#{object.inspect} does not respond to `#{@method_name}`"
170
180
  raise StubError, msg, orig_caller.map(&:to_s)
171
181
  end
172
- is_constant = object.kind_of?(Module)
182
+ is_constant = object.is_a?(Module)
173
183
  local_object_methods = object.methods(false).map(&:to_s)
174
184
  all_object_methods = object.methods.map(&:to_s)
175
185
  if (is_constant && !local_object_methods.include?(@method_name)) ||
@@ -180,7 +190,8 @@ module MuchStub
180
190
  method
181
191
  end
182
192
 
183
- if !local_object_methods.include?(@name) # already stubbed
193
+ # already stubbed
194
+ unless local_object_methods.include?(@name)
184
195
  @metaclass.send(:alias_method, @name, @method_name)
185
196
  end
186
197
  @method = object.method(@name)
@@ -194,19 +205,21 @@ module MuchStub
194
205
  end
195
206
 
196
207
  def lookup(args, orig_caller)
197
- @lookup.fetch(args) {
198
- self.do || begin
208
+ @lookup.fetch(args) do
209
+ self.do ||
210
+ begin
199
211
  msg = "#{inspect_call(args)} not stubbed."
200
212
  inspect_lookup_stubs.tap do |stubs|
201
- msg += "\nStubs:\n#{stubs}" if !stubs.empty?
213
+ msg += "\nStubs:\n#{stubs}" unless stubs.empty?
202
214
  end
203
215
  raise NotStubbedError, msg, orig_caller.map(&:to_s)
204
216
  end
205
- } ||
206
- raise(
207
- StubError,
208
- "#{inspect_call(args)} stubbed with no block.",
209
- orig_caller.map(&:to_s))
217
+ end ||
218
+ raise(
219
+ StubError,
220
+ "#{inspect_call(args)} stubbed with no block.",
221
+ orig_caller.map(&:to_s),
222
+ )
210
223
  end
211
224
 
212
225
  def inspect_lookup_stubs
@@ -242,9 +255,12 @@ module MuchStub
242
255
  end
243
256
  end
244
257
 
245
- NullStub = Class.new do
246
- def teardown; end # no-op
247
- end
258
+ NullStub =
259
+ Class.new do
260
+ def teardown
261
+ # no-op
262
+ end
263
+ end
248
264
 
249
265
  module ParameterList
250
266
  LETTERS = ("a".."z").to_a.freeze
@@ -257,8 +273,6 @@ module MuchStub
257
273
  params.join(", ")
258
274
  end
259
275
 
260
- private
261
-
262
276
  def self.get_arity(object, method_name)
263
277
  object.method(method_name).arity
264
278
  rescue NameError
data/much-stub.gemspec CHANGED
@@ -1,24 +1,32 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  lib = File.expand_path("../lib", __FILE__)
3
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
6
  require "much-stub/version"
5
7
 
6
8
  Gem::Specification.new do |gem|
7
- gem.name = "much-stub"
8
- gem.version = MuchStub::VERSION
9
- gem.authors = ["Kelly Redding", "Collin Redding"]
10
- gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
11
- gem.summary = "Stubbing API for replacing method calls on objects in test runs."
12
- gem.description = "Stubbing API for replacing method calls on objects in test runs."
13
- gem.homepage = "https://github.com/redding/much-stub"
14
- gem.license = "MIT"
15
-
16
- gem.files = `git ls-files`.split($/)
9
+ gem.name = "much-stub"
10
+ gem.version = MuchStub::VERSION
11
+ gem.authors = ["Kelly Redding", "Collin Redding"]
12
+ gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
13
+
14
+ gem.summary =
15
+ "Stubbing API for replacing method calls on objects in test runs."
16
+ gem.description =
17
+ "Stubbing API for replacing method calls on objects in test runs."
18
+
19
+ gem.homepage = "https://github.com/redding/much-stub"
20
+ gem.license = "MIT"
21
+
22
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
23
+
17
24
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
25
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
26
  gem.require_paths = ["lib"]
20
27
 
21
- gem.required_ruby_version = "~> 2.5"
28
+ gem.required_ruby_version = ">= 2.5"
22
29
 
23
- gem.add_development_dependency("assert", ["~> 2.18.2"])
30
+ gem.add_development_dependency("assert", ["~> 2.19.2"])
31
+ gem.add_development_dependency("much-style-guide", ["~> 0.6.0"])
24
32
  end
data/test/helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # this file is automatically required when you run `assert`
2
4
  # put any test helpers here
3
5
 
@@ -12,7 +14,7 @@ require "test/support/factory"
12
14
  # 1.8.7 backfills
13
15
 
14
16
  # Array#sample
15
- if !(a = Array.new).respond_to?(:sample) && a.respond_to?(:choice)
17
+ if !(a = []).respond_to?(:sample) && a.respond_to?(:choice)
16
18
  class Array
17
19
  alias_method :sample, :choice
18
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "assert/factory"
2
4
 
3
5
  module Factory