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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c919fffe36f51d10375e595ccb204bc198e25cf8315e266b58ac003e5a3044e3
4
- data.tar.gz: e9f7fd2ebc16cbfb02a35386e6e18167e4c2d7135d892818cfef0828bbac3d29
3
+ metadata.gz: 1e49df5d697e2d441b06483b44261e8edb5ac59b7003c5356d88d6be106db79e
4
+ data.tar.gz: 17aebafd7cd92d511915bced0d87279e8a0a271ba4ed593a7cdd465c5514c31c
5
5
  SHA512:
6
- metadata.gz: 036dc3f8f4fe03014d3fd841c3db206cb3f4d044238f995f204ea66379763e1dd4f66882fd87571eaf1fa5a473af3b4dd28cdd943d7ff1dfb902b03ef1849b86
7
- data.tar.gz: bfaa969a76685774eedbceb4842b977a3bdb39dc48055035a93c85b53cf9a7029b9f6592722307a96d0b03ac2ff51ed0d5b406012469334eaf92c11f3bfd855c
6
+ metadata.gz: 0d37e33a3218ebde8de313aa0707c690f1d06c28b04f552dcc6611d09334d52b73a4aeafc50b132fdc7c1266f1a430a2affffc17928857ecebdefa788e081fa6
7
+ data.tar.gz: 777a239771115649469b1eff69936a5bd64c1815915ee322300028864d44092481d94b637c0b778b85020a965b900af7d3414ab903dc0ee703cd4dfabc18c47d
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "Ruby",
3
+ "image": "mcr.microsoft.com/devcontainers/ruby:0-3.1",
4
+ "postCreateCommand": "bin/setup"
5
+ }
@@ -1,50 +1,24 @@
1
- ---
2
1
  name: Continuous Integration
3
- env:
4
- SLACK_CHANNEL_ID: C0317P7C9C2
5
- on:
6
- push:
7
- branches-ignore:
8
- - refs/tags/*_staging
9
- - refs/tags/*_production
2
+
3
+ on: push
4
+
5
+ permissions:
6
+ contents: read
7
+
10
8
  jobs:
11
- build:
12
- runs-on: ubuntu-18.04
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ ruby-version: ['3.1']
13
14
  steps:
14
- - name: Checkout branch
15
- uses: actions/checkout@v2
16
- - name: Extract branch name
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
- path: vendor/bundle
24
- key: "${{ runner.OS }}-gem-cache-${{ hashFiles('**/*.gemspec')
25
- }}"
26
- restore-keys: "${{ runner.OS }}-gem-cache-\n"
27
- - uses: "cachix/install-nix-action@8d6d5e949675fbadb765c6b1a975047fa5f09b27"
28
- with:
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
- Documentation:
3
- Enabled: false
4
- Rails:
5
- Enabled: true
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
+ require: rubocop-rspec
4
+
6
5
  AllCops:
7
- Include:
8
- - app/**/*.rb
9
- - lib/**/*.rb
10
- - spec/**/*.rb
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
- RSpec/MissingExampleGroupArgument:
46
- Enabled: false
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
- RSpec/AggregateFailures:
58
- Enabled: true
59
- Include:
60
- - spec/**/*.rb
61
- Rails/InverseOf:
14
+
15
+ RSpec/NamedSubject:
62
16
  Enabled: false
63
- Rails/Present:
17
+
18
+ RSpec/MultipleExpectations:
64
19
  Enabled: false
65
- Rails/TimeZone:
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
- source 'https://rubygems.org'
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 'guard-livereload', require: false
8
- gem 'guard-rspec'
9
- gem 'pry-byebug'
10
- gem 'rb-fsevent', require: false
11
- gem 'rspec'
12
- gem 'rubocop-rspec'
13
- gem 'rubocop'
14
- gem 'stackprof'
15
- gem 'tapioca'
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 'ffaker'
20
- gem 'simplecov'
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/tricycle/rspec-sorbet/workflows/Continuous%20Integration/badge.svg)
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/tricycle/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.
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
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'bundler/setup'
4
- require 'rspec/sorbet'
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 'irb'
14
+ require "irb"
14
15
  IRB.start(__FILE__)
data/bin/rbi ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bin/tapioca gems rspec-core rspec-expectations rspec-github rspec-support rspec
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
@@ -4,5 +4,3 @@ IFS=$'\n\t'
4
4
  set -vx
5
5
 
6
6
  bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/bin/tapioca CHANGED
@@ -9,8 +9,10 @@
9
9
  #
10
10
 
11
11
  require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
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
 
@@ -1,35 +1,35 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- BASE_FOLDER_PATH = 'rspec'
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) && !['.', '..'].include?(entry.to_s)
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 == 'all.rb' || entry[-3..-1] != '.rb'
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, '**', '*')).sort.reject do |entry|
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] == '/all.rb' || entry[-3..-1] != '.rb'
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('/')[0..-2].join('/') + '/'
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, 'all.rb')
32
- File.open(require_file_path, 'w') do |file|
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__, 'lib', BASE_FOLDER_PATH)
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
@@ -3,6 +3,6 @@
3
3
 
4
4
  # THIS FILE IS AUTOGENERATED AND SHOULD NOT BE MANUALLY MODIFIED
5
5
 
6
- require 'rspec/sorbet/all'
6
+ require "rspec/sorbet/all"
7
7
 
8
- require 'rspec/sorbet'
8
+ require "rspec/sorbet"
@@ -3,5 +3,5 @@
3
3
 
4
4
  # THIS FILE IS AUTOGENERATED AND SHOULD NOT BE MANUALLY MODIFIED
5
5
 
6
- require 'rspec/sorbet/doubles'
7
- require 'rspec/sorbet/version'
6
+ require "rspec/sorbet/doubles"
7
+ require "rspec/sorbet/version"
@@ -1,37 +1,82 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'sorbet-runtime'
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
- @existing_handler = T::Configuration.instance_variable_get(:@call_validation_error_handler)
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
- INLINE_DOUBLE_REGEX =
26
- /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
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 @existing_handler
74
+ raise TypeError, opts[:pretty_message] unless @existing_call_validation_error_handler
31
75
 
32
- @existing_handler.call(signature, opts)
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(',').map do |expected_type|
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
- if double_type == 'Class'
52
- raise error if t_method != 'class_of'
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?('...') && message.match?(VERIFYING_DOUBLE_OR_DOUBLE)
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]
@@ -3,6 +3,6 @@
3
3
 
4
4
  module RSpec
5
5
  module Sorbet
6
- VERSION = '1.9.1'
6
+ VERSION = "1.9.2"
7
7
  end
8
8
  end
data/lib/rspec/sorbet.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'rspec/sorbet/doubles'
4
+ require "rspec/sorbet/doubles"
5
5
 
6
6
  module RSpec
7
7
  module Sorbet
data/rspec-sorbet.gemspec CHANGED
@@ -1,32 +1,34 @@
1
- lib = File.expand_path('lib', __dir__)
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 'rspec/sorbet/version'
6
+ require "rspec/sorbet/version"
5
7
 
6
8
  Gem::Specification.new do |spec|
7
- spec.name = 'rspec-sorbet'
9
+ spec.name = "rspec-sorbet"
8
10
  spec.version = RSpec::Sorbet::VERSION
9
- spec.authors = ['Samuel Giles']
10
- spec.email = ['samuel.giles@bellroy.com']
11
+ spec.authors = ["Samuel Giles"]
12
+ spec.email = ["sam@samuelgil.es"]
11
13
 
12
- spec.summary = 'A small gem consisting of helpers for using Sorbet & RSpec together.'
13
- spec.homepage = 'https://github.com/tricycle/rspec-sorbet'
14
- spec.license = 'MIT'
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 = `git ls-files -z`.split("\x0").reject do |f|
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 = 'exe'
23
+ spec.bindir = "exe"
22
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
- spec.require_paths = ['lib']
25
+ spec.require_paths = ["lib"]
24
26
 
25
- spec.add_dependency 'sorbet-runtime'
27
+ spec.add_dependency("sorbet-runtime")
26
28
 
27
- spec.add_development_dependency 'bundler'
28
- spec.add_development_dependency 'pry'
29
- spec.add_development_dependency 'rake', '>= 13.0'
30
- spec.add_development_dependency 'rspec', '>= 3.0'
31
- spec.add_development_dependency 'sorbet'
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.1
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: 1980-01-01 00:00:00.000000000 Z
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
- - samuel.giles@bellroy.com
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
- - run_ci.sh
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.2.26
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
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -e
3
- rm -f Gemfile.lock
4
- bundle config gem.fury.io $GEMFURY_DEPLOY_TOKEN
5
- bundle install
6
- bundle exec srb tc
7
- METRICS=1 bundle exec rspec spec
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
- }