rspec-sorbet 1.0.0 → 1.1.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
  SHA256:
3
- metadata.gz: dfa6e3ee8be246791457ead7ccfadfb915bc17def59dec8f615287e8cbda3aba
4
- data.tar.gz: 34c42b3831bc5712a67e544bc56d768c8617e917ede3f2251ad5a22000e50629
3
+ metadata.gz: 5658116844f34d4b596c0f46bbdcefa667a82d3186905f0acf0961d3654ec660
4
+ data.tar.gz: 38d680e034afe8cd469882f210efec1e7fb23c3ef4f3b3ec40f027069864451d
5
5
  SHA512:
6
- metadata.gz: a1b97aa16c1923938827dc55a7e2b8574dd116ed5c88c43530ff47758bee34f9e8b401275b743fb5cd667427307cf0791218d2c33315605da6478798a4f11d48
7
- data.tar.gz: 831e6e1f418ac631a7ec9ffc774a682e70ffe7908600d3c20253d6612b4d8d58368e53bcc7c912c10f5b153edab7c9e3825790d7eebb2cb29b0de5b2d0baec95
6
+ metadata.gz: 2377abcbc26c8d5925a868bb6ff2ca4f675769bc5a3522f253eb001f3e5d4f5e85cca4d669da2adde281eca7487a7405a2ea5b344c221ad154f8d62d62f24e26
7
+ data.tar.gz: d3ba0390f07496a8b1e9d06f344f701f66e1dcb4c3b47d378c8420d0e9e36b748c9e020e03836a08aaeda6053f811b626de0784f4dec98a41f25ee2097d3de48
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ 1.1.0
2
+
3
+ * Add basic `instance_double` verification to help check the type of an instance double.
4
+
1
5
  1.0.0
2
6
 
3
7
  * Initial release
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # RSpec Sorbet
1
+ ![rspec-sorbet](https://user-images.githubusercontent.com/2643026/63100456-02c12c00-bf6f-11e9-8430-630a27bc6e42.png)
2
+
3
+ # RSpec Sorbet [![Gem Version](https://badge.fury.io/rb/rspec-sorbet.svg)](https://badge.fury.io/rb/rspec-sorbet)
2
4
 
3
5
  A small gem consisting of helpers for using Sorbet & RSpec together.
4
6
 
@@ -15,7 +17,7 @@ require 'rspec/sorbet'
15
17
 
16
18
  ### Allowing Instance Doubles
17
19
 
18
- Out of the box if your using `instance_double`'s in your tests you'll encounter errors such as the following:
20
+ Out of the box if you're using `instance_double`'s in your tests you'll encounter errors such as the following:
19
21
 
20
22
  ```
21
23
  TypeError:
@@ -23,7 +25,7 @@ Out of the box if your using `instance_double`'s in your tests you'll encounter
23
25
  Caller: /Users/samuelgiles/Documents/Projects/Clients/Bellroy/bellroy/spec/lib/checkout/use_cases/my_use_case.rb:9
24
26
  ```
25
27
 
26
- Drop the following into your `spec_helper.rb` to allow instance doubles to be used:
28
+ Drop the following into your `spec_helper.rb` to allow `instance_double` to be used without breaking type checking:
27
29
 
28
30
  ```ruby
29
31
  RSpec::Sorbet.allow_instance_doubles!
@@ -5,11 +5,6 @@ require 'sorbet-runtime'
5
5
  module RSpec
6
6
  module Sorbet
7
7
  module InstanceDoubles
8
- WHITELISTED_ERROR_MESSAGES = [
9
- 'RSpec::Mocks::InstanceVerifyingDouble',
10
- 'InstanceDouble'
11
- ].freeze
12
-
13
8
  def allow_instance_doubles!
14
9
  T::Configuration.inline_type_error_handler = proc do |error|
15
10
  inline_type_error_handler(error)
@@ -22,18 +17,73 @@ module RSpec
22
17
 
23
18
  private
24
19
 
20
+ INLINE_INSTANCE_DOUBLE_REGEX =
21
+ /T.let: Expected type (T.any\()?(?<expected_classes>[a-zA-Z:: ,]*)(\))?, got type (.*) with value #<InstanceDouble\((?<doubled_module>[a-zA-Z:: ,]*)\)/.freeze
22
+
25
23
  def inline_type_error_handler(error)
26
- raise error unless error.is_a?(TypeError) && message_is_whitelisted?(error.message)
24
+ case error
25
+ when TypeError
26
+ message = error.message
27
+ return if instance_double_message_with_ellipsis?(message) || typed_array_message?(message)
28
+
29
+ _, expected_types_string, doubled_module_string = (message.match(INLINE_INSTANCE_DOUBLE_REGEX) || [])[0..2]
30
+ raise error unless expected_types_string && doubled_module_string
31
+
32
+ expected_types = expected_types_string.split(',').map do |expected_type_string|
33
+ Object.const_get(expected_type_string.strip)
34
+ end
35
+ doubled_module = Object.const_get(doubled_module_string)
36
+
37
+ valid = expected_types.any? do |expected_type|
38
+ doubled_module.ancestors.include?(expected_type)
39
+ end
40
+
41
+ raise error unless valid
42
+ else
43
+ raise error
44
+ end
27
45
  end
28
46
 
29
- def call_validation_error_handler(_signature, opts)
30
- raise TypeError, opts[:pretty_message] unless message_is_whitelisted?(opts[:message])
47
+ INSTANCE_VERIFYING_DOUBLE_OR_INSTANCE_DOUBLE =
48
+ /(RSpec::Mocks::InstanceVerifyingDouble|InstanceDouble)/.freeze
49
+
50
+ def instance_double_message_with_ellipsis?(message)
51
+ message.include?('...') && message.match?(INSTANCE_VERIFYING_DOUBLE_OR_INSTANCE_DOUBLE)
31
52
  end
32
53
 
33
- def message_is_whitelisted?(message)
34
- WHITELISTED_ERROR_MESSAGES.any? do |whitelisted_message|
35
- message.include?(whitelisted_message)
54
+ TYPED_ARRAY_MESSAGE = /got T::Array/.freeze
55
+
56
+ def typed_array_message?(message)
57
+ message.match?(TYPED_ARRAY_MESSAGE)
58
+ end
59
+
60
+ def call_validation_error_handler(_signature, opts)
61
+ should_raise = true
62
+
63
+ if opts[:pretty_message].match?(INSTANCE_VERIFYING_DOUBLE_OR_INSTANCE_DOUBLE)
64
+ typing = opts[:type]
65
+ value = opts[:value].is_a?(Array) ? opts[:value].first : opts[:value]
66
+ target = value.instance_variable_get(:@doubled_module).target
67
+
68
+ case typing
69
+ when T::Types::TypedArray
70
+ typing = typing.type
71
+ end
72
+
73
+ case typing
74
+ when T::Types::Simple
75
+ should_raise = !target.ancestors.include?(typing.raw_type)
76
+ when T::Types::Union
77
+ valid = typing.types.map(&:raw_type).any? do |type|
78
+ target.ancestors.include?(type)
79
+ end
80
+ should_raise = !valid
81
+ else
82
+ should_raise = !target.ancestors.include?(typing)
83
+ end
36
84
  end
85
+
86
+ raise TypeError, opts[:pretty_message] if should_raise
37
87
  end
38
88
  end
39
89
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module Sorbet
5
- VERSION = '1.0.0'
5
+ VERSION = '1.1.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-sorbet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giles
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-15 00:00:00.000000000 Z
11
+ date: 2019-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet