sorbet-rails 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -4
- data/lib/sorbet-rails/dependent_gem_rbis/README.md +1 -0
- data/lib/sorbet-rails/{actionmailer.rbi → dependent_gem_rbis/actionmailer.rbi} +0 -0
- data/lib/sorbet-rails/dependent_gem_rbis/activejob.rbi +3 -0
- data/lib/sorbet-rails/{activerecord.rbi → dependent_gem_rbis/activerecord.rbi} +0 -0
- data/lib/sorbet-rails/job_rbi_formatter.rb +75 -0
- data/lib/sorbet-rails/mailer_rbi_formatter.rb +1 -1
- data/lib/sorbet-rails/model_plugins/active_record_finder_methods.rb +1 -1
- data/lib/sorbet-rails/tasks/rails_rbi.rake +20 -0
- data/lib/sorbet-rails/type_assert/type_assert.rb +5 -0
- data/sorbet-rails.gemspec +1 -1
- data/spec/generators/rails-template.rb +17 -0
- data/spec/generators/sorbet_test_cases.rb +12 -0
- data/spec/job_rbi_formatter_spec.rb +13 -0
- data/spec/rake_rails_rbi_jobs_spec.rb +20 -0
- data/spec/support/v5.0/Gemfile.lock +8 -8
- data/spec/support/v5.0/app/jobs/award_house_point_hourglasses.rb +12 -0
- data/spec/support/v5.0/sorbet_test_cases.rb +12 -0
- data/spec/support/v5.1/Gemfile.lock +8 -8
- data/spec/support/v5.1/app/jobs/award_house_point_hourglasses.rb +12 -0
- data/spec/support/v5.1/sorbet_test_cases.rb +12 -0
- data/spec/support/v5.2/Gemfile.lock +44 -44
- data/spec/support/v5.2/app/jobs/award_house_point_hourglasses.rb +12 -0
- data/spec/support/v5.2/sorbet_test_cases.rb +12 -0
- data/spec/support/v6.0/Gemfile.lock +58 -58
- data/spec/support/v6.0/app/jobs/award_house_point_hourglasses.rb +12 -0
- data/spec/support/v6.0/sorbet_test_cases.rb +12 -0
- data/spec/test_data/v5.0/expected_application_job.rbi +20 -0
- data/spec/test_data/v5.0/expected_application_mailer.rbi +1 -1
- data/spec/test_data/v5.0/expected_award_house_point_hourglasses.rbi +20 -0
- data/spec/test_data/v5.0/expected_daily_prophet_mailer.rbi +1 -1
- data/spec/test_data/v5.0/expected_hogwarts_acceptance_mailer.rbi +1 -1
- data/spec/test_data/v5.0/expected_internal_metadata.rbi +12 -0
- data/spec/test_data/v5.0/expected_potion.rbi +12 -0
- data/spec/test_data/v5.0/expected_robe.rbi +12 -0
- data/spec/test_data/v5.0/expected_schema_migration.rbi +12 -0
- data/spec/test_data/v5.0/expected_school.rbi +12 -0
- data/spec/test_data/v5.0/expected_spell_book.rbi +12 -0
- data/spec/test_data/v5.0/expected_squib.rbi +12 -0
- data/spec/test_data/v5.0/expected_wand.rbi +12 -0
- data/spec/test_data/v5.0/expected_wizard.rbi +12 -0
- data/spec/test_data/v5.0/expected_wizard_wo_spellbook.rbi +12 -0
- data/spec/test_data/v5.1/expected_application_job.rbi +20 -0
- data/spec/test_data/v5.1/expected_application_mailer.rbi +1 -1
- data/spec/test_data/v5.1/expected_award_house_point_hourglasses.rbi +20 -0
- data/spec/test_data/v5.1/expected_daily_prophet_mailer.rbi +1 -1
- data/spec/test_data/v5.1/expected_hogwarts_acceptance_mailer.rbi +1 -1
- data/spec/test_data/v5.1/expected_internal_metadata.rbi +12 -0
- data/spec/test_data/v5.1/expected_potion.rbi +12 -0
- data/spec/test_data/v5.1/expected_robe.rbi +12 -0
- data/spec/test_data/v5.1/expected_schema_migration.rbi +12 -0
- data/spec/test_data/v5.1/expected_school.rbi +12 -0
- data/spec/test_data/v5.1/expected_spell_book.rbi +12 -0
- data/spec/test_data/v5.1/expected_squib.rbi +12 -0
- data/spec/test_data/v5.1/expected_wand.rbi +12 -0
- data/spec/test_data/v5.1/expected_wizard.rbi +12 -0
- data/spec/test_data/v5.1/expected_wizard_wo_spellbook.rbi +12 -0
- data/spec/test_data/v5.2/expected_application_job.rbi +20 -0
- data/spec/test_data/v5.2/expected_application_mailer.rbi +1 -1
- data/spec/test_data/v5.2/expected_attachment.rbi +12 -0
- data/spec/test_data/v5.2/expected_award_house_point_hourglasses.rbi +20 -0
- data/spec/test_data/v5.2/expected_blob.rbi +12 -0
- data/spec/test_data/v5.2/expected_daily_prophet_mailer.rbi +1 -1
- data/spec/test_data/v5.2/expected_hogwarts_acceptance_mailer.rbi +1 -1
- data/spec/test_data/v5.2/expected_internal_metadata.rbi +12 -0
- data/spec/test_data/v5.2/expected_potion.rbi +12 -0
- data/spec/test_data/v5.2/expected_robe.rbi +12 -0
- data/spec/test_data/v5.2/expected_schema_migration.rbi +12 -0
- data/spec/test_data/v5.2/expected_school.rbi +12 -0
- data/spec/test_data/v5.2/expected_spell_book.rbi +12 -0
- data/spec/test_data/v5.2/expected_squib.rbi +12 -0
- data/spec/test_data/v5.2/expected_wand.rbi +12 -0
- data/spec/test_data/v5.2/expected_wizard.rbi +12 -0
- data/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi +12 -0
- data/spec/test_data/v6.0/expected_application_job.rbi +20 -0
- data/spec/test_data/v6.0/expected_application_mailer.rbi +1 -1
- data/spec/test_data/v6.0/expected_attachment.rbi +12 -0
- data/spec/test_data/v6.0/expected_award_house_point_hourglasses.rbi +20 -0
- data/spec/test_data/v6.0/expected_blob.rbi +12 -0
- data/spec/test_data/v6.0/expected_daily_prophet_mailer.rbi +1 -1
- data/spec/test_data/v6.0/expected_hogwarts_acceptance_mailer.rbi +1 -1
- data/spec/test_data/v6.0/expected_internal_metadata.rbi +12 -0
- data/spec/test_data/v6.0/expected_potion.rbi +12 -0
- data/spec/test_data/v6.0/expected_robe.rbi +12 -0
- data/spec/test_data/v6.0/expected_schema_migration.rbi +12 -0
- data/spec/test_data/v6.0/expected_school.rbi +12 -0
- data/spec/test_data/v6.0/expected_spell_book.rbi +12 -0
- data/spec/test_data/v6.0/expected_squib.rbi +12 -0
- data/spec/test_data/v6.0/expected_wand.rbi +12 -0
- data/spec/test_data/v6.0/expected_wizard.rbi +12 -0
- data/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi +12 -0
- metadata +34 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7e0b556a5c7db33a8fa24c494fa70265802a360eb842545b6124d54ade20e47
|
4
|
+
data.tar.gz: 5f26a6773d2769e1dfc523f4202b179ded8deaebb65e05ade61291f03153f164
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc61969e6954e727113e9e74ba48925c15ee07b940fbe5d3a711d62270f90ba06ce9c36373420a3cf02c9a52bda3256ef63d9bea6bf2bcd580dfa592faba068c
|
7
|
+
data.tar.gz: 8c0bb6e747de6ac12c77b326b01d941f3f24fdd6444fca05d573ff26c20a2d0d679bbcd713adb37f66919781446137d3f0fdd21bb39b36241c6e1d6a98ac1de6
|
data/README.md
CHANGED
@@ -34,6 +34,7 @@ Add `sorbet-rails` to the [`:default` group](https://bundler.io/v2.0/guides/grou
|
|
34
34
|
❯ bundle exec rake rails_rbi:models
|
35
35
|
❯ bundle exec rake rails_rbi:helpers
|
36
36
|
❯ bundle exec rake rails_rbi:mailers
|
37
|
+
❯ bundle exec rake rails_rbi:jobs
|
37
38
|
❯ bundle exec rake rails_rbi:custom
|
38
39
|
|
39
40
|
# or run them all at once
|
@@ -163,7 +164,7 @@ Generates only typed enum setter & getter:
|
|
163
164
|
#### `RelationType` alias
|
164
165
|
|
165
166
|
There are several kinds of relations of a model: `User::ActiveRecord_Relation`, `User::ActiveRecord_AssociationRelation` and `User::ActiveRecord_Associations_CollectionProxy`. Usually the code may need just any relation type. We add a `Model::RelationType` type alias for every model to use it.
|
166
|
-
|
167
|
+
|
167
168
|
```ruby
|
168
169
|
class User
|
169
170
|
RelationType = T.type_alias do
|
@@ -235,11 +236,21 @@ This Rake task generates RBI files for all mailer classes in the Rails applicati
|
|
235
236
|
❯ bundle exec rake rails_rbi:mailers
|
236
237
|
```
|
237
238
|
|
238
|
-
Since mailing action methods
|
239
|
+
Since mailing action methods are based on instance methods defined in a mailer class, the signature of a mailing action method will be dependent on the signature the instance method has
|
239
240
|
- If there is a (sorbet) sig written for the instance method, it generates a matching sig for the mailing action method
|
240
241
|
- If not, all the params in the mailing action method will be T.untyped.
|
241
242
|
- For return type though, the mailing action method will return `ActionMailer::MessageDelivery` instead of the return type of the instance method.
|
242
243
|
|
244
|
+
### Jobs
|
245
|
+
|
246
|
+
This Rake task generates RBI files for all jobs classes in the Rails application (all descendants of `ActiveJob::Base`).
|
247
|
+
```sh
|
248
|
+
❯ bundle exec rake rails_rbi:jobs
|
249
|
+
```
|
250
|
+
|
251
|
+
It will generate `perform_later` and `perform_now` methods for
|
252
|
+
the job classes matching the signature of the `perform` method of the job. If there is a (sorbet) sig written for `perform`, it will use the same sig for `perform_*` methods.
|
253
|
+
|
243
254
|
## Runtime Features
|
244
255
|
|
245
256
|
In addition to features provided by the static generator, `sorbet-rails` can
|
@@ -252,8 +263,8 @@ specific environment group (eg. `development` only).
|
|
252
263
|
- `find_n`, `first_n`, `last_n`
|
253
264
|
- `pluck_to_tstruct`
|
254
265
|
- `typed_enum`
|
255
|
-
|
256
|
-
- Model Relation:
|
266
|
+
|
267
|
+
- Model Relation:
|
257
268
|
- Make relation classes public. By default, relation classes like `User::ActiveRecord_Relation`, `User::ActiveRecord_AssociationRelation` are private
|
258
269
|
- Add type alias, eg `Model::RelationType`, to represents any type of relation of a model.
|
259
270
|
|
@@ -0,0 +1 @@
|
|
1
|
+
This folder contains RBI files used for type-checking sorbet-rails source code itself.
|
File without changes
|
File without changes
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# typed: strict
|
2
|
+
require('parlour')
|
3
|
+
require('sorbet-rails/sorbet_utils.rb')
|
4
|
+
|
5
|
+
class SorbetRails::JobRbiFormatter
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
Parameter = ::Parlour::RbiGenerator::Parameter
|
9
|
+
|
10
|
+
sig { params(job_class: T.class_of(ActiveJob::Base)).void }
|
11
|
+
def initialize(job_class)
|
12
|
+
@job_class = T.let(job_class, T.class_of(ActiveJob::Base))
|
13
|
+
@parlour = T.let(Parlour::RbiGenerator.new, Parlour::RbiGenerator)
|
14
|
+
end
|
15
|
+
|
16
|
+
sig {returns(String)}
|
17
|
+
def generate_rbi
|
18
|
+
puts "-- Generate sigs for mailer #{@job_class.name} --"
|
19
|
+
|
20
|
+
@parlour.root.add_comments([
|
21
|
+
'This is an autogenerated file for Rails\' jobs.',
|
22
|
+
'Please rerun bundle exec rake rails_rbi:jobs to regenerate.'
|
23
|
+
])
|
24
|
+
|
25
|
+
@parlour.root.create_class(@job_class.name) do |job_rbi|
|
26
|
+
method_def = @job_class.instance_method(:perform)
|
27
|
+
parameters = SorbetRails::SorbetUtils.parameters_from_method_def(method_def)
|
28
|
+
job_rbi.create_method(
|
29
|
+
"perform_later",
|
30
|
+
parameters: parameters,
|
31
|
+
class_method: true,
|
32
|
+
)
|
33
|
+
job_rbi.create_method(
|
34
|
+
"perform_now",
|
35
|
+
parameters: parameters,
|
36
|
+
class_method: true,
|
37
|
+
)
|
38
|
+
# Override the signature for "set" so that we can support it
|
39
|
+
# At run-time, this method returns a `ActiveJob::ConfiguredJob` but
|
40
|
+
# we fake the signature to return "T.self_class" so that
|
41
|
+
# sorbet can type-check when `perform_later` is called on it
|
42
|
+
# See: https://guides.rubyonrails.org/active_job_basics.html#enqueue-the-job
|
43
|
+
job_rbi.create_method(
|
44
|
+
"set",
|
45
|
+
# Documentation: https://api.rubyonrails.org/classes/ActiveJob/Core/ClassMethods.html
|
46
|
+
parameters: [
|
47
|
+
Parameter.new(
|
48
|
+
"wait:",
|
49
|
+
type: "T.nilable(ActiveSupport::Duration)",
|
50
|
+
default: "nil",
|
51
|
+
),
|
52
|
+
Parameter.new(
|
53
|
+
"wait_until:",
|
54
|
+
type: "T.nilable(T.any(ActiveSupport::TimeWithZone, Date, Time))",
|
55
|
+
default: "nil",
|
56
|
+
),
|
57
|
+
Parameter.new(
|
58
|
+
"queue:",
|
59
|
+
type: "T.nilable(T.any(String, Symbol))",
|
60
|
+
default: "nil",
|
61
|
+
),
|
62
|
+
Parameter.new(
|
63
|
+
"priority:",
|
64
|
+
type: "T.nilable(Integer)",
|
65
|
+
default: "nil",
|
66
|
+
),
|
67
|
+
],
|
68
|
+
return_type: "T.self_type",
|
69
|
+
class_method: true,
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
@parlour.rbi
|
74
|
+
end
|
75
|
+
end
|
@@ -16,7 +16,7 @@ class SorbetRails::MailerRbiFormatter
|
|
16
16
|
puts "-- Generate sigs for mailer #{@mailer_class.name} --"
|
17
17
|
|
18
18
|
@parlour.root.add_comments([
|
19
|
-
|
19
|
+
"This is an autogenerated file for Rails' mailers.",
|
20
20
|
'Please rerun bundle exec rake rails_rbi:mailers to regenerate.'
|
21
21
|
])
|
22
22
|
|
@@ -98,7 +98,7 @@ class SorbetRails::ModelPlugins::ActiveRecordFinderMethods < SorbetRails::ModelP
|
|
98
98
|
class_method: class_method,
|
99
99
|
)
|
100
100
|
|
101
|
-
["any?", "many?", "none?", "one?"].each do |method_name|
|
101
|
+
["any?", "many?", "none?", "one?", "empty?"].each do |method_name|
|
102
102
|
class_rbi.create_method(
|
103
103
|
method_name,
|
104
104
|
parameters: [ Parameter.new("*args", type: "T.untyped") ],
|
@@ -2,6 +2,7 @@ require("sorbet-rails/model_rbi_formatter")
|
|
2
2
|
require("sorbet-rails/routes_rbi_formatter")
|
3
3
|
require("sorbet-rails/helper_rbi_formatter")
|
4
4
|
require("sorbet-rails/mailer_rbi_formatter")
|
5
|
+
require("sorbet-rails/job_rbi_formatter")
|
5
6
|
require("sorbet-rails/utils")
|
6
7
|
|
7
8
|
RAILS_RBI_RAKE_DIR = File.dirname(__FILE__)
|
@@ -18,6 +19,7 @@ namespace :rails_rbi do
|
|
18
19
|
Rake::Task['rails_rbi:models'].invoke
|
19
20
|
Rake::Task['rails_rbi:helpers'].invoke
|
20
21
|
Rake::Task['rails_rbi:mailers'].invoke
|
22
|
+
Rake::Task['rails_rbi:jobs'].invoke
|
21
23
|
Rake::Task['rails_rbi:custom'].invoke
|
22
24
|
end
|
23
25
|
|
@@ -110,6 +112,24 @@ namespace :rails_rbi do
|
|
110
112
|
end
|
111
113
|
end
|
112
114
|
|
115
|
+
desc "Generate rbis for rails mailers"
|
116
|
+
task :jobs, [:root_dir] => :environment do |t, args|
|
117
|
+
SorbetRails::Utils.rails_eager_load_all!
|
118
|
+
all_jobs = ActiveJob::Base.descendants
|
119
|
+
|
120
|
+
all_jobs.each do |job_class|
|
121
|
+
file_path = Rails.root.join(
|
122
|
+
"sorbet",
|
123
|
+
"rails-rbi",
|
124
|
+
"jobs",
|
125
|
+
"#{job_class.name.underscore}.rbi",
|
126
|
+
)
|
127
|
+
formatter = SorbetRails::JobRbiFormatter.new(job_class)
|
128
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
129
|
+
File.write(file_path, formatter.generate_rbi)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
113
133
|
def generate_rbis_for_models(model_classes, available_classes)
|
114
134
|
available_class_names = Set.new(available_classes.map { |c| c.name })
|
115
135
|
formatted = model_classes.map do |model_class|
|
@@ -3,6 +3,11 @@ require 'sorbet-runtime'
|
|
3
3
|
require 'sorbet-rails/type_assert/type_assert_interface'
|
4
4
|
require 'sorbet-rails/type_assert/type_assert_impl'
|
5
5
|
|
6
|
+
# Make this type visible even when the concrete
|
7
|
+
# implementation cannot be loaded.
|
8
|
+
module TypeAssertImpl
|
9
|
+
end
|
10
|
+
|
6
11
|
class TA
|
7
12
|
extend T::Sig
|
8
13
|
extend T::Generic
|
data/sorbet-rails.gemspec
CHANGED
@@ -374,6 +374,22 @@ def create_mailers
|
|
374
374
|
RUBY
|
375
375
|
end
|
376
376
|
|
377
|
+
def create_jobs
|
378
|
+
file "app/jobs/award_house_point_hourglasses.rb", <<~RUBY
|
379
|
+
# N.B. You imagine the wizards update the point magically somehow?
|
380
|
+
# Nope, there is a "goblin" that takes their "give points" request and do it
|
381
|
+
# behind the scene.
|
382
|
+
class AwardHousePointHourglasses < ApplicationJob
|
383
|
+
extend T::Sig
|
384
|
+
|
385
|
+
sig { params(student: Wizard, point: Integer).void }
|
386
|
+
def perform(student:, point:)
|
387
|
+
# TODO: award point to student's house
|
388
|
+
end
|
389
|
+
end
|
390
|
+
RUBY
|
391
|
+
end
|
392
|
+
|
377
393
|
def add_sorbet_test_files
|
378
394
|
file "typed-override.yaml", <<~YAML
|
379
395
|
true:
|
@@ -417,6 +433,7 @@ after_bundle do
|
|
417
433
|
create_models
|
418
434
|
create_migrations
|
419
435
|
create_mailers
|
436
|
+
create_jobs
|
420
437
|
add_sorbet_test_files
|
421
438
|
|
422
439
|
Bundler.with_clean_env do
|
@@ -181,8 +181,20 @@ T.assert_type!(Wizard::House::Slytherin, Wizard::House)
|
|
181
181
|
# Mythical plugin
|
182
182
|
T.assert_type!(Wand.mythicals, T::Array[Wand])
|
183
183
|
|
184
|
+
# Mailers
|
184
185
|
T.assert_type!(HogwartsAcceptanceMailer.notify(wizard), ActionMailer::MessageDelivery)
|
185
186
|
|
187
|
+
# Jobs
|
188
|
+
AwardHousePointHourglasses.perform_later(student: wizard, point: 10)
|
189
|
+
AwardHousePointHourglasses.perform_now(student: wizard, point: 10)
|
190
|
+
AwardHousePointHourglasses.
|
191
|
+
set(queue: :daily, wait: 5.minutes).
|
192
|
+
perform_later(student: wizard, point: 10)
|
193
|
+
AwardHousePointHourglasses.
|
194
|
+
set(priority: 10, wait_until: Time.now.tomorrow).
|
195
|
+
perform_later(student: wizard, point: 10)
|
196
|
+
|
197
|
+
|
186
198
|
T.assert_type!(wizard.broom_nimbus?, T::Boolean)
|
187
199
|
T.assert_type!(wizard.color_brown_eyes?, T::Boolean)
|
188
200
|
T.assert_type!(wizard.quidditch_keeper?, T::Boolean)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'sorbet-rails/mailer_rbi_formatter'
|
3
|
+
|
4
|
+
RSpec.describe SorbetRails::MailerRbiFormatter do
|
5
|
+
|
6
|
+
it 'returns the expected rbi for a given array of helpers' do
|
7
|
+
formatter = SorbetRails::JobRbiFormatter.new(AwardHousePointHourglasses)
|
8
|
+
expect_match_file(
|
9
|
+
formatter.generate_rbi,
|
10
|
+
'expected_award_house_point_hourglasses.rbi'
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'rake rails_rbi:jobs', type: :task do
|
4
|
+
let!(:generated_dir_path) { Rails.root.join("sorbet", "rails-rbi", "jobs") }
|
5
|
+
|
6
|
+
it "preloads the Rails environment" do
|
7
|
+
expect(task.prerequisites).to include("environment")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "generates jobs rbi correctly" do
|
11
|
+
task.invoke
|
12
|
+
expect_files(
|
13
|
+
base_dir: generated_dir_path,
|
14
|
+
files: [
|
15
|
+
"application_job.rbi",
|
16
|
+
"award_house_point_hourglasses.rbi",
|
17
|
+
],
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../../..
|
3
3
|
specs:
|
4
|
-
sorbet-rails (0.6.
|
4
|
+
sorbet-rails (0.6.2)
|
5
5
|
method_source (>= 0.9.2)
|
6
6
|
parlour (~> 2.0)
|
7
7
|
parser (>= 2.7)
|
@@ -69,19 +69,19 @@ GEM
|
|
69
69
|
nokogiri (>= 1.5.9)
|
70
70
|
mail (2.7.1)
|
71
71
|
mini_mime (>= 0.1.1)
|
72
|
-
method_source (0.
|
72
|
+
method_source (1.0.0)
|
73
73
|
mini_mime (1.0.2)
|
74
74
|
mini_portile2 (2.4.0)
|
75
75
|
minitest (5.14.0)
|
76
76
|
nio4r (2.5.2)
|
77
77
|
nokogiri (1.10.9)
|
78
78
|
mini_portile2 (~> 2.4.0)
|
79
|
-
parlour (2.
|
79
|
+
parlour (2.1.0)
|
80
80
|
commander (~> 4.5)
|
81
81
|
parser
|
82
82
|
rainbow (~> 3.0)
|
83
83
|
sorbet-runtime (>= 0.5)
|
84
|
-
parser (2.7.0.
|
84
|
+
parser (2.7.0.5)
|
85
85
|
ast (~> 2.4.0)
|
86
86
|
polyfill (1.8.0)
|
87
87
|
puma (3.12.4)
|
@@ -114,15 +114,15 @@ GEM
|
|
114
114
|
rainbow (3.0.0)
|
115
115
|
rake (13.0.1)
|
116
116
|
safe_type (1.1.1)
|
117
|
-
sorbet (0.5.
|
118
|
-
sorbet-static (= 0.5.
|
117
|
+
sorbet (0.5.5472)
|
118
|
+
sorbet-static (= 0.5.5472)
|
119
119
|
sorbet-coerce (0.2.4)
|
120
120
|
polyfill (~> 1.8)
|
121
121
|
safe_type (~> 1.1, >= 1.1.1)
|
122
122
|
sorbet (>= 0.4.4704)
|
123
123
|
sorbet-runtime (>= 0.4.4704)
|
124
|
-
sorbet-runtime (0.5.
|
125
|
-
sorbet-static (0.5.
|
124
|
+
sorbet-runtime (0.5.5472)
|
125
|
+
sorbet-static (0.5.5472-universal-darwin-14)
|
126
126
|
sprockets (4.0.0)
|
127
127
|
concurrent-ruby (~> 1.0)
|
128
128
|
rack (> 1, < 3)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# typed: strong
|
2
|
+
# N.B. You imagine the wizards update the point magically somehow?
|
3
|
+
# Nope, there is a "goblin" that takes their "give points" request and do it
|
4
|
+
# behind the scene.
|
5
|
+
class AwardHousePointHourglasses < ApplicationJob
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
sig { params(student: Wizard, point: Integer).void }
|
9
|
+
def perform(student:, point:)
|
10
|
+
# TODO: award point to student's house
|
11
|
+
end
|
12
|
+
end
|
@@ -181,8 +181,20 @@ T.assert_type!(Wizard::House::Slytherin, Wizard::House)
|
|
181
181
|
# Mythical plugin
|
182
182
|
T.assert_type!(Wand.mythicals, T::Array[Wand])
|
183
183
|
|
184
|
+
# Mailers
|
184
185
|
T.assert_type!(HogwartsAcceptanceMailer.notify(wizard), ActionMailer::MessageDelivery)
|
185
186
|
|
187
|
+
# Jobs
|
188
|
+
AwardHousePointHourglasses.perform_later(student: wizard, point: 10)
|
189
|
+
AwardHousePointHourglasses.perform_now(student: wizard, point: 10)
|
190
|
+
AwardHousePointHourglasses.
|
191
|
+
set(queue: :daily, wait: 5.minutes).
|
192
|
+
perform_later(student: wizard, point: 10)
|
193
|
+
AwardHousePointHourglasses.
|
194
|
+
set(priority: 10, wait_until: Time.now.tomorrow).
|
195
|
+
perform_later(student: wizard, point: 10)
|
196
|
+
|
197
|
+
|
186
198
|
T.assert_type!(wizard.broom_nimbus?, T::Boolean)
|
187
199
|
T.assert_type!(wizard.color_brown_eyes?, T::Boolean)
|
188
200
|
T.assert_type!(wizard.quidditch_keeper?, T::Boolean)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../../..
|
3
3
|
specs:
|
4
|
-
sorbet-rails (0.6.
|
4
|
+
sorbet-rails (0.6.2)
|
5
5
|
method_source (>= 0.9.2)
|
6
6
|
parlour (~> 2.0)
|
7
7
|
parser (>= 2.7)
|
@@ -70,19 +70,19 @@ GEM
|
|
70
70
|
nokogiri (>= 1.5.9)
|
71
71
|
mail (2.7.1)
|
72
72
|
mini_mime (>= 0.1.1)
|
73
|
-
method_source (0.
|
73
|
+
method_source (1.0.0)
|
74
74
|
mini_mime (1.0.2)
|
75
75
|
mini_portile2 (2.4.0)
|
76
76
|
minitest (5.14.0)
|
77
77
|
nio4r (2.5.2)
|
78
78
|
nokogiri (1.10.9)
|
79
79
|
mini_portile2 (~> 2.4.0)
|
80
|
-
parlour (2.
|
80
|
+
parlour (2.1.0)
|
81
81
|
commander (~> 4.5)
|
82
82
|
parser
|
83
83
|
rainbow (~> 3.0)
|
84
84
|
sorbet-runtime (>= 0.5)
|
85
|
-
parser (2.7.0.
|
85
|
+
parser (2.7.0.5)
|
86
86
|
ast (~> 2.4.0)
|
87
87
|
polyfill (1.8.0)
|
88
88
|
puma (3.12.4)
|
@@ -115,15 +115,15 @@ GEM
|
|
115
115
|
rainbow (3.0.0)
|
116
116
|
rake (13.0.1)
|
117
117
|
safe_type (1.1.1)
|
118
|
-
sorbet (0.5.
|
119
|
-
sorbet-static (= 0.5.
|
118
|
+
sorbet (0.5.5472)
|
119
|
+
sorbet-static (= 0.5.5472)
|
120
120
|
sorbet-coerce (0.2.4)
|
121
121
|
polyfill (~> 1.8)
|
122
122
|
safe_type (~> 1.1, >= 1.1.1)
|
123
123
|
sorbet (>= 0.4.4704)
|
124
124
|
sorbet-runtime (>= 0.4.4704)
|
125
|
-
sorbet-runtime (0.5.
|
126
|
-
sorbet-static (0.5.
|
125
|
+
sorbet-runtime (0.5.5472)
|
126
|
+
sorbet-static (0.5.5472-universal-darwin-14)
|
127
127
|
sprockets (4.0.0)
|
128
128
|
concurrent-ruby (~> 1.0)
|
129
129
|
rack (> 1, < 3)
|