rspec-sorbet 1.9.1 → 1.9.2
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 +4 -4
- data/.devcontainer/devcontainer.json +5 -0
- data/.github/workflows/ci.yml +20 -46
- data/.rubocop.yml +16 -60
- data/CHANGELOG.md +9 -0
- data/Gemfile +15 -12
- data/README.md +3 -3
- data/Rakefile +3 -1
- data/bin/console +4 -3
- data/bin/rbi +6 -0
- data/bin/rspec +27 -0
- data/bin/rubocop +27 -0
- data/bin/setup +0 -2
- data/bin/tapioca +4 -2
- data/generate_require_files.rb +10 -10
- data/lib/rspec/all.rb +2 -2
- data/lib/rspec/sorbet/all.rb +2 -2
- data/lib/rspec/sorbet/doubles.rb +68 -16
- data/lib/rspec/sorbet/version.rb +1 -1
- data/lib/rspec/sorbet.rb +1 -1
- data/rspec-sorbet.gemspec +19 -17
- metadata +13 -13
- data/nix/sources.json +0 -14
- data/nix/sources.nix +0 -194
- data/run_ci.sh +0 -7
- data/shell.nix +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e49df5d697e2d441b06483b44261e8edb5ac59b7003c5356d88d6be106db79e
|
4
|
+
data.tar.gz: 17aebafd7cd92d511915bced0d87279e8a0a271ba4ed593a7cdd465c5514c31c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d37e33a3218ebde8de313aa0707c690f1d06c28b04f552dcc6611d09334d52b73a4aeafc50b132fdc7c1266f1a430a2affffc17928857ecebdefa788e081fa6
|
7
|
+
data.tar.gz: 777a239771115649469b1eff69936a5bd64c1815915ee322300028864d44092481d94b637c0b778b85020a965b900af7d3414ab903dc0ee703cd4dfabc18c47d
|
data/.github/workflows/ci.yml
CHANGED
@@ -1,50 +1,24 @@
|
|
1
|
-
---
|
2
1
|
name: Continuous Integration
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
- refs/tags/*_production
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
permissions:
|
6
|
+
contents: read
|
7
|
+
|
10
8
|
jobs:
|
11
|
-
|
12
|
-
runs-on: ubuntu-
|
9
|
+
test:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
ruby-version: ['3.1']
|
13
14
|
steps:
|
14
|
-
-
|
15
|
-
|
16
|
-
|
17
|
-
shell: bash
|
18
|
-
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
19
|
-
id: extract_branch
|
20
|
-
- name: Cache gems
|
21
|
-
uses: actions/cache@v2
|
15
|
+
- uses: actions/checkout@v3
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
22
18
|
with:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
-
|
28
|
-
|
29
|
-
extra_nix_config: |
|
30
|
-
post-build-hook = /etc/nix/upload-to-cache.sh
|
31
|
-
substituters = https://cache.nixos.org/
|
32
|
-
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
|
33
|
-
nix_path: nixpkgs=channel:nixos-21.05
|
34
|
-
- name: Run CI through nix-shell
|
35
|
-
env:
|
36
|
-
GEMFURY_DEPLOY_TOKEN: ${{ secrets.GEMFURY_DEPLOY_TOKEN }}
|
37
|
-
run: nix-shell --run "chmod 755 ./run_ci.sh && ./run_ci.sh"
|
38
|
-
- name: Post to Slack if build fails
|
39
|
-
if: failure() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'
|
40
|
-
|| github.ref == 'refs/heads/stable')
|
41
|
-
uses: pullreminders/slack-action@a5a262c896a1cc80dcbae59ba95513e2dfb21439
|
42
|
-
env:
|
43
|
-
SLACK_BOT_TOKEN: "${{ secrets.BELLROY_SLACK_TOKEN }}"
|
44
|
-
with:
|
45
|
-
args: '{\"channel\":\"${{ env.SLACK_CHANNEL_ID }}\",\"text\":\"* ${{ github.repository }} BUILD
|
46
|
-
FAILURE*\", \"attachments\": [{ \"fallback\": \"Failure summary\", \"color\":
|
47
|
-
\"#ff0000\", \"fields\": [{\"title\": \"Branch\", \"value\":\"${{ steps.extract_branch.outputs.branch
|
48
|
-
}}\"}, {\"title\": \"Who broke it\", \"value\":\"${{ github.actor }}\"},
|
49
|
-
{ \"title\": \"Build output\", \"value\": \"https://github.com/${{ github.repository
|
50
|
-
}}/commit/${{ github.sha }}/checks\", \"short\": false }]}]}'
|
19
|
+
ruby-version: ${{ matrix.ruby-version }}
|
20
|
+
bundler-cache: true
|
21
|
+
- name: Run RSpec tests
|
22
|
+
run: bin/rspec
|
23
|
+
- name: Check for Rubocop offenses
|
24
|
+
run: bin/rubocop --format github
|
data/.rubocop.yml
CHANGED
@@ -1,66 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
Enabled: true
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
3
|
+
require: rubocop-rspec
|
4
|
+
|
6
5
|
AllCops:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Exclude:
|
12
|
-
- app/assets/**/*
|
13
|
-
- bin/**/*
|
14
|
-
- client/node_modules/**/*
|
15
|
-
- config/**/*
|
16
|
-
- coverage/**/*
|
17
|
-
- data/**/*
|
18
|
-
- db/**/*
|
19
|
-
- db_*/**/*
|
20
|
-
- dw/**/*
|
21
|
-
- log/**/*
|
22
|
-
- phrase/**/*
|
23
|
-
- public/**/*
|
24
|
-
- tmp/**/*
|
25
|
-
- vendor/**/*
|
26
|
-
TargetRubyVersion: 2.5
|
27
|
-
Metrics/LineLength:
|
28
|
-
Max: 100
|
29
|
-
Layout/MultilineMethodCallIndentation:
|
30
|
-
EnforcedStyle: indented
|
31
|
-
Style/PercentLiteralDelimiters:
|
32
|
-
PreferredDelimiters:
|
33
|
-
"%w": "[]"
|
34
|
-
RSpec/ExampleLength:
|
35
|
-
Enabled: false
|
36
|
-
Max: 10
|
37
|
-
RSpec/MultipleExpectations:
|
38
|
-
Enabled: false
|
39
|
-
Max: 10
|
40
|
-
RSpec/NestedGroups:
|
41
|
-
Enabled: false
|
42
|
-
Max: 10
|
43
|
-
RSpec/MessageExpectation:
|
6
|
+
NewCops: disable
|
7
|
+
SuggestExtensions: false
|
8
|
+
|
9
|
+
RSpec/LeakyConstantDeclaration:
|
44
10
|
Enabled: false
|
45
|
-
|
46
|
-
|
47
|
-
require:
|
48
|
-
- rubocop-performance
|
49
|
-
- rubocop-rspec
|
50
|
-
- test_prof/rubocop
|
51
|
-
Metrics/BlockLength:
|
52
|
-
Enabled: false
|
53
|
-
RSpec/MessageSpies:
|
54
|
-
Enabled: false
|
55
|
-
RSpec/ExpectInHook:
|
11
|
+
|
12
|
+
RSpec/ExampleLength:
|
56
13
|
Enabled: false
|
57
|
-
|
58
|
-
|
59
|
-
Include:
|
60
|
-
- spec/**/*.rb
|
61
|
-
Rails/InverseOf:
|
14
|
+
|
15
|
+
RSpec/NamedSubject:
|
62
16
|
Enabled: false
|
63
|
-
|
17
|
+
|
18
|
+
RSpec/MultipleExpectations:
|
64
19
|
Enabled: false
|
65
|
-
|
20
|
+
|
21
|
+
RSpec/VerifiedDoubles:
|
66
22
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.9.2
|
4
|
+
|
5
|
+
- Rubocop offenses resolved
|
6
|
+
- Sorbet signatures added to `RSpec::Sorbet::Doubles`
|
7
|
+
- Added `RSpec::Sorbet.reset!` to restore handlers to previous state
|
8
|
+
- Added fix to prevent `SystemStackError` by keeping track of when handlers have been configured. (thanks [@alex-tan](https://github.com/alex-tan))
|
9
|
+
- Added logic to pass type error onwards to existing inline type error handler.
|
10
|
+
- Slimmed down Gem RBIs to minimum needed for `srb tc` to pass in development.
|
11
|
+
|
3
12
|
## 1.9.1
|
4
13
|
|
5
14
|
- Support `T.nilable(T.class_of(...))` among others (thanks [@deecewan](https://github.com/deecewan))
|
data/Gemfile
CHANGED
@@ -1,21 +1,24 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
2
4
|
|
3
5
|
# Specify your gem's dependencies in rspec-sorbet.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
8
|
group :development, :test do
|
7
|
-
gem
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
13
|
-
gem
|
14
|
-
gem
|
15
|
-
gem
|
9
|
+
gem "guard-livereload", require: false
|
10
|
+
gem "guard-rspec"
|
11
|
+
gem "pry-byebug"
|
12
|
+
gem "rb-fsevent", require: false
|
13
|
+
gem "rspec"
|
14
|
+
gem "rubocop-rspec"
|
15
|
+
gem "rubocop-shopify"
|
16
|
+
gem "rubocop"
|
17
|
+
gem "stackprof"
|
18
|
+
gem "tapioca"
|
16
19
|
end
|
17
20
|
|
18
21
|
group :test do
|
19
|
-
gem
|
20
|
-
gem
|
22
|
+
gem "ffaker"
|
23
|
+
gem "rspec-github", require: false
|
21
24
|
end
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|

|
2
2
|
|
3
|
-
# RSpec Sorbet [](https://badge.fury.io/rb/rspec-sorbet) ](https://badge.fury.io/rb/rspec-sorbet) 
|
4
4
|
|
5
5
|
A small gem consisting of helpers for using Sorbet & RSpec together.
|
6
6
|
|
@@ -19,7 +19,7 @@ require 'rspec/sorbet'
|
|
19
19
|
|
20
20
|
Out of the box if you're using `instance_double`, `class_double` or `object_double` in your specs you'll encounter errors such as the following:
|
21
21
|
|
22
|
-
```
|
22
|
+
```ruby
|
23
23
|
TypeError:
|
24
24
|
Parameter 'my_parameter': Expected type MyObject, got type RSpec::Mocks::InstanceVerifyingDouble with value #<InstanceDouble(MyObject) (anonymous)>
|
25
25
|
Caller: /Users/samuelgiles/Documents/Projects/Clients/Bellroy/bellroy/spec/lib/checkout/use_cases/my_use_case.rb:9
|
@@ -33,7 +33,7 @@ RSpec::Sorbet.allow_doubles!
|
|
33
33
|
|
34
34
|
### `eq` matcher usage with `T::Struct`'s
|
35
35
|
|
36
|
-
Using the [`eq` matcher](https://www.rubydoc.info/github/rspec/rspec-expectations/RSpec%2FMatchers:eq) to compare [`T::Struct`'s](https://sorbet.org/docs/tstruct) might not behave as you'd expect whereby two separate instances of the same struct class with identical attributes are not `==` out of the box. The standalone [sorbet-struct-comparable](https://github.com/
|
36
|
+
Using the [`eq` matcher](https://www.rubydoc.info/github/rspec/rspec-expectations/RSpec%2FMatchers:eq) to compare [`T::Struct`'s](https://sorbet.org/docs/tstruct) might not behave as you'd expect whereby two separate instances of the same struct class with identical attributes are not `==` out of the box. The standalone [sorbet-struct-comparable](https://github.com/samuelgiles/sorbet-struct-comparable) gem may be of interest if you are looking for a simple attribute based comparison that will help make the `eq` matcher behave as you expect.
|
37
37
|
|
38
38
|
### Specifying a custom validation handler
|
39
39
|
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "rspec/sorbet"
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require 'rspec/sorbet'
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require "irb"
|
14
15
|
IRB.start(__FILE__)
|
data/bin/rbi
ADDED
data/bin/rspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/bin/rubocop
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "rubygems"
|
25
|
+
require "bundler/setup"
|
26
|
+
|
27
|
+
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/setup
CHANGED
data/bin/tapioca
CHANGED
@@ -9,8 +9,10 @@
|
|
9
9
|
#
|
10
10
|
|
11
11
|
require "pathname"
|
12
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
|
13
|
-
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
|
13
|
+
"../../Gemfile",
|
14
|
+
Pathname.new(__FILE__).realpath,
|
15
|
+
)
|
14
16
|
|
15
17
|
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
18
|
|
data/generate_require_files.rb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
BASE_FOLDER_PATH =
|
4
|
+
BASE_FOLDER_PATH = "rspec"
|
5
5
|
|
6
6
|
def directories_in(root)
|
7
7
|
Dir.entries(root).sort.select do |entry|
|
8
8
|
fully_qualified_entry = File.join(root, entry)
|
9
|
-
File.directory?(fully_qualified_entry) && ![
|
9
|
+
File.directory?(fully_qualified_entry) && ![".", ".."].include?(entry.to_s)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def files_in(root)
|
14
14
|
Dir.entries(root).sort.reject do |entry|
|
15
15
|
fully_qualified_entry = File.join(root, entry)
|
16
|
-
File.directory?(fully_qualified_entry) || entry.to_s ==
|
16
|
+
File.directory?(fully_qualified_entry) || entry.to_s == "all.rb" || entry[-3..-1] != ".rb"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def recursive_files_in(root)
|
21
|
-
full_paths = Dir.glob(File.join(root,
|
21
|
+
full_paths = Dir.glob(File.join(root, "**", "*")).sort.reject do |entry|
|
22
22
|
fully_qualified_entry = File.join(root, entry)
|
23
|
-
File.directory?(fully_qualified_entry) || entry[-7..-1] ==
|
23
|
+
File.directory?(fully_qualified_entry) || entry[-7..-1] == "/all.rb" || entry[-3..-1] != ".rb"
|
24
24
|
end
|
25
25
|
|
26
|
-
remove_path = root.split(
|
27
|
-
full_paths.map { |full_path| full_path.gsub(remove_path,
|
26
|
+
remove_path = root.split("/")[0..-2].join("/") + "/"
|
27
|
+
full_paths.map { |full_path| full_path.gsub(remove_path, "") }
|
28
28
|
end
|
29
29
|
|
30
30
|
def write_require_file(root, require_directories, require_files)
|
31
|
-
require_file_path = File.join(root,
|
32
|
-
File.open(require_file_path,
|
31
|
+
require_file_path = File.join(root, "all.rb")
|
32
|
+
File.open(require_file_path, "w") do |file|
|
33
33
|
file.write("# frozen_string_literal: true\n\n")
|
34
34
|
file.write("# THIS FILE IS AUTOGENERATED AND SHOULD NOT BE MANUALLY MODIFIED\n\n")
|
35
35
|
require_directories.each do |require_directory|
|
@@ -40,7 +40,7 @@ def write_require_file(root, require_directories, require_files)
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
root = File.join(__dir__,
|
43
|
+
root = File.join(__dir__, "lib", BASE_FOLDER_PATH)
|
44
44
|
directories = directories_in(root)
|
45
45
|
write_require_file(root, directories, files_in(root))
|
46
46
|
directories.each do |directory|
|
data/lib/rspec/all.rb
CHANGED
data/lib/rspec/sorbet/all.rb
CHANGED
data/lib/rspec/sorbet/doubles.rb
CHANGED
@@ -1,37 +1,82 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
4
|
+
require "sorbet-runtime"
|
5
5
|
|
6
6
|
module RSpec
|
7
7
|
module Sorbet
|
8
8
|
module Doubles
|
9
|
+
extend T::Sig
|
10
|
+
extend T::Helpers
|
11
|
+
|
12
|
+
requires_ancestor { Kernel }
|
13
|
+
|
14
|
+
sig { void }
|
9
15
|
def allow_doubles!
|
16
|
+
reset! if configured
|
17
|
+
|
18
|
+
self.existing_inline_type_error_handler = T::Configuration.instance_variable_get(
|
19
|
+
:@inline_type_error_handler,
|
20
|
+
)
|
10
21
|
T::Configuration.inline_type_error_handler = proc do |error|
|
11
22
|
inline_type_error_handler(error)
|
12
23
|
end
|
13
24
|
|
14
|
-
|
15
|
-
|
25
|
+
self.existing_call_validation_error_handler = T::Configuration.instance_variable_get(
|
26
|
+
:@call_validation_error_handler,
|
27
|
+
)
|
16
28
|
T::Configuration.call_validation_error_handler = proc do |signature, opts|
|
17
29
|
call_validation_error_handler(signature, opts)
|
18
30
|
end
|
31
|
+
|
32
|
+
self.configured = true
|
33
|
+
end
|
34
|
+
|
35
|
+
sig { params(clear_existing: T::Boolean).void }
|
36
|
+
def reset!(clear_existing: false)
|
37
|
+
if clear_existing
|
38
|
+
self.existing_inline_type_error_handler = nil
|
39
|
+
self.existing_call_validation_error_handler = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
T::Configuration.instance_variable_set(
|
43
|
+
:@inline_type_error_handler,
|
44
|
+
existing_inline_type_error_handler,
|
45
|
+
)
|
46
|
+
T::Configuration.instance_variable_set(
|
47
|
+
:@call_validation_error_handler,
|
48
|
+
existing_call_validation_error_handler,
|
49
|
+
)
|
50
|
+
|
51
|
+
self.configured = false
|
19
52
|
end
|
20
53
|
|
21
54
|
alias_method :allow_instance_doubles!, :allow_doubles!
|
22
55
|
|
23
56
|
private
|
24
57
|
|
25
|
-
|
26
|
-
|
58
|
+
sig { returns(T.nilable(T.proc.params(signature: Exception).void)) }
|
59
|
+
attr_accessor :existing_inline_type_error_handler
|
60
|
+
|
61
|
+
sig { returns(T.nilable(T.proc.params(signature: T.untyped, opts: T::Hash[T.untyped, T.untyped]).void)) }
|
62
|
+
attr_accessor :existing_call_validation_error_handler
|
27
63
|
|
64
|
+
sig { returns(T.nilable(T::Boolean)) }
|
65
|
+
attr_accessor :configured
|
28
66
|
|
67
|
+
# rubocop:disable Layout/LineLength
|
68
|
+
INLINE_DOUBLE_REGEX =
|
69
|
+
T.let(/T.(?:let|cast): Expected type (?:T.(?<t_method>any|nilable|class_of)\()*(?<expected_types>[a-zA-Z0-9:: ,]*)(\))*, got (?:type .* with value )?#<(?<double_type>Instance|Class|Object)?Double([\(]|[ ])(?<doubled_type>[a-zA-Z0-9:: ,]*)(\))?/.freeze, Regexp)
|
70
|
+
# rubocop:enable Layout/LineLength
|
71
|
+
|
72
|
+
sig { params(signature: T.untyped, opts: T.untyped).void }
|
29
73
|
def handle_call_validation_error(signature, opts)
|
30
|
-
raise TypeError, opts[:pretty_message] unless @
|
74
|
+
raise TypeError, opts[:pretty_message] unless @existing_call_validation_error_handler
|
31
75
|
|
32
|
-
@
|
76
|
+
@existing_call_validation_error_handler.call(signature, opts)
|
33
77
|
end
|
34
78
|
|
79
|
+
sig { params(error: Exception).void }
|
35
80
|
def inline_type_error_handler(error)
|
36
81
|
case error
|
37
82
|
when TypeError
|
@@ -41,15 +86,16 @@ module RSpec
|
|
41
86
|
raise error unless (match = message.match(INLINE_DOUBLE_REGEX))
|
42
87
|
|
43
88
|
t_method = match[:t_method]
|
44
|
-
expected_types = match[:expected_types].split(
|
89
|
+
expected_types = T.must(match[:expected_types]).split(",").map do |expected_type|
|
45
90
|
Object.const_get(expected_type.strip)
|
46
91
|
end
|
47
92
|
double_type = match[:double_type]
|
48
93
|
return if double_type.nil?
|
49
|
-
doubled_type = Object.const_get(match[:doubled_type])
|
50
94
|
|
51
|
-
|
52
|
-
|
95
|
+
doubled_type = Object.const_get(T.must(match[:doubled_type]))
|
96
|
+
|
97
|
+
if double_type == "Class"
|
98
|
+
raise error if t_method != "class_of"
|
53
99
|
|
54
100
|
valid = expected_types.any? do |expected_type|
|
55
101
|
doubled_type <= expected_type
|
@@ -64,30 +110,36 @@ module RSpec
|
|
64
110
|
else
|
65
111
|
raise error
|
66
112
|
end
|
113
|
+
|
114
|
+
existing_inline_type_error_handler&.call(error)
|
67
115
|
end
|
68
116
|
|
117
|
+
sig { params(message: String).returns(T::Boolean) }
|
69
118
|
def unable_to_check_type_for_message?(message)
|
70
119
|
double_message_with_ellipsis?(message) ||
|
71
120
|
typed_array_message?(message)
|
72
121
|
end
|
73
122
|
|
74
123
|
VERIFYING_DOUBLE_OR_DOUBLE =
|
75
|
-
/(RSpec::Mocks::(Instance|Class|Object)VerifyingDouble|(Instance|Class|Object)?Double)/.freeze
|
124
|
+
T.let(/(RSpec::Mocks::(Instance|Class|Object)VerifyingDouble|(Instance|Class|Object)?Double)/.freeze, Regexp)
|
76
125
|
|
126
|
+
sig { params(message: String).returns(T::Boolean) }
|
77
127
|
def double_message_with_ellipsis?(message)
|
78
|
-
message.include?(
|
128
|
+
message.include?("...") && message.match?(VERIFYING_DOUBLE_OR_DOUBLE)
|
79
129
|
end
|
80
130
|
|
81
|
-
TYPED_ARRAY_MESSAGE = /got T::Array/.freeze
|
131
|
+
TYPED_ARRAY_MESSAGE = T.let(/got T::Array/.freeze, Regexp)
|
82
132
|
|
133
|
+
sig { params(message: String).returns(T::Boolean) }
|
83
134
|
def typed_array_message?(message)
|
84
135
|
message.match?(TYPED_ARRAY_MESSAGE)
|
85
136
|
end
|
86
137
|
|
138
|
+
sig { params(signature: T.untyped, opts: T::Hash[T.untyped, T.untyped]).void }
|
87
139
|
def call_validation_error_handler(signature, opts)
|
88
140
|
should_raise = true
|
89
141
|
|
90
|
-
message = opts.fetch(:pretty_message, opts.fetch(:message,
|
142
|
+
message = opts.fetch(:pretty_message, opts.fetch(:message, ""))
|
91
143
|
if message.match?(VERIFYING_DOUBLE_OR_DOUBLE)
|
92
144
|
typing = opts[:type]
|
93
145
|
value = opts[:value].is_a?(Array) ? opts[:value].first : opts[:value]
|
data/lib/rspec/sorbet/version.rb
CHANGED
data/lib/rspec/sorbet.rb
CHANGED
data/rspec-sorbet.gemspec
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
|
4
|
-
require
|
6
|
+
require "rspec/sorbet/version"
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
9
|
+
spec.name = "rspec-sorbet"
|
8
10
|
spec.version = RSpec::Sorbet::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
+
spec.authors = ["Samuel Giles"]
|
12
|
+
spec.email = ["sam@samuelgil.es"]
|
11
13
|
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
14
|
+
spec.summary = "A small gem consisting of helpers for using Sorbet & RSpec together."
|
15
|
+
spec.homepage = "https://github.com/samuelgiles/rspec-sorbet"
|
16
|
+
spec.license = "MIT"
|
15
17
|
|
16
18
|
# Specify which files should be added to the gem when it is released.
|
17
19
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
-
spec.files =
|
20
|
+
spec.files = %x(git ls-files -z).split("\x0").reject do |f|
|
19
21
|
f.match(%r{^(sorbet|spec)/}) && !f.match(%r{^spec/support/factories/})
|
20
22
|
end
|
21
|
-
spec.bindir =
|
23
|
+
spec.bindir = "exe"
|
22
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
-
spec.require_paths = [
|
25
|
+
spec.require_paths = ["lib"]
|
24
26
|
|
25
|
-
spec.add_dependency
|
27
|
+
spec.add_dependency("sorbet-runtime")
|
26
28
|
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
29
|
+
spec.add_development_dependency("bundler")
|
30
|
+
spec.add_development_dependency("pry")
|
31
|
+
spec.add_development_dependency("rake", ">= 13.0")
|
32
|
+
spec.add_development_dependency("rspec", ">= 3.0")
|
33
|
+
spec.add_development_dependency("sorbet")
|
32
34
|
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.9.
|
4
|
+
version: 1.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Giles
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|
@@ -94,13 +94,14 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description:
|
97
|
+
description:
|
98
98
|
email:
|
99
|
-
-
|
99
|
+
- sam@samuelgil.es
|
100
100
|
executables: []
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
+
- ".devcontainer/devcontainer.json"
|
104
105
|
- ".github/workflows/ci.yml"
|
105
106
|
- ".gitignore"
|
106
107
|
- ".rspec"
|
@@ -111,6 +112,9 @@ files:
|
|
111
112
|
- README.md
|
112
113
|
- Rakefile
|
113
114
|
- bin/console
|
115
|
+
- bin/rbi
|
116
|
+
- bin/rspec
|
117
|
+
- bin/rubocop
|
114
118
|
- bin/setup
|
115
119
|
- bin/tapioca
|
116
120
|
- generate_require_files.rb
|
@@ -119,16 +123,12 @@ files:
|
|
119
123
|
- lib/rspec/sorbet/all.rb
|
120
124
|
- lib/rspec/sorbet/doubles.rb
|
121
125
|
- lib/rspec/sorbet/version.rb
|
122
|
-
- nix/sources.json
|
123
|
-
- nix/sources.nix
|
124
126
|
- rspec-sorbet.gemspec
|
125
|
-
|
126
|
-
- shell.nix
|
127
|
-
homepage: https://github.com/tricycle/rspec-sorbet
|
127
|
+
homepage: https://github.com/samuelgiles/rspec-sorbet
|
128
128
|
licenses:
|
129
129
|
- MIT
|
130
130
|
metadata: {}
|
131
|
-
post_install_message:
|
131
|
+
post_install_message:
|
132
132
|
rdoc_options: []
|
133
133
|
require_paths:
|
134
134
|
- lib
|
@@ -143,8 +143,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
145
|
requirements: []
|
146
|
-
rubygems_version: 3.
|
147
|
-
signing_key:
|
146
|
+
rubygems_version: 3.3.26
|
147
|
+
signing_key:
|
148
148
|
specification_version: 4
|
149
149
|
summary: A small gem consisting of helpers for using Sorbet & RSpec together.
|
150
150
|
test_files: []
|
data/nix/sources.json
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"nixpkgs": {
|
3
|
-
"branch": "nixos-22.05",
|
4
|
-
"description": "Nix packages collection",
|
5
|
-
"homepage": "https://github.com/NixOS/nixpkgs",
|
6
|
-
"owner": "NixOS",
|
7
|
-
"repo": "nixpkgs",
|
8
|
-
"rev": "1935dd8fdab8e022a9d958419663162fd840014c",
|
9
|
-
"sha256": "1z0nkqpwahlaz362lcdx5qcdvwdzr5a3bdfirjgbf9jg37rsbwl2",
|
10
|
-
"type": "tarball",
|
11
|
-
"url": "https://github.com/NixOS/nixpkgs/archive/1935dd8fdab8e022a9d958419663162fd840014c.tar.gz",
|
12
|
-
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
13
|
-
}
|
14
|
-
}
|
data/nix/sources.nix
DELETED
@@ -1,194 +0,0 @@
|
|
1
|
-
# This file has been generated by Niv.
|
2
|
-
|
3
|
-
let
|
4
|
-
|
5
|
-
#
|
6
|
-
# The fetchers. fetch_<type> fetches specs of type <type>.
|
7
|
-
#
|
8
|
-
|
9
|
-
fetch_file = pkgs: name: spec:
|
10
|
-
let
|
11
|
-
name' = sanitizeName name + "-src";
|
12
|
-
in
|
13
|
-
if spec.builtin or true then
|
14
|
-
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
|
15
|
-
else
|
16
|
-
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
|
17
|
-
|
18
|
-
fetch_tarball = pkgs: name: spec:
|
19
|
-
let
|
20
|
-
name' = sanitizeName name + "-src";
|
21
|
-
in
|
22
|
-
if spec.builtin or true then
|
23
|
-
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
|
24
|
-
else
|
25
|
-
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
|
26
|
-
|
27
|
-
fetch_git = name: spec:
|
28
|
-
let
|
29
|
-
ref =
|
30
|
-
if spec ? ref then spec.ref else
|
31
|
-
if spec ? branch then "refs/heads/${spec.branch}" else
|
32
|
-
if spec ? tag then "refs/tags/${spec.tag}" else
|
33
|
-
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
|
34
|
-
submodules = if spec ? submodules then spec.submodules else false;
|
35
|
-
submoduleArg =
|
36
|
-
let
|
37
|
-
nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
|
38
|
-
emptyArgWithWarning =
|
39
|
-
if submodules == true
|
40
|
-
then
|
41
|
-
builtins.trace
|
42
|
-
(
|
43
|
-
"The niv input \"${name}\" uses submodules "
|
44
|
-
+ "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
|
45
|
-
+ "does not support them"
|
46
|
-
)
|
47
|
-
{}
|
48
|
-
else {};
|
49
|
-
in
|
50
|
-
if nixSupportsSubmodules
|
51
|
-
then { inherit submodules; }
|
52
|
-
else emptyArgWithWarning;
|
53
|
-
in
|
54
|
-
builtins.fetchGit
|
55
|
-
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
|
56
|
-
|
57
|
-
fetch_local = spec: spec.path;
|
58
|
-
|
59
|
-
fetch_builtin-tarball = name: throw
|
60
|
-
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
|
61
|
-
$ niv modify ${name} -a type=tarball -a builtin=true'';
|
62
|
-
|
63
|
-
fetch_builtin-url = name: throw
|
64
|
-
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
|
65
|
-
$ niv modify ${name} -a type=file -a builtin=true'';
|
66
|
-
|
67
|
-
#
|
68
|
-
# Various helpers
|
69
|
-
#
|
70
|
-
|
71
|
-
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
|
72
|
-
sanitizeName = name:
|
73
|
-
(
|
74
|
-
concatMapStrings (s: if builtins.isList s then "-" else s)
|
75
|
-
(
|
76
|
-
builtins.split "[^[:alnum:]+._?=-]+"
|
77
|
-
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
|
78
|
-
)
|
79
|
-
);
|
80
|
-
|
81
|
-
# The set of packages used when specs are fetched using non-builtins.
|
82
|
-
mkPkgs = sources: system:
|
83
|
-
let
|
84
|
-
sourcesNixpkgs =
|
85
|
-
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
|
86
|
-
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
|
87
|
-
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
|
88
|
-
in
|
89
|
-
if builtins.hasAttr "nixpkgs" sources
|
90
|
-
then sourcesNixpkgs
|
91
|
-
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
|
92
|
-
import <nixpkgs> {}
|
93
|
-
else
|
94
|
-
abort
|
95
|
-
''
|
96
|
-
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
|
97
|
-
add a package called "nixpkgs" to your sources.json.
|
98
|
-
'';
|
99
|
-
|
100
|
-
# The actual fetching function.
|
101
|
-
fetch = pkgs: name: spec:
|
102
|
-
|
103
|
-
if ! builtins.hasAttr "type" spec then
|
104
|
-
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
|
105
|
-
else if spec.type == "file" then fetch_file pkgs name spec
|
106
|
-
else if spec.type == "tarball" then fetch_tarball pkgs name spec
|
107
|
-
else if spec.type == "git" then fetch_git name spec
|
108
|
-
else if spec.type == "local" then fetch_local spec
|
109
|
-
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
|
110
|
-
else if spec.type == "builtin-url" then fetch_builtin-url name
|
111
|
-
else
|
112
|
-
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
|
113
|
-
|
114
|
-
# If the environment variable NIV_OVERRIDE_${name} is set, then use
|
115
|
-
# the path directly as opposed to the fetched source.
|
116
|
-
replace = name: drv:
|
117
|
-
let
|
118
|
-
saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
|
119
|
-
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
|
120
|
-
in
|
121
|
-
if ersatz == "" then drv else
|
122
|
-
# this turns the string into an actual Nix path (for both absolute and
|
123
|
-
# relative paths)
|
124
|
-
if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
|
125
|
-
|
126
|
-
# Ports of functions for older nix versions
|
127
|
-
|
128
|
-
# a Nix version of mapAttrs if the built-in doesn't exist
|
129
|
-
mapAttrs = builtins.mapAttrs or (
|
130
|
-
f: set: with builtins;
|
131
|
-
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
|
132
|
-
);
|
133
|
-
|
134
|
-
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
|
135
|
-
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
|
136
|
-
|
137
|
-
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
|
138
|
-
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
|
139
|
-
|
140
|
-
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
|
141
|
-
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
|
142
|
-
concatMapStrings = f: list: concatStrings (map f list);
|
143
|
-
concatStrings = builtins.concatStringsSep "";
|
144
|
-
|
145
|
-
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
|
146
|
-
optionalAttrs = cond: as: if cond then as else {};
|
147
|
-
|
148
|
-
# fetchTarball version that is compatible between all the versions of Nix
|
149
|
-
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
|
150
|
-
let
|
151
|
-
inherit (builtins) lessThan nixVersion fetchTarball;
|
152
|
-
in
|
153
|
-
if lessThan nixVersion "1.12" then
|
154
|
-
fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
|
155
|
-
else
|
156
|
-
fetchTarball attrs;
|
157
|
-
|
158
|
-
# fetchurl version that is compatible between all the versions of Nix
|
159
|
-
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
|
160
|
-
let
|
161
|
-
inherit (builtins) lessThan nixVersion fetchurl;
|
162
|
-
in
|
163
|
-
if lessThan nixVersion "1.12" then
|
164
|
-
fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
|
165
|
-
else
|
166
|
-
fetchurl attrs;
|
167
|
-
|
168
|
-
# Create the final "sources" from the config
|
169
|
-
mkSources = config:
|
170
|
-
mapAttrs (
|
171
|
-
name: spec:
|
172
|
-
if builtins.hasAttr "outPath" spec
|
173
|
-
then abort
|
174
|
-
"The values in sources.json should not have an 'outPath' attribute"
|
175
|
-
else
|
176
|
-
spec // { outPath = replace name (fetch config.pkgs name spec); }
|
177
|
-
) config.sources;
|
178
|
-
|
179
|
-
# The "config" used by the fetchers
|
180
|
-
mkConfig =
|
181
|
-
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
|
182
|
-
, sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
|
183
|
-
, system ? builtins.currentSystem
|
184
|
-
, pkgs ? mkPkgs sources system
|
185
|
-
}: rec {
|
186
|
-
# The sources, i.e. the attribute set of spec name to spec
|
187
|
-
inherit sources;
|
188
|
-
|
189
|
-
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
|
190
|
-
inherit pkgs;
|
191
|
-
};
|
192
|
-
|
193
|
-
in
|
194
|
-
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
|
data/run_ci.sh
DELETED
data/shell.nix
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
{ sources ? import ./nix/sources.nix }:
|
2
|
-
let
|
3
|
-
nixpkgs = import sources.nixpkgs { };
|
4
|
-
in
|
5
|
-
nixpkgs.mkShell {
|
6
|
-
name = "bellroy-gem-env";
|
7
|
-
buildInputs = with nixpkgs; [
|
8
|
-
bundler
|
9
|
-
libnotify
|
10
|
-
niv
|
11
|
-
pkg-config
|
12
|
-
readline
|
13
|
-
ruby_2_7
|
14
|
-
zlib
|
15
|
-
]
|
16
|
-
++ (if stdenv.hostPlatform.isDarwin then [ libiconv darwin.apple_sdk.frameworks.CoreServices ] else [ ]);
|
17
|
-
shellHook = ''
|
18
|
-
bundle config --local path "$PWD/vendor/bundle"
|
19
|
-
'';
|
20
|
-
}
|