redis-promise 0.1.0

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +74 -0
  3. data/CHANGELOG.md +19 -0
  4. data/LICENSE +21 -0
  5. data/README.md +151 -0
  6. data/Rakefile +12 -0
  7. data/lib/redis/promise/resolver.rb +47 -0
  8. data/lib/redis/promise/resque.rb +49 -0
  9. data/lib/redis/promise/version.rb +8 -0
  10. data/lib/redis/promise.rb +83 -0
  11. data/sorbet/config +7 -0
  12. data/sorbet/rbi/annotations/.gitattributes +1 -0
  13. data/sorbet/rbi/annotations/minitest.rbi +120 -0
  14. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  15. data/sorbet/rbi/gems/.gitattributes +1 -0
  16. data/sorbet/rbi/gems/ast@2.4.3.rbi +586 -0
  17. data/sorbet/rbi/gems/byebug@13.0.0.rbi +37 -0
  18. data/sorbet/rbi/gems/connection_pool@3.0.2.rbi +340 -0
  19. data/sorbet/rbi/gems/date@3.5.1.rbi +403 -0
  20. data/sorbet/rbi/gems/erb@6.0.4.rbi +814 -0
  21. data/sorbet/rbi/gems/io-console@0.8.2.rbi +9 -0
  22. data/sorbet/rbi/gems/json@2.19.5.rbi +2250 -0
  23. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +323 -0
  24. data/sorbet/rbi/gems/minitest@5.27.0.rbi +1549 -0
  25. data/sorbet/rbi/gems/parallel@2.1.0.rbi +359 -0
  26. data/sorbet/rbi/gems/pp@0.6.3.rbi +388 -0
  27. data/sorbet/rbi/gems/prettyprint@0.2.0.rbi +477 -0
  28. data/sorbet/rbi/gems/psych@5.3.1.rbi +2555 -0
  29. data/sorbet/rbi/gems/racc@1.8.1.rbi +168 -0
  30. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
  31. data/sorbet/rbi/gems/rake@13.4.2.rbi +3258 -0
  32. data/sorbet/rbi/gems/redis-client@0.29.0.rbi +1203 -0
  33. data/sorbet/rbi/gems/redis@5.4.1.rbi +3552 -0
  34. data/sorbet/rbi/gems/reline@0.6.3.rbi +2995 -0
  35. data/sorbet/rbi/gems/rubocop-espago@1.2.0.rbi +9 -0
  36. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
  37. data/sorbet/rbi/gems/shoulda-context@2.0.0.rbi +563 -0
  38. data/sorbet/rbi/gems/stringio@3.2.0.rbi +9 -0
  39. data/sorbet/rbi/gems/tsort@0.2.0.rbi +393 -0
  40. data/sorbet/rbi/gems/unicode-display_width@3.2.0.rbi +132 -0
  41. data/sorbet/rbi/gems/unicode-emoji@4.2.0.rbi +254 -0
  42. data/sorbet/rbi/shims/gems/resque.rbi +9 -0
  43. data/sorbet/rbi/shims/gems/shoulda-context.rbi +16 -0
  44. data/sorbet/rbi/todo.rbi +5 -0
  45. data/sorbet/tapioca/config.yml +31 -0
  46. data/sorbet/tapioca/extensions/load_gem.rb +1 -0
  47. data/sorbet/tapioca/require.rb +5 -0
  48. metadata +117 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b87c0c0b6399954b74fb54514c2e7b97cb800a5cf6b18025d80cbdcf084d6402
4
+ data.tar.gz: de74a5dc0a7e53dfa122af59ec5410a0cb4addeacd848695b14d9da8eecbee70
5
+ SHA512:
6
+ metadata.gz: bdd765fc640c834fb59eb97e1eda6bb59e8b5623f348ebbb677f5c1e067103824b64f192f89d5f302287e6e1a16b44503e251a2e751358be1d1dc83bf3a576d8
7
+ data.tar.gz: '080b8d58f3ad11e1305d9575d8393561584a7a452a04c1a7f2168216ba1371fb13346357d12586df60a8b2e0fb173a9cd221a24a292b1922b55700a441208d63'
@@ -0,0 +1,74 @@
1
+ name: CI Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main", "develop" ]
6
+ pull_request:
7
+ branches: [ "main", "develop" ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ services:
13
+ # Label used to access the service container
14
+ redis:
15
+ # Docker Hub image
16
+ image: redis
17
+ # Set health checks to wait until redis has started
18
+ options: >-
19
+ --health-cmd "redis-cli ping"
20
+ --health-interval 10s
21
+ --health-timeout 5s
22
+ --health-retries 5
23
+ ports:
24
+ # Maps port 6379 on service container to the host
25
+ - 6379:6379
26
+ env:
27
+ CI: true
28
+ # The hostname used to communicate with the Redis service container
29
+ REDIS_HOST: localhost
30
+ # The default Redis port
31
+ REDIS_PORT: 6379
32
+ strategy:
33
+ matrix:
34
+ ruby-version: [ "3.3", "3.4", "4.0" ]
35
+ steps:
36
+ - name: Checkout code
37
+ uses: actions/checkout@v3
38
+ - name: Install Ruby and gems
39
+ uses: ruby/setup-ruby@v1
40
+ with:
41
+ ruby-version: ${{ matrix.ruby-version }}
42
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
43
+ - name: Run unit tests
44
+ run: bundle exec rake test
45
+
46
+ lint:
47
+ runs-on: ubuntu-latest
48
+ env:
49
+ CI: true
50
+ steps:
51
+ - name: Checkout code
52
+ uses: actions/checkout@v3
53
+ - name: Install Ruby and gems
54
+ uses: ruby/setup-ruby@v1
55
+ with:
56
+ ruby-version: "4.0"
57
+ bundler-cache: true
58
+ - name: Lint Ruby files
59
+ run: bundle exec rubocop --parallel
60
+
61
+ typecheck:
62
+ runs-on: ubuntu-latest
63
+ env:
64
+ CI: true
65
+ steps:
66
+ - name: Checkout code
67
+ uses: actions/checkout@v3
68
+ - name: Install Ruby and gems
69
+ uses: ruby/setup-ruby@v1
70
+ with:
71
+ ruby-version: "4.0"
72
+ bundler-cache: true
73
+ - name: Typecheck Ruby files
74
+ run: bundle exec srb tc
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ Add changes in new features here. Do not change the gem's version in pull/merge requests.
11
+
12
+ ### Changes
13
+ -
14
+
15
+ ## [0.1.0] - 22.05.2026
16
+
17
+ [Diff](https://github.com/Verseth/ruby-redis-promise/compare/v0.0.0...v0.1.0)
18
+
19
+ - Initial release
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mateusz Drewniak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # Redis::Promise
2
+
3
+ This Ruby gem adds promises built on Redis.
4
+ It enables you to resolve or reject a redis promise based on a key and
5
+ await the result in another thread or on another machine/service.
6
+
7
+ It can be used in tandem with job frameworks like `resque` or `sidekiq` in order
8
+ to get back a result from an asynchronous task.
9
+
10
+ ## Installation
11
+
12
+ Install the gem and add to the application's Gemfile by executing:
13
+
14
+ ```bash
15
+ bundle add redis-promise
16
+ ```
17
+
18
+ If bundler is not being used to manage dependencies, install the gem by executing:
19
+
20
+ ```bash
21
+ gem install redis-promise
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ This library adds two basic types `Redis::Promise` and `Redis::Promise::Resolver`.
27
+ The Promise object can be used to await a resolved (success) value or a rejected (error) value.
28
+ The Resolver object can be used to resolve or reject a promise. These two objects are tied together by a common redis key where the result gets stored.
29
+
30
+ The basic idea is that you use a `Redis::Promise::Resolver` to resolve/reject the promise in one context eg. a thread or a different service. You then use `Redis::Promise` in another context to get (await) the value.
31
+
32
+ ### Threads
33
+
34
+ Using the `Redis::Promise::create` helper to create a promise
35
+ and its resolver at the same time.
36
+
37
+ ```rb
38
+ require 'redis/promise'
39
+
40
+ redis = Redis.new
41
+ promise, resolver = Redis::Promise.create(redis)
42
+
43
+ threads = []
44
+ threads << Thread.new do
45
+ sleep(3)
46
+ resolver.resolve("OK!")
47
+ end
48
+
49
+ threads << Thread.new do
50
+ result = promise.await #=> "OK!"
51
+ end
52
+
53
+ threads.each(&:join)
54
+ # should print "OK!" after 3 seconds
55
+ ```
56
+
57
+ Creating a separate promise and resolver.
58
+ Notice that the promise and resolver have to get their own
59
+ Redis connection instances, that's because the `promise.await`
60
+ blocks the entire redis connection making it impossible to resolve
61
+ the promise using the same connection.
62
+
63
+ ```rb
64
+ require 'redis/promise'
65
+
66
+ redis = Redis.new
67
+ threads = []
68
+
69
+ promise = Redis::Promise.new(redis)
70
+ threads << Thread.new do
71
+ puts promise.await #=> "OK!"
72
+ end
73
+
74
+ resolver = Redis::Promise::Resolver.new(redis, key: promise.key)
75
+ threads << Thread.new do
76
+ sleep(3)
77
+ resolver.resolve("OK!")
78
+ end
79
+
80
+ threads.each(&:join)
81
+ ```
82
+
83
+ ### Resque
84
+
85
+ You could use it in resque or any other job system to get the result from an asynchronous task.
86
+
87
+ ```rb
88
+ # ========
89
+ # job definition
90
+
91
+ class SomeJob
92
+ @queue = :example
93
+
94
+ def self.perform(promise_key)
95
+ resolver = Redis::Promise::Resolver.new(
96
+ Resque.redis,
97
+ key: promise_key,
98
+ )
99
+ resolver.resolve(42)
100
+ end
101
+ end
102
+
103
+ # ========
104
+ # some other place in the app
105
+
106
+ promise = Redis::Promise.new(Resque.redis)
107
+ Resque.enqueue(SomeJob, promise.key)
108
+
109
+ promise.await #=> 42
110
+ # you got a value back from a resque job!
111
+ ```
112
+
113
+ #### Plugin
114
+
115
+ There is an additional resque plugin you can load
116
+ to make it more convenient.
117
+
118
+ ```rb
119
+ require 'redis/promise/resque'
120
+
121
+ class SomeJob
122
+ include Redis::Promise::Resque
123
+
124
+ @queue = :example
125
+
126
+ run do |n|
127
+ raise ArgumentError, "number must be positive: #{n}" if n < 0
128
+
129
+ n * 69
130
+ end
131
+ end
132
+
133
+ # enqueueing returns a promise
134
+ promise = SomeJob.enqueue(42)
135
+ promise.await #=> 2898
136
+
137
+ # errors thrown in the job get caught and rethrown on await
138
+ promise = SomeJob.enqueue(-2)
139
+ promise.await
140
+ #! Redis::Promise::RejectedError(value: "[ArgumentError]: number must be positive: -2")
141
+ ```
142
+
143
+ ## Development
144
+
145
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
146
+
147
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
148
+
149
+ ## Contributing
150
+
151
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Verseth/ruby-redis-promise.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'minitest/test_task'
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test rubocop]
@@ -0,0 +1,47 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ class Redis
5
+ class Promise
6
+ # An object used to resolve or reject
7
+ # a redis promise.
8
+ class Resolver
9
+ #: Redis
10
+ attr_reader :redis
11
+
12
+ #: String
13
+ attr_reader :key
14
+
15
+ #: (Redis, ?id: String, ?namespace: String, ?key: String) -> void
16
+ def initialize(redis, id: SecureRandom.uuid_v4, namespace: 'global', key: "promise:#{namespace}:#{id}")
17
+ @redis = redis.dup #: Redis
18
+ @key = key
19
+ end
20
+
21
+ # Resolve the promise with the given value.
22
+ # The value gets serialized to JSON using `to_json`.
23
+ #
24
+ #: (top) -> void
25
+ def resolve(value)
26
+ serialized = { value: value }.to_json
27
+ push(serialized)
28
+ end
29
+
30
+ # Reject the promise with the given value.
31
+ # The value gets serialized to JSON using `to_json`.
32
+ #
33
+ #: (top) -> void
34
+ def reject(err)
35
+ serialized = { err: err }.to_json
36
+ push(serialized)
37
+ end
38
+
39
+ private
40
+
41
+ #: (String) -> void
42
+ def push(serialized)
43
+ @redis.rpush(@key, serialized)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,49 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class Redis
5
+ class Promise
6
+ # An additional mixin for Resque jobs.
7
+ module Resque
8
+ extend T::Helpers
9
+
10
+ # Thrown when an invalid resque job class
11
+ # was used to enqueue a promise
12
+ class InvalidJobError < Error; end
13
+
14
+ # @requires_ancestor: Kernel
15
+ module ClassMethods
16
+ #: -> Redis
17
+ def promise_redis = ::Resque.redis
18
+
19
+ #: (*top) -> Promise
20
+ def enqueue(*args)
21
+ promise = Promise.new(promise_redis)
22
+ T.unsafe(::Resque).enqueue(self, promise.key, *args) # rubocop:disable Sorbet/ForbidTUnsafe
23
+
24
+ promise
25
+ end
26
+
27
+ #: (String, *untyped) -> void
28
+ def perform(promise_key, *args); end
29
+
30
+ #: { (untyped) -> void } -> void
31
+ def run(&block)
32
+ define_singleton_method :perform do |promise_key, *args|
33
+ promise = Promise::Resolver.new(promise_redis, key: promise_key)
34
+
35
+ begin
36
+ result = block.call(*args)
37
+ promise.resolve(result)
38
+ rescue StandardError => e
39
+ promise.reject("[#{e.class}]: #{e.message}")
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+ mixes_in_class_methods(ClassMethods)
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ class Redis
5
+ class Promise # rubocop:disable Style/StaticClass
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
@@ -0,0 +1,83 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require 'redis'
5
+ require 'json'
6
+ require 'securerandom'
7
+ require 'sorbet-runtime'
8
+ require_relative 'promise/version'
9
+ require_relative 'promise/resolver'
10
+
11
+ class Redis
12
+ # An object used to wait for a value or an error
13
+ # from redis.
14
+ class Promise
15
+ # Base error for `Redis::Promise`
16
+ class Error < StandardError; end
17
+ # Thrown when the timeout has been exceeded while
18
+ # awaiting a `Redis::Promise`
19
+ class TimeoutError < Error; end
20
+
21
+ # Thrown when an awaited promise has been rejected.
22
+ class RejectedError < Error
23
+ #: untyped
24
+ attr_reader :value
25
+
26
+ #: (untyped) -> void
27
+ def initialize(value)
28
+ @value = value
29
+ super("rejected redis promise: #{value.inspect}")
30
+ end
31
+ end
32
+
33
+ class << self
34
+ # Create a pair of Promise and Resolver objects for the same key.
35
+ # The resolver can be used to either resolve or reject the promise.
36
+ # The promise can be used to wait for the result.
37
+ #
38
+ #: (Redis, ?id: String, ?namespace: String) -> [Promise, Resolver]
39
+ def create(redis, id: SecureRandom.uuid_v4, namespace: 'global')
40
+ key = "promise:#{namespace}:#{id}"
41
+
42
+ promise = Promise.new(redis, key: key)
43
+ resolver = Resolver.new(redis, key: key)
44
+
45
+ [promise, resolver]
46
+ end
47
+ end
48
+
49
+ #: Redis
50
+ attr_reader :redis
51
+
52
+ #: String
53
+ attr_reader :key
54
+
55
+ #: (Redis, ?id: String, ?namespace: String, ?key: String) -> void
56
+ def initialize(redis, id: SecureRandom.uuid_v4, namespace: 'global', key: "promise:#{namespace}:#{id}")
57
+ @redis = redis.dup #: Redis
58
+ @key = key
59
+ end
60
+
61
+ # Blocks the current thread until the resolved or rejected value
62
+ # is available. By default it blocks indefinitely.
63
+ # If the promise has been successfully resolved its value gets returned.
64
+ # If the promise has been rejected a `Redis::Promise::RejectedError` gets thrown.
65
+ #
66
+ # You can provide an optional `timeout:` argument that is a float
67
+ # of number of seconds the client should wait for the value.
68
+ # If the timeout is exceeded a `Redis::Promise::TimeoutError` is thrown.
69
+ #
70
+ #: (?timeout: Float | Integer) -> untyped
71
+ def await(timeout: 0)
72
+ result = @redis.blpop(@key, timeout: timeout)
73
+ raise TimeoutError unless result
74
+
75
+ parsed = JSON.parse(result[1], symbolize_names: true)
76
+
77
+ err = parsed[:err]
78
+ raise RejectedError.new(err) if err # rubocop:disable Style/RaiseArgs
79
+
80
+ parsed[:value]
81
+ end
82
+ end
83
+ end
data/sorbet/config ADDED
@@ -0,0 +1,7 @@
1
+ --dir
2
+ .
3
+ --enable-experimental-requires-ancestor
4
+ --enable-experimental-rbs-comments
5
+ --parser=prism
6
+ --ignore=tmp/
7
+ --ignore=vendor/
@@ -0,0 +1 @@
1
+ **/*.rbi linguist-vendored=true
@@ -0,0 +1,120 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module Minitest::Assertions
8
+ sig { params(test: T.anything, msg: T.anything).returns(TrueClass) }
9
+ def assert(test, msg = nil); end
10
+
11
+ sig { params(obj: T.anything, msg: T.anything).returns(TrueClass) }
12
+ def assert_empty(obj, msg = nil); end
13
+
14
+ sig { params(exp: T.anything, act: T.anything, msg: T.anything).returns(TrueClass) }
15
+ def assert_equal(exp, act, msg = nil); end
16
+
17
+ sig { params(exp: T.anything, act: T.anything, delta: Numeric, msg: T.anything).returns(TrueClass) }
18
+ def assert_in_delta(exp, act, delta = T.unsafe(nil), msg = nil); end
19
+
20
+ sig { params(a: T.anything, b: T.anything, epsilon: Numeric, msg: T.anything).returns(TrueClass) }
21
+ def assert_in_epsilon(a, b, epsilon = T.unsafe(nil), msg = nil); end
22
+
23
+ sig { params(collection: T.anything, obj: T.anything, msg: T.anything).returns(TrueClass) }
24
+ def assert_includes(collection, obj, msg = nil); end
25
+
26
+ sig { params(cls: T.anything, obj: T.anything, msg: T.anything).returns(TrueClass) }
27
+ def assert_instance_of(cls, obj, msg = nil); end
28
+
29
+ sig { params(cls: T.anything, obj: T.anything, msg: T.anything).returns(TrueClass) }
30
+ def assert_kind_of(cls, obj, msg = nil); end
31
+
32
+ sig { params(matcher: T.any(String, Regexp), obj: T.anything, msg: T.anything).returns(MatchData) }
33
+ def assert_match(matcher, obj, msg = nil); end
34
+
35
+ sig { params(obj: T.anything, msg: T.anything).returns(TrueClass) }
36
+ def assert_nil(obj, msg = nil); end
37
+
38
+ sig { params(o1: T.anything, op: T.any(Symbol, String), o2: T.anything, msg: T.anything).returns(TrueClass) }
39
+ def assert_operator(o1, op, o2 = T.unsafe(nil), msg = nil); end
40
+
41
+ sig { params(stdout: T.nilable(T.any(String, Regexp)), stderr: T.nilable(T.any(String, Regexp)), block: T.proc.void).returns(T::Boolean) }
42
+ def assert_output(stdout = nil, stderr = nil, &block); end
43
+
44
+ sig { params(path: T.any(String, Pathname), msg: T.anything).returns(TrueClass) }
45
+ def assert_path_exists(path, msg = nil); end
46
+
47
+ sig { params(block: T.proc.void).returns(TrueClass) }
48
+ def assert_pattern(&block); end
49
+
50
+ sig { params(o1: T.anything, op: T.any(String, Symbol), msg: T.anything).returns(TrueClass) }
51
+ def assert_predicate(o1, op, msg = nil); end
52
+
53
+ sig { params(exp: NilClass, block: T.proc.void).returns(StandardError) }
54
+ sig { type_parameters(:T).params(exp: T.any(T::Class[T.type_parameter(:T)], Regexp, String), block: T.proc.void).returns(T.type_parameter(:T)) }
55
+ def assert_raises(*exp, &block); end
56
+
57
+ sig { params(obj: T.anything, meth: T.any(String, Symbol), msg: T.anything, include_all: T::Boolean).returns(TrueClass) }
58
+ def assert_respond_to(obj, meth, msg = nil, include_all: false); end
59
+
60
+ sig { params(exp: T.anything, act: T.anything, msg: T.anything).returns(TrueClass) }
61
+ def assert_same(exp, act, msg = nil); end
62
+
63
+ # @version < 6.0.0
64
+ sig { params(send_ary: T::Array[T.anything], m: T.anything).returns(T::Boolean) }
65
+ def assert_send(send_ary, m = nil); end
66
+
67
+ sig { params(block: T.proc.void).returns(T::Boolean) }
68
+ def assert_silent(&block); end
69
+
70
+ sig { params(sym: Symbol, msg: T.anything, block: T.proc.void).returns(T.anything) }
71
+ def assert_throws(sym, msg = nil, &block); end
72
+
73
+ sig { params(test: T.anything, msg: T.anything).returns(TrueClass) }
74
+ def refute(test, msg = nil); end
75
+
76
+ sig { params(obj: T.anything, msg: T.anything).returns(TrueClass) }
77
+ def refute_empty(obj, msg = nil); end
78
+
79
+ sig { params(exp: T.anything, act: T.anything, msg: T.anything).returns(TrueClass) }
80
+ def refute_equal(exp, act, msg = nil); end
81
+
82
+ sig { params(exp: T.anything, act: T.anything, delta: Numeric, msg: T.anything).returns(TrueClass) }
83
+ def refute_in_delta(exp, act, delta = T.unsafe(nil), msg = nil); end
84
+
85
+ sig { params(a: T.anything, b: T.anything, epsilon: Numeric, msg: T.anything).returns(TrueClass) }
86
+ def refute_in_epsilon(a, b, epsilon = T.unsafe(nil), msg = nil); end
87
+
88
+ sig { params(collection: T.anything, obj: T.anything, msg: T.anything).returns(TrueClass) }
89
+ def refute_includes(collection, obj, msg = nil); end
90
+
91
+ sig { params(cls: T.anything, obj: T.anything, msg: T.anything).returns(TrueClass) }
92
+ def refute_instance_of(cls, obj, msg = nil); end
93
+
94
+ sig { params(cls: T.anything, obj: T.anything, msg: T.anything).returns(TrueClass) }
95
+ def refute_kind_of(cls, obj, msg = nil); end
96
+
97
+ sig { params(matcher: T.any(String, Regexp), obj: T.anything, msg: T.anything).returns(TrueClass) }
98
+ def refute_match(matcher, obj, msg = nil); end
99
+
100
+ sig { params(obj: T.anything, msg: T.anything).returns(TrueClass) }
101
+ def refute_nil(obj, msg = nil); end
102
+
103
+ sig { params(block: T.proc.void).returns(TrueClass) }
104
+ def refute_pattern(&block); end
105
+
106
+ sig { params(o1: T.anything, op: T.any(Symbol, String), o2: T.anything, msg: T.anything).returns(TrueClass) }
107
+ def refute_operator(o1, op, o2 = T.unsafe(nil), msg = nil); end
108
+
109
+ sig { params(path: T.any(String, Pathname), msg: T.anything).returns(TrueClass) }
110
+ def refute_path_exists(path, msg = nil); end
111
+
112
+ sig { params(o1: T.anything, op: T.any(String, Symbol), msg: T.anything).returns(TrueClass) }
113
+ def refute_predicate(o1, op, msg = nil); end
114
+
115
+ sig { params(obj: T.anything, meth: T.any(String, Symbol), msg: T.anything, include_all: T::Boolean).returns(TrueClass) }
116
+ def refute_respond_to(obj, meth, msg = nil, include_all: false); end
117
+
118
+ sig { params(exp: T.anything, act: T.anything, msg: T.anything).returns(TrueClass) }
119
+ def refute_same(exp, act, msg = nil); end
120
+ end