mocktail 1.1.2 → 1.1.3

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: 7eb64f90875e53a9bfd5b4d995f8526eb6695dd9bd8a88c850b02eed851cb96d
4
- data.tar.gz: ae2b4443a3740c375c70e7e490cbe3463d9672f17665ae47930b6ee614e9891d
3
+ metadata.gz: 0aa187046d2e07280352ba6f0296f5573bda910acb111e06d0932f0e2518064e
4
+ data.tar.gz: c3e5e74d586969ea5dd88dc86c20a9d2e6f223f1bb8a438325583a8d8fb20bae
5
5
  SHA512:
6
- metadata.gz: de8d47071e93c4d406391a1155dea9b6a1a9ac89f56422ae29e6dda5f134c9e5e724ec8006aba833b5ff19d9d2dff4550384bc349506f5ab9cefe3fd2185af1d
7
- data.tar.gz: 5bf88d0aadc08fe9a9380312cf491146439e72e335091e2e79849196b74e93aba20b0fac2d122152a4661008ee243b5b3b39cb6408fc776b2cc2567ffca0924f
6
+ metadata.gz: 224a377d46c11b830b90a828e6a0c294e940c3492cde42fda9aa0f865b97cdc69773571d4464bd4bbe185aa29e6860c5a4c2b3b87a458382a84b330ddce5df3e
7
+ data.tar.gz: 10562536842265afc7f6bef9fa63a8ebab657e78941f13bc0e38cb49cf8f43785d1d926d0f5afe103165d337fe2163cba88aa4aee220004c8a2494e5f5493d4c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # 1.1.3
2
+
3
+ * Improve the robustness of how we call the original methods on doubles &
4
+ replaced class methods on mocks internally by Mocktail to avoid behavior being
5
+ altered by how users configure mock objects
6
+
7
+ # 1.1.2
8
+
9
+ * Fix cases where classes that redefine built-in methods could cause issues when
10
+ Mocktail in turn called those methods internally
11
+ [#15](https://github.com/testdouble/mocktail/pull/15)
12
+
1
13
  # 1.1.1
2
14
 
3
15
  * Improve output for undefined singleton methods
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mocktail (1.1.2)
4
+ mocktail (1.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,19 +1,18 @@
1
1
  require_relative "../../share/cleans_backtrace"
2
- require_relative "../../share/compares_safely"
2
+ require_relative "../../share/bind"
3
3
 
4
4
  module Mocktail
5
5
  class DescribesUnsatisfiedStubbing
6
6
  def initialize
7
7
  @cleans_backtrace = CleansBacktrace.new
8
- @compares_safely = ComparesSafely.new
9
8
  end
10
9
 
11
10
  def describe(dry_call)
12
11
  UnsatisfyingCall.new(
13
12
  call: dry_call,
14
13
  other_stubbings: Mocktail.cabinet.stubbings.select { |stubbing|
15
- @compares_safely.compare(dry_call.double, stubbing.recording.double) &&
16
- @compares_safely.compare(dry_call.method, stubbing.recording.method)
14
+ Bind.call(dry_call.double, :==, stubbing.recording.double) &&
15
+ dry_call.method == stubbing.recording.method
17
16
  },
18
17
  backtrace: @cleans_backtrace.clean(Error.new).backtrace
19
18
  )
@@ -0,0 +1,14 @@
1
+ module Mocktail
2
+ module Bind
3
+ def self.call(mock, method_name, *args, **kwargs, &blk)
4
+ if Mocktail.cabinet.double_for_instance(mock)
5
+ Object.instance_method(method_name).bind_call(mock, *args, **kwargs, &blk)
6
+ elsif (type_replacement = TopShelf.instance.type_replacement_if_exists_for(mock)) &&
7
+ (og_method = type_replacement.original_methods&.find { |m| m.name == method_name })
8
+ og_method.call(*args, **kwargs, &blk)
9
+ else
10
+ mock.__send__(method_name, *args, **kwargs, &blk)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,14 +1,10 @@
1
- require_relative "compares_safely"
1
+ require_relative "bind"
2
2
 
3
3
  module Mocktail
4
4
  class DeterminesMatchingCalls
5
- def initialize
6
- @compares_safely = ComparesSafely.new
7
- end
8
-
9
5
  def determine(real_call, demo_call, demo_config)
10
- @compares_safely.compare(real_call.double, demo_call.double) &&
11
- @compares_safely.compare(real_call.method, demo_call.method) &&
6
+ Bind.call(real_call.double, :==, demo_call.double) &&
7
+ real_call.method == demo_call.method &&
12
8
 
13
9
  # Matcher implementation will replace this:
14
10
  args_match?(real_call.args, demo_call.args, demo_config.ignore_extra_args) &&
@@ -55,11 +51,11 @@ module Mocktail
55
51
  end
56
52
 
57
53
  def match?(real_arg, demo_arg)
58
- if demo_arg.respond_to?(:is_mocktail_matcher?) &&
54
+ if Bind.call(demo_arg, :respond_to?, :is_mocktail_matcher?) &&
59
55
  demo_arg.is_mocktail_matcher?
60
56
  demo_arg.match?(real_arg)
61
57
  else
62
- demo_arg == real_arg # TODO <-- test if mock object and call safe compare if so, otherwise ==
58
+ Bind.call(demo_arg, :==, real_arg)
63
59
  end
64
60
  end
65
61
  end
@@ -1,22 +1,18 @@
1
- require_relative "../share/compares_safely"
1
+ require_relative "../share/bind"
2
2
 
3
3
  module Mocktail
4
4
  class TransformsParams
5
- def initialize
6
- @compares_safely = ComparesSafely.new
7
- end
8
-
9
5
  def transform(dry_call)
10
6
  params = dry_call.original_method.parameters
11
7
 
12
8
  Signature.new(
13
9
  positional_params: Params.new(
14
10
  all: params.select { |t, _|
15
- [:req, :opt, :rest].any? { |param_type| @compares_safely.compare(t, param_type) }
11
+ [:req, :opt, :rest].any? { |param_type| Bind.call(t, :==, param_type) }
16
12
  }.map { |_, name| name },
17
- required: params.select { |t, _| @compares_safely.compare(t, :req) }.map { |_, n| n },
18
- optional: params.select { |t, _| @compares_safely.compare(t, :opt) }.map { |_, n| n },
19
- rest: params.find { |t, _| @compares_safely.compare(t, :rest) } & [1]
13
+ required: params.select { |t, _| Bind.call(t, :==, :req) }.map { |_, n| n },
14
+ optional: params.select { |t, _| Bind.call(t, :==, :opt) }.map { |_, n| n },
15
+ rest: params.find { |t, _| Bind.call(t, :==, :rest) } & [1]
20
16
  ),
21
17
  positional_args: dry_call.args,
22
18
 
@@ -24,13 +20,13 @@ module Mocktail
24
20
  all: params.select { |type, _|
25
21
  [:keyreq, :key, :keyrest].include?(type)
26
22
  }.map { |_, name| name },
27
- required: params.select { |t, _| @compares_safely.compare(t, :keyreq) }.map { |_, n| n },
28
- optional: params.select { |t, _| @compares_safely.compare(t, :key) }.map { |_, n| n },
29
- rest: params.find { |t, _| @compares_safely.compare(t, :keyrest) } & [1]
23
+ required: params.select { |t, _| Bind.call(t, :==, :keyreq) }.map { |_, n| n },
24
+ optional: params.select { |t, _| Bind.call(t, :==, :key) }.map { |_, n| n },
25
+ rest: params.find { |t, _| Bind.call(t, :==, :keyrest) } & [1]
30
26
  ),
31
27
  keyword_args: dry_call.kwargs,
32
28
 
33
- block_param: params.find { |t, _| @compares_safely.compare(t, :block) } & [1],
29
+ block_param: params.find { |t, _| Bind.call(t, :==, :block) } & [1],
34
30
  block_arg: dry_call.block
35
31
  )
36
32
  end
@@ -1,4 +1,4 @@
1
- require_relative "../share/compares_safely"
1
+ require_relative "../share/bind"
2
2
 
3
3
  # The Cabinet stores all thread-local state, so anything that goes here
4
4
  # is guaranteed by Mocktail to be local to the currently-running thread
@@ -8,7 +8,6 @@ module Mocktail
8
8
  attr_reader :calls, :stubbings, :unsatisfying_calls
9
9
 
10
10
  def initialize
11
- @compares_safely = ComparesSafely.new
12
11
  @doubles = []
13
12
  @calls = []
14
13
  @stubbings = []
@@ -48,18 +47,21 @@ module Mocktail
48
47
  end
49
48
 
50
49
  def double_for_instance(thing)
51
- @doubles.find { |double| @compares_safely.compare(double.dry_instance, thing) }
50
+ @doubles.find { |double|
51
+ # Intentionally calling directly to avoid an infinite recursion in Bind.call
52
+ Object.instance_method(:==).bind_call(double.dry_instance, thing)
53
+ }
52
54
  end
53
55
 
54
56
  def stubbings_for_double(double)
55
57
  @stubbings.select { |stubbing|
56
- @compares_safely.compare(stubbing.recording.double, double.dry_instance)
58
+ Bind.call(stubbing.recording.double, :==, double.dry_instance)
57
59
  }
58
60
  end
59
61
 
60
62
  def calls_for_double(double)
61
63
  @calls.select { |call|
62
- @compares_safely.compare(call.double, double.dry_instance)
64
+ Bind.call(call.double, :==, double.dry_instance)
63
65
  }
64
66
  end
65
67
  end
@@ -1,3 +1,3 @@
1
1
  module Mocktail
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mocktail
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Searls
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-25 00:00:00.000000000 Z
11
+ date: 2022-06-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -67,8 +67,8 @@ files:
67
67
  - lib/mocktail/replaces_type/redefines_new.rb
68
68
  - lib/mocktail/replaces_type/redefines_singleton_methods.rb
69
69
  - lib/mocktail/resets_state.rb
70
+ - lib/mocktail/share/bind.rb
70
71
  - lib/mocktail/share/cleans_backtrace.rb
71
- - lib/mocktail/share/compares_safely.rb
72
72
  - lib/mocktail/share/creates_identifier.rb
73
73
  - lib/mocktail/share/determines_matching_calls.rb
74
74
  - lib/mocktail/share/stringifies_call.rb
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  - !ruby/object:Gem::Version
120
120
  version: '0'
121
121
  requirements: []
122
- rubygems_version: 3.3.6
122
+ rubygems_version: 3.3.7
123
123
  signing_key:
124
124
  specification_version: 4
125
125
  summary: Take your objects, and make them a double
@@ -1,7 +0,0 @@
1
- module Mocktail
2
- class ComparesSafely
3
- def compare(thing, other_thing)
4
- Object.instance_method(:==).bind_call(thing, other_thing)
5
- end
6
- end
7
- end