checkoff 0.58.1 → 0.59.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.
@@ -1,751 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Checkoff
4
- module TaskSelectorClasses
5
- # Base class to evaluate a task selector function given fully evaluated arguments
6
- class FunctionEvaluator
7
- # @param task_selector [Array<(Symbol, Array)>,String]
8
- # @param tasks [Checkoff::Tasks]
9
- def initialize(task_selector:,
10
- tasks:)
11
- @task_selector = task_selector
12
- @tasks = tasks
13
- end
14
-
15
- # @sg-ignore
16
- # @param _index [Integer]
17
- def evaluate_arg?(_index)
18
- true
19
- end
20
-
21
- # @sg-ignore
22
- # @return [Boolean]
23
- def matches?
24
- raise 'Override me!'
25
- end
26
-
27
- private
28
-
29
- # @param object [Object]
30
- # @param fn_name [Symbol]
31
- def fn?(object, fn_name)
32
- object.is_a?(Array) && !object.empty? && [fn_name, fn_name.to_s].include?(object[0])
33
- end
34
-
35
- # @param task [Asana::Resources::Task]
36
- # @param field_name [Symbol]
37
- #
38
- # @sg-ignore
39
- # @return [Date, nil]
40
- def pull_date_field_by_name(task, field_name)
41
- if field_name == :modified
42
- return Time.parse(task.modified_at).to_date unless task.modified_at.nil?
43
-
44
- return nil
45
- end
46
-
47
- if field_name == :due
48
- return Time.parse(task.due_at).to_date unless task.due_at.nil?
49
-
50
- return Date.parse(task.due_on) unless task.due_on.nil?
51
-
52
- return nil
53
- end
54
-
55
- raise "Teach me how to handle field #{field_name}"
56
- end
57
-
58
- # @param task [Asana::Resources::Task]
59
- # @param field_name [Symbol]
60
- #
61
- # @sg-ignore
62
- # @return [Date, Time, nil]
63
- def pull_date_or_time_field_by_name(task, field_name)
64
- if field_name == :due
65
- return Time.parse(task.due_at) unless task.due_at.nil?
66
-
67
- return Date.parse(task.due_on) unless task.due_on.nil?
68
-
69
- return nil
70
- end
71
-
72
- if field_name == :start
73
- return Time.parse(task.start_at) unless task.start_at.nil?
74
-
75
- return Date.parse(task.start_on) unless task.start_on.nil?
76
-
77
- return nil
78
- end
79
-
80
- raise "Teach me how to handle field #{field_name}"
81
- end
82
-
83
- # @sg-ignore
84
- # @param task [Asana::Resources::Task]
85
- # @param custom_field_gid [String]
86
- # @return [Hash]
87
- def pull_custom_field_or_raise(task, custom_field_gid)
88
- # @type [Array<Hash>]
89
- custom_fields = task.custom_fields
90
- if custom_fields.nil?
91
- raise "Could not find custom_fields under task (was 'custom_fields' included in 'extra_fields'?)"
92
- end
93
-
94
- # @sg-ignore
95
- # @type [Hash, nil]
96
- matched_custom_field = custom_fields.find { |data| data.fetch('gid') == custom_field_gid }
97
- if matched_custom_field.nil?
98
- raise "Could not find custom field with gid #{custom_field_gid} " \
99
- "in task #{task.gid} with custom fields #{custom_fields}"
100
- end
101
-
102
- matched_custom_field
103
- end
104
-
105
- # @return [Array<(Symbol, Array)>]
106
- attr_reader :task_selector
107
-
108
- # @sg-ignore
109
- # @param custom_field [Hash]
110
- # @return [Array<String>]
111
- def pull_enum_values(custom_field)
112
- resource_subtype = custom_field.fetch('resource_subtype')
113
- case resource_subtype
114
- when 'enum'
115
- [custom_field.fetch('enum_value')]
116
- when 'multi_enum'
117
- custom_field.fetch('multi_enum_values')
118
- else
119
- raise "Teach me how to handle resource_subtype #{resource_subtype}"
120
- end
121
- end
122
-
123
- # @param custom_field [Hash]
124
- # @param enum_value [Object, nil]
125
- # @return [Array<String>]
126
- def find_gids(custom_field, enum_value)
127
- if enum_value.nil?
128
- []
129
- else
130
- raise "Unexpected enabled value on custom field: #{custom_field}" if enum_value.fetch('enabled') == false
131
-
132
- [enum_value.fetch('gid')]
133
- end
134
- end
135
-
136
- # @param task [Asana::Resources::Task]
137
- # @param custom_field_gid [String]
138
- # @return [Array<String>]
139
- def pull_custom_field_values_gids(task, custom_field_gid)
140
- custom_field = pull_custom_field_or_raise(task, custom_field_gid)
141
- pull_enum_values(custom_field).flat_map do |enum_value|
142
- find_gids(custom_field, enum_value)
143
- end
144
- end
145
-
146
- # @sg-ignore
147
- # @param task [Asana::Resources::Task]
148
- # @param custom_field_name [String]
149
- # @return [Hash, nil]
150
- def pull_custom_field_by_name(task, custom_field_name)
151
- custom_fields = task.custom_fields
152
- if custom_fields.nil?
153
- raise "custom fields not found on task - did you add 'custom_fields' in your extra_fields argument?"
154
- end
155
-
156
- # @sg-ignore
157
- # @type [Hash, nil]
158
- custom_fields.find { |field| field.fetch('name') == custom_field_name }
159
- end
160
-
161
- # @param task [Asana::Resources::Task]
162
- # @param custom_field_name [String]
163
- # @return [Hash]
164
- def pull_custom_field_by_name_or_raise(task, custom_field_name)
165
- custom_field = pull_custom_field_by_name(task, custom_field_name)
166
- if custom_field.nil?
167
- raise "Could not find custom field with name #{custom_field_name} " \
168
- "in task #{task.gid} with custom fields #{task.custom_fields}"
169
- end
170
- custom_field
171
- end
172
- end
173
-
174
- # :and function
175
- class AndFunctionEvaluator < FunctionEvaluator
176
- FUNCTION_NAME = :and
177
-
178
- def matches?
179
- fn?(task_selector, FUNCTION_NAME)
180
- end
181
-
182
- # @param _task [Asana::Resources::Task]
183
- # @param lhs [Object]
184
- # @param rhs [Object]
185
- # @return [Object]
186
- def evaluate(_task, lhs, rhs)
187
- lhs && rhs
188
- end
189
- end
190
-
191
- # :or function
192
- #
193
- # Does not yet shortcut, but may in future - be careful with side
194
- # effects!
195
- class OrFunctionEvaluator < FunctionEvaluator
196
- FUNCTION_NAME = :or
197
-
198
- def matches?
199
- fn?(task_selector, FUNCTION_NAME)
200
- end
201
-
202
- # @param _task [Asana::Resources::Task]
203
- # @param lhs [Object]
204
- # @param rhs [Object]
205
- # @return [Object]
206
- def evaluate(_task, lhs, rhs)
207
- lhs || rhs
208
- end
209
- end
210
-
211
- # :not function
212
- class NotFunctionEvaluator < FunctionEvaluator
213
- FUNCTION_NAME = :not
214
-
215
- def matches?
216
- fn?(task_selector, FUNCTION_NAME)
217
- end
218
-
219
- # @param _task [Asana::Resources::Task]
220
- # @param subvalue [Object]
221
- # @return [Boolean]
222
- def evaluate(_task, subvalue)
223
- !subvalue
224
- end
225
- end
226
-
227
- # :nil? function
228
- class NilPFunctionEvaluator < FunctionEvaluator
229
- def matches?
230
- fn?(task_selector, :nil?)
231
- end
232
-
233
- # @param _task [Asana::Resources::Task]
234
- # @param subvalue [Object]
235
- # @return [Boolean]
236
- def evaluate(_task, subvalue)
237
- subvalue.nil?
238
- end
239
- end
240
-
241
- # :equals? function
242
- class EqualsPFunctionEvaluator < FunctionEvaluator
243
- FUNCTION_NAME = :equals?
244
-
245
- def matches?
246
- fn?(task_selector, FUNCTION_NAME)
247
- end
248
-
249
- # @param _task [Asana::Resources::Task]
250
- # @param lhs [Object]
251
- # @param rhs [Object]
252
- # @return [Boolean]
253
- def evaluate(_task, lhs, rhs)
254
- lhs == rhs
255
- end
256
- end
257
-
258
- # :tag function
259
- class TagPFunctionEvaluator < FunctionEvaluator
260
- def matches?
261
- fn?(task_selector, :tag)
262
- end
263
-
264
- # @param _index [Integer]
265
- def evaluate_arg?(_index)
266
- false
267
- end
268
-
269
- # @sg-ignore
270
- # @param task [Asana::Resources::Task]
271
- # @param tag_name [String]
272
- # @return [Boolean]
273
- def evaluate(task, tag_name)
274
- task.tags.map(&:name).include? tag_name
275
- end
276
- end
277
-
278
- # :due function
279
- class DuePFunctionEvaluator < FunctionEvaluator
280
- def matches?
281
- fn?(task_selector, :due)
282
- end
283
-
284
- # @param task [Asana::Resources::Task]
285
- # @param ignore_dependencies [Boolean]
286
- # @return [Boolean]
287
- def evaluate(task, ignore_dependencies: false)
288
- @tasks.task_ready?(task, ignore_dependencies: ignore_dependencies)
289
- end
290
- end
291
-
292
- # :unassigned function
293
- class UnassignedPFunctionEvaluator < FunctionEvaluator
294
- def matches?
295
- fn?(task_selector, :unassigned)
296
- end
297
-
298
- # @param task [Asana::Resources::Task]
299
- # @return [Boolean]
300
- def evaluate(task)
301
- task.assignee.nil?
302
- end
303
- end
304
-
305
- # :due_date_set function
306
- class DueDateSetPFunctionEvaluator < FunctionEvaluator
307
- FUNCTION_NAME = :due_date_set
308
-
309
- def matches?
310
- fn?(task_selector, FUNCTION_NAME)
311
- end
312
-
313
- # @sg-ignore
314
- # @param task [Asana::Resources::Task]
315
- # @return [Boolean]
316
- def evaluate(task)
317
- !task.due_at.nil? || !task.due_on.nil?
318
- end
319
- end
320
-
321
- # :due_between_n_days function
322
- class DueBetweenRelativePFunctionEvaluator < FunctionEvaluator
323
- FUNCTION_NAME = :due_between_relative
324
-
325
- def matches?
326
- fn?(task_selector, FUNCTION_NAME)
327
- end
328
-
329
- # @param _index [Integer]
330
- def evaluate_arg?(_index)
331
- false
332
- end
333
-
334
- # @param task [Asana::Resources::Task]
335
- # @param beginning_num_days_from_now [Integer]
336
- # @param end_num_days_from_now [Integer]
337
- # @param ignore_dependencies [Boolean]
338
- #
339
- # @return [Boolean]
340
- def evaluate(task, beginning_num_days_from_now, end_num_days_from_now, ignore_dependencies: false)
341
- beginning_n_days_from_now_time = (Time.now + (beginning_num_days_from_now * 24 * 60 * 60))
342
- end_n_days_from_now_time = (Time.now + (end_num_days_from_now * 24 * 60 * 60))
343
-
344
- # @type [Date, Time, nil]
345
- task_date_or_time = pull_date_or_time_field_by_name(task, :start) ||
346
- pull_date_or_time_field_by_name(task, :due)
347
-
348
- return false if task_date_or_time.nil?
349
-
350
- # if time
351
- in_range = if task_date_or_time.is_a?(Time)
352
- task_date_or_time > beginning_n_days_from_now_time &&
353
- task_date_or_time <= end_n_days_from_now_time
354
- else
355
- # if date
356
- task_date_or_time > beginning_n_days_from_now_time.to_date &&
357
- task_date_or_time <= end_n_days_from_now_time.to_date
358
- end
359
-
360
- return false unless in_range
361
-
362
- return false if !ignore_dependencies && @tasks.incomplete_dependencies?(task)
363
-
364
- true
365
- end
366
- end
367
-
368
- # :custom_field_value function
369
- class CustomFieldValueFunctionEvaluator < FunctionEvaluator
370
- FUNCTION_NAME = :custom_field_value
371
-
372
- def matches?
373
- fn?(task_selector, FUNCTION_NAME)
374
- end
375
-
376
- # @param _index [Integer]
377
- def evaluate_arg?(_index)
378
- false
379
- end
380
-
381
- # @param task [Asana::Resources::Task]
382
- # @param custom_field_name [String]
383
- # @return [String, nil]
384
- def evaluate(task, custom_field_name)
385
- custom_field = pull_custom_field_by_name(task, custom_field_name)
386
- return nil if custom_field.nil?
3
+ require_relative 'selector_classes/common'
4
+ require_relative 'selector_classes/task'
5
+ require_relative 'selector_evaluator'
387
6
 
388
- custom_field['display_value']
389
- end
390
- end
391
-
392
- # :custom_field_gid_value function
393
- class CustomFieldGidValueFunctionEvaluator < FunctionEvaluator
394
- def matches?
395
- fn?(task_selector, :custom_field_gid_value)
396
- end
397
-
398
- def evaluate_arg?(_index)
399
- false
400
- end
401
-
402
- # @sg-ignore
403
- # @param task [Asana::Resources::Task]
404
- # @param custom_field_gid [String]
405
- # @return [String, nil]
406
- def evaluate(task, custom_field_gid)
407
- custom_field = pull_custom_field_or_raise(task, custom_field_gid)
408
- custom_field['display_value']
409
- end
410
- end
411
-
412
- # :custom_field_gid_value_contains_any_gid function
413
- class CustomFieldGidValueContainsAnyGidFunctionEvaluator < FunctionEvaluator
414
- FUNCTION_NAME = :custom_field_gid_value_contains_any_gid
415
-
416
- def matches?
417
- fn?(task_selector, FUNCTION_NAME)
418
- end
419
-
420
- def evaluate_arg?(_index)
421
- false
422
- end
423
-
424
- # @param task [Asana::Resources::Task]
425
- # @param custom_field_gid [String]
426
- # @param custom_field_values_gids [Array<String>]
427
- # @return [Boolean]
428
- def evaluate(task, custom_field_gid, custom_field_values_gids)
429
- actual_custom_field_values_gids = pull_custom_field_values_gids(task, custom_field_gid)
430
-
431
- actual_custom_field_values_gids.any? do |custom_field_value|
432
- custom_field_values_gids.include?(custom_field_value)
433
- end
434
- end
435
- end
436
-
437
- # :custom_field_gid_value_contains_all_gids function
438
- class CustomFieldGidValueContainsAllGidsFunctionEvaluator < FunctionEvaluator
439
- FUNCTION_NAME = :custom_field_gid_value_contains_all_gids
440
-
441
- def matches?
442
- fn?(task_selector, FUNCTION_NAME)
443
- end
444
-
445
- def evaluate_arg?(_index)
446
- false
447
- end
448
-
449
- # @param task [Asana::Resources::Task]
450
- # @param custom_field_gid [String]
451
- # @param custom_field_values_gids [Array<String>]
452
- # @return [Boolean]
453
- def evaluate(task, custom_field_gid, custom_field_values_gids)
454
- actual_custom_field_values_gids = pull_custom_field_values_gids(task, custom_field_gid)
455
-
456
- custom_field_values_gids.all? do |custom_field_value|
457
- actual_custom_field_values_gids.include?(custom_field_value)
458
- end
459
- end
460
- end
461
-
462
- # :field_less_than_n_days_ago
463
- class FieldLessThanNDaysAgoPFunctionEvaluator < FunctionEvaluator
464
- FUNCTION_NAME = :field_less_than_n_days_ago
465
-
466
- def matches?
467
- fn?(task_selector, FUNCTION_NAME)
468
- end
469
-
470
- def evaluate_arg?(_index)
471
- false
472
- end
473
-
474
- # @param task [Asana::Resources::Task]
475
- # @param field_name [Symbol]
476
- # @param num_days [Integer]
477
- #
478
- # @return [Boolean]
479
- def evaluate(task, field_name, num_days)
480
- date = pull_date_field_by_name(task, field_name)
481
-
482
- return false if date.nil?
483
-
484
- # @sg-ignore
485
- n_days_ago = Date.today - num_days
486
- # @sg-ignore
487
- date < n_days_ago
488
- end
489
- end
490
-
491
- # :field_greater_than_or_equal_to_n_days_from_today
492
- class FieldGreaterThanOrEqualToNDaysFromTodayPFunctionEvaluator < FunctionEvaluator
493
- FUNCTION_NAME = :field_greater_than_or_equal_to_n_days_from_today
494
-
495
- def matches?
496
- fn?(task_selector, FUNCTION_NAME)
497
- end
498
-
499
- def evaluate_arg?(_index)
500
- false
501
- end
502
-
503
- # @param task [Asana::Resources::Task]
504
- # @param field_name [Symbol]
505
- # @param num_days [Integer]
506
- #
507
- # @return [Boolean]
508
- def evaluate(task, field_name, num_days)
509
- date = pull_date_field_by_name(task, field_name)
510
-
511
- return false if date.nil?
512
-
513
- # @sg-ignore
514
- n_days_from_today = Date.today + num_days
515
- # @sg-ignore
516
- date >= n_days_from_today
517
- end
518
- end
519
-
520
- # :custom_field_less_than_n_days_from_now function
521
- class CustomFieldLessThanNDaysFromNowFunctionEvaluator < FunctionEvaluator
522
- FUNCTION_NAME = :custom_field_less_than_n_days_from_now
523
-
524
- def matches?
525
- fn?(task_selector, FUNCTION_NAME)
526
- end
527
-
528
- def evaluate_arg?(_index)
529
- false
530
- end
531
-
532
- # @param task [Asana::Resources::Task]
533
- # @param custom_field_name [String]
534
- # @param num_days [Integer]
535
- # @return [Boolean]
536
- def evaluate(task, custom_field_name, num_days)
537
- custom_field = pull_custom_field_by_name_or_raise(task, custom_field_name)
538
-
539
- # @sg-ignore
540
- # @type [String, nil]
541
- time_str = custom_field.fetch('display_value')
542
- return false if time_str.nil?
543
-
544
- time = Time.parse(time_str)
545
- n_days_from_now = (Time.now + (num_days * 24 * 60 * 60))
546
- time < n_days_from_now
547
- end
548
- end
549
-
550
- # :custom_field_greater_than_or_equal_to_n_days_from_now function
551
- class CustomFieldGreaterThanOrEqualToNDaysFromNowFunctionEvaluator < FunctionEvaluator
552
- FUNCTION_NAME = :custom_field_greater_than_or_equal_to_n_days_from_now
553
-
554
- def matches?
555
- fn?(task_selector, FUNCTION_NAME)
556
- end
557
-
558
- def evaluate_arg?(_index)
559
- false
560
- end
561
-
562
- # @param task [Asana::Resources::Task]
563
- # @param custom_field_name [String]
564
- # @param num_days [Integer]
565
- # @return [Boolean]
566
- def evaluate(task, custom_field_name, num_days)
567
- custom_field = pull_custom_field_by_name_or_raise(task, custom_field_name)
568
-
569
- # @sg-ignore
570
- # @type [String, nil]
571
- time_str = custom_field.fetch('display_value')
572
- return false if time_str.nil?
573
-
574
- time = Time.parse(time_str)
575
- n_days_from_now = (Time.now + (num_days * 24 * 60 * 60))
576
- time >= n_days_from_now
577
- end
578
- end
579
-
580
- # :last_story_created_less_than_n_days_ago function
581
- class LastStoryCreatedLessThanNDaysAgoFunctionEvaluator < FunctionEvaluator
582
- FUNCTION_NAME = :last_story_created_less_than_n_days_ago
583
-
584
- def matches?
585
- fn?(task_selector, FUNCTION_NAME)
586
- end
587
-
588
- def evaluate_arg?(_index)
589
- false
590
- end
591
-
592
- # @param task [Asana::Resources::Task]
593
- # @param num_days [Integer]
594
- # @param excluding_resource_subtypes [Array<String>]
595
- # @return [Boolean]
596
- def evaluate(task, num_days, excluding_resource_subtypes)
597
- # for whatever reason, .last on the enumerable does not impose ordering; .to_a does!
598
-
599
- # @type [Array<Asana::Resources::Story>]
600
- stories = task.stories(per_page: 100).to_a.reject do |story|
601
- excluding_resource_subtypes.include? story.resource_subtype
602
- end
603
- return true if stories.empty? # no stories == infinitely old!
604
-
605
- last_story = stories.last
606
- last_story_created_at = Time.parse(last_story.created_at)
607
- n_days_ago = Time.now - (num_days * 24 * 60 * 60)
608
- last_story_created_at < n_days_ago
609
- end
610
- end
611
-
612
- # String literals
613
- class StringLiteralEvaluator < FunctionEvaluator
614
- def matches?
615
- task_selector.is_a?(String)
616
- end
617
-
618
- # @sg-ignore
619
- # @param _task [Asana::Resources::Task]
620
- # @return [String]
621
- def evaluate(_task)
622
- task_selector
623
- end
624
- end
625
-
626
- # :estimate_exceeds_duration
627
- class EstimateExceedsDurationFunctionEvaluator < FunctionEvaluator
628
- FUNCTION_NAME = :estimate_exceeds_duration
629
-
630
- def matches?
631
- fn?(task_selector, FUNCTION_NAME)
632
- end
633
-
634
- # @param task [Asana::Resources::Task]
635
- # @return [Float]
636
- def calculate_allocated_hours(task)
637
- due_on = nil
638
- start_on = nil
639
- start_on = Date.parse(task.start_on) unless task.start_on.nil?
640
- due_on = Date.parse(task.due_on) unless task.due_on.nil?
641
- allocated_hours = 8.0
642
- # @sg-ignore
643
- allocated_hours = (due_on - start_on + 1).to_i * 8.0 if start_on && due_on
644
- allocated_hours
645
- end
646
-
647
- # @param task [Asana::Resources::Task]
648
- # @return [Boolean]
649
- def evaluate(task)
650
- custom_field = pull_custom_field_by_name_or_raise(task, 'Estimated time')
651
-
652
- # @sg-ignore
653
- # @type [Integer, nil]
654
- estimate_minutes = custom_field.fetch('number_value')
655
-
656
- # no estimate set
657
- return false if estimate_minutes.nil?
658
-
659
- estimate_hours = estimate_minutes / 60.0
660
-
661
- allocated_hours = calculate_allocated_hours(task)
662
-
663
- estimate_hours > allocated_hours
664
- end
665
- end
666
- end
667
-
668
- # Evaluator task selectors against a task
669
- class TaskSelectorEvaluator
7
+ module Checkoff
8
+ # Evaluates task selectors against a task
9
+ class TaskSelectorEvaluator < SelectorEvaluator
670
10
  # @param task [Asana::Resources::Task]
671
11
  # @param tasks [Checkoff::Tasks]
672
12
  def initialize(task:,
673
13
  tasks: Checkoff::Tasks.new)
674
- @task = task
14
+ @item = task
675
15
  @tasks = tasks
16
+ super()
676
17
  end
677
18
 
19
+ private
20
+
678
21
  FUNCTION_EVALUTORS = [
679
- Checkoff::TaskSelectorClasses::NotFunctionEvaluator,
680
- Checkoff::TaskSelectorClasses::NilPFunctionEvaluator,
681
- Checkoff::TaskSelectorClasses::EqualsPFunctionEvaluator,
682
- Checkoff::TaskSelectorClasses::TagPFunctionEvaluator,
683
- Checkoff::TaskSelectorClasses::CustomFieldValueFunctionEvaluator,
684
- Checkoff::TaskSelectorClasses::CustomFieldGidValueFunctionEvaluator,
685
- Checkoff::TaskSelectorClasses::CustomFieldGidValueContainsAnyGidFunctionEvaluator,
686
- Checkoff::TaskSelectorClasses::CustomFieldGidValueContainsAllGidsFunctionEvaluator,
687
- Checkoff::TaskSelectorClasses::AndFunctionEvaluator,
688
- Checkoff::TaskSelectorClasses::OrFunctionEvaluator,
689
- Checkoff::TaskSelectorClasses::DuePFunctionEvaluator,
690
- Checkoff::TaskSelectorClasses::DueBetweenRelativePFunctionEvaluator,
691
- Checkoff::TaskSelectorClasses::UnassignedPFunctionEvaluator,
692
- Checkoff::TaskSelectorClasses::DueDateSetPFunctionEvaluator,
693
- Checkoff::TaskSelectorClasses::FieldLessThanNDaysAgoPFunctionEvaluator,
694
- Checkoff::TaskSelectorClasses::FieldGreaterThanOrEqualToNDaysFromTodayPFunctionEvaluator,
695
- Checkoff::TaskSelectorClasses::CustomFieldLessThanNDaysFromNowFunctionEvaluator,
696
- Checkoff::TaskSelectorClasses::CustomFieldGreaterThanOrEqualToNDaysFromNowFunctionEvaluator,
697
- Checkoff::TaskSelectorClasses::LastStoryCreatedLessThanNDaysAgoFunctionEvaluator,
698
- Checkoff::TaskSelectorClasses::StringLiteralEvaluator,
699
- Checkoff::TaskSelectorClasses::EstimateExceedsDurationFunctionEvaluator,
22
+ Checkoff::SelectorClasses::Common::NotFunctionEvaluator,
23
+ Checkoff::SelectorClasses::Common::NilPFunctionEvaluator,
24
+ Checkoff::SelectorClasses::Common::EqualsPFunctionEvaluator,
25
+ Checkoff::SelectorClasses::Task::TagPFunctionEvaluator,
26
+ Checkoff::SelectorClasses::Common::CustomFieldValueFunctionEvaluator,
27
+ Checkoff::SelectorClasses::Common::CustomFieldGidValueFunctionEvaluator,
28
+ Checkoff::SelectorClasses::Common::CustomFieldGidValueContainsAnyGidFunctionEvaluator,
29
+ Checkoff::SelectorClasses::Common::CustomFieldGidValueContainsAllGidsFunctionEvaluator,
30
+ Checkoff::SelectorClasses::Common::AndFunctionEvaluator,
31
+ Checkoff::SelectorClasses::Common::OrFunctionEvaluator,
32
+ Checkoff::SelectorClasses::Task::DuePFunctionEvaluator,
33
+ Checkoff::SelectorClasses::Task::DueBetweenRelativePFunctionEvaluator,
34
+ Checkoff::SelectorClasses::Task::UnassignedPFunctionEvaluator,
35
+ Checkoff::SelectorClasses::Task::DueDateSetPFunctionEvaluator,
36
+ Checkoff::SelectorClasses::Task::FieldLessThanNDaysAgoPFunctionEvaluator,
37
+ Checkoff::SelectorClasses::Task::FieldGreaterThanOrEqualToNDaysFromTodayPFunctionEvaluator,
38
+ Checkoff::SelectorClasses::Task::CustomFieldLessThanNDaysFromNowFunctionEvaluator,
39
+ Checkoff::SelectorClasses::Task::CustomFieldGreaterThanOrEqualToNDaysFromNowFunctionEvaluator,
40
+ Checkoff::SelectorClasses::Task::LastStoryCreatedLessThanNDaysAgoFunctionEvaluator,
41
+ Checkoff::SelectorClasses::Common::StringLiteralEvaluator,
42
+ Checkoff::SelectorClasses::Task::EstimateExceedsDurationFunctionEvaluator,
700
43
  ].freeze
701
44
 
702
- # @param task_selector [Array]
703
- # @return [Boolean, Object, nil]
704
- def evaluate(task_selector)
705
- return true if task_selector.empty?
706
-
707
- # @param evaluator_class [Class<TaskSelectorClasses::FunctionEvaluator>]
708
- FUNCTION_EVALUTORS.each do |evaluator_class|
709
- # @sg-ignore
710
- evaluator = evaluator_class.new(task_selector: task_selector,
711
- tasks: tasks)
712
-
713
- next unless evaluator.matches?
714
-
715
- return try_this_evaluator(task_selector, evaluator)
716
- end
717
-
718
- raise "Syntax issue trying to handle #{task_selector.inspect}"
45
+ # @return [Array<Class<TaskSelectorClasses::FunctionEvaluator>>]
46
+ def function_evaluators
47
+ FUNCTION_EVALUTORS
719
48
  end
720
49
 
721
- private
722
-
723
- # @sg-ignore
724
- # @param task_selector [Array]
725
- # @param evaluator [TaskSelectorClasses::FunctionEvaluator]
726
- # @return [Boolean, Object, nil]
727
- def try_this_evaluator(task_selector, evaluator)
728
- # if task_selector is an array
729
- evaluated_args = if task_selector.is_a?(Array)
730
- task_selector[1..].map.with_index do |item, index|
731
- if evaluator.evaluate_arg?(index)
732
- evaluate(item)
733
- else
734
- item
735
- end
736
- end
737
- else
738
- []
739
- end
740
-
741
- evaluator.evaluate(task, *evaluated_args)
50
+ # @return [Hash]
51
+ def initializer_kwargs
52
+ { tasks: tasks }
742
53
  end
743
54
 
744
55
  # @return [Asana::Resources::Task]
745
- attr_reader :task
56
+ attr_reader :item
746
57
  # @return [Checkoff::Tasks]
747
58
  attr_reader :tasks
748
- # @return [Array<(Symbol, Array)>]
749
- attr_reader :task_selector
750
59
  end
751
60
  end