sevencop 0.24.4 → 0.26.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9088cb86686701cb1c115190aeff24d1e4828ff5db228981edbcfbd0303b941
4
- data.tar.gz: a1ae55865f74bd7e4707be7df3d53964c622c048484f4e679e90fc7604383456
3
+ metadata.gz: 9b03712edc9d72494a99f77fe83b616b83314f1b72347dd96fbe30d3ecb66508
4
+ data.tar.gz: bf06a9f54c5dfea1d64c357d70e14287b389efe7f26474c87355e38ab7bc5736
5
5
  SHA512:
6
- metadata.gz: a871f2e1ce6a83aa0e78a77f2445f73fffb33c4019fbb99f91cfc9bd717ad9fd46548322de8816dcc745113a1304bc0024ecacf28629a745e93612d1286f3d58
7
- data.tar.gz: 58765fd6530c476d4a3c411cce6373c3f9f42b804e4b91a6f5e6ac43fbb923ade08e538ccdf27c3d2b94da24a43feb33392e94841e25a33ac2e65e5f11d3017d
6
+ metadata.gz: 260701a809a5b831e985ff159550b62bec1e0801c80dbfd7ed79a55ab9297307512116c6cc96161bdf374a8afcd350ea993543b335d5621f296d5d2bbdc451d1
7
+ data.tar.gz: 894f7f028033cf169c1f5576b29418245dfbe052f6e088e5f5a021c040fef68ab9784f969a98c17287ebbfe5832d79f2d107fd932b5d1f0953c04c07d8f6f07a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sevencop (0.24.4)
4
+ sevencop (0.26.0)
5
5
  activesupport
6
6
  rubocop
7
7
 
data/README.md CHANGED
@@ -38,6 +38,7 @@ Note that all cops are `Enabled: false` by default.
38
38
  - [Sevencop/MethodDefinitionOrdered](lib/rubocop/cop/sevencop/method_definition_ordered.rb)
39
39
  - [Sevencop/RailsActionName](lib/rubocop/cop/sevencop/rails_action_name.rb)
40
40
  - [Sevencop/RailsBelongsToOptional](lib/rubocop/cop/sevencop/rails_belongs_to_optional.rb)
41
+ - [Sevencop/RailsDateAndTimeCalculation](lib/rubocop/cop/sevencop/rails_date_and_time_calculation.rb)
41
42
  - [Sevencop/RailsInferredSpecType](lib/rubocop/cop/sevencop/rails_inferred_spec_type.rb)
42
43
  - [Sevencop/RailsOrderField](lib/rubocop/cop/sevencop/rails_order_field.rb)
43
44
  - [Sevencop/RailsUniquenessValidatorExplicitCaseSensitivity](lib/rubocop/cop/sevencop/rails_uniqueness_validator_explicit_case_sensitivity.rb)
data/config/default.yml CHANGED
@@ -91,6 +91,13 @@ Sevencop/RailsBelongsToOptional:
91
91
  Safe: false
92
92
  VersionAdded: '0.5'
93
93
 
94
+ Sevencop/RailsDateAndTimeCalculation:
95
+ Description: |
96
+ Prefer ActiveSupport date and time helper.
97
+ Enabled: false
98
+ Safe: false
99
+ VersionAdded: '0.26'
100
+
94
101
  Sevencop/RailsInferredSpecType:
95
102
  Description: |
96
103
  Identifies redundant spec type.
@@ -139,6 +146,7 @@ Sevencop/RSpecExamplesInSameGroup:
139
146
  Combine examples in the same groups in the time-consuming kinds of specs.
140
147
  Enabled: false
141
148
  VersionAdded: '0.17'
149
+ IncludeSharedExamples: false
142
150
  Include:
143
151
  - spec/controllers/**/*
144
152
  - spec/requests/**/*
@@ -0,0 +1,768 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Sevencop
6
+ # Prefer ActiveSupport date and time helper.
7
+ #
8
+ # @safety
9
+ # This cop is unsafe becuase it considers that `n.days` is a Duration,
10
+ # and `date` in `date == Date.current` is a Date, but there is no guarantee.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # Time.zone.now
15
+ #
16
+ # # good
17
+ # Time.current
18
+ #
19
+ # # bad
20
+ # Time.zone.today
21
+ #
22
+ # # good
23
+ # Date.current
24
+ #
25
+ # # bad
26
+ # Time.current.to_date
27
+ #
28
+ # # good
29
+ # Date.current
30
+ #
31
+ # # bad
32
+ # Date.current.tomorrow
33
+ #
34
+ # # good
35
+ # Date.tomorrow
36
+ #
37
+ # # bad
38
+ # Date.current.yesterday
39
+ #
40
+ # # good
41
+ # Date.yesterday
42
+ #
43
+ # # bad
44
+ # date == Date.current
45
+ # Date.current == date
46
+ #
47
+ # # good
48
+ # date.today?
49
+ #
50
+ # # bad
51
+ # date == Date.tomorrow
52
+ # Date.tomorrow == date
53
+ #
54
+ # # good
55
+ # date.tomorrow?
56
+ #
57
+ # # bad
58
+ # date == Date.yesterday
59
+ # Date.yesterday == date
60
+ #
61
+ # # good
62
+ # date.yesterday?
63
+ #
64
+ # # bad
65
+ # Time.current - n.days
66
+ # Time.zone.now - n.days
67
+ #
68
+ # # good
69
+ # n.days.ago
70
+ #
71
+ # # bad
72
+ # Time.current + n.days
73
+ #
74
+ # # good
75
+ # n.days.since
76
+ #
77
+ # # bad
78
+ # Date.current - 1
79
+ # Date.current - 1.day
80
+ #
81
+ # # good
82
+ # Date.yesterday
83
+ #
84
+ # # bad
85
+ # Date.current + 1
86
+ # Date.current + 1.day
87
+ #
88
+ # # good
89
+ # Date.tomorrow
90
+ #
91
+ # # bad
92
+ # time.after?(Time.current)
93
+ # time > Time.current
94
+ # Time.current < time
95
+ # Time.current.before?(time)
96
+ #
97
+ # # good
98
+ # time.future?
99
+ #
100
+ # # bad
101
+ # time.before?(Time.current)
102
+ # time < Time.current
103
+ # Time.current > time
104
+ # Time.current.after?(time)
105
+ #
106
+ # # good
107
+ # time.past?
108
+ class RailsDateAndTimeCalculation < Base
109
+ extend AutoCorrector
110
+
111
+ CALCULATION_METHOD_NAMES = ::Set.new(
112
+ %i[
113
+ -
114
+ +
115
+ ]
116
+ ).freeze
117
+
118
+ COMPARISON_METHOD_NAMES = ::Set.new(
119
+ %i[
120
+ <
121
+ >
122
+ after?
123
+ before?
124
+ ]
125
+ ).freeze
126
+
127
+ DURATION_METHOD_NAMES = ::Set.new(
128
+ %i[
129
+ day
130
+ days
131
+ fortnight
132
+ fortnights
133
+ hour
134
+ hours
135
+ minute
136
+ minutes
137
+ month
138
+ months
139
+ second
140
+ seconds
141
+ week
142
+ weeks
143
+ year
144
+ years
145
+ ]
146
+ ).freeze
147
+
148
+ MSG = 'Prefer ActiveSupport date and time helper.'
149
+
150
+ RESTRICT_ON_SEND = [
151
+ *CALCULATION_METHOD_NAMES,
152
+ *COMPARISON_METHOD_NAMES,
153
+ :==,
154
+ :now,
155
+ :to_date,
156
+ :today,
157
+ :tomorrow,
158
+ :yesterday
159
+ ].freeze
160
+
161
+ # @param node [RuboCop::AST::SendNode]
162
+ # @return [void]
163
+ def on_send(node)
164
+ case node.method_name
165
+ when :-
166
+ check_subtraction(node)
167
+ when :+
168
+ check_addition(node)
169
+ when :==
170
+ check_equality(node)
171
+ when :<, :before?
172
+ check_less_than(node)
173
+ when :>, :after?
174
+ check_greater_than(node)
175
+ when :now
176
+ check_now(node)
177
+ when :to_date
178
+ check_to_date(node)
179
+ when :today
180
+ check_today(node)
181
+ when :tomorrow
182
+ check_tomorrow(node)
183
+ when :yesterday
184
+ check_yesterday(node)
185
+ end
186
+ end
187
+
188
+ private
189
+
190
+ # @!method comparison_to_time_current?(node)
191
+ # @param node [RuboCop::AST::Node]
192
+ # @return [Boolean]
193
+ def_node_matcher :comparison_to_time_current?, <<~PATTERN
194
+ {
195
+ #comparison_for_future? |
196
+ #comparison_for_past?
197
+ }
198
+ PATTERN
199
+
200
+ # @!method comparison_for_future?(node)
201
+ # @param node [RuboCop::AST::Node]
202
+ # @return [Boolean]
203
+ def_node_matcher :comparison_for_future?, <<~PATTERN
204
+ {
205
+ #comparison_for_future_with_time_current_left? |
206
+ #comparison_for_future_with_time_current_right?
207
+ }
208
+ PATTERN
209
+
210
+ # @!method comparison_for_future_with_time_current_left?(node)
211
+ # @param node [RuboCop::AST::Node]
212
+ # @return [Boolean]
213
+ def_node_matcher :comparison_for_future_with_time_current_left?, <<~PATTERN
214
+ (send
215
+ #time_current?
216
+ {:< | :before?}
217
+ _
218
+ )
219
+ PATTERN
220
+
221
+ # @!method comparison_for_future_with_time_current_right?(node)
222
+ # @param node [RuboCop::AST::Node]
223
+ # @return [Boolean]
224
+ def_node_matcher :comparison_for_future_with_time_current_right?, <<~PATTERN
225
+ (send
226
+ _
227
+ {:> | :after?}
228
+ #time_current?
229
+ )
230
+ PATTERN
231
+
232
+ # @!method comparison_for_past?(node)
233
+ # @param node [RuboCop::AST::Node]
234
+ # @return [Boolean]
235
+ def_node_matcher :comparison_for_past?, <<~PATTERN
236
+ {
237
+ #comparison_for_past_with_time_current_left? |
238
+ #comparison_for_past_with_time_current_right?
239
+ }
240
+ PATTERN
241
+
242
+ # @!method comparison_for_past_with_time_current_left?(node)
243
+ # @param node [RuboCop::AST::Node]
244
+ # @return [Boolean]
245
+ def_node_matcher :comparison_for_past_with_time_current_left?, <<~PATTERN
246
+ (send
247
+ #time_current?
248
+ {:> | :after?}
249
+ _
250
+ )
251
+ PATTERN
252
+
253
+ # @!method comparison_for_past_with_time_current_right?(node)
254
+ # @param node [RuboCop::AST::Node]
255
+ # @return [Boolean]
256
+ def_node_matcher :comparison_for_past_with_time_current_right?, <<~PATTERN
257
+ (send
258
+ _
259
+ {:< | :before?}
260
+ #time_current?
261
+ )
262
+ PATTERN
263
+
264
+ # @!method date_current?(node)
265
+ # @param node [RuboCop::AST::Node]
266
+ # @return [Booelan]
267
+ def_node_matcher :date_current?, <<~PATTERN
268
+ (send
269
+ (const
270
+ {nil? | cbase}
271
+ :Date
272
+ )
273
+ :current
274
+ )
275
+ PATTERN
276
+
277
+ # @!method date_current_minus_one_day?(node)
278
+ # @param node [RuboCop::AST::Node]
279
+ # @return [Boolean]
280
+ def_node_matcher :date_current_minus_one_day?, <<~PATTERN
281
+ (send
282
+ #date_current?
283
+ :-
284
+ #one_day_on_date_calculation?
285
+ )
286
+ PATTERN
287
+
288
+ # @!method date_current_plus_one_day?(node)
289
+ # @param node [RuboCop::AST::Node]
290
+ # @return [Boolean]
291
+ def_node_matcher :date_current_plus_one_day?, <<~PATTERN
292
+ (send
293
+ #date_current?
294
+ :+
295
+ #one_day_on_date_calculation?
296
+ )
297
+ PATTERN
298
+
299
+ # @!method date_current_with?(node, method_name)
300
+ # @param node [RuboCop::AST::Node]
301
+ # @param method_name [Symbol]
302
+ # @return [Boolean]
303
+ def_node_matcher :date_current_with?, <<~PATTERN
304
+ (send
305
+ #date_current?
306
+ %1
307
+ )
308
+ PATTERN
309
+
310
+ # @!method date_with?(node, method_name)
311
+ # @param node [RuboCop::AST::Node]
312
+ # @param method_name [Symbol]
313
+ # @return [Boolean]
314
+ def_node_matcher :date_with?, <<~PATTERN
315
+ (send
316
+ (const
317
+ {nil? | cbase}
318
+ :Date
319
+ )
320
+ %1
321
+ )
322
+ PATTERN
323
+
324
+ # @!method duration?(node)
325
+ # @param node [RuboCop::AST::Node]
326
+ # @return [Boolean]
327
+ def_node_matcher :duration?, <<~PATTERN
328
+ (send
329
+ _
330
+ DURATION_METHOD_NAMES
331
+ )
332
+ PATTERN
333
+
334
+ # @!method duration_calculation_to_time_current?(node)
335
+ # @param node [RuboCop::AST::Node]
336
+ # @return [Boolean]
337
+ def_node_matcher :duration_calculation_to_time_current?, <<~PATTERN
338
+ (send
339
+ #time_current?
340
+ _
341
+ #duration?
342
+ )
343
+ PATTERN
344
+
345
+ # @!method equals_to_date_with_left?(node, method_name)
346
+ # @param node [RuboCop::AST::Node]
347
+ # @param method_name [Symbol]
348
+ # @return [Boolean]
349
+ def_node_matcher :equals_to_date_with_left?, <<~PATTERN
350
+ (send
351
+ #date_with?(%1)
352
+ :==
353
+ _
354
+ )
355
+ PATTERN
356
+
357
+ # @!method equals_to_date_with_right?(node, method_name)
358
+ # @param node [RuboCop::AST::Node]
359
+ # @param method_name [Symbol]
360
+ # @return [Boolean]
361
+ def_node_matcher :equals_to_date_with_right?, <<~PATTERN
362
+ (send
363
+ _
364
+ :==
365
+ #date_with?(%1)
366
+ )
367
+ PATTERN
368
+
369
+ # @!method one_day_on_date_calculation?(node)
370
+ # @param node [RuboCop::AST::Node]
371
+ # @return [Boolean]
372
+ def_node_matcher :one_day_on_date_calculation?, <<~PATTERN
373
+ {
374
+ (int 1) |
375
+ (send (int 1) :day)
376
+ }
377
+ PATTERN
378
+
379
+ # @!method time_current?(node)
380
+ # @param node [RuboCop::AST::Node]
381
+ # @return [Boolean]
382
+ def_node_matcher :time_current?, <<~PATTERN
383
+ (send
384
+ (const
385
+ {nil? | cbase}
386
+ :Time
387
+ )
388
+ :current
389
+ )
390
+ PATTERN
391
+
392
+ # @!method time_current_to_date?(node)
393
+ # @param node [RuboCop::AST::Node]
394
+ # @return [Boolean]
395
+ def_node_matcher :time_current_to_date?, <<~PATTERN
396
+ (send
397
+ #time_current?
398
+ :to_date
399
+ )
400
+ PATTERN
401
+
402
+ # @!method time_zone_with?(node, method_name)
403
+ # @param node [RuboCop::AST::Node]
404
+ # @param method_name [Symbol]
405
+ # @return [Boolean]
406
+ def_node_matcher :time_zone_with?, <<~PATTERN
407
+ (send
408
+ (send
409
+ (const
410
+ {nil? | cbase}
411
+ :Time
412
+ )
413
+ :zone
414
+ )
415
+ %1
416
+ )
417
+ PATTERN
418
+
419
+ # @param corrector [RuboCop::Cop::Corrector]
420
+ # @param node [RuboCop::AST::SendNode]
421
+ # @return [void]
422
+ def autocorrect_to_comparison_helper_for_time_current(
423
+ corrector,
424
+ node
425
+ )
426
+ corrector.replace(
427
+ node,
428
+ format(
429
+ '%<time>s.%<helper_method_name>s',
430
+ helper_method_name: helper_method_name_for_comparison(node),
431
+ time: find_comparison_subject_to_time_current(node).source
432
+ )
433
+ )
434
+ end
435
+
436
+ # @param corrector [RuboCop::Cop::Corrector]
437
+ # @param helper_method_name [Symbol]
438
+ # @param node [RuboCop::AST::SendNode]
439
+ # @return [void]
440
+ def autocorrect_to_duration_helper(
441
+ corrector,
442
+ node,
443
+ helper_method_name:
444
+ )
445
+ corrector.replace(
446
+ node,
447
+ format(
448
+ '%<duration>s.%<helper_method_name>s',
449
+ duration: node.first_argument.source,
450
+ helper_method_name: helper_method_name
451
+ )
452
+ )
453
+ end
454
+
455
+ # @param corrector [RuboCop::Cop::Corrector]
456
+ # @param date_method_name [Symbol]
457
+ # @param helper_method_name [Symbol]
458
+ # @param node [RuboCop::AST::SendNode]
459
+ # @return [void]
460
+ def autocorrect_to_equality_helper_for_date(
461
+ corrector,
462
+ node,
463
+ date_method_name:,
464
+ helper_method_name:
465
+ )
466
+ corrector.replace(
467
+ node,
468
+ format(
469
+ '%<date>s.%<helper_method_name>s',
470
+ date: find_equality_subject_to_date_with(node, date_method_name).source,
471
+ helper_method_name: helper_method_name
472
+ )
473
+ )
474
+ end
475
+
476
+ # @param node [RuboCop::AST::SendNode]
477
+ # @return [void]
478
+ def check_addition(node)
479
+ check_addition_to_date_current(node)
480
+ check_addition_to_time_current(node)
481
+ end
482
+
483
+ # @param node [RuboCop::AST::SendNode]
484
+ # @return [void]
485
+ def check_addition_to_date_current(node)
486
+ return unless date_current_plus_one_day?(node)
487
+
488
+ add_offense(node) do |corrector|
489
+ replace_keeping_cbase(
490
+ corrector: corrector,
491
+ node: node,
492
+ with: 'Date.tomorrow'
493
+ )
494
+ end
495
+ end
496
+
497
+ # @param node [RuboCop::AST::SendNode]
498
+ # @return [void]
499
+ def check_addition_to_time_current(node)
500
+ return unless duration_calculation_to_time_current?(node)
501
+
502
+ add_offense(node) do |corrector|
503
+ autocorrect_to_duration_helper(
504
+ corrector,
505
+ node,
506
+ helper_method_name: :since
507
+ )
508
+ end
509
+ end
510
+
511
+ # @param node [RuboCop::AST::SendNode]
512
+ # @return [void]
513
+ def check_equality(node)
514
+ check_equality_to_date_current(node)
515
+ check_equality_to_date_tomorrow(node)
516
+ check_equality_to_date_yesterday(node)
517
+ end
518
+
519
+ # @param node [RuboCop::AST::SendNode]
520
+ # @return [void]
521
+ def check_equality_to_date_current(node)
522
+ return unless equals_to_date_with?(node, :current)
523
+
524
+ add_offense(node) do |corrector|
525
+ autocorrect_to_equality_helper_for_date(
526
+ corrector,
527
+ node,
528
+ date_method_name: :current,
529
+ helper_method_name: :today?
530
+ )
531
+ end
532
+ end
533
+
534
+ # @param node [RuboCop::AST::SendNode]
535
+ # @return [void]
536
+ def check_equality_to_date_tomorrow(node)
537
+ return unless equals_to_date_with?(node, :tomorrow)
538
+
539
+ add_offense(node) do |corrector|
540
+ autocorrect_to_equality_helper_for_date(
541
+ corrector,
542
+ node,
543
+ date_method_name: :tomorrow,
544
+ helper_method_name: :tomorrow?
545
+ )
546
+ end
547
+ end
548
+
549
+ # @param node [RuboCop::AST::SendNode]
550
+ # @return [void]
551
+ def check_equality_to_date_yesterday(node)
552
+ return unless equals_to_date_with?(node, :yesterday)
553
+
554
+ add_offense(node) do |corrector|
555
+ autocorrect_to_equality_helper_for_date(
556
+ corrector,
557
+ node,
558
+ date_method_name: :yesterday,
559
+ helper_method_name: :yesterday?
560
+ )
561
+ end
562
+ end
563
+
564
+ # @param node [RuboCop::AST::SendNode]
565
+ # @return [void]
566
+ def check_greater_than(node)
567
+ return unless comparison_to_time_current?(node)
568
+
569
+ add_offense(node) do |corrector|
570
+ autocorrect_to_comparison_helper_for_time_current(
571
+ corrector,
572
+ node
573
+ )
574
+ end
575
+ end
576
+ alias check_less_than check_greater_than
577
+
578
+ # @param node [RuboCop::AST::SendNode]
579
+ # @return [void]
580
+ def check_now(node)
581
+ return unless time_zone_with?(node, :now)
582
+
583
+ add_offense(node) do |corrector|
584
+ replace_keeping_cbase(
585
+ corrector: corrector,
586
+ node: node,
587
+ with: 'Time.current'
588
+ )
589
+ end
590
+ end
591
+
592
+ # @param node [RuboCop::AST::SendNode]
593
+ # @return [void]
594
+ def check_subtraction(node)
595
+ check_subtraction_to_date_current(node)
596
+ check_subtraction_to_time_current(node)
597
+ end
598
+
599
+ # @param node [RuboCop::AST::SendNode]
600
+ # @return [void]
601
+ def check_subtraction_to_date_current(node)
602
+ return unless date_current_minus_one_day?(node)
603
+
604
+ add_offense(node) do |corrector|
605
+ replace_keeping_cbase(
606
+ corrector: corrector,
607
+ node: node,
608
+ with: 'Date.yesterday'
609
+ )
610
+ end
611
+ end
612
+
613
+ # @param node [RuboCop::AST::SendNode]
614
+ # @return [void]
615
+ def check_subtraction_to_time_current(node)
616
+ return unless duration_calculation_to_time_current?(node)
617
+
618
+ add_offense(node) do |corrector|
619
+ autocorrect_to_duration_helper(
620
+ corrector,
621
+ node,
622
+ helper_method_name: :ago
623
+ )
624
+ end
625
+ end
626
+
627
+ # @param node [RuboCop::AST::SendNode]
628
+ # @return [void]
629
+ def check_to_date(node)
630
+ return unless time_current_to_date?(node)
631
+
632
+ add_offense(node) do |corrector|
633
+ replace_keeping_cbase(
634
+ corrector: corrector,
635
+ node: node,
636
+ with: 'Date.current'
637
+ )
638
+ end
639
+ end
640
+
641
+ # @param node [RuboCop::AST::SendNode]
642
+ # @return [void]
643
+ def check_today(node)
644
+ check_today_to_date_current(node)
645
+ check_today_to_time_zone(node)
646
+ end
647
+
648
+ # @param node [RuboCop::AST::SendNode]
649
+ # @return [void]
650
+ def check_today_to_date_current(node)
651
+ return unless date_current_with?(node, :today)
652
+
653
+ add_offense(node) do |corrector|
654
+ replace_keeping_cbase(
655
+ corrector: corrector,
656
+ node: node,
657
+ with: 'Date.current'
658
+ )
659
+ end
660
+ end
661
+
662
+ # @param node [RuboCop::AST::SendNode]
663
+ # @return [void]
664
+ def check_today_to_time_zone(node)
665
+ return unless time_zone_with?(node, :today)
666
+
667
+ add_offense(node) do |corrector|
668
+ replace_keeping_cbase(
669
+ corrector: corrector,
670
+ node: node,
671
+ with: 'Date.current'
672
+ )
673
+ end
674
+ end
675
+
676
+ # @param node [RuboCop::AST::SendNode]
677
+ # @return [void]
678
+ def check_tomorrow(node)
679
+ return unless date_current_with?(node, :tomorrow)
680
+
681
+ add_offense(node) do |corrector|
682
+ replace_keeping_cbase(
683
+ corrector: corrector,
684
+ node: node,
685
+ with: 'Date.tomorrow'
686
+ )
687
+ end
688
+ end
689
+
690
+ # @param node [RuboCop::AST::SendNode]
691
+ # @return [void]
692
+ def check_yesterday(node)
693
+ return unless date_current_with?(node, :yesterday)
694
+
695
+ add_offense(node) do |corrector|
696
+ replace_keeping_cbase(
697
+ corrector: corrector,
698
+ node: node,
699
+ with: 'Date.yesterday'
700
+ )
701
+ end
702
+ end
703
+
704
+ # @param node [RuboCop::AST::SendNode]
705
+ # @param method_name [Symbol]
706
+ # @return [Boolean]
707
+ def equals_to_date_with?(
708
+ node,
709
+ method_name
710
+ )
711
+ equals_to_date_with_left?(node, method_name) ||
712
+ equals_to_date_with_right?(node, method_name)
713
+ end
714
+
715
+ # @param node [RuboCop::AST::SendNode]
716
+ # @return [RuboCop::AST::Node]
717
+ def find_comparison_subject_to_time_current(node)
718
+ if time_current?(node.receiver)
719
+ node.first_argument
720
+ else
721
+ node.receiver
722
+ end
723
+ end
724
+
725
+ # @param node [RuboCop::AST::SendNode]
726
+ # @param method_name [Symbol]
727
+ # @return [RuboCop::AST::Node]
728
+ def find_equality_subject_to_date_with(
729
+ node,
730
+ method_name
731
+ )
732
+ if date_with?(node.receiver, method_name)
733
+ node.first_argument
734
+ else
735
+ node.receiver
736
+ end
737
+ end
738
+
739
+ # @param node [RuboCop::AST::SendNode]
740
+ # @return [Symbol]
741
+ def helper_method_name_for_comparison(node)
742
+ if comparison_for_future?(node)
743
+ :future?
744
+ else
745
+ :past?
746
+ end
747
+ end
748
+
749
+ # @param corrector [RuboCop::Cop::Corrector]
750
+ # @param node [RuboCop::AST::SendNode]
751
+ # @param with [String]
752
+ # @return [void]
753
+ def replace_keeping_cbase(
754
+ corrector:,
755
+ node:,
756
+ with:
757
+ )
758
+ corrector.replace(
759
+ node.location.expression.with(
760
+ begin_pos: node.each_descendant(:const).first.location.name.begin_pos
761
+ ),
762
+ with
763
+ )
764
+ end
765
+ end
766
+ end
767
+ end
768
+ end
@@ -6,7 +6,6 @@ module RuboCop
6
6
  # Combine examples in same group in the time-consuming kinds of specs.
7
7
  #
8
8
  # @example
9
- #
10
9
  # # bad
11
10
  # context 'when user is logged in' do
12
11
  # it 'returns 200' do
@@ -27,20 +26,42 @@ module RuboCop
27
26
  # end
28
27
  # end
29
28
  #
29
+ # # bad - IncludeSharedExamples: true
30
+ # context 'when user is logged in' do
31
+ # it 'returns 200' do
32
+ # subject
33
+ # expect(response).to have_http_status(200)
34
+ # end
35
+ #
36
+ # includes_examples 'creates Foo'
37
+ # end
30
38
  class RSpecExamplesInSameGroup < Base
31
- EXAMPLE_METHOD_NAMES_REGULAR = ::Set[
39
+ METHOD_NAMES_FOR_REGULAR_EXAMPLE = ::Set[
40
+ :example,
32
41
  :it,
33
42
  :its,
34
- :specify,
35
- :example,
36
43
  :scenario,
44
+ :specify
37
45
  ].freeze
38
46
 
47
+ METHOD_NAMES_FOR_SHARED_EXAMPLES = ::Set[
48
+ :include_examples,
49
+ :it_behaves_like,
50
+ :it_should_behave_like
51
+ ]
52
+
39
53
  MSG = 'Combine examples in the same group in the time-consuming kinds of specs.'
40
54
 
41
- # @param node [RuboCop::AST::BlockNode]
55
+ RESTRICT_ON_SEND = [
56
+ *METHOD_NAMES_FOR_REGULAR_EXAMPLE,
57
+ *METHOD_NAMES_FOR_SHARED_EXAMPLES
58
+ ].freeze
59
+
60
+ # @param node [RuboCop::AST::SendNode]
42
61
  # @return [void]
43
- def on_block(node)
62
+ def on_send(node)
63
+ node = node.block_node || node
64
+
44
65
  return unless example?(node)
45
66
 
46
67
  previous_sibling_example = previous_sibling_example_of(node)
@@ -48,27 +69,45 @@ module RuboCop
48
69
 
49
70
  add_offense(node)
50
71
  end
51
- alias on_numblock on_block
52
72
 
53
73
  private
54
74
 
55
- # @!method example?(node)
56
- # @param node [RuboCop::AST::Node]
57
- # @return [Boolean]
58
- def_node_matcher :example?, <<~PATTERN
59
- (block
60
- (send nil? EXAMPLE_METHOD_NAMES_REGULAR ...)
61
- ...
62
- )
63
- PATTERN
75
+ # @param node [RuboCop::AST::BlockNode, RuboCop::AST::SendNode]
76
+ # @return [Boolean]
77
+ def example?(node)
78
+ if include_shared_examples?
79
+ regular_example?(node) || shared_example?(node)
80
+ else
81
+ regular_example?(node)
82
+ end
83
+ end
84
+
85
+ # @return [Boolean]
86
+ def include_shared_examples?
87
+ cop_config['IncludeSharedExamples']
88
+ end
64
89
 
65
- # @param node [RuboCop::AST::BlockNode]
66
- # @return [RuboCop::AST::BlockNode, nil]
90
+ # @param node [RuboCop::AST::BlockNode, RuboCop::AST::SendNode]
91
+ # @return [RuboCop::AST::BlockNode, RuboCop::AST::SendNode, nil]
67
92
  def previous_sibling_example_of(node)
93
+ return unless node.parent&.begin_type?
94
+
68
95
  node.left_siblings.find do |sibling|
69
96
  sibling.is_a?(::RuboCop::AST::Node) && example?(sibling)
70
97
  end
71
98
  end
99
+
100
+ # @param node [RuboCop::AST::BlockNode, RuboCop::AST::SendNode]
101
+ # @return [Boolean]
102
+ def regular_example?(node)
103
+ METHOD_NAMES_FOR_REGULAR_EXAMPLE.include?(node.method_name)
104
+ end
105
+
106
+ # @param node [RuboCop::AST::BlockNode, RuboCop::AST::SendNode]
107
+ # @return [Boolean]
108
+ def shared_example?(node)
109
+ METHOD_NAMES_FOR_SHARED_EXAMPLES.include?(node.method_name)
110
+ end
72
111
  end
73
112
  end
74
113
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sevencop
4
- VERSION = '0.24.4'
4
+ VERSION = '0.26.0'
5
5
  end
data/lib/sevencop.rb CHANGED
@@ -14,6 +14,7 @@ require_relative 'rubocop/cop/sevencop/method_definition_keyword_argument_ordere
14
14
  require_relative 'rubocop/cop/sevencop/method_definition_ordered'
15
15
  require_relative 'rubocop/cop/sevencop/rails_action_name'
16
16
  require_relative 'rubocop/cop/sevencop/rails_belongs_to_optional'
17
+ require_relative 'rubocop/cop/sevencop/rails_date_and_time_calculation'
17
18
  require_relative 'rubocop/cop/sevencop/rails_inferred_spec_type'
18
19
  require_relative 'rubocop/cop/sevencop/rails_order_field'
19
20
  require_relative 'rubocop/cop/sevencop/rails_uniqueness_validator_explicit_case_sensitivity'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sevencop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.4
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-27 00:00:00.000000000 Z
11
+ date: 2022-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,7 @@ files:
66
66
  - lib/rubocop/cop/sevencop/method_definition_ordered.rb
67
67
  - lib/rubocop/cop/sevencop/rails_action_name.rb
68
68
  - lib/rubocop/cop/sevencop/rails_belongs_to_optional.rb
69
+ - lib/rubocop/cop/sevencop/rails_date_and_time_calculation.rb
69
70
  - lib/rubocop/cop/sevencop/rails_inferred_spec_type.rb
70
71
  - lib/rubocop/cop/sevencop/rails_order_field.rb
71
72
  - lib/rubocop/cop/sevencop/rails_uniqueness_validator_explicit_case_sensitivity.rb