rspec-sorbet 1.9.1 → 1.9.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![rspec-sorbet](https://user-images.githubusercontent.com/2643026/63100456-02c12c00-bf6f-11e9-8430-630a27bc6e42.png)
|
2
2
|
|
3
|
-
# RSpec Sorbet [![Gem Version](https://badge.fury.io/rb/rspec-sorbet.svg)](https://badge.fury.io/rb/rspec-sorbet) ![CI Badge](https://github.com/
|
3
|
+
# RSpec Sorbet [![Gem Version](https://badge.fury.io/rb/rspec-sorbet.svg)](https://badge.fury.io/rb/rspec-sorbet) ![CI Badge](https://github.com/samuelgiles/rspec-sorbet/workflows/Continuous%20Integration/badge.svg)
|
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
|
-
}
|