type_toolkit 0.0.5 → 0.0.7
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 +4 -4
- data/.github/workflows/ci.yml +0 -4
- data/README.md +61 -0
- data/Rakefile +0 -7
- data/benchmark/.rubocop.yml +7 -0
- data/benchmark/abstract_methods_benchmark.rb +221 -0
- data/benchmark/interface_startup_performance.rb +128 -0
- data/benchmark/module_benchmark.rb +62 -0
- data/config/default.yml +5 -0
- data/docs/design/inherited_implementation_problem.md +258 -0
- data/docs/design/self_dot_methods.md +79 -0
- data/lib/rubocop/cop/type_toolkit/plugin.rb +1 -1
- data/lib/rubocop/cop/type_toolkit/prefer_not_nil.rb +150 -0
- data/lib/rubocop-type_toolkit.rb +1 -0
- data/lib/type_toolkit/abstract_method_receiver.rb +39 -0
- data/lib/type_toolkit/dsl.rb +66 -0
- data/lib/type_toolkit/ext/method.rb +11 -0
- data/lib/type_toolkit/ext/module.rb +7 -0
- data/lib/type_toolkit/ext/nil_assertions.rb +3 -1
- data/lib/type_toolkit/has_abstract_methods.rb +108 -0
- data/lib/type_toolkit/interface.rb +38 -0
- data/lib/type_toolkit/method_def_recorder.rb +53 -0
- data/lib/type_toolkit/method_patch.rb +16 -0
- data/lib/type_toolkit/version.rb +1 -1
- data/lib/type_toolkit.rb +3 -0
- data/sorbet/config +3 -1
- data/sorbet/rbi/gems/benchmark-ips@2.14.0.rbi +981 -0
- data/sorbet/rbi/gems/{erb@6.0.1.rbi → erb@6.0.1.1.rbi} +2 -2
- data/sorbet/rbi/gems/{json@2.18.1.rbi → json@2.19.9.rbi} +115 -161
- data/sorbet/rbi/gems/minitest@5.27.0.rbi +707 -0
- data/sorbet/rbi/gems/rexml@3.4.4.rbi +0 -167
- data/sorbet/rbi/gems/rubocop-ast@1.49.0.rbi +6 -0
- data/sorbet/rbi/gems/rubocop@1.84.2.rbi +7 -0
- data/sorbet/rbi/gems/tapioca@0.17.10.rbi +1 -0
- data/sorbet/rbi/gems/{yard@0.9.38.rbi → yard@0.9.44.rbi} +1206 -241
- data/sorbet/rbi/shims/core.rbi +19 -0
- data/sorbet/rbi/shims/minitest.rbi +5 -2
- data/sorbet/rbi/shims/rubocop_minitest.rbi +5 -2
- data/spec/interface_spec.rb +419 -0
- data/spec/misc/how_method_added_hooks_work_spec.rb +63 -0
- data/spec/rubocop/cop/type_toolkit/prefer_not_nil_spec.rb +464 -0
- data/spec/spec_helper.rb +14 -0
- metadata +24 -4
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "spec_helper"
|
|
5
|
+
require "rubocop"
|
|
6
|
+
require "rubocop/minitest/assert_offense"
|
|
7
|
+
require "rubocop-type_toolkit"
|
|
8
|
+
|
|
9
|
+
module RuboCop
|
|
10
|
+
module Cop
|
|
11
|
+
module TypeToolkit
|
|
12
|
+
class PreferNotNilSpec < ::Minitest::Spec
|
|
13
|
+
include RuboCop::Minitest::AssertOffense
|
|
14
|
+
|
|
15
|
+
MSG = "TypeToolkit/PreferNotNil: #{format(PreferNotNil::MSG, method: :must)}"
|
|
16
|
+
BECAUSE_MSG = "TypeToolkit/PreferNotNil: #{format(PreferNotNil::MSG, method: :must_because)}"
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
@cop = PreferNotNil.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "autocorrects T.must" do
|
|
23
|
+
assert_offense(<<~RUBY)
|
|
24
|
+
value = T.must(foo)
|
|
25
|
+
^^^^^^^^^^^ #{MSG}
|
|
26
|
+
RUBY
|
|
27
|
+
|
|
28
|
+
assert_correction(<<~RUBY)
|
|
29
|
+
value = foo.not_nil!
|
|
30
|
+
RUBY
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "autocorrects ::T.must" do
|
|
34
|
+
assert_offense(<<~RUBY)
|
|
35
|
+
value = ::T.must(foo)
|
|
36
|
+
^^^^^^^^^^^^^ #{MSG}
|
|
37
|
+
RUBY
|
|
38
|
+
|
|
39
|
+
assert_correction(<<~RUBY)
|
|
40
|
+
value = foo.not_nil!
|
|
41
|
+
RUBY
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "autocorrects inside string interpolation" do
|
|
45
|
+
assert_offense(<<~RUBY)
|
|
46
|
+
string = "\#{T.must(foo)}"
|
|
47
|
+
^^^^^^^^^^^ #{MSG}
|
|
48
|
+
RUBY
|
|
49
|
+
|
|
50
|
+
assert_correction(<<~RUBY)
|
|
51
|
+
string = "\#{foo.not_nil!}"
|
|
52
|
+
RUBY
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "preserves the precedence of conditional and range expressions" do
|
|
56
|
+
assert_offense(<<~RUBY)
|
|
57
|
+
conditional = T.must(condition ? foo : bar)
|
|
58
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
59
|
+
range = T.must(foo..bar)
|
|
60
|
+
^^^^^^^^^^^^^^^^ #{MSG}
|
|
61
|
+
RUBY
|
|
62
|
+
|
|
63
|
+
assert_correction(<<~RUBY)
|
|
64
|
+
conditional = (condition ? foo : bar).not_nil!
|
|
65
|
+
range = (foo..bar).not_nil!
|
|
66
|
+
RUBY
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "parenthesizes every expression that requires it" do
|
|
70
|
+
assert_offense(<<~RUBY)
|
|
71
|
+
operator = T.must(foo + bar)
|
|
72
|
+
^^^^^^^^^^^^^^^^^ #{MSG}
|
|
73
|
+
logical = T.must(foo || bar)
|
|
74
|
+
^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
75
|
+
grouped = T.must((foo || bar))
|
|
76
|
+
^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
77
|
+
assignment = T.must(foo = bar)
|
|
78
|
+
^^^^^^^^^^^^^^^^^ #{MSG}
|
|
79
|
+
block_value = T.must(foo { bar })
|
|
80
|
+
^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
81
|
+
block_with_arguments = T.must(foo(arg) { |value| value })
|
|
82
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
83
|
+
defined_value = T.must(defined?(foo))
|
|
84
|
+
^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
85
|
+
def example
|
|
86
|
+
T.must(yield foo)
|
|
87
|
+
^^^^^^^^^^^^^^^^^ #{MSG}
|
|
88
|
+
end
|
|
89
|
+
def implicit_super
|
|
90
|
+
T.must(super)
|
|
91
|
+
^^^^^^^^^^^^^ #{MSG}
|
|
92
|
+
end
|
|
93
|
+
def explicit_super
|
|
94
|
+
T.must(super(foo))
|
|
95
|
+
^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
96
|
+
end
|
|
97
|
+
RUBY
|
|
98
|
+
|
|
99
|
+
assert_correction(<<~RUBY)
|
|
100
|
+
operator = (foo + bar).not_nil!
|
|
101
|
+
logical = (foo || bar).not_nil!
|
|
102
|
+
grouped = (foo || bar).not_nil!
|
|
103
|
+
assignment = (foo = bar).not_nil!
|
|
104
|
+
block_value = foo { bar }.not_nil!
|
|
105
|
+
block_with_arguments = foo(arg) { |value| value }.not_nil!
|
|
106
|
+
defined_value = (defined?(foo)).not_nil!
|
|
107
|
+
def example
|
|
108
|
+
(yield foo).not_nil!
|
|
109
|
+
end
|
|
110
|
+
def implicit_super
|
|
111
|
+
(super).not_nil!
|
|
112
|
+
end
|
|
113
|
+
def explicit_super
|
|
114
|
+
(super(foo)).not_nil!
|
|
115
|
+
end
|
|
116
|
+
RUBY
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "preserves the precedence of command calls" do
|
|
120
|
+
assert_offense(<<~RUBY)
|
|
121
|
+
value = T.must(fetch value)
|
|
122
|
+
^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
123
|
+
RUBY
|
|
124
|
+
|
|
125
|
+
assert_correction(<<~RUBY)
|
|
126
|
+
value = (fetch value).not_nil!
|
|
127
|
+
RUBY
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "autocorrects multiline command calls" do
|
|
131
|
+
assert_offense(<<~RUBY)
|
|
132
|
+
T.must foo
|
|
133
|
+
^^^^^^^^^^ #{MSG}
|
|
134
|
+
.bar
|
|
135
|
+
RUBY
|
|
136
|
+
|
|
137
|
+
assert_correction(<<~RUBY)
|
|
138
|
+
foo
|
|
139
|
+
.bar.not_nil!
|
|
140
|
+
RUBY
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "does not add unnecessary parentheses to parenthesized calls" do
|
|
144
|
+
assert_offense(<<~RUBY)
|
|
145
|
+
value = T.must(fetch(value))
|
|
146
|
+
^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
147
|
+
RUBY
|
|
148
|
+
|
|
149
|
+
assert_correction(<<~RUBY)
|
|
150
|
+
value = fetch(value).not_nil!
|
|
151
|
+
RUBY
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "parenthesizes bracket method calls only when required" do
|
|
155
|
+
assert_offense(<<~RUBY)
|
|
156
|
+
bracketed = T.must(foo[bar]).foo
|
|
157
|
+
^^^^^^^^^^^^^^^^ #{MSG}
|
|
158
|
+
explicit = T.must(foo.[](bar)).foo
|
|
159
|
+
^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
160
|
+
command = T.must(foo.[] bar).foo
|
|
161
|
+
^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
162
|
+
RUBY
|
|
163
|
+
|
|
164
|
+
assert_correction(<<~RUBY)
|
|
165
|
+
bracketed = foo[bar].not_nil!.foo
|
|
166
|
+
explicit = foo.[](bar).not_nil!.foo
|
|
167
|
+
command = (foo.[] bar).not_nil!.foo
|
|
168
|
+
RUBY
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "does not group an argument that makes the call multiline" do
|
|
172
|
+
assert_offense(<<~RUBY)
|
|
173
|
+
T.must(foo
|
|
174
|
+
^^^^^^^^^^ #{MSG}
|
|
175
|
+
.bar)
|
|
176
|
+
RUBY
|
|
177
|
+
|
|
178
|
+
assert_correction(<<~RUBY)
|
|
179
|
+
foo
|
|
180
|
+
.bar.not_nil!
|
|
181
|
+
RUBY
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "preserves a multiline receiver without parentheses" do
|
|
185
|
+
assert_offense(<<~RUBY)
|
|
186
|
+
T.must(
|
|
187
|
+
^^^^^^^ #{MSG}
|
|
188
|
+
foo.
|
|
189
|
+
bar
|
|
190
|
+
)
|
|
191
|
+
RUBY
|
|
192
|
+
|
|
193
|
+
assert_correction(<<~RUBY)
|
|
194
|
+
foo.
|
|
195
|
+
bar.not_nil!
|
|
196
|
+
RUBY
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "preserves comments in multiline calls" do
|
|
200
|
+
assert_offense(<<~RUBY)
|
|
201
|
+
value = T.must(
|
|
202
|
+
^^^^^^^ #{MSG}
|
|
203
|
+
# Proven non-nil by validation.
|
|
204
|
+
foo,
|
|
205
|
+
)
|
|
206
|
+
RUBY
|
|
207
|
+
|
|
208
|
+
assert_correction(<<~RUBY)
|
|
209
|
+
value = (
|
|
210
|
+
# Proven non-nil by validation.
|
|
211
|
+
foo
|
|
212
|
+
).not_nil!
|
|
213
|
+
RUBY
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "drops unnecessary grouping from multiline calls without comments" do
|
|
217
|
+
assert_offense(<<~RUBY)
|
|
218
|
+
first = T .must(
|
|
219
|
+
^^^^^^^^ #{MSG}
|
|
220
|
+
foo,
|
|
221
|
+
)
|
|
222
|
+
second = T
|
|
223
|
+
^ #{MSG}
|
|
224
|
+
.must(
|
|
225
|
+
bar,
|
|
226
|
+
)
|
|
227
|
+
RUBY
|
|
228
|
+
|
|
229
|
+
assert_correction(<<~RUBY)
|
|
230
|
+
first = foo.not_nil!
|
|
231
|
+
second = bar.not_nil!
|
|
232
|
+
RUBY
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it "preserves a multiline call chain without parentheses" do
|
|
236
|
+
assert_offense(<<~RUBY)
|
|
237
|
+
variant = T.must(
|
|
238
|
+
^^^^^^^ #{MSG}
|
|
239
|
+
InventoryItemVariant.preload(:variant).where(inventory_item_id: @inventory_item_id).first!.variant
|
|
240
|
+
)
|
|
241
|
+
RUBY
|
|
242
|
+
|
|
243
|
+
assert_correction(<<~RUBY)
|
|
244
|
+
variant = InventoryItemVariant.preload(:variant).where(inventory_item_id: @inventory_item_id).first!.variant.not_nil!
|
|
245
|
+
RUBY
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "removes a trailing comma before an inline comment" do
|
|
249
|
+
assert_offense(<<~RUBY)
|
|
250
|
+
value = T.must(
|
|
251
|
+
^^^^^^^ #{MSG}
|
|
252
|
+
foo, # Proven non-nil.
|
|
253
|
+
)
|
|
254
|
+
RUBY
|
|
255
|
+
|
|
256
|
+
assert_correction(<<~RUBY)
|
|
257
|
+
value = (
|
|
258
|
+
foo # Proven non-nil.
|
|
259
|
+
).not_nil!
|
|
260
|
+
RUBY
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "preserves grouping around heredocs in multiline calls" do
|
|
264
|
+
assert_offense(<<~RUBY)
|
|
265
|
+
value = T.must(
|
|
266
|
+
^^^^^^^ #{MSG}
|
|
267
|
+
<<~TEXT
|
|
268
|
+
hello
|
|
269
|
+
TEXT
|
|
270
|
+
)
|
|
271
|
+
RUBY
|
|
272
|
+
|
|
273
|
+
assert_correction(<<~RUBY)
|
|
274
|
+
value = (
|
|
275
|
+
<<~TEXT
|
|
276
|
+
hello
|
|
277
|
+
TEXT
|
|
278
|
+
).not_nil!
|
|
279
|
+
RUBY
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "preserves grouping around nested heredocs in multiline calls" do
|
|
283
|
+
assert_offense(<<~RUBY)
|
|
284
|
+
value = T.must(
|
|
285
|
+
^^^^^^^ #{MSG}
|
|
286
|
+
foo(<<~TEXT)
|
|
287
|
+
hello
|
|
288
|
+
TEXT
|
|
289
|
+
)
|
|
290
|
+
RUBY
|
|
291
|
+
|
|
292
|
+
assert_correction(<<~RUBY)
|
|
293
|
+
value = (
|
|
294
|
+
foo(<<~TEXT)
|
|
295
|
+
hello
|
|
296
|
+
TEXT
|
|
297
|
+
).not_nil!
|
|
298
|
+
RUBY
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "preserves grouping around a heredoc T.must nested in another call" do
|
|
302
|
+
assert_offense(<<~RUBY)
|
|
303
|
+
value = foo(
|
|
304
|
+
T.must(
|
|
305
|
+
^^^^^^^ #{MSG}
|
|
306
|
+
<<~TEXT
|
|
307
|
+
hello
|
|
308
|
+
TEXT
|
|
309
|
+
)
|
|
310
|
+
)
|
|
311
|
+
RUBY
|
|
312
|
+
|
|
313
|
+
assert_correction(<<~RUBY)
|
|
314
|
+
value = foo(
|
|
315
|
+
(
|
|
316
|
+
<<~TEXT
|
|
317
|
+
hello
|
|
318
|
+
TEXT
|
|
319
|
+
).not_nil!
|
|
320
|
+
)
|
|
321
|
+
RUBY
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "autocorrects nested T.must calls" do
|
|
325
|
+
assert_offense(<<~RUBY)
|
|
326
|
+
value = T.must(T.must(foo).bar)
|
|
327
|
+
^^^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
328
|
+
^^^^^^^^^^^ #{MSG}
|
|
329
|
+
RUBY
|
|
330
|
+
|
|
331
|
+
assert_correction(<<~RUBY)
|
|
332
|
+
value = foo.not_nil!.bar.not_nil!
|
|
333
|
+
RUBY
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "autocorrects three nested T.must calls" do
|
|
337
|
+
assert_offense(<<~RUBY)
|
|
338
|
+
value = T.must(T.must(T.must(foo).bar).baz)
|
|
339
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
340
|
+
^^^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
341
|
+
^^^^^^^^^^^ #{MSG}
|
|
342
|
+
RUBY
|
|
343
|
+
|
|
344
|
+
assert_correction(<<~RUBY)
|
|
345
|
+
value = foo.not_nil!.bar.not_nil!.baz.not_nil!
|
|
346
|
+
RUBY
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
it "reports heredoc reasons without leaving orphaned heredoc bodies" do
|
|
350
|
+
assert_offense(<<~RUBY)
|
|
351
|
+
value = T.must_because(foo) { <<~REASON }
|
|
352
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{BECAUSE_MSG}
|
|
353
|
+
Proven non-nil.
|
|
354
|
+
REASON
|
|
355
|
+
RUBY
|
|
356
|
+
|
|
357
|
+
assert_no_corrections
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it "preserves the reason without attaching the block to the corrected call" do
|
|
361
|
+
assert_offense(<<~RUBY)
|
|
362
|
+
value = T.must_because(foo) { "reason" }.bar
|
|
363
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{BECAUSE_MSG}
|
|
364
|
+
RUBY
|
|
365
|
+
|
|
366
|
+
assert_correction(<<~RUBY)
|
|
367
|
+
value = (
|
|
368
|
+
# reason
|
|
369
|
+
foo.not_nil!
|
|
370
|
+
).bar
|
|
371
|
+
RUBY
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "preserves multiline reasons and argument comments" do
|
|
375
|
+
assert_offense(<<~RUBY)
|
|
376
|
+
value = ::T.must_because(
|
|
377
|
+
^^^^^^^^^^^^^^^^^ #{BECAUSE_MSG}
|
|
378
|
+
# Validated earlier.
|
|
379
|
+
foo,
|
|
380
|
+
) do
|
|
381
|
+
# Explain the invariant.
|
|
382
|
+
"validated for \#{user}"
|
|
383
|
+
end
|
|
384
|
+
RUBY
|
|
385
|
+
|
|
386
|
+
assert_correction(<<~RUBY)
|
|
387
|
+
value = (
|
|
388
|
+
# # Explain the invariant.
|
|
389
|
+
# validated for \#{user}
|
|
390
|
+
# Validated earlier.
|
|
391
|
+
foo
|
|
392
|
+
).not_nil!
|
|
393
|
+
RUBY
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it "keeps trailing arguments and string interpolation outside the reason comment" do
|
|
397
|
+
assert_offense(<<~'RUBY', message: BECAUSE_MSG)
|
|
398
|
+
values = [T.must_because(foo) { 'reason' }, bar]
|
|
399
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ %{message}
|
|
400
|
+
text = "#{T.must_because(foo) { "reason" }}"
|
|
401
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ %{message}
|
|
402
|
+
RUBY
|
|
403
|
+
|
|
404
|
+
assert_correction(<<~'RUBY')
|
|
405
|
+
values = [(
|
|
406
|
+
# reason
|
|
407
|
+
foo.not_nil!
|
|
408
|
+
), bar]
|
|
409
|
+
text = "#{(
|
|
410
|
+
# reason
|
|
411
|
+
foo.not_nil!
|
|
412
|
+
)}"
|
|
413
|
+
RUBY
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
it "corrects mixed nested assertions without overlapping edits" do
|
|
417
|
+
assert_offense(<<~RUBY)
|
|
418
|
+
value = T.must(T.must_because(T.must(foo)) { "reason" })
|
|
419
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{MSG}
|
|
420
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{BECAUSE_MSG}
|
|
421
|
+
^^^^^^^^^^^ #{MSG}
|
|
422
|
+
RUBY
|
|
423
|
+
|
|
424
|
+
assert_correction(<<~RUBY)
|
|
425
|
+
value = (
|
|
426
|
+
# reason
|
|
427
|
+
foo.not_nil!.not_nil!
|
|
428
|
+
).not_nil!
|
|
429
|
+
RUBY
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
it "comments out assertions in the reason rather than correcting them" do
|
|
433
|
+
assert_offense(<<~RUBY)
|
|
434
|
+
value = T.must_because(foo) { T.must(bar) }
|
|
435
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{BECAUSE_MSG}
|
|
436
|
+
^^^^^^^^^^^ #{MSG}
|
|
437
|
+
RUBY
|
|
438
|
+
|
|
439
|
+
assert_correction(<<~RUBY)
|
|
440
|
+
value = (
|
|
441
|
+
# T.must(bar)
|
|
442
|
+
foo.not_nil!
|
|
443
|
+
)
|
|
444
|
+
RUBY
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
it "ignores other receivers, methods, and argument counts" do
|
|
448
|
+
assert_no_offenses(<<~RUBY)
|
|
449
|
+
Other::T.must(foo)
|
|
450
|
+
object.must(foo)
|
|
451
|
+
T.let(foo, String)
|
|
452
|
+
T.must(foo, bar)
|
|
453
|
+
T.must(*values)
|
|
454
|
+
Other::T.must_because(foo) { "reason" }
|
|
455
|
+
object.must_because(foo) { "reason" }
|
|
456
|
+
T.must_because(foo, bar) { "reason" }
|
|
457
|
+
T.must_because(*values) { "reason" }
|
|
458
|
+
T.must_because(foo, &reason)
|
|
459
|
+
RUBY
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -6,3 +6,17 @@ require "type_toolkit"
|
|
|
6
6
|
|
|
7
7
|
require "minitest/autorun"
|
|
8
8
|
require "minitest/spec"
|
|
9
|
+
|
|
10
|
+
module Minitest
|
|
11
|
+
class Spec
|
|
12
|
+
#: () { () -> void } -> TypeToolkit::AbstractMethodNotImplementedError
|
|
13
|
+
def assert_abstract(&block)
|
|
14
|
+
assert_raises(TypeToolkit::AbstractMethodNotImplementedError, &block)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#: -> bot
|
|
20
|
+
def assert_never_called!
|
|
21
|
+
raise Minitest::Assertion, "This should never be called"
|
|
22
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: type_toolkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Momchilov
|
|
@@ -52,12 +52,27 @@ files:
|
|
|
52
52
|
- ".ruby-version"
|
|
53
53
|
- README.md
|
|
54
54
|
- Rakefile
|
|
55
|
+
- benchmark/.rubocop.yml
|
|
56
|
+
- benchmark/abstract_methods_benchmark.rb
|
|
57
|
+
- benchmark/interface_startup_performance.rb
|
|
58
|
+
- benchmark/module_benchmark.rb
|
|
55
59
|
- config/default.yml
|
|
60
|
+
- docs/design/inherited_implementation_problem.md
|
|
61
|
+
- docs/design/self_dot_methods.md
|
|
56
62
|
- lib/rubocop-type_toolkit.rb
|
|
57
63
|
- lib/rubocop/cop/type_toolkit/dont_expect_unexpected_nil.rb
|
|
58
64
|
- lib/rubocop/cop/type_toolkit/plugin.rb
|
|
65
|
+
- lib/rubocop/cop/type_toolkit/prefer_not_nil.rb
|
|
59
66
|
- lib/type_toolkit.rb
|
|
67
|
+
- lib/type_toolkit/abstract_method_receiver.rb
|
|
68
|
+
- lib/type_toolkit/dsl.rb
|
|
69
|
+
- lib/type_toolkit/ext/method.rb
|
|
70
|
+
- lib/type_toolkit/ext/module.rb
|
|
60
71
|
- lib/type_toolkit/ext/nil_assertions.rb
|
|
72
|
+
- lib/type_toolkit/has_abstract_methods.rb
|
|
73
|
+
- lib/type_toolkit/interface.rb
|
|
74
|
+
- lib/type_toolkit/method_def_recorder.rb
|
|
75
|
+
- lib/type_toolkit/method_patch.rb
|
|
61
76
|
- lib/type_toolkit/version.rb
|
|
62
77
|
- sig/type_toolkit.rbs
|
|
63
78
|
- sorbet/config
|
|
@@ -66,12 +81,13 @@ files:
|
|
|
66
81
|
- sorbet/rbi/annotations/rainbow.rbi
|
|
67
82
|
- sorbet/rbi/gems/.gitattributes
|
|
68
83
|
- sorbet/rbi/gems/ast@2.4.3.rbi
|
|
84
|
+
- sorbet/rbi/gems/benchmark-ips@2.14.0.rbi
|
|
69
85
|
- sorbet/rbi/gems/benchmark@0.5.0.rbi
|
|
70
86
|
- sorbet/rbi/gems/date@3.5.1.rbi
|
|
71
|
-
- sorbet/rbi/gems/erb@6.0.1.rbi
|
|
87
|
+
- sorbet/rbi/gems/erb@6.0.1.1.rbi
|
|
72
88
|
- sorbet/rbi/gems/erubi@1.13.1.rbi
|
|
73
89
|
- sorbet/rbi/gems/io-console@0.8.2.rbi
|
|
74
|
-
- sorbet/rbi/gems/json@2.
|
|
90
|
+
- sorbet/rbi/gems/json@2.19.9.rbi
|
|
75
91
|
- sorbet/rbi/gems/language_server-protocol@3.17.0.5.rbi
|
|
76
92
|
- sorbet/rbi/gems/lint_roller@1.1.0.rbi
|
|
77
93
|
- sorbet/rbi/gems/logger@1.7.0.rbi
|
|
@@ -107,15 +123,19 @@ files:
|
|
|
107
123
|
- sorbet/rbi/gems/unicode-display_width@3.2.0.rbi
|
|
108
124
|
- sorbet/rbi/gems/unicode-emoji@4.2.0.rbi
|
|
109
125
|
- sorbet/rbi/gems/yard-sorbet@0.9.0.rbi
|
|
110
|
-
- sorbet/rbi/gems/yard@0.9.
|
|
126
|
+
- sorbet/rbi/gems/yard@0.9.44.rbi
|
|
127
|
+
- sorbet/rbi/shims/core.rbi
|
|
111
128
|
- sorbet/rbi/shims/minitest.rbi
|
|
112
129
|
- sorbet/rbi/shims/rubocop_minitest.rbi
|
|
113
130
|
- sorbet/rbi/todo.rbi
|
|
114
131
|
- sorbet/tapioca/config.yml
|
|
115
132
|
- sorbet/tapioca/require.rb
|
|
116
133
|
- spec/.rubocop.yml
|
|
134
|
+
- spec/interface_spec.rb
|
|
135
|
+
- spec/misc/how_method_added_hooks_work_spec.rb
|
|
117
136
|
- spec/nil_assertions_spec.rb
|
|
118
137
|
- spec/rubocop/cop/type_toolkit/dont_expect_unexpected_nil_spec.rb
|
|
138
|
+
- spec/rubocop/cop/type_toolkit/prefer_not_nil_spec.rb
|
|
119
139
|
- spec/spec_helper.rb
|
|
120
140
|
- spec/type_toolkit_spec.rb
|
|
121
141
|
homepage: https://github.com/Shopify/type_kit
|