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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -4
  3. data/lib/sorbet-rails/dependent_gem_rbis/README.md +1 -0
  4. data/lib/sorbet-rails/{actionmailer.rbi → dependent_gem_rbis/actionmailer.rbi} +0 -0
  5. data/lib/sorbet-rails/dependent_gem_rbis/activejob.rbi +3 -0
  6. data/lib/sorbet-rails/{activerecord.rbi → dependent_gem_rbis/activerecord.rbi} +0 -0
  7. data/lib/sorbet-rails/job_rbi_formatter.rb +75 -0
  8. data/lib/sorbet-rails/mailer_rbi_formatter.rb +1 -1
  9. data/lib/sorbet-rails/model_plugins/active_record_finder_methods.rb +1 -1
  10. data/lib/sorbet-rails/tasks/rails_rbi.rake +20 -0
  11. data/lib/sorbet-rails/type_assert/type_assert.rb +5 -0
  12. data/sorbet-rails.gemspec +1 -1
  13. data/spec/generators/rails-template.rb +17 -0
  14. data/spec/generators/sorbet_test_cases.rb +12 -0
  15. data/spec/job_rbi_formatter_spec.rb +13 -0
  16. data/spec/rake_rails_rbi_jobs_spec.rb +20 -0
  17. data/spec/support/v5.0/Gemfile.lock +8 -8
  18. data/spec/support/v5.0/app/jobs/award_house_point_hourglasses.rb +12 -0
  19. data/spec/support/v5.0/sorbet_test_cases.rb +12 -0
  20. data/spec/support/v5.1/Gemfile.lock +8 -8
  21. data/spec/support/v5.1/app/jobs/award_house_point_hourglasses.rb +12 -0
  22. data/spec/support/v5.1/sorbet_test_cases.rb +12 -0
  23. data/spec/support/v5.2/Gemfile.lock +44 -44
  24. data/spec/support/v5.2/app/jobs/award_house_point_hourglasses.rb +12 -0
  25. data/spec/support/v5.2/sorbet_test_cases.rb +12 -0
  26. data/spec/support/v6.0/Gemfile.lock +58 -58
  27. data/spec/support/v6.0/app/jobs/award_house_point_hourglasses.rb +12 -0
  28. data/spec/support/v6.0/sorbet_test_cases.rb +12 -0
  29. data/spec/test_data/v5.0/expected_application_job.rbi +20 -0
  30. data/spec/test_data/v5.0/expected_application_mailer.rbi +1 -1
  31. data/spec/test_data/v5.0/expected_award_house_point_hourglasses.rbi +20 -0
  32. data/spec/test_data/v5.0/expected_daily_prophet_mailer.rbi +1 -1
  33. data/spec/test_data/v5.0/expected_hogwarts_acceptance_mailer.rbi +1 -1
  34. data/spec/test_data/v5.0/expected_internal_metadata.rbi +12 -0
  35. data/spec/test_data/v5.0/expected_potion.rbi +12 -0
  36. data/spec/test_data/v5.0/expected_robe.rbi +12 -0
  37. data/spec/test_data/v5.0/expected_schema_migration.rbi +12 -0
  38. data/spec/test_data/v5.0/expected_school.rbi +12 -0
  39. data/spec/test_data/v5.0/expected_spell_book.rbi +12 -0
  40. data/spec/test_data/v5.0/expected_squib.rbi +12 -0
  41. data/spec/test_data/v5.0/expected_wand.rbi +12 -0
  42. data/spec/test_data/v5.0/expected_wizard.rbi +12 -0
  43. data/spec/test_data/v5.0/expected_wizard_wo_spellbook.rbi +12 -0
  44. data/spec/test_data/v5.1/expected_application_job.rbi +20 -0
  45. data/spec/test_data/v5.1/expected_application_mailer.rbi +1 -1
  46. data/spec/test_data/v5.1/expected_award_house_point_hourglasses.rbi +20 -0
  47. data/spec/test_data/v5.1/expected_daily_prophet_mailer.rbi +1 -1
  48. data/spec/test_data/v5.1/expected_hogwarts_acceptance_mailer.rbi +1 -1
  49. data/spec/test_data/v5.1/expected_internal_metadata.rbi +12 -0
  50. data/spec/test_data/v5.1/expected_potion.rbi +12 -0
  51. data/spec/test_data/v5.1/expected_robe.rbi +12 -0
  52. data/spec/test_data/v5.1/expected_schema_migration.rbi +12 -0
  53. data/spec/test_data/v5.1/expected_school.rbi +12 -0
  54. data/spec/test_data/v5.1/expected_spell_book.rbi +12 -0
  55. data/spec/test_data/v5.1/expected_squib.rbi +12 -0
  56. data/spec/test_data/v5.1/expected_wand.rbi +12 -0
  57. data/spec/test_data/v5.1/expected_wizard.rbi +12 -0
  58. data/spec/test_data/v5.1/expected_wizard_wo_spellbook.rbi +12 -0
  59. data/spec/test_data/v5.2/expected_application_job.rbi +20 -0
  60. data/spec/test_data/v5.2/expected_application_mailer.rbi +1 -1
  61. data/spec/test_data/v5.2/expected_attachment.rbi +12 -0
  62. data/spec/test_data/v5.2/expected_award_house_point_hourglasses.rbi +20 -0
  63. data/spec/test_data/v5.2/expected_blob.rbi +12 -0
  64. data/spec/test_data/v5.2/expected_daily_prophet_mailer.rbi +1 -1
  65. data/spec/test_data/v5.2/expected_hogwarts_acceptance_mailer.rbi +1 -1
  66. data/spec/test_data/v5.2/expected_internal_metadata.rbi +12 -0
  67. data/spec/test_data/v5.2/expected_potion.rbi +12 -0
  68. data/spec/test_data/v5.2/expected_robe.rbi +12 -0
  69. data/spec/test_data/v5.2/expected_schema_migration.rbi +12 -0
  70. data/spec/test_data/v5.2/expected_school.rbi +12 -0
  71. data/spec/test_data/v5.2/expected_spell_book.rbi +12 -0
  72. data/spec/test_data/v5.2/expected_squib.rbi +12 -0
  73. data/spec/test_data/v5.2/expected_wand.rbi +12 -0
  74. data/spec/test_data/v5.2/expected_wizard.rbi +12 -0
  75. data/spec/test_data/v5.2/expected_wizard_wo_spellbook.rbi +12 -0
  76. data/spec/test_data/v6.0/expected_application_job.rbi +20 -0
  77. data/spec/test_data/v6.0/expected_application_mailer.rbi +1 -1
  78. data/spec/test_data/v6.0/expected_attachment.rbi +12 -0
  79. data/spec/test_data/v6.0/expected_award_house_point_hourglasses.rbi +20 -0
  80. data/spec/test_data/v6.0/expected_blob.rbi +12 -0
  81. data/spec/test_data/v6.0/expected_daily_prophet_mailer.rbi +1 -1
  82. data/spec/test_data/v6.0/expected_hogwarts_acceptance_mailer.rbi +1 -1
  83. data/spec/test_data/v6.0/expected_internal_metadata.rbi +12 -0
  84. data/spec/test_data/v6.0/expected_potion.rbi +12 -0
  85. data/spec/test_data/v6.0/expected_robe.rbi +12 -0
  86. data/spec/test_data/v6.0/expected_schema_migration.rbi +12 -0
  87. data/spec/test_data/v6.0/expected_school.rbi +12 -0
  88. data/spec/test_data/v6.0/expected_spell_book.rbi +12 -0
  89. data/spec/test_data/v6.0/expected_squib.rbi +12 -0
  90. data/spec/test_data/v6.0/expected_wand.rbi +12 -0
  91. data/spec/test_data/v6.0/expected_wizard.rbi +12 -0
  92. data/spec/test_data/v6.0/expected_wizard_wo_spellbook.rbi +12 -0
  93. metadata +34 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2400ac696f93d779e930dac9f4d6e5781f1ce976e1ee98599a222a78c658588
4
- data.tar.gz: 25d8ef2f00b2eb87afe05144323927df66f328ffe2bcff00c578396824d5053e
3
+ metadata.gz: a7e0b556a5c7db33a8fa24c494fa70265802a360eb842545b6124d54ade20e47
4
+ data.tar.gz: 5f26a6773d2769e1dfc523f4202b179ded8deaebb65e05ade61291f03153f164
5
5
  SHA512:
6
- metadata.gz: 8bb839d0eb25c882678e7099796b30ad4215d722a809038593b589c3c6b1bb2b37c42813539e0e314977425052f24b11f85f193f03c84aceb0145d32f0e361bb
7
- data.tar.gz: ce4d93314cbeb06d881177429ba7df4b02d5c7783e9cae839dbfa46fb746b611d13dcc49fd996baf839319af47d848d44860e4561474db104d79fd8f797220f4
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 is 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
+ 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.
@@ -0,0 +1,3 @@
1
+ # typed: strong
2
+ class ActiveJob::Base
3
+ end
@@ -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
- 'This is an autogenerated file for Rails helpers.',
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{sorbet-rails}
3
- s.version = "0.6.1"
3
+ s.version = "0.6.2"
4
4
  s.date = %q{2019-04-18}
5
5
  s.summary = %q{Set of tools to make Sorbet work with Rails seamlessly.}
6
6
  s.authors = ["Chan Zuckerberg Initiative"]
@@ -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.1)
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.9.2)
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.0.0)
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.4)
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.5420)
118
- sorbet-static (= 0.5.5420)
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.5420)
125
- sorbet-static (0.5.5420-universal-darwin-14)
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.1)
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.9.2)
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.0.0)
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.4)
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.5420)
119
- sorbet-static (= 0.5.5420)
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.5420)
126
- sorbet-static (0.5.5420-universal-darwin-14)
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)