much-stub 0.1.4 → 0.1.8

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: 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