Passed
Push — master ( 9213a8...e174b6 )
by Kevin
02:14
created

TaskTest::onlyBetweenExtensionSkipProvider()

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
nc 1
nop 0
1
<?php
2
3
namespace Zenstruck\ScheduleBundle\Tests\Schedule;
4
5
use PHPUnit\Framework\TestCase;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\TestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Symfony\Component\Mime\Email;
7
use Symfony\Contracts\HttpClient\HttpClientInterface;
8
use Zenstruck\ScheduleBundle\Schedule;
9
use Zenstruck\ScheduleBundle\Schedule\Exception\SkipTask;
10
use Zenstruck\ScheduleBundle\Schedule\Extension;
11
use Zenstruck\ScheduleBundle\Schedule\Extension\SingleServerExtension;
12
use Zenstruck\ScheduleBundle\Schedule\ScheduleRunContext;
13
use Zenstruck\ScheduleBundle\Schedule\Task;
14
use Zenstruck\ScheduleBundle\Schedule\Task\TaskRunContext;
15
use Zenstruck\ScheduleBundle\Tests\Fixture\MockTask;
16
17
/**
18
 * @author Kevin Bond <[email protected]>
19
 */
20
final class TaskTest extends TestCase
21
{
22
    /**
23
     * @test
24
     */
25
    public function can_set_description()
26
    {
27
        $task = self::task()->description('my description');
28
29
        $this->assertSame('my description', $task->getDescription());
30
        $this->assertSame('my description', (string) $task);
31
    }
32
33
    /**
34
     * @test
35
     */
36
    public function can_set_timezone()
37
    {
38
        $task = self::task();
39
40
        $this->assertNull($task->getTimezone());
41
42
        $task->timezone('UTC');
43
44
        $this->assertSame('UTC', $task->getTimezone()->getName());
45
46
        $task->timezone(new \DateTimeZone('America/Los_Angeles'));
47
48
        $this->assertSame('America/Los_Angeles', $task->getTimezone()->getName());
49
    }
50
51
    /**
52
     * @test
53
     */
54
    public function can_get_next_run()
55
    {
56
        $this->assertSame(
57
            (new \DateTime('1st Jan next year'))->getTimestamp(),
58
            self::task()->yearly()->getNextRun()->getTimestamp()
59
        );
60
    }
61
62
    /**
63
     * @test
64
     */
65
    public function can_determine_if_due()
66
    {
67
        $this->assertTrue(self::task()->everyMinute()->isDue());
68
    }
69
70
    /**
71
     * @test
72
     * @dataProvider frequencyProvider
73
     */
74
    public function can_fluently_create_frequency(callable $createTask, string $expectedExpression)
75
    {
76
        $task = $createTask();
77
78
        $this->assertSame($expectedExpression, (string) $task->getExpression());
79
        $this->assertInstanceOf(\DateTimeInterface::class, $task->getNextRun());
80
    }
81
82
    public static function frequencyProvider(): array
83
    {
84
        return [
85
            [function () { return self::task(); }, '* * * * *'],
86
            [function () { return self::task()->minutes(37)->cron('0 0,12 1 */2 *'); }, '0 0,12 1 */2 *'],
87
            [function () { return self::task()->weekly()->everyMinute(); }, '* * * * *'],
88
            [function () { return self::task()->weekly()->everyFiveMinutes(); }, '*/5 * * * *'],
89
            [function () { return self::task()->weekly()->everyTenMinutes(); }, '*/10 * * * *'],
90
            [function () { return self::task()->weekly()->everyFifteenMinutes(); }, '*/15 * * * *'],
91
            [function () { return self::task()->weekly()->everyTwentyMinutes(); }, '*/20 * * * *'],
92
            [function () { return self::task()->weekly()->everyThirtyMinutes(); }, '0,30 * * * *'],
93
            [function () { return self::task()->minutes(37)->hourly(); }, '0 * * * *'],
94
            [function () { return self::task()->minutes(37)->hourlyAt(2); }, '2 * * * *'],
95
            [function () { return self::task()->minutes(37)->hourlyAt(2, 3, '4-5'); }, '2,3,4-5 * * * *'],
96
            [function () { return self::task()->minutes(37)->daily(); }, '0 0 * * *'],
97
            [function () { return self::task()->minutes(37)->dailyOn(2, 3, '4-5'); }, '0 2,3,4-5 * * *'],
98
            [function () { return self::task()->minutes(37)->dailyBetween(9, 17); }, '0 9-17 * * *'],
99
            [function () { return self::task()->minutes(37)->twiceDaily(); }, '0 1,13 * * *'],
100
            [function () { return self::task()->minutes(37)->twiceDaily(2, 14); }, '0 2,14 * * *'],
101
            [function () { return self::task()->minutes(37)->dailyAt(2); }, '0 2 * * *'],
102
            [function () { return self::task()->minutes(37)->dailyAt('1:34'); }, '34 1 * * *'],
103
            [function () { return self::task()->minutes(37)->weekly(); }, '0 0 * * 0'],
104
            [function () { return self::task()->minutes(37)->weeklyOn(2, 3, '4-5'); }, '0 0 * * 2,3,4-5'],
105
            [function () { return self::task()->minutes(37)->monthly(); }, '0 0 1 * *'],
106
            [function () { return self::task()->minutes(37)->monthlyOn(2, 3, '4-5'); }, '0 0 2,3,4-5 * *'],
107
            [function () { return self::task()->minutes(37)->twiceMonthly(); }, '0 0 1,16 * *'],
108
            [function () { return self::task()->minutes(37)->twiceMonthly(3, 17); }, '0 0 3,17 * *'],
109
            [function () { return self::task()->minutes(37)->quarterly(); }, '0 0 1 */3 *'],
110
            [function () { return self::task()->minutes(37)->yearly(); }, '0 0 1 1 *'],
111
            [function () { return self::task()->weekly()->minutes(2, 3, '4-5'); }, '2,3,4-5 0 * * 0'],
112
            [function () { return self::task()->weekly()->hours(2, 3, '4-5'); }, '0 2,3,4-5 * * 0'],
113
            [function () { return self::task()->weekly()->daysOfMonth(2, 3, '4-5'); }, '0 0 2,3,4-5 * 0'],
114
            [function () { return self::task()->weekly()->months(2, 3, '4-5'); }, '0 0 * 2,3,4-5 0'],
115
            [function () { return self::task()->monthly()->daysOfWeek(2, 3, '4-5'); }, '0 0 1 * 2,3,4-5'],
116
            [function () { return self::task()->minutes(37)->weekdays(); }, '37 * * * 1-5'],
117
            [function () { return self::task()->minutes(37)->weekends(); }, '37 * * * 0,6'],
118
            [function () { return self::task()->minutes(37)->mondays(); }, '37 * * * 1'],
119
            [function () { return self::task()->minutes(37)->tuesdays(); }, '37 * * * 2'],
120
            [function () { return self::task()->minutes(37)->wednesdays(); }, '37 * * * 3'],
121
            [function () { return self::task()->minutes(37)->thursdays(); }, '37 * * * 4'],
122
            [function () { return self::task()->minutes(37)->fridays(); }, '37 * * * 5'],
123
            [function () { return self::task()->minutes(37)->saturdays(); }, '37 * * * 6'],
124
            [function () { return self::task()->minutes(37)->sundays(); }, '37 * * * 0'],
125
            [function () { return self::task()->weekly()->at(1); }, '0 1 * * 0'],
126
            [function () { return self::task()->weekly()->at('2:45'); }, '45 2 * * 0'],
127
128
            [function () { return self::task()->cron('invalid...')->mondays(); }, '* * * * 1'],
129
130
            [function () { return self::task()->cron('@hourly'); }, '@hourly'],
131
            [function () { return self::task()->cron('@daily'); }, '@daily'],
132
            [function () { return self::task()->cron('@weekly'); }, '@weekly'],
133
            [function () { return self::task()->cron('@monthly'); }, '@monthly'],
134
            [function () { return self::task()->cron('@yearly'); }, '@yearly'],
135
            [function () { return self::task()->cron('@annually'); }, '@annually'],
136
137
            [function () { return self::task('my task')->cron('# 0 * * *'); }, '56 0 * * *'],
138
            [function () { return self::task('my task')->cron('#daily'); }, '56 20 * * *'],
139
            [function () { return self::task('my task')->cron('#midnight'); }, '56 2 * * *'],
140
            [function () { return self::task('my task')->cron('#midnight')->daily(); }, '0 0 * * *'],
141
        ];
142
    }
143
144
    /**
145
     * @test
146
     */
147
    public function has_unique_id_based_on_description_and_frequency()
148
    {
149
        $this->assertSame(self::task()->getId(), self::task()->getId());
150
        $this->assertNotSame(self::task()->daily()->getId(), self::task()->getId());
151
        $this->assertNotSame(self::task('task1')->getId(), self::task('task2')->getId());
152
        $this->assertNotSame((new class('task') extends Task {
153
        })->getId(), self::task('task')->getId());
154
    }
155
156
    /**
157
     * @test
158
     */
159
    public function false_when_filter_skips_task()
160
    {
161
        $task = self::task();
162
163
        $task->when('boolean value', false);
164
165
        $this->expectException(SkipTask::class);
166
        $this->expectExceptionMessage('boolean value');
167
168
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
0 ignored issues
show
Bug introduced by
The method filterTask() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

168
        $task->getExtensions()[0]->/** @scrutinizer ignore-call */ 
169
                                   filterTask(self::taskRunContext());
Loading history...
169
    }
170
171
    /**
172
     * @test
173
     */
174
    public function callback_returning_false_when_filter_skips_task()
175
    {
176
        $task = self::task();
177
178
        $task->when('callback value', function () { return false; });
179
180
        $this->expectException(SkipTask::class);
181
        $this->expectExceptionMessage('callback value');
182
183
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
184
    }
185
186
    /**
187
     * @test
188
     */
189
    public function true_when_filter_allows_task_to_run()
190
    {
191
        $task = self::task();
192
193
        $task->when('boolean value', true);
194
195
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
196
197
        $this->assertTrue(true);
198
    }
199
200
    /**
201
     * @test
202
     */
203
    public function callback_returning_true_when_filter_allows_task_to_run()
204
    {
205
        $task = self::task();
206
207
        $task->when('callback value', function () { return true; });
208
209
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
210
211
        $this->assertTrue(true);
212
    }
213
214
    /**
215
     * @test
216
     */
217
    public function true_skip_filter_skips_task()
218
    {
219
        $task = self::task();
220
221
        $task->skip('boolean value', true);
222
223
        $this->expectException(SkipTask::class);
224
        $this->expectExceptionMessage('boolean value');
225
226
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
227
    }
228
229
    /**
230
     * @test
231
     */
232
    public function callback_returning_true_skip_filter_skips_task()
233
    {
234
        $task = self::task();
235
236
        $task->skip('callback value', function () { return true; });
237
238
        $this->expectException(SkipTask::class);
239
        $this->expectExceptionMessage('callback value');
240
241
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
242
    }
243
244
    /**
245
     * @test
246
     */
247
    public function false_skip_filter_allows_task_to_run()
248
    {
249
        $task = self::task();
250
251
        $task->skip('boolean value', false);
252
253
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
254
255
        $this->assertTrue(true);
256
    }
257
258
    /**
259
     * @test
260
     */
261
    public function callback_returning_false_skip_filter_allows_task_to_run()
262
    {
263
        $task = self::task();
264
265
        $task->skip('callback value', function () { return false; });
266
267
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
268
269
        $this->assertTrue(true);
270
    }
271
272
    /**
273
     * @test
274
     */
275
    public function can_add_callback_extensions()
276
    {
277
        $task = self::task();
278
        $calls = [];
279
280
        $task->filter(function () use (&$calls) { $calls[] = 'filter'; });
281
        $task->before(function () use (&$calls) { $calls[] = 'before'; });
282
        $task->after(function () use (&$calls) { $calls[] = 'after'; });
283
        $task->then(function () use (&$calls) { $calls[] = 'then'; });
284
        $task->onSuccess(function () use (&$calls) { $calls[] = 'onSuccess'; });
285
        $task->onFailure(function () use (&$calls) { $calls[] = 'onFailure'; });
286
287
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
288
        $task->getExtensions()[1]->beforeTask(self::taskRunContext());
0 ignored issues
show
Bug introduced by
The method beforeTask() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

288
        $task->getExtensions()[1]->/** @scrutinizer ignore-call */ 
289
                                   beforeTask(self::taskRunContext());
Loading history...
289
        $task->getExtensions()[2]->afterTask(self::taskRunContext());
0 ignored issues
show
Bug introduced by
The method afterTask() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

289
        $task->getExtensions()[2]->/** @scrutinizer ignore-call */ 
290
                                   afterTask(self::taskRunContext());
Loading history...
290
        $task->getExtensions()[3]->afterTask(self::taskRunContext());
291
        $task->getExtensions()[4]->onTaskSuccess(self::taskRunContext());
0 ignored issues
show
Bug introduced by
The method onTaskSuccess() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

291
        $task->getExtensions()[4]->/** @scrutinizer ignore-call */ 
292
                                   onTaskSuccess(self::taskRunContext());
Loading history...
292
        $task->getExtensions()[5]->onTaskFailure(self::taskRunContext());
0 ignored issues
show
Bug introduced by
The method onTaskFailure() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...n\SelfHandlingExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

292
        $task->getExtensions()[5]->/** @scrutinizer ignore-call */ 
293
                                   onTaskFailure(self::taskRunContext());
Loading history...
293
294
        $this->assertSame([
295
            'filter',
296
            'before',
297
            'after',
298
            'then',
299
            'onSuccess',
300
            'onFailure',
301
        ], $calls);
302
    }
303
304
    /**
305
     * @test
306
     */
307
    public function can_add_ping_extensions()
308
    {
309
        $task = self::task();
310
311
        $task->pingBefore('http://before.com');
312
        $task->pingAfter('http://after.com', 'POST');
313
        $task->thenPing('http://then.com');
314
        $task->pingOnSuccess('http://success.com');
315
        $task->pingOnFailure('http://failure.com');
316
317
        $client = $this->createMock(HttpClientInterface::class);
318
        $client->expects($this->exactly(5))->method('request')->withConsecutive(
319
            [$this->equalTo('GET'), $this->equalTo('http://before.com'), $this->isType('array')],
320
            [$this->equalTo('POST'), $this->equalTo('http://after.com'), $this->isType('array')],
321
            [$this->equalTo('GET'), $this->equalTo('http://then.com'), $this->isType('array')],
322
            [$this->equalTo('GET'), $this->equalTo('http://success.com'), $this->isType('array')],
323
            [$this->equalTo('GET'), $this->equalTo('http://failure.com'), $this->isType('array')]
324
        );
325
326
        $task->getExtensions()[0]->setHttpClient($client)->beforeTask(self::taskRunContext());
0 ignored issues
show
Bug introduced by
The method setHttpClient() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...Extension\PingExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

326
        $task->getExtensions()[0]->/** @scrutinizer ignore-call */ 
327
                                   setHttpClient($client)->beforeTask(self::taskRunContext());
Loading history...
327
        $task->getExtensions()[1]->setHttpClient($client)->afterTask(self::taskRunContext());
328
        $task->getExtensions()[2]->setHttpClient($client)->afterTask(self::taskRunContext());
329
        $task->getExtensions()[3]->setHttpClient($client)->onTaskSuccess(self::taskRunContext());
330
        $task->getExtensions()[4]->setHttpClient($client)->onTaskFailure(self::taskRunContext());
331
    }
332
333
    /**
334
     * @test
335
     * @dataProvider emailAfterMethodProvider
336
     */
337
    public function can_add_email_after_extension($method)
338
    {
339
        $task = self::task();
340
        $task->{$method}('[email protected]', 'my subject', function (Email $email) {
341
            $email->cc('[email protected]');
342
        });
343
344
        $this->assertTrue($task->getExtensions()[0]->isHook(Extension::TASK_AFTER));
0 ignored issues
show
Bug introduced by
The method isHook() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...xtension\EmailExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

344
        $this->assertTrue($task->getExtensions()[0]->/** @scrutinizer ignore-call */ isHook(Extension::TASK_AFTER));
Loading history...
345
        $this->assertSame('[email protected]', $task->getExtensions()[0]->getEmail()->getTo()[0]->toString());
0 ignored issues
show
Bug introduced by
The method getEmail() does not exist on Zenstruck\ScheduleBundle\Schedule\Extension. It seems like you code against a sub-type of Zenstruck\ScheduleBundle\Schedule\Extension such as Zenstruck\ScheduleBundle...xtension\EmailExtension. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

345
        $this->assertSame('[email protected]', $task->getExtensions()[0]->/** @scrutinizer ignore-call */ getEmail()->getTo()[0]->toString());
Loading history...
346
        $this->assertSame('[email protected]', $task->getExtensions()[0]->getEmail()->getCc()[0]->toString());
347
        $this->assertSame('my subject', $task->getExtensions()[0]->getEmail()->getSubject());
348
    }
349
350
    public static function emailAfterMethodProvider()
351
    {
352
        return [
353
            ['emailAfter'],
354
            ['thenEmail'],
355
        ];
356
    }
357
358
    /**
359
     * @test
360
     */
361
    public function can_add_email_on_failure_extension()
362
    {
363
        $task = self::task();
364
        $task->emailOnFailure('[email protected]', 'my subject', function (Email $email) {
365
            $email->cc('[email protected]');
366
        });
367
368
        $this->assertTrue($task->getExtensions()[0]->isHook(Extension::TASK_FAILURE));
369
        $this->assertSame('[email protected]', $task->getExtensions()[0]->getEmail()->getTo()[0]->toString());
370
        $this->assertSame('[email protected]', $task->getExtensions()[0]->getEmail()->getCc()[0]->toString());
371
        $this->assertSame('my subject', $task->getExtensions()[0]->getEmail()->getSubject());
372
    }
373
374
    /**
375
     * @test
376
     */
377
    public function can_add_single_server_extension()
378
    {
379
        $task = self::task()->onSingleServer();
380
381
        $this->assertInstanceOf(SingleServerExtension::class, $task->getExtensions()[0]);
382
    }
383
384
    /**
385
     * @test
386
     */
387
    public function can_add_without_overlapping_extension()
388
    {
389
        $task1 = self::task('task')->withoutOverlapping();
390
        $task2 = self::task('task')->withoutOverlapping();
391
392
        $task1->getExtensions()[0]->filterTask(self::taskRunContext());
393
394
        $this->expectException(SkipTask::class);
395
        $this->expectExceptionMessage('Task running in another process.');
396
397
        $task2->getExtensions()[0]->filterTask(self::taskRunContext());
398
    }
399
400
    /**
401
     * @test
402
     * @dataProvider onlyBetweenExtensionSkipProvider
403
     */
404
    public function only_between_extension_skip($start, $end, $inclusive)
405
    {
406
        $start = (new \DateTime($start))->format('H:i');
407
        $end = (new \DateTime($end))->format('H:i');
408
409
        $task = self::task()->onlyBetween($start, $end, $inclusive);
410
411
        $this->expectException(SkipTask::class);
412
        $this->expectExceptionMessage("Only runs between {$start} and {$end}");
413
414
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
415
    }
416
417
    public static function onlyBetweenExtensionSkipProvider()
418
    {
419
        return [
420
            ['+2 minutes', '+3 minutes', true],
421
            ['now', '+3 minutes', false],
422
            ['+5 minutes', '+23 hours', true],
423
        ];
424
    }
425
426
    /**
427
     * @test
428
     * @dataProvider onlyBetweenExtensionRunProvider
429
     */
430
    public function only_between_extension_run($start, $end, $inclusive)
431
    {
432
        $start = (new \DateTime($start))->format('H:i');
433
        $end = (new \DateTime($end))->format('H:i');
434
435
        $task = self::task()->onlyBetween($start, $end, $inclusive);
436
437
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
438
439
        $this->assertTrue(true);
440
    }
441
442
    public static function onlyBetweenExtensionRunProvider()
443
    {
444
        return [
445
            ['now', '+3 minutes', true],
446
            ['-1 minute', '+3 minutes', false],
447
            ['-1 minutes', '+23 hours', true],
448
        ];
449
    }
450
451
    /**
452
     * @test
453
     * @dataProvider unlessBetweenExtensionSkipProvider
454
     */
455
    public function unless_between_extension_skip($start, $end, $inclusive)
456
    {
457
        $start = (new \DateTime($start))->format('H:i');
458
        $end = (new \DateTime($end))->format('H:i');
459
460
        $task = self::task()->unlessBetween($start, $end, $inclusive);
461
462
        $this->expectException(SkipTask::class);
463
        $this->expectExceptionMessage("Only runs if not between {$start} and {$end}");
464
465
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
466
    }
467
468
    public static function unlessBetweenExtensionSkipProvider()
469
    {
470
        return [
471
            ['-1 minute', '+3 minutes', false],
472
            ['now', '+3 minutes', true],
473
            ['-1 minutes', '+23 hours', true],
474
        ];
475
    }
476
477
    /**
478
     * @test
479
     * @dataProvider unlessBetweenExtensionRunProvider
480
     */
481
    public function unless_between_extension_run($start, $end, $inclusive)
482
    {
483
        $start = (new \DateTime($start))->format('H:i');
484
        $end = (new \DateTime($end))->format('H:i');
485
486
        $task = self::task()->unlessBetween($start, $end, $inclusive);
487
488
        $task->getExtensions()[0]->filterTask(self::taskRunContext());
489
490
        $this->assertTrue(true);
491
    }
492
493
    public static function unlessBetweenExtensionRunProvider()
494
    {
495
        return [
496
            ['now', '+3 minutes', false],
497
            ['+1 minute', '+3 minutes', true],
498
            ['+5 minutes', '+23 hours', true],
499
        ];
500
    }
501
502
    private static function taskRunContext(): TaskRunContext
503
    {
504
        return new TaskRunContext(new ScheduleRunContext(new Schedule()), self::task());
505
    }
506
507
    private static function task(string $description = 'task description'): Task
508
    {
509
        return new MockTask($description);
510
    }
511
}
512