diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..f1143f7 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,38 @@ +setRules([ + '@PhpCsFixer' => true, + 'strict_param' => true, + 'fopen_flags' => false, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'native_constant_invocation' => [ + 'include' => ['PNG_ALL_FILTERS'], + 'strict' => true, + ], + 'array_indentation' => true, + 'static_lambda' => true, + 'return_assignment' => false, + 'method_argument_space' => [ + 'on_multiline' => 'ensure_fully_multiline', + ], + 'trailing_comma_in_multiline' => [ + 'elements' => ['arrays', 'arguments', 'parameters'] + ], + 'php_unit_test_class_requires_covers' => false, + 'php_unit_internal_class' => [], + ]) + ->setRiskyAllowed(true) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__.'/src') + ->in(__DIR__.'/tests') + ) +; diff --git a/README.md b/README.md index 376e7b7..72e4176 100644 --- a/README.md +++ b/README.md @@ -16,20 +16,33 @@ RFC : https://tools.ietf.org/html/rfc5545#page-37 ### Create recurrences using object method ```php -$recurrence = (new Recurrence()) - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodStartAt(new \Datetime('2017-01-01')) - ->setPeriodEndAt(new \Datetime('2017-12-31')) - ->setInterval(1); -$periods = (new DatetimeProvider())->provide($recurrence); +$frequency = new Frequency(Frequency::FREQUENCY_MONTHLY); +$interval = 1; +$periodStartAt = new \DateTime('2017-01-01'); +$periodEndAt = new \DateTime('2017-12-31'); +$count = null; +$constraints = []; + + +$recurrence = new Recurrence( + $frequency, + $interval, + $periodStartAt, + $periodEndAt, + $count, + $constraints +); + +$periods = (new \Recurrence\DatetimeProvider())->provide($recurrence); ``` -Available methods : -- `setFrequency` (`Frequency`) : set `FREQ` option -- `setPeriodStartAt` (`\Datetime()`) : set `DTSTART` option -- `setPeriodEndAt` (`\Datetime()`) : set `UNTIL` option -- `setInterval` (`integer`) : set `INTERVAL` option -- `setCount` (`integer`) : set `COUNT` option +Parameters: +- `$frequency` (`Frequency`): Determine the recurrence period (daily, weekly, ...). +- `$interval` (`integer`): Interval base on the frequency (a monthly frequency with an interval of `2` mean every 2 months). +- `$periodStartAt` (`DateTime`): Recurrence period start at. +- `$periodEndAt` (`DateTime`, nullable): Recurrence period end at. +- `$count` (`integer`, nullable): Limit the number of recurrence. +- `$constraints` (`RecurrenceConstraintInterface[]`): Some additional constraints that help you to manage some useful cases. ### Create recurrences from RRULE standard expression @@ -60,10 +73,6 @@ Supported rules : You can add some constraint to `Recurrence` in order to manage more precisely generated datetimes. For example, if you do not want to generate datetime on wednesday (day `3` according to date format in PHP), add this constraint : -```php -$recurrence->addConstraint(new ExcludeDaysOfWeekConstraint([3])); -``` - * `EndOfMonthConstraint` : if recurrence has `MONTHLY` frequency and start date is last day of current month, force last day of month for all datetimes * `ExcludeDaysOfWeekConstraint` : if datetime is concerned, `DatetimeProvider` will return next valid date * `ExcludeWeekendConstraint` : if datetime is concerned, `DatetimeProvider` will return next monday @@ -106,5 +115,3 @@ Or even better, compare the 2 benchmarks and see if you don't degrade performanc ``` ./vendor/bin/phpbench run --report=aggregate --ref=initial ``` - - diff --git a/src/Recurrence/Constraint/DatetimeConstraint/DatetimeConstraintInterface.php b/src/Recurrence/Constraint/DatetimeConstraint/DatetimeConstraintInterface.php index 3f07665..07df9bf 100644 --- a/src/Recurrence/Constraint/DatetimeConstraint/DatetimeConstraintInterface.php +++ b/src/Recurrence/Constraint/DatetimeConstraint/DatetimeConstraintInterface.php @@ -6,5 +6,5 @@ interface DatetimeConstraintInterface { - public function apply(Recurrence $recurrence, \Datetime $datetime): \Datetime | null; + public function apply(Recurrence $recurrence, \DateTime $datetime): \DateTime|null; } diff --git a/src/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php b/src/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php index abbca5b..8298493 100644 --- a/src/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php +++ b/src/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php @@ -20,7 +20,7 @@ public function __construct(array $excludedDays = []) } foreach ($excludedDays as $excludedDay) { - $excludedDay = filter_var($excludedDay, FILTER_VALIDATE_INT); + $excludedDay = filter_var($excludedDay, \FILTER_VALIDATE_INT); if (!$excludedDay || $excludedDay < 1 || $excludedDay > 7) { throw new \InvalidArgumentException('Exclude day must be an integer between 1 and 7'); @@ -30,9 +30,9 @@ public function __construct(array $excludedDays = []) } } - public function apply(Recurrence $recurrence, \Datetime $datetime): \Datetime + public function apply(Recurrence $recurrence, \DateTime $datetime): \DateTime { - while (in_array((int) $datetime->format('N'), $this->excludedDays)) { + while (in_array((int) $datetime->format('N'), $this->excludedDays, true)) { $datetime->modify('+1 day'); } diff --git a/src/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php b/src/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php index 8e2f20f..f264b5b 100644 --- a/src/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php +++ b/src/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php @@ -7,7 +7,7 @@ class ExcludeWeekendConstraint implements DatetimeConstraintInterface, RecurrenceConstraintInterface { - public function apply(Recurrence $recurrence, \Datetime $datetime): \Datetime + public function apply(Recurrence $recurrence, \DateTime $datetime): \DateTime { if ($this->isWeekend($datetime)) { // Add 1 or 2 days to skip weekend (we didn't use `next monday` pattern of \Datetime::format cause it remove time) @@ -18,8 +18,8 @@ public function apply(Recurrence $recurrence, \Datetime $datetime): \Datetime return $datetime; } - private function isWeekend(\Datetime$datetime): bool + private function isWeekend(\DateTime $datetime): bool { - return ((int) $datetime->format('N') >= 6); + return (int) $datetime->format('N') >= 6; } } diff --git a/src/Recurrence/DatetimeProvider.php b/src/Recurrence/DatetimeProvider.php index b4b58dd..19bf78b 100644 --- a/src/Recurrence/DatetimeProvider.php +++ b/src/Recurrence/DatetimeProvider.php @@ -5,7 +5,6 @@ use Recurrence\Constraint\DatetimeConstraint\DatetimeConstraintInterface; use Recurrence\Model\Recurrence; use Recurrence\Provider\DatetimeProviderFactory; -use Recurrence\Validator\RecurrenceValidator; class DatetimeProvider { @@ -14,8 +13,6 @@ class DatetimeProvider */ public function provide(Recurrence $recurrence): array { - RecurrenceValidator::validate($recurrence); - $provider = DatetimeProviderFactory::create($recurrence); $datetimes = $provider->provide($recurrence); @@ -38,7 +35,7 @@ public function provide(Recurrence $recurrence): array // Avoid duplicate datetime due to constraint updates if (empty($filteredDatetimes) || $previousDatetime != $filteredDatetime) { $filteredDatetimes[] = $filteredDatetime; - $previousDatetime = $filteredDatetime; + $previousDatetime = $filteredDatetime; } } diff --git a/src/Recurrence/Model/Frequency.php b/src/Recurrence/Model/Frequency.php index c8806a0..63f4652 100644 --- a/src/Recurrence/Model/Frequency.php +++ b/src/Recurrence/Model/Frequency.php @@ -4,16 +4,35 @@ use Recurrence\Model\Exception\InvalidFrequencyOptionException; +/** + * TODO: replace by enum. + */ class Frequency { - public const FREQUENCY_YEARLY = 'YEARLY'; - public const FREQUENCY_MONTHLY = 'MONTHLY'; - public const FREQUENCY_WEEKLY = 'WEEKLY'; - public const FREQUENCY_DAILY = 'DAILY'; - public const FREQUENCY_HOURLY = 'HOURLY'; + public const FREQUENCY_YEARLY = 'YEARLY'; + public const FREQUENCY_MONTHLY = 'MONTHLY'; + public const FREQUENCY_WEEKLY = 'WEEKLY'; + public const FREQUENCY_DAILY = 'DAILY'; + public const FREQUENCY_HOURLY = 'HOURLY'; public const FREQUENCY_MINUTELY = 'MINUTELY'; public const FREQUENCY_SECONDLY = 'SECONDLY'; + public const DATEINTERVAL_YEARLY = 'P1Y'; + public const DATEINTERVAL_MONTHLY = 'P1M'; + public const DATEINTERVAL_WEEKLY = 'P1W'; + public const DATEINTERVAL_DAILY = 'P1D'; + public const DATEINTERVAL_HOURLY = 'PT1H'; + public const DATEINTERVAL_MINUTELY = 'PT1M'; + public const DATEINTERVAL_SECONDLY = 'PT1S'; + + public const DATETIME_YEARLY = '+1 years'; + public const DATETIME_MONTHLY = '+1 months'; + public const DATETIME_WEEKLY = '+1 weeks'; + public const DATETIME_DAILY = '+1 days'; + public const DATETIME_HOURLY = '+1 hours'; + public const DATETIME_MINUTELY = '+1 minutes'; + public const DATETIME_SECONDLY = '+1 seconds'; + private array $frequencies = [ self::FREQUENCY_YEARLY, self::FREQUENCY_MONTHLY, @@ -24,38 +43,22 @@ class Frequency self::FREQUENCY_SECONDLY, ]; - public const DATEINTERVAL_YEARLY = 'P1Y'; - public const DATEINTERVAL_MONTHLY = 'P1M'; - public const DATEINTERVAL_WEEKLY = 'P1W'; - public const DATEINTERVAL_DAILY = 'P1D'; - public const DATEINTERVAL_HOURLY = 'PT1H'; - public const DATEINTERVAL_MINUTELY = 'PT1M'; - public const DATEINTERVAL_SECONDLY = 'PT1S'; - private array $dateIntervalFrequencies = [ - self::FREQUENCY_YEARLY => self::DATEINTERVAL_YEARLY, - self::FREQUENCY_MONTHLY => self::DATEINTERVAL_MONTHLY, - self::FREQUENCY_WEEKLY => self::DATEINTERVAL_WEEKLY, - self::FREQUENCY_DAILY => self::DATEINTERVAL_DAILY, - self::FREQUENCY_HOURLY => self::DATEINTERVAL_HOURLY, + self::FREQUENCY_YEARLY => self::DATEINTERVAL_YEARLY, + self::FREQUENCY_MONTHLY => self::DATEINTERVAL_MONTHLY, + self::FREQUENCY_WEEKLY => self::DATEINTERVAL_WEEKLY, + self::FREQUENCY_DAILY => self::DATEINTERVAL_DAILY, + self::FREQUENCY_HOURLY => self::DATEINTERVAL_HOURLY, self::FREQUENCY_MINUTELY => self::DATEINTERVAL_MINUTELY, self::FREQUENCY_SECONDLY => self::DATEINTERVAL_SECONDLY, ]; - public const DATETIME_YEARLY = '+1 years'; - public const DATETIME_MONTHLY = '+1 months'; - public const DATETIME_WEEKLY = '+1 weeks'; - public const DATETIME_DAILY = '+1 days'; - public const DATETIME_HOURLY = '+1 hours'; - public const DATETIME_MINUTELY = '+1 minutes'; - public const DATETIME_SECONDLY = '+1 seconds'; - private array $dateTimeFrequencies = [ - self::FREQUENCY_YEARLY => self::DATETIME_YEARLY, - self::FREQUENCY_MONTHLY => self::DATETIME_MONTHLY, - self::FREQUENCY_WEEKLY => self::DATETIME_WEEKLY, - self::FREQUENCY_DAILY => self::DATETIME_DAILY, - self::FREQUENCY_HOURLY => self::DATETIME_HOURLY, + self::FREQUENCY_YEARLY => self::DATETIME_YEARLY, + self::FREQUENCY_MONTHLY => self::DATETIME_MONTHLY, + self::FREQUENCY_WEEKLY => self::DATETIME_WEEKLY, + self::FREQUENCY_DAILY => self::DATETIME_DAILY, + self::FREQUENCY_HOURLY => self::DATETIME_HOURLY, self::FREQUENCY_MINUTELY => self::DATETIME_MINUTELY, self::FREQUENCY_SECONDLY => self::DATETIME_SECONDLY, ]; @@ -64,13 +67,18 @@ class Frequency public function __construct(string $frequencyName) { - if (!in_array($frequencyName, $this->frequencies)) { + if (!in_array($frequencyName, $this->frequencies, true)) { throw new InvalidFrequencyOptionException(sprintf('Invalid frequency name. Supported values are : %s', implode(', ', $this->frequencies))); } $this->frequencyName = $frequencyName; } + public function __toString(): string + { + return $this->frequencyName; + } + public function convertToDateIntervalFormat(): string { return $this->dateIntervalFrequencies[$this->frequencyName]; @@ -80,9 +88,4 @@ public function convertToDateTimeFormat(): string { return $this->dateTimeFrequencies[$this->frequencyName]; } - - public function __toString(): string - { - return $this->frequencyName; - } } diff --git a/src/Recurrence/Model/Recurrence.php b/src/Recurrence/Model/Recurrence.php index 234ce51..897f160 100644 --- a/src/Recurrence/Model/Recurrence.php +++ b/src/Recurrence/Model/Recurrence.php @@ -3,74 +3,60 @@ namespace Recurrence\Model; use Recurrence\Constraint\DatetimeConstraint\DatetimeConstraintInterface; +use Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint; use Recurrence\Constraint\ProviderConstraint\ProviderConstraintInterface; use Recurrence\Constraint\RecurrenceConstraintInterface; +use Recurrence\Model\Exception\InvalidRecurrenceException; class Recurrence { - private ?Frequency $frequency = null; - private \Datetime $periodStartAt; - private ?\Datetime $periodEndAt = null; - private int $interval = 1; - private ?int $count = null; - private array $constraints = []; - - public function __construct() - { - $this->setPeriodStartAt(new \DateTime()); - } - - public function setPeriodStartAt(\Datetime $periodStartAt): self - { - $this->periodStartAt = $periodStartAt; - - return $this; - } + public function __construct( + private Frequency $frequency, + private int $interval, + private \DateTime $periodStartAt, + private ?\DateTime $periodEndAt = null, + private ?int $count = null, + private array $constraints = [], + ) { + if (null !== $count && $periodEndAt) { + throw new InvalidRecurrenceException('Recurrence cannot have [COUNT] and [UNTIL] option at the same time'); + } - public function getPeriodStartAt(): \Datetime - { - return $this->periodStartAt; - } + if (null === $count && null === $periodEndAt) { + throw new InvalidRecurrenceException('Recurrence required [COUNT] or [UNTIL] option'); + } - public function setPeriodEndAt(\Datetime $periodEndAt): self - { - $this->periodEndAt = $periodEndAt; + $constraintNames = array_map(static function ($constraint) { return $constraint::class; }, $constraints); + $duplicateConstraints = array_diff_key($constraintNames, array_unique($constraintNames)); - return $this; + if (!empty($duplicateConstraints)) { + throw new \InvalidArgumentException(sprintf('Duplicate constraint [%s]', implode(', ', $duplicateConstraints))); + } } - public function getPeriodEndAt(): ?\Datetime + public function getFrequency(): ?Frequency { - return $this->periodEndAt; + return $this->frequency; } - public function hasPeriodEndAt(): bool + public function getInterval(): int { - return $this->periodEndAt !== null; + return $this->interval; } - public function setFrequency(Frequency $frequency): self + public function getPeriodStartAt(): \DateTime { - $this->frequency = $frequency; - - return $this; + return $this->periodStartAt; } - public function getFrequency(): ?Frequency + public function getPeriodEndAt(): ?\DateTime { - return $this->frequency; + return $this->periodEndAt; } - public function getInterval(): int + public function hasPeriodEndAt(): bool { - return $this->interval; - } - - public function setInterval(int $interval): self - { - $this->interval = $interval; - - return $this; + return null !== $this->periodEndAt; } public function getCount(): ?int @@ -80,14 +66,7 @@ public function getCount(): ?int public function hasCount(): bool { - return $this->count !== null; - } - - public function setCount(int $count): self - { - $this->count = $count; - - return $this; + return null !== $this->count; } public function getConstraints(): array @@ -95,28 +74,32 @@ public function getConstraints(): array return $this->constraints; } - public function setConstraints(array $constraints): self + public function hasConstraints(): bool { - $this->constraints = []; - - foreach ($constraints as $constraint) { - $this->addConstraint($constraint); - } - - return $this; + return !empty($this->constraints); } - public function hasConstraints(): bool + public function hasConstraint(string $constraintClassName): bool { - return !empty($this->constraints); + foreach ($this->constraints as $key => $constraint) { + if ($constraint::class == $constraintClassName) { + return true; + } + } + + return false; } public function addConstraint(RecurrenceConstraintInterface $constraint): self { - if ($this->hasConstraint(get_class($constraint))) { + if ($this->hasConstraint($constraint::class)) { throw new \InvalidArgumentException(sprintf('Duplicate constraint [%s]', get_class($constraint))); } + if ($constraint instanceof EndOfMonthConstraint && Frequency::FREQUENCY_MONTHLY !== $this->frequency->__toString()) { + throw new InvalidRecurrenceException('End of month constraint can be applied only with monthly frequency'); + } + $this->constraints[] = $constraint; return $this; @@ -125,7 +108,7 @@ public function addConstraint(RecurrenceConstraintInterface $constraint): self public function removeConstraint(string $constraintClassName): self { foreach ($this->constraints as $key => $constraint) { - if (get_class($constraint) == $constraintClassName) { + if ($constraint::class == $constraintClassName) { unset($this->constraints[$key]); break; @@ -137,17 +120,6 @@ public function removeConstraint(string $constraintClassName): self return $this; } - public function hasConstraint(string $constraintClassName): bool - { - foreach ($this->constraints as $key => $constraint) { - if (get_class($constraint) == $constraintClassName) { - return true; - } - } - - return false; - } - public function hasProviderConstraint(): bool { foreach ($this->constraints as $key => $constraint) { diff --git a/src/Recurrence/Provider/AbstractDatetimeProvider.php b/src/Recurrence/Provider/AbstractDatetimeProvider.php index ef980b9..a6ea76b 100644 --- a/src/Recurrence/Provider/AbstractDatetimeProvider.php +++ b/src/Recurrence/Provider/AbstractDatetimeProvider.php @@ -6,13 +6,13 @@ abstract class AbstractDatetimeProvider { - public function estimatePeriodEndAt(Recurrence $recurrence): ?\Datetime + public function estimatePeriodEndAt(Recurrence $recurrence): ?\DateTime { $periodEndAt = $recurrence->getPeriodEndAt(); if ($recurrence->hasCount()) { $periodEndAt = clone $recurrence->getPeriodStartAt(); - $periodEndAt->modify(str_replace('1', ($recurrence->getCount()*$recurrence->getInterval()), $recurrence->getFrequency()->convertToDateTimeFormat())); + $periodEndAt->modify(str_replace('1', $recurrence->getCount() * $recurrence->getInterval(), $recurrence->getFrequency()->convertToDateTimeFormat())); } return $periodEndAt; diff --git a/src/Recurrence/Provider/DatetimeProviderFactory.php b/src/Recurrence/Provider/DatetimeProviderFactory.php index f17f413..31ef41c 100644 --- a/src/Recurrence/Provider/DatetimeProviderFactory.php +++ b/src/Recurrence/Provider/DatetimeProviderFactory.php @@ -8,14 +8,14 @@ class DatetimeProviderFactory { - public static function create(Recurrence $recurrence): EndOfMonthProvider | OptimizedProvider + public static function create(Recurrence $recurrence): EndOfMonthProvider|OptimizedProvider { $provider = new OptimizedProvider(); if ( - $recurrence->hasConstraint(EndOfMonthConstraint::class) && - (string) $recurrence->getFrequency() == Frequency::FREQUENCY_MONTHLY && - in_array((int) $recurrence->getPeriodStartAt()->format('d'), [29, 30, 31]) + $recurrence->hasConstraint(EndOfMonthConstraint::class) + && Frequency::FREQUENCY_MONTHLY == (string) $recurrence->getFrequency() + && in_array((int) $recurrence->getPeriodStartAt()->format('d'), [29, 30, 31], true) ) { $provider = new EndOfMonthProvider(); } diff --git a/src/Recurrence/Provider/OptimizedProvider.php b/src/Recurrence/Provider/OptimizedProvider.php index 4d37225..5202a70 100644 --- a/src/Recurrence/Provider/OptimizedProvider.php +++ b/src/Recurrence/Provider/OptimizedProvider.php @@ -16,7 +16,7 @@ public function provide(Recurrence $recurrence): array $periodEndAt = ($recurrence->hasPeriodEndAt()) ? $recurrence->getPeriodEndAt() : $this->estimatePeriodEndAt($recurrence); // Transform interval in Datetime interval expression - if ($recurrence->getInterval() !== 1) { + if (1 !== $recurrence->getInterval()) { $interval = str_replace('1', $recurrence->getInterval(), $interval); } @@ -25,7 +25,7 @@ public function provide(Recurrence $recurrence): array $recurrences = iterator_to_array(new \DatePeriod( $recurrence->getPeriodStartAt(), $dateInterval, - $periodEndAt + $periodEndAt, )); // When having count option, return only amount of recurrences requested diff --git a/src/Recurrence/Rrule/Extractor/AbstractExtractor.php b/src/Recurrence/Rrule/Extractor/AbstractExtractor.php index 7df46e2..ac67c5f 100644 --- a/src/Recurrence/Rrule/Extractor/AbstractExtractor.php +++ b/src/Recurrence/Rrule/Extractor/AbstractExtractor.php @@ -28,8 +28,8 @@ public function extract(string $rRule): ?array */ public function throwExceptionOnInvalidParameter(string $rRule, string $ruleKey): void { - if ((preg_match(sprintf('/%s=([\d\w]+)/', $ruleKey), $rRule, $matches) === 1)) { - throw new InvalidRruleException($ruleKey, ((count($matches) > 0) ? implode(', ', array_slice($matches, 1)) : '')); + if (1 === preg_match(sprintf('/%s=([\d\w]+)/', $ruleKey), $rRule, $matches)) { + throw new InvalidRruleException($ruleKey, (count($matches) > 0) ? implode(', ', array_slice($matches, 1)) : ''); } } } diff --git a/src/Recurrence/Rrule/Extractor/CountExtractor.php b/src/Recurrence/Rrule/Extractor/CountExtractor.php index e9c0a88..3b4d32e 100644 --- a/src/Recurrence/Rrule/Extractor/CountExtractor.php +++ b/src/Recurrence/Rrule/Extractor/CountExtractor.php @@ -2,8 +2,6 @@ namespace Recurrence\Rrule\Extractor; -use Recurrence\Rrule\Extractor\AbstractExtractor; - class CountExtractor extends AbstractExtractor { public const RRULE_PARAMETER = 'COUNT'; diff --git a/src/Recurrence/Rrule/Extractor/DtStartExtractor.php b/src/Recurrence/Rrule/Extractor/DtStartExtractor.php index ab049af..361eb48 100644 --- a/src/Recurrence/Rrule/Extractor/DtStartExtractor.php +++ b/src/Recurrence/Rrule/Extractor/DtStartExtractor.php @@ -2,8 +2,6 @@ namespace Recurrence\Rrule\Extractor; -use Recurrence\Rrule\Extractor\AbstractExtractor; - class DtStartExtractor extends AbstractExtractor { public const RRULE_PARAMETER = 'DTSTART'; diff --git a/src/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php b/src/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php index 4a1f0b9..7f3c064 100644 --- a/src/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php +++ b/src/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php @@ -2,8 +2,6 @@ namespace Recurrence\Rrule\Extractor; -use Recurrence\Rrule\Extractor\AbstractExtractor; - class DtStartTimezonedExtractor extends AbstractExtractor { public const RRULE_PARAMETER = 'DTSTART;TZID'; diff --git a/src/Recurrence/Rrule/Extractor/FreqExtractor.php b/src/Recurrence/Rrule/Extractor/FreqExtractor.php index 2722b14..79b77fc 100644 --- a/src/Recurrence/Rrule/Extractor/FreqExtractor.php +++ b/src/Recurrence/Rrule/Extractor/FreqExtractor.php @@ -2,8 +2,6 @@ namespace Recurrence\Rrule\Extractor; -use Recurrence\Rrule\Extractor\AbstractExtractor; - class FreqExtractor extends AbstractExtractor { public const RRULE_PARAMETER = 'FREQ'; diff --git a/src/Recurrence/Rrule/Extractor/IntervalExtractor.php b/src/Recurrence/Rrule/Extractor/IntervalExtractor.php index b754932..9c81f04 100644 --- a/src/Recurrence/Rrule/Extractor/IntervalExtractor.php +++ b/src/Recurrence/Rrule/Extractor/IntervalExtractor.php @@ -2,8 +2,6 @@ namespace Recurrence\Rrule\Extractor; -use Recurrence\Rrule\Extractor\AbstractExtractor; - class IntervalExtractor extends AbstractExtractor { public const RRULE_PARAMETER = 'INTERVAL'; diff --git a/src/Recurrence/Rrule/RecurrenceProvider.php b/src/Recurrence/Rrule/RecurrenceProvider.php index a2650a1..f82c52c 100644 --- a/src/Recurrence/Rrule/RecurrenceProvider.php +++ b/src/Recurrence/Rrule/RecurrenceProvider.php @@ -2,37 +2,36 @@ namespace Recurrence\Rrule; -use Recurrence\Model\Exception\InvalidRecurrenceException; +use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Model\Exception\InvalidRruleExpressionException; use Recurrence\Model\Recurrence; -use Recurrence\Model\Exception\InvalidRruleException; -use Recurrence\Validator\RecurrenceValidator; class RecurrenceProvider { /** - * Map extractor/transformer names with Recurrence attributes + * Map extractor/transformer names with Recurrence parameters. */ private array $options = [ - 'Count' => 'count', - 'Interval' => 'interval', - 'Freq' => 'frequency', - 'DtStartTimezoned' => 'periodStartAt', - 'DtStart' => 'periodStartAt', - 'UntilTimezoned' => 'periodEndAt', - 'Until' => 'periodEndAt', + 'Count', + 'Interval', + 'Freq', + 'DtStartTimezoned', + 'DtStart', + 'UntilTimezoned', + 'Until', ]; /** - * @return Recurrence * @throws InvalidRruleException */ public function create(string $rRule): Recurrence { - $recurrence = new Recurrence(); + $parameters = []; // Process all options supported - foreach ($this->options as $option => $attribute) { + foreach ($this->options as $option) { + $parameters[$option] = null; + // Create extractor $className = 'Recurrence\Rrule\Extractor\\'.$option.'Extractor'; $extractor = new $className(); @@ -42,31 +41,41 @@ public function create(string $rRule): Recurrence $className = 'Recurrence\Rrule\Transformer\\'.$option.'Transformer'; $transformer = new $className(); - // Set Recurrence attribute - $recurrence = $this->setAttribute($recurrence, $attribute, $transformer->transform($values)); + $parameters[$option] = $transformer->transform($values); } } - try { - RecurrenceValidator::validate($recurrence); - } catch (InvalidRecurrenceException $e) { - throw new InvalidRruleExpressionException($e->getMessage()); - } + $this->validate($parameters); - return $recurrence; + return new Recurrence( + $parameters['Freq'], + $parameters['Interval'], + $parameters['DtStartTimezoned'] ?? $parameters['DtStart'], + $parameters['UntilTimezoned'] ?? $parameters['Until'], + $parameters['Count'], + ); } - /** - * @param mixed $value - */ - private function setAttribute(Recurrence $recurrence, string $attribute, $value): Recurrence + private function validate(array $parameters): void { - $method = sprintf('set%s', ucfirst($attribute)); + if (empty($parameters['Freq'])) { + throw new InvalidRruleExpressionException(sprintf('Missing [Freq] option.')); + } + + if (empty($parameters['Interval'])) { + throw new InvalidRruleExpressionException(sprintf('Missing [Interval] option.')); + } - if ($value && method_exists($recurrence, $method)) { - $recurrence->$method($value); + if (empty($parameters['DtStart']) && empty($parameters['DtStartTimezoned'])) { + throw new InvalidRruleExpressionException(sprintf('Missing [DtStart] or [DtStartTimezoned] option.')); } - return $recurrence; + if (empty($parameters['UntilTimezoned']) && empty($parameters['Until']) && empty($parameters['Count'])) { + throw new InvalidRruleExpressionException(sprintf('Recurrence required [COUNT] or [UNTIL] option.')); + } + + if ((!empty($parameters['UntilTimezoned']) || !empty($parameters['Until'])) && !empty($parameters['Count'])) { + throw new InvalidRruleExpressionException(sprintf('Recurrence cannot have [COUNT] and [UNTIL] option at the same time.')); + } } } diff --git a/src/Recurrence/Rrule/Transformer/CountTransformer.php b/src/Recurrence/Rrule/Transformer/CountTransformer.php index c68365f..5622e61 100644 --- a/src/Recurrence/Rrule/Transformer/CountTransformer.php +++ b/src/Recurrence/Rrule/Transformer/CountTransformer.php @@ -2,8 +2,8 @@ namespace Recurrence\Rrule\Transformer; -use Recurrence\Rrule\Extractor\CountExtractor; use Recurrence\Model\Exception\InvalidRruleException; +use Recurrence\Rrule\Extractor\CountExtractor; class CountTransformer implements RruleTransformerInterface { @@ -23,7 +23,7 @@ public function transform(array $values): int protected function validate(array $values): void { if (!isset($values[0]) || !is_numeric($values[0])) { - throw new InvalidRruleException(CountExtractor::RRULE_PARAMETER, ((isset($values[0])) ? (string) $values[0] : '')); + throw new InvalidRruleException(CountExtractor::RRULE_PARAMETER, (isset($values[0])) ? (string) $values[0] : ''); } } } diff --git a/src/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php b/src/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php index 01686d0..0c8f2d1 100644 --- a/src/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php +++ b/src/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php @@ -2,12 +2,11 @@ namespace Recurrence\Rrule\Transformer; -use Recurrence\Rrule\Extractor\DtStartTimezonedExtractor; use Recurrence\Model\Exception\InvalidRruleException; +use Recurrence\Rrule\Extractor\DtStartTimezonedExtractor; /** - * Class DtStartTimezonedTransformer - * @package Recurrence\Rrule\Transformer + * Class DtStartTimezonedTransformer. */ class DtStartTimezonedTransformer implements RruleTransformerInterface { diff --git a/src/Recurrence/Rrule/Transformer/DtStartTransformer.php b/src/Recurrence/Rrule/Transformer/DtStartTransformer.php index 9ff3599..2574c81 100644 --- a/src/Recurrence/Rrule/Transformer/DtStartTransformer.php +++ b/src/Recurrence/Rrule/Transformer/DtStartTransformer.php @@ -2,8 +2,8 @@ namespace Recurrence\Rrule\Transformer; -use Recurrence\Rrule\Extractor\DtStartExtractor; use Recurrence\Model\Exception\InvalidRruleException; +use Recurrence\Rrule\Extractor\DtStartExtractor; class DtStartTransformer implements RruleTransformerInterface { @@ -14,15 +14,15 @@ public function transform(array $values): \DateTime { $this->validate($values); - if (count($values) == 2 && substr($values[1], -1) == 'Z') { + if (2 == count($values) && 'Z' == substr($values[1], -1)) { $dtStart = \DateTime::createFromFormat('Ymd\THis\Z', $values[0], new \DateTimeZone('UTC')); - } elseif (count($values) == 2) { + } elseif (2 == count($values)) { $dtStart = \DateTime::createFromFormat('Ymd\THis', $values[0]); } else { $dtStart = \DateTime::createFromFormat('Ymd', $values[0]); } - if ($dtStart === false) { + if (false === $dtStart) { throw new InvalidRruleException(DtStartExtractor::RRULE_PARAMETER, (string) $values[0]); } diff --git a/src/Recurrence/Rrule/Transformer/FreqTransformer.php b/src/Recurrence/Rrule/Transformer/FreqTransformer.php index 98e30ed..5ece984 100644 --- a/src/Recurrence/Rrule/Transformer/FreqTransformer.php +++ b/src/Recurrence/Rrule/Transformer/FreqTransformer.php @@ -2,10 +2,10 @@ namespace Recurrence\Rrule\Transformer; +use Recurrence\Model\Exception\InvalidFrequencyOptionException; +use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Model\Frequency; use Recurrence\Rrule\Extractor\FreqExtractor; -use Recurrence\Model\Exception\InvalidRruleException; -use Recurrence\Model\Exception\InvalidFrequencyOptionException; class FreqTransformer implements RruleTransformerInterface { diff --git a/src/Recurrence/Rrule/Transformer/IntervalTransformer.php b/src/Recurrence/Rrule/Transformer/IntervalTransformer.php index 4b59f75..673a003 100644 --- a/src/Recurrence/Rrule/Transformer/IntervalTransformer.php +++ b/src/Recurrence/Rrule/Transformer/IntervalTransformer.php @@ -13,7 +13,7 @@ class IntervalTransformer extends CountTransformer protected function validate(array $values): void { if (!isset($values[0]) || !is_numeric($values[0])) { - throw new InvalidRruleException(IntervalExtractor::RRULE_PARAMETER, ((isset($values[0])) ? (string) $values[0] : '')); + throw new InvalidRruleException(IntervalExtractor::RRULE_PARAMETER, (isset($values[0])) ? (string) $values[0] : ''); } } } diff --git a/src/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php b/src/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php index ac08a3d..8a125fb 100644 --- a/src/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php +++ b/src/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php @@ -2,8 +2,8 @@ namespace Recurrence\Rrule\Transformer; -use Recurrence\Rrule\Extractor\UntilTimezonedExtractor; use Recurrence\Model\Exception\InvalidRruleException; +use Recurrence\Rrule\Extractor\UntilTimezonedExtractor; class UntilTimezonedTransformer extends DtStartTimezonedTransformer { diff --git a/src/Recurrence/Rrule/Transformer/UntilTransformer.php b/src/Recurrence/Rrule/Transformer/UntilTransformer.php index 3b7910e..be25ec7 100644 --- a/src/Recurrence/Rrule/Transformer/UntilTransformer.php +++ b/src/Recurrence/Rrule/Transformer/UntilTransformer.php @@ -2,8 +2,8 @@ namespace Recurrence\Rrule\Transformer; -use Recurrence\Rrule\Extractor\UntilExtractor; use Recurrence\Model\Exception\InvalidRruleException; +use Recurrence\Rrule\Extractor\UntilExtractor; class UntilTransformer extends DtStartTransformer { diff --git a/src/Recurrence/Validator/RecurrenceValidator.php b/src/Recurrence/Validator/RecurrenceValidator.php deleted file mode 100644 index abb80e4..0000000 --- a/src/Recurrence/Validator/RecurrenceValidator.php +++ /dev/null @@ -1,35 +0,0 @@ -getFrequency()) { - throw new InvalidRecurrenceException('Frequency is required'); - } - - if ($recurrence->hasCount() && $recurrence->getPeriodEndAt()) { - throw new InvalidRecurrenceException('Recurrence cannot have [COUNT] and [UNTIL] option at the same time'); - } - - if (!$recurrence->hasCount() && !$recurrence->getPeriodEndAt()) { - throw new InvalidRecurrenceException('Recurrence required [COUNT] or [UNTIL] option'); - } - - if ($recurrence->hasConstraint(EndOfMonthConstraint::class) && (string) $recurrence->getFrequency() != Frequency::FREQUENCY_MONTHLY) { - throw new InvalidRecurrenceException('End of month constraint can be applied only with monthly frequency'); - } - - return true; - } -} diff --git a/tests/benchmark/Recurrence/DatetimeProviderBench.php b/tests/benchmark/Recurrence/DatetimeProviderBench.php index 91d60cc..a7af7cf 100644 --- a/tests/benchmark/Recurrence/DatetimeProviderBench.php +++ b/tests/benchmark/Recurrence/DatetimeProviderBench.php @@ -6,16 +6,19 @@ class DatetimeProviderBench { /** * @Revs(50) + * * @Iterations(3) + * * @OutputTimeUnit("seconds", precision=6) */ public function benchStandardPeriod() { - $recurrence = (new \Recurrence\Model\Recurrence()) - ->setPeriodStartAt(new \Datetime('2017-01-01')) - ->setPeriodEndAt(new \Datetime('2018-01-01')) - ->setFrequency(new \Recurrence\Model\Frequency('MONTHLY')) - ; + $recurrence = new \Recurrence\Model\Recurrence( + new \Recurrence\Model\Frequency('MONTHLY'), + 1, + new \DateTime('2017-01-01'), + new \DateTime('2018-01-01'), + ); $period = (new \Recurrence\DatetimeProvider())->provide($recurrence); foreach ($period as $date) { @@ -25,16 +28,19 @@ public function benchStandardPeriod() /** * @Revs(50) + * * @Iterations(3) + * * @OutputTimeUnit("seconds", precision=6) */ public function benchLongPeriod() { - $recurrence = (new \Recurrence\Model\Recurrence()) - ->setPeriodStartAt(new \Datetime('2017-01-01')) - ->setPeriodEndAt(new \Datetime('2027-01-01')) - ->setFrequency(new \Recurrence\Model\Frequency('MONTHLY')) - ; + $recurrence = new \Recurrence\Model\Recurrence( + new \Recurrence\Model\Frequency('MONTHLY'), + 1, + new \DateTime('2017-01-01'), + new \DateTime('2027-01-01'), + ); $period = (new \Recurrence\DatetimeProvider())->provide($recurrence); foreach ($period as $date) { @@ -44,16 +50,19 @@ public function benchLongPeriod() /** * @Revs(50) + * * @Iterations(3) + * * @OutputTimeUnit("seconds", precision=6) */ public function benchManyRecurrencesPeriod() { - $recurrence = (new \Recurrence\Model\Recurrence()) - ->setPeriodStartAt(new \Datetime('2017-01-01')) - ->setPeriodEndAt(new \Datetime('2018-01-01')) - ->setFrequency(new \Recurrence\Model\Frequency('DAILY')) - ; + $recurrence = new \Recurrence\Model\Recurrence( + new \Recurrence\Model\Frequency('DAILY'), + 1, + new \DateTime('2017-01-01'), + new \DateTime('2018-01-01'), + ); $period = (new \Recurrence\DatetimeProvider())->provide($recurrence); foreach ($period as $date) { @@ -63,17 +72,22 @@ public function benchManyRecurrencesPeriod() /** * @Revs(50) + * * @Iterations(3) + * * @OutputTimeUnit("seconds", precision=6) */ public function benchEndOfMonthProviderPeriod() { - $recurrence = (new \Recurrence\Model\Recurrence()) - ->setPeriodStartAt(new \Datetime('2017-01-01')) - ->setPeriodEndAt(new \Datetime('2018-01-01')) - ->setFrequency(new \Recurrence\Model\Frequency('MONTHLY')) - ->addConstraint(new \Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint()) - ; + $recurrence = new \Recurrence\Model\Recurrence( + new \Recurrence\Model\Frequency('MONTHLY'), + 1, + new \DateTime('2017-01-01'), + new \DateTime('2018-01-01'), + null, + [new \Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint()], + ); + $period = (new \Recurrence\DatetimeProvider())->provide($recurrence); foreach ($period as $date) { diff --git a/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php b/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php index 954933b..36e6088 100644 --- a/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php +++ b/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeDaysOfWeekConstraint.php @@ -2,17 +2,16 @@ namespace Recurrence\tests\units\Constraint\DatetimeConstraint; -use atoum; - -use Recurrence\Model\Recurrence; use Recurrence\Constraint\DatetimeConstraint\ExcludeDaysOfWeekConstraint as TestedExcludeDaysOfWeekConstraint; +use Recurrence\Model\Frequency; +use Recurrence\Model\Recurrence; -class ExcludeDaysOfWeekConstraint extends atoum +class ExcludeDaysOfWeekConstraint extends \atoum { public function testInvalidOptions(): void { $this->assert - ->exception(function () { + ->exception(static function () { new TestedExcludeDaysOfWeekConstraint([1, 2, 3, 4, 5, 6, 7, 8]); }) ->isInstanceOf(\InvalidArgumentException::class) @@ -20,7 +19,7 @@ public function testInvalidOptions(): void ; $this->assert - ->exception(function () { + ->exception(static function () { new TestedExcludeDaysOfWeekConstraint([1, 'ratatouille']); }) ->isInstanceOf(\InvalidArgumentException::class) @@ -28,7 +27,7 @@ public function testInvalidOptions(): void ; $this->assert - ->exception(function () { + ->exception(static function () { new TestedExcludeDaysOfWeekConstraint([1, 12]); }) ->isInstanceOf(\InvalidArgumentException::class) @@ -38,13 +37,23 @@ public function testInvalidOptions(): void /** * @dataProvider datetimesLessOneDayProvider + * + * @param mixed $originalDatetime + * @param mixed $expectedDatetime */ public function testExcludeOneDayOfWeek($originalDatetime, $expectedDatetime): void { $constraint = new TestedExcludeDaysOfWeekConstraint([3]); + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-31'), + new \DateTime('2018-01-01'), + ); + $this->assert - ->object($constraint->apply(new Recurrence(), $originalDatetime)) + ->object($constraint->apply($recurrence, $originalDatetime)) ->isEqualTo($expectedDatetime) ; } @@ -53,32 +62,32 @@ public function datetimesLessOneDayProvider(): array { return [ [ - new \Datetime('2017-01-01'), - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), + new \DateTime('2017-01-01'), ], [ - new \Datetime('2017-01-02'), - new \Datetime('2017-01-02'), + new \DateTime('2017-01-02'), + new \DateTime('2017-01-02'), ], [ - new \Datetime('2017-01-03'), - new \Datetime('2017-01-03'), + new \DateTime('2017-01-03'), + new \DateTime('2017-01-03'), ], [ - new \Datetime('2017-01-04'), - new \Datetime('2017-01-05'), + new \DateTime('2017-01-04'), + new \DateTime('2017-01-05'), ], [ - new \Datetime('2017-01-05'), - new \Datetime('2017-01-05'), + new \DateTime('2017-01-05'), + new \DateTime('2017-01-05'), ], [ - new \Datetime('2017-01-06'), - new \Datetime('2017-01-06'), + new \DateTime('2017-01-06'), + new \DateTime('2017-01-06'), ], [ - new \Datetime('2017-01-07'), - new \Datetime('2017-01-07'), + new \DateTime('2017-01-07'), + new \DateTime('2017-01-07'), ], ]; } @@ -90,8 +99,15 @@ public function testExcludeMultipleDaysOfWeek(\DateTime $originalDatetime, \Date { $constraint = new TestedExcludeDaysOfWeekConstraint([2, 5]); + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-31'), + new \DateTime('2018-01-01'), + ); + $this->assert - ->object($constraint->apply(new Recurrence(), $originalDatetime)) + ->object($constraint->apply($recurrence, $originalDatetime)) ->isEqualTo($expectedDatetime) ; } @@ -100,33 +116,33 @@ public function datetimesLessMultipleDaysProvider(): array { return [ [ - new \Datetime('2017-01-01'), - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), + new \DateTime('2017-01-01'), ], [ - new \Datetime('2017-01-02'), - new \Datetime('2017-01-02'), + new \DateTime('2017-01-02'), + new \DateTime('2017-01-02'), ], [ - new \Datetime('2017-01-03'), - new \Datetime('2017-01-04'), + new \DateTime('2017-01-03'), + new \DateTime('2017-01-04'), ], [ - new \Datetime('2017-01-04'), - new \Datetime('2017-01-04'), + new \DateTime('2017-01-04'), + new \DateTime('2017-01-04'), ], [ - new \Datetime('2017-01-05'), - new \Datetime('2017-01-05'), + new \DateTime('2017-01-05'), + new \DateTime('2017-01-05'), ], [ - new \Datetime('2017-01-06'), - new \Datetime('2017-01-07'), + new \DateTime('2017-01-06'), + new \DateTime('2017-01-07'), ], [ - new \Datetime('2017-01-07'), - new \Datetime('2017-01-07'), + new \DateTime('2017-01-07'), + new \DateTime('2017-01-07'), ], ]; } -} \ No newline at end of file +} diff --git a/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php b/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php index 2467984..b43edbc 100644 --- a/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php +++ b/tests/units/Recurrence/Constraint/DatetimeConstraint/ExcludeWeekendConstraint.php @@ -2,23 +2,31 @@ namespace Recurrence\tests\units\Constraint\DatetimeConstraint; -use atoum; - -use Recurrence\Model\Recurrence; use Recurrence\Constraint\DatetimeConstraint\ExcludeWeekendConstraint as TestedExcludeWeekendConstraint; +use Recurrence\Model\Frequency; +use Recurrence\Model\Recurrence; -class ExcludeWeekendConstraint extends atoum +class ExcludeWeekendConstraint extends \atoum { - /** * @dataProvider datetimesProvider + * + * @param mixed $originalDatetime + * @param mixed $expectedDatetime */ public function testDatetimes($originalDatetime, $expectedDatetime): void { $constraint = new TestedExcludeWeekendConstraint(); + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-31'), + new \DateTime('2018-01-01'), + ); + $this->assert - ->object($constraint->apply(new Recurrence(), $originalDatetime)) + ->object($constraint->apply($recurrence, $originalDatetime)) ->isEqualTo($expectedDatetime) ; } @@ -28,33 +36,33 @@ public function datetimesProvider(): array return [ // List of datetimes which are not on saturday or sunday [ - new \Datetime('2017-01-02'), - new \Datetime('2017-01-02'), + new \DateTime('2017-01-02'), + new \DateTime('2017-01-02'), ], [ - new \Datetime('2017-01-03'), - new \Datetime('2017-01-03'), + new \DateTime('2017-01-03'), + new \DateTime('2017-01-03'), ], [ - new \Datetime('2017-01-04'), - new \Datetime('2017-01-04'), + new \DateTime('2017-01-04'), + new \DateTime('2017-01-04'), ], [ - new \Datetime('2017-01-05'), - new \Datetime('2017-01-05'), + new \DateTime('2017-01-05'), + new \DateTime('2017-01-05'), ], [ - new \Datetime('2017-01-06'), - new \Datetime('2017-01-06'), + new \DateTime('2017-01-06'), + new \DateTime('2017-01-06'), ], // List of datetimes in weekend [ - new \Datetime('2017-01-01'), - new \Datetime('2017-01-02'), + new \DateTime('2017-01-01'), + new \DateTime('2017-01-02'), ], [ - new \Datetime('2016-12-31'), - new \Datetime('2017-01-02'), + new \DateTime('2016-12-31'), + new \DateTime('2017-01-02'), ], ]; } diff --git a/tests/units/Recurrence/DatetimeProvider.php b/tests/units/Recurrence/DatetimeProvider.php index 171bf19..bb041ee 100644 --- a/tests/units/Recurrence/DatetimeProvider.php +++ b/tests/units/Recurrence/DatetimeProvider.php @@ -2,86 +2,92 @@ namespace Recurrence\tests\units; -use atoum; - use Recurrence\Constraint\DatetimeConstraint\ExcludeWeekendConstraint; -use Recurrence\Model\Exception\InvalidRecurrenceException; -use Recurrence\Model\Recurrence; use Recurrence\Model\Frequency; +use Recurrence\Model\Recurrence; -class DatetimeProvider extends atoum +class DatetimeProvider extends \atoum { - - public function testSuccess(): void + public function testProvider(): void { - $recurrence = new Recurrence(); - $recurrence->setFrequency(new Frequency('MONTHLY')); - $recurrence->setCount(2); + $recurrence = new Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + null, + 2, + ); $periods = (new \Recurrence\DatetimeProvider())->provide($recurrence); $this->assert ->integer(count($periods)) - ->isEqualTo(2); + ->isEqualTo(2) + ; - $recurrence = new Recurrence(); - $recurrence->setFrequency(new Frequency('MONTHLY')); - $recurrence->setCount(2); - $recurrence->setInterval(2); + $recurrence = new Recurrence( + new Frequency('MONTHLY'), + 2, + new \DateTime(), + null, + 2, + ); $periods = (new \Recurrence\DatetimeProvider())->provide($recurrence); $this->assert ->integer(count($periods)) - ->isEqualTo(2); + ->isEqualTo(2) + ; - $recurrence = new Recurrence(); - $recurrence->setFrequency(new Frequency('MONTHLY')); + $periodStartAt = new \DateTime(); $periodEndAt = clone $recurrence->getPeriodStartAt(); $periodEndAt->modify('+1 months'); - $recurrence->setPeriodEndAt($periodEndAt); + $recurrence = new Recurrence( + new Frequency('MONTHLY'), + 1, + $periodStartAt, + $periodEndAt, + ); $periods = (new \Recurrence\DatetimeProvider())->provide($recurrence); $this->assert ->integer(count($periods)) - ->isEqualTo(1); + ->isEqualTo(1) + ; - $recurrence = new Recurrence(); - $recurrence->setFrequency(new Frequency('MONTHLY')); + $periodStartAt = new \DateTime(); $periodEndAt = clone $recurrence->getPeriodStartAt(); $periodEndAt->modify('+12 months'); - $recurrence->setPeriodEndAt($periodEndAt); - $recurrence->addConstraint(new ExcludeWeekendConstraint()); + + $recurrence = new Recurrence( + new Frequency('MONTHLY'), + 1, + $periodStartAt, + $periodEndAt, + null, + [new ExcludeWeekendConstraint()], + ); $periods = (new \Recurrence\DatetimeProvider())->provide($recurrence); $this->assert ->integer(count($periods)) - ->isEqualTo(12); - } - - public function testFailed(): void - { - $this->assert - ->exception(function () { - $recurrence = new Recurrence(); - $recurrence->setCount(2); - - (new \Recurrence\DatetimeProvider())->provide($recurrence); - }) - ->isInstanceOf(InvalidRecurrenceException::class) - ->hasMessage('Frequency is required') + ->isEqualTo(12) ; } public function testNoDuplicateDays(): void { - $recurrence = new Recurrence(); - $recurrence->setFrequency(new Frequency('DAILY')); - $recurrence->setPeriodStartAt(new \Datetime('2017-01-01')); - $recurrence->setPeriodEndAt(new \Datetime('2017-01-15')); - $recurrence->addConstraint(new ExcludeWeekendConstraint()); + $recurrence = new Recurrence( + new Frequency('DAILY'), + 1, + new \DateTime('2017-01-01'), + new \DateTime('2017-01-15'), + null, + [new ExcludeWeekendConstraint()], + ); $periods = (new \Recurrence\DatetimeProvider())->provide($recurrence); diff --git a/tests/units/Recurrence/Model/Exception/InvalidRruleException.php b/tests/units/Recurrence/Model/Exception/InvalidRruleException.php index 3ed5fb5..feed338 100644 --- a/tests/units/Recurrence/Model/Exception/InvalidRruleException.php +++ b/tests/units/Recurrence/Model/Exception/InvalidRruleException.php @@ -2,17 +2,15 @@ namespace Recurrence\tests\units\Model\Exception; -use atoum; - -class InvalidRruleException extends atoum +class InvalidRruleException extends \atoum { - public function testContructor(): void { $exception = (new \Recurrence\Model\Exception\InvalidRruleException('BIRD', 'IS_THE_WORD')); $this->assert ->string($exception->getMessage()) - ->isEqualTo('Invalid RRULE [BIRD] option : [IS_THE_WORD]'); + ->isEqualTo('Invalid RRULE [BIRD] option : [IS_THE_WORD]') + ; } } diff --git a/tests/units/Recurrence/Model/Frequency.php b/tests/units/Recurrence/Model/Frequency.php index d706b8f..6c8ee23 100644 --- a/tests/units/Recurrence/Model/Frequency.php +++ b/tests/units/Recurrence/Model/Frequency.php @@ -2,17 +2,15 @@ namespace Recurrence\tests\units\Model; -use atoum; use Recurrence\Model\Exception\InvalidFrequencyOptionException; -class Frequency extends atoum +class Frequency extends \atoum { - public function testContructor(): void { $this->assert - ->exception(function () { - (new \Recurrence\Model\Frequency('RANDOMLY')); + ->exception(static function () { + new \Recurrence\Model\Frequency('RANDOMLY'); }) ->isInstanceOf(InvalidFrequencyOptionException::class) ->hasMessage('Invalid frequency name. Supported values are : YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY') @@ -28,7 +26,34 @@ public function testConvertToDateIntervalFormat(string $frequencyName, string $e $this->assert ->string((string) $frequency->convertToDateIntervalFormat()) - ->isEqualTo($expected); + ->isEqualTo($expected) + ; + } + + /** + * @dataProvider convertToDateTimeProvider + */ + public function testConvertToDateTimeFormat(string $frequencyName, string $expected): void + { + $frequency = (new \Recurrence\Model\Frequency($frequencyName)); + + $this->assert + ->string((string) $frequency->convertToDateTimeFormat()) + ->isEqualTo($expected) + ; + } + + /** + * @dataProvider toStringProvider + */ + public function testToString(string $frequencyName, string $expected): void + { + $frequency = (new \Recurrence\Model\Frequency($frequencyName)); + + $this->assert + ->string((string) $frequency) + ->isEqualTo($expected) + ; } protected function convertToDateIntervalProvider(): array @@ -44,18 +69,6 @@ protected function convertToDateIntervalProvider(): array ]; } - /** - * @dataProvider convertToDateTimeProvider - */ - public function testConvertToDateTimeFormat(string $frequencyName, string $expected): void - { - $frequency = (new \Recurrence\Model\Frequency($frequencyName)); - - $this->assert - ->string((string) $frequency->convertToDateTimeFormat()) - ->isEqualTo($expected); - } - protected function convertToDateTimeProvider(): array { return [ @@ -69,18 +82,6 @@ protected function convertToDateTimeProvider(): array ]; } - /** - * @dataProvider toStringProvider - */ - public function testToString(string $frequencyName, string $expected): void - { - $frequency = (new \Recurrence\Model\Frequency($frequencyName)); - - $this->assert - ->string((string) $frequency) - ->isEqualTo($expected); - } - protected function toStringProvider(): array { return [ diff --git a/tests/units/Recurrence/Model/Recurrence.php b/tests/units/Recurrence/Model/Recurrence.php index 1967f10..038cc2c 100644 --- a/tests/units/Recurrence/Model/Recurrence.php +++ b/tests/units/Recurrence/Model/Recurrence.php @@ -2,22 +2,28 @@ namespace Recurrence\tests\units\Model; -use atoum; -use Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint; use Recurrence\Constraint\DatetimeConstraint\ExcludeWeekendConstraint; +use Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint; +use Recurrence\Model\Frequency; use Recurrence\tests\units\Constraint\DatetimeConstraint\ExcludeDaysOfWeekConstraint; -class Recurrence extends atoum +class Recurrence extends \atoum { public function testContructor(): void { - $now = new \Datetime(); + $now = new \DateTime(); - $recurrence = new \Recurrence\Model\Recurrence(); + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + null, + 2, + ); $this->assert ->object($recurrence->getPeriodStartAt()) - ->isInstanceOf(\Datetime::class) + ->isInstanceOf(\DateTime::class) ; $this->assert @@ -29,21 +35,30 @@ public function testContructor(): void public function testDuplicateConstraint(): void { $this->assert - ->exception(function () { - (new \Recurrence\Model\Recurrence()) - ->addConstraint(new EndOfMonthConstraint()) - ->addConstraint(new EndOfMonthConstraint()) - ; + ->exception(static function () { + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + null, + 10, + [new EndOfMonthConstraint(), new EndOfMonthConstraint()], + ); }) ->isInstanceOf(\InvalidArgumentException::class) ->hasMessage('Duplicate constraint [Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint]') ; $this->assert - ->exception(function () { - (new \Recurrence\Model\Recurrence()) - ->setConstraints([new EndOfMonthConstraint(), new EndOfMonthConstraint()]) - ; + ->exception(static function () { + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + null, + 10, + [new EndOfMonthConstraint(), new EndOfMonthConstraint()], + ); }) ->isInstanceOf(\InvalidArgumentException::class) ->hasMessage('Duplicate constraint [Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint]') @@ -52,11 +67,14 @@ public function testDuplicateConstraint(): void public function testRemoveConstraint(): void { - $recurrence = - (new \Recurrence\Model\Recurrence()) - ->addConstraint(new EndOfMonthConstraint()) - ->addConstraint(new ExcludeWeekendConstraint()) - ; + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + null, + 10, + [new EndOfMonthConstraint(), new ExcludeWeekendConstraint()], + ); $this->assert ->integer(count($recurrence->getConstraints())) @@ -80,11 +98,14 @@ public function testRemoveConstraint(): void public function testHasConstraint(): void { - $recurrence = - (new \Recurrence\Model\Recurrence()) - ->addConstraint(new EndOfMonthConstraint()) - ->addConstraint(new ExcludeWeekendConstraint()) - ; + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + null, + 10, + [new EndOfMonthConstraint(), new ExcludeWeekendConstraint()], + ); $this->assert ->boolean($recurrence->hasConstraint(EndOfMonthConstraint::class)) @@ -99,7 +120,12 @@ public function testHasConstraint(): void public function testHasConstraints(): void { - $recurrence = new \Recurrence\Model\Recurrence(); + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + new \DateTime(), + ); $this->assert ->boolean($recurrence->hasConstraints()) @@ -108,7 +134,8 @@ public function testHasConstraints(): void $recurrence ->addConstraint(new EndOfMonthConstraint()) - ->addConstraint(new ExcludeWeekendConstraint()); + ->addConstraint(new ExcludeWeekendConstraint()) + ; $this->assert ->boolean($recurrence->hasConstraints()) @@ -118,7 +145,12 @@ public function testHasConstraints(): void public function testHasProviderConstraint(): void { - $recurrence = new \Recurrence\Model\Recurrence(); + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + new \DateTime(), + ); $this->assert ->boolean($recurrence->hasProviderConstraint()) @@ -126,7 +158,8 @@ public function testHasProviderConstraint(): void ; $recurrence - ->addConstraint(new ExcludeWeekendConstraint()); + ->addConstraint(new ExcludeWeekendConstraint()) + ; $this->assert ->boolean($recurrence->hasProviderConstraint()) @@ -134,7 +167,8 @@ public function testHasProviderConstraint(): void ; $recurrence - ->addConstraint(new EndOfMonthConstraint()); + ->addConstraint(new EndOfMonthConstraint()) + ; $this->assert ->boolean($recurrence->hasProviderConstraint()) @@ -144,7 +178,12 @@ public function testHasProviderConstraint(): void public function testHasDatetimeConstraint(): void { - $recurrence = new \Recurrence\Model\Recurrence(); + $recurrence = new \Recurrence\Model\Recurrence( + new Frequency('MONTHLY'), + 1, + new \DateTime(), + new \DateTime(), + ); $this->assert ->boolean($recurrence->hasDatetimeConstraint()) @@ -152,7 +191,8 @@ public function testHasDatetimeConstraint(): void ; $recurrence - ->addConstraint(new EndOfMonthConstraint()); + ->addConstraint(new EndOfMonthConstraint()) + ; $this->assert ->boolean($recurrence->hasDatetimeConstraint()) @@ -160,7 +200,8 @@ public function testHasDatetimeConstraint(): void ; $recurrence - ->addConstraint(new ExcludeWeekendConstraint()); + ->addConstraint(new ExcludeWeekendConstraint()) + ; $this->assert ->boolean($recurrence->hasDatetimeConstraint()) diff --git a/tests/units/Recurrence/Provider/AbstractDatetimeProvider.php b/tests/units/Recurrence/Provider/AbstractDatetimeProvider.php index 03843c9..b049f62 100644 --- a/tests/units/Recurrence/Provider/AbstractDatetimeProvider.php +++ b/tests/units/Recurrence/Provider/AbstractDatetimeProvider.php @@ -2,46 +2,45 @@ namespace Recurrence\tests\units\Provider; -use atoum; - use Recurrence\Model\Frequency; use Recurrence\Model\Recurrence; use Recurrence\Provider\OptimizedProvider; -class AbstractDatetimeProvider extends atoum +class AbstractDatetimeProvider extends \atoum { public function testEstimatePeriodEndAt(): void { $provider = new OptimizedProvider(); // With COUNT option - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_MONTHLY)) - ->setPeriodStartAt(new \Datetime('2017-01-01 00:00:00')) - ->setCount(2) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-01 00:00:00'), + null, + 2, + ); $this->assert ->object($provider->estimatePeriodEndAt($recurrence)) ->isInstanceOf(\DateTime::class) ->object($provider->estimatePeriodEndAt($recurrence)) - ->isEqualTo(new \Datetime('2017-03-01 00:00:00')) + ->isEqualTo(new \DateTime('2017-03-01 00:00:00')) ; // Without COUNT option - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_MONTHLY)) - ->setPeriodStartAt(new \Datetime('2017-01-01 00:00:00')) - ->setPeriodEndAt(new \Datetime('2017-03-02 13:37:00')) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-01 00:00:00'), + new \DateTime('2017-03-02 13:37:00'), + ); $this->assert ->object($provider->estimatePeriodEndAt($recurrence)) ->isInstanceOf(\DateTime::class) ->object($provider->estimatePeriodEndAt($recurrence)) - ->isEqualTo(new \Datetime('2017-03-02 13:37:00')) + ->isEqualTo(new \DateTime('2017-03-02 13:37:00')) ; } } diff --git a/tests/units/Recurrence/Provider/DatetimeProviderFactory.php b/tests/units/Recurrence/Provider/DatetimeProviderFactory.php index 5a2e7ed..5802baa 100644 --- a/tests/units/Recurrence/Provider/DatetimeProviderFactory.php +++ b/tests/units/Recurrence/Provider/DatetimeProviderFactory.php @@ -2,8 +2,6 @@ namespace Recurrence\tests\units\Provider; -use atoum; - use Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint; use Recurrence\Model\Frequency; use Recurrence\Model\Recurrence; @@ -11,15 +9,17 @@ use Recurrence\Provider\EndOfMonthProvider; use Recurrence\Provider\OptimizedProvider; -class DatetimeProviderFactory extends atoum +class DatetimeProviderFactory extends \atoum { public function testStandardRecurrence(): void { - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_MONTHLY)) - ->setCount(2) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime(), + null, + 2, + ); $this->assert ->object(TestedDatetimeProviderFactory::create($recurrence)) @@ -29,51 +29,55 @@ public function testStandardRecurrence(): void public function testRecurrenceWithEndOfMonthConstraint(): void { - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_MONTHLY)) - ->setPeriodStartAt(new \DateTime('2017-01-31')) - ->setCount(2) - ->addConstraint(new EndOfMonthConstraint()) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-31'), + null, + 2, + [new EndOfMonthConstraint()], + ); $this->assert ->object(TestedDatetimeProviderFactory::create($recurrence)) ->isInstanceOf(EndOfMonthProvider::class) ; - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_MONTHLY)) - ->setPeriodStartAt(new \DateTime('2017-01-28')) - ->setCount(2) - ->addConstraint(new EndOfMonthConstraint()) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-28'), + null, + 2, + [new EndOfMonthConstraint()], + ); $this->assert ->object(TestedDatetimeProviderFactory::create($recurrence)) ->isInstanceOf(OptimizedProvider::class) ; - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_DAILY)) - ->setPeriodStartAt(new \DateTime('2017-01-31')) - ->setCount(2) - ->addConstraint(new EndOfMonthConstraint()) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_DAILY), + 1, + new \DateTime('2017-01-31'), + null, + 2, + [new EndOfMonthConstraint()], + ); $this->assert ->object(TestedDatetimeProviderFactory::create($recurrence)) ->isInstanceOf(OptimizedProvider::class) ; - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency(Frequency::FREQUENCY_MONTHLY)) - ->setPeriodStartAt(new \DateTime('2017-01-31')) - ->setCount(2) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + new \DateTime('2017-01-31'), + null, + 2, + ); $this->assert ->object(TestedDatetimeProviderFactory::create($recurrence)) diff --git a/tests/units/Recurrence/Provider/EndOfMonthProvider.php b/tests/units/Recurrence/Provider/EndOfMonthProvider.php index f828cbe..2453c7c 100644 --- a/tests/units/Recurrence/Provider/EndOfMonthProvider.php +++ b/tests/units/Recurrence/Provider/EndOfMonthProvider.php @@ -2,36 +2,37 @@ namespace Recurrence\tests\units\Provider; -use atoum; - use Recurrence\Model\Frequency; use Recurrence\Model\Recurrence; use Recurrence\Provider\EndOfMonthProvider as TestedEndOfMonthProvider; -class EndOfMonthProvider extends atoum +class EndOfMonthProvider extends \atoum { public function testProvideWithCount(): void { - $perioStartAt = new \Datetime('2017-01-01'); + $perioStartAt = new \DateTime('2017-01-01'); - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodStartAt($perioStartAt) - ->setCount(10) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + $perioStartAt, + null, + 10, + ); $provider = new TestedEndOfMonthProvider(); $datetimes = $provider->provide($recurrence); $this->assert ->integer(count($datetimes)) - ->isEqualTo(10); + ->isEqualTo(10) + ; foreach ($datetimes as $datetime) { $this->assert ->object($datetime) - ->isEqualTo($perioStartAt); + ->isEqualTo($perioStartAt) + ; $perioStartAt->modify('last day of next month'); } @@ -39,27 +40,29 @@ public function testProvideWithCount(): void public function testProvideWithEndPeriod(): void { - $perioStartAt = new \Datetime('2017-01-01'); - $periodEndAt = new \Datetime('2017-10-01'); + $perioStartAt = new \DateTime('2017-01-01'); + $periodEndAt = new \DateTime('2017-10-01'); - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodStartAt($perioStartAt) - ->setPeriodEndAt($periodEndAt) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + $perioStartAt, + $periodEndAt, + ); $provider = new TestedEndOfMonthProvider(); $datetimes = $provider->provide($recurrence); $this->assert ->integer(count($datetimes)) - ->isEqualTo(9); + ->isEqualTo(9) + ; foreach ($datetimes as $datetime) { $this->assert ->object($datetime) - ->isEqualTo($perioStartAt); + ->isEqualTo($perioStartAt) + ; $perioStartAt->modify('last day of next month'); } diff --git a/tests/units/Recurrence/Provider/OptimizedProvider.php b/tests/units/Recurrence/Provider/OptimizedProvider.php index d393347..e2e7a08 100644 --- a/tests/units/Recurrence/Provider/OptimizedProvider.php +++ b/tests/units/Recurrence/Provider/OptimizedProvider.php @@ -2,39 +2,39 @@ namespace Recurrence\tests\units\Provider; -use atoum; - use Recurrence\Model\Frequency; use Recurrence\Model\Recurrence; use Recurrence\Provider\OptimizedProvider as TestedOptimizedProvider; -class OptimizedProvider extends atoum +class OptimizedProvider extends \atoum { /** * @dataProvider datetimesWithoutIntervalProvider */ public function testWithoutIntervalProvide(int $position, \DateTime $periodStartAt, int $countOption, \DateTime $expected): void { - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodStartAt($periodStartAt) - ->setCount($countOption) - ; - - $provider = new TestedOptimizedProvider(); + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + $periodStartAt, + null, + $countOption, + ); + + $provider = new TestedOptimizedProvider(); $datetimes = $provider->provide($recurrence); $this->assert ->integer(count($datetimes)) - ->isEqualTo($countOption); + ->isEqualTo($countOption) + ; $this->assert ->object($datetimes[$position]) - ->isEqualTo($expected); + ->isEqualTo($expected) + ; } - /** * @dataProvider datetimesWithoutIntervalProvider */ @@ -43,23 +43,25 @@ public function testWithoutIntervalAndWithoutCountProvide(int $position, \DateTi $periodEndAt = clone $periodStartAt; $periodEndAt->modify(sprintf('+%d months', $countOption)); - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodStartAt($periodStartAt) - ->setPeriodEndAt($periodEndAt) - ; + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 1, + $periodStartAt, + $periodEndAt, + ); - $provider = new TestedOptimizedProvider(); + $provider = new TestedOptimizedProvider(); $datetimes = $provider->provide($recurrence); $this->assert ->integer(count($datetimes)) - ->isEqualTo($countOption); + ->isEqualTo($countOption) + ; $this->assert ->object($datetimes[$position]) - ->isEqualTo($expected); + ->isEqualTo($expected) + ; } public function datetimesWithoutIntervalProvider(): array @@ -67,73 +69,74 @@ public function datetimesWithoutIntervalProvider(): array return [ [ 0, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), ], [ 1, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-02-01'), + new \DateTime('2017-02-01'), ], [ 2, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-03-01'), + new \DateTime('2017-03-01'), ], [ 3, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-04-01'), + new \DateTime('2017-04-01'), ], [ 4, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-05-01'), + new \DateTime('2017-05-01'), ], [ 5, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-06-01'), + new \DateTime('2017-06-01'), ], [ 6, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 10, - new \Datetime('2017-07-01'), + new \DateTime('2017-07-01'), ], ]; } - /** * @dataProvider datetimesWithIntervalProvider */ public function testWithIntervalProvide(int $position, \DateTime $periodStartAt, int $countOption, \DateTime $expected): void { - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodStartAt($periodStartAt) - ->setCount($countOption) - ->setInterval(2) - ; - - $provider = new TestedOptimizedProvider(); + $recurrence = new Recurrence( + new Frequency(Frequency::FREQUENCY_MONTHLY), + 2, + $periodStartAt, + null, + $countOption, + ); + + $provider = new TestedOptimizedProvider(); $datetimes = $provider->provide($recurrence); $this->assert ->integer(count($datetimes)) - ->isEqualTo($countOption); + ->isEqualTo($countOption) + ; $this->assert ->object($datetimes[$position]) - ->isEqualTo($expected); + ->isEqualTo($expected) + ; } public function datetimesWithIntervalProvider(): array @@ -141,27 +144,27 @@ public function datetimesWithIntervalProvider(): array return [ [ 0, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 4, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), ], [ 1, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 4, - new \Datetime('2017-03-01'), + new \DateTime('2017-03-01'), ], [ 2, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 4, - new \Datetime('2017-05-01'), + new \DateTime('2017-05-01'), ], [ 3, - new \Datetime('2017-01-01'), + new \DateTime('2017-01-01'), 4, - new \Datetime('2017-07-01'), + new \DateTime('2017-07-01'), ], ]; } diff --git a/tests/units/Recurrence/Rrule/Extractor/CountExtractor.php b/tests/units/Recurrence/Rrule/Extractor/CountExtractor.php index 0927bc5..794bbed 100644 --- a/tests/units/Recurrence/Rrule/Extractor/CountExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/CountExtractor.php @@ -2,19 +2,18 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Rrule\RecurrenceProvider; -class CountExtractor extends atoum +class CountExtractor extends \atoum { /** - * Failed : Use an invalid COUNT value + * Failed : Use an invalid COUNT value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\CountExtractor())->extract('FREQ=MONTHLY;DTSTART=20170520;COUNT=WRONG'); }) ->isInstanceOf(InvalidRruleException::class) @@ -23,7 +22,7 @@ public function testInvalidValue(): void } /** - * Success : No COUNT option + * Success : No COUNT option. */ public function testNoValue(): void { @@ -36,7 +35,7 @@ public function testNoValue(): void } /** - * Success : Use a valid COUNT value + * Success : Use a valid COUNT value. */ public function testValidValue(): void { @@ -56,13 +55,13 @@ public function testValidValue(): void } /** - * Failed : Missing value for RRULE option + * Failed : Missing value for RRULE option. */ public function tesMissingRruleValue(): void { // Missing COUNT value in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new RecurrenceProvider())->create('FREQ=MONTHLY;BYMONTHDAY=1;COUNT'); }) ->isInstanceOf(InvalidRruleException::class) diff --git a/tests/units/Recurrence/Rrule/Extractor/DtStartExtractor.php b/tests/units/Recurrence/Rrule/Extractor/DtStartExtractor.php index 2c2cbef..21601ca 100644 --- a/tests/units/Recurrence/Rrule/Extractor/DtStartExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/DtStartExtractor.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class DtStartExtractor extends atoum +class DtStartExtractor extends \atoum { /** - * Failed : Use an invalid DTSTART value + * Failed : Use an invalid DTSTART value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\DtStartExtractor())->extract('FREQ=MONTHLY;DTSTART=20ERROR12;COUNT=1'); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,7 +21,7 @@ public function testInvalidValue(): void } /** - * Success : No DTSTART option + * Success : No DTSTART option. */ public function testNoValue(): void { @@ -35,7 +34,7 @@ public function testNoValue(): void } /** - * Success : Use a valid DTSTART value + * Success : Use a valid DTSTART value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php b/tests/units/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php index 45d7cb7..24f1f2b 100644 --- a/tests/units/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/DtStartTimezonedExtractor.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class DtStartTimezonedExtractor extends atoum +class DtStartTimezonedExtractor extends \atoum { /** - * Failed : Use an invalid DTSTART;TZID value + * Failed : Use an invalid DTSTART;TZID value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\DtStartTimezonedExtractor())->extract('FREQ=MONTHLY;DTSTART;TZID=20ERROR12;COUNT=1'); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,7 +21,7 @@ public function testInvalidValue(): void } /** - * Success : No DTSTART;TZID option + * Success : No DTSTART;TZID option. */ public function testNoValue(): void { @@ -35,7 +34,7 @@ public function testNoValue(): void } /** - * Success : Use a valid DTSTART;TZID value + * Success : Use a valid DTSTART;TZID value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Extractor/FreqExtractor.php b/tests/units/Recurrence/Rrule/Extractor/FreqExtractor.php index 40badcd..21c28f9 100644 --- a/tests/units/Recurrence/Rrule/Extractor/FreqExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/FreqExtractor.php @@ -2,19 +2,18 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Rrule\RecurrenceProvider; -class FreqExtractor extends atoum +class FreqExtractor extends \atoum { /** - * Failed : Use an invalid FREQ value + * Failed : Use an invalid FREQ value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\FreqExtractor())->extract('FREQ=1337;DTSTART=20170520;COUNT=1'); }) ->isInstanceOf(InvalidRruleException::class) @@ -23,7 +22,7 @@ public function testInvalidValue(): void } /** - * Success : No FREQ option + * Success : No FREQ option. */ public function testNoValue(): void { @@ -36,7 +35,7 @@ public function testNoValue(): void } /** - * Success : Use a valid FREQ value + * Success : Use a valid FREQ value. */ public function testValidValue(): void { @@ -56,13 +55,13 @@ public function testValidValue(): void } /** - * Failed : Missing value for RRULE option + * Failed : Missing value for RRULE option. */ public function tesMissingRruleValue(): void { // Missing COUNT value in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new RecurrenceProvider())->create('BYMONTHDAY=1;COUNT'); }) ->isInstanceOf(InvalidRruleException::class) diff --git a/tests/units/Recurrence/Rrule/Extractor/IntervalExtractor.php b/tests/units/Recurrence/Rrule/Extractor/IntervalExtractor.php index 58e9cc4..f0cd500 100644 --- a/tests/units/Recurrence/Rrule/Extractor/IntervalExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/IntervalExtractor.php @@ -2,20 +2,19 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Model\Exception\InvalidRruleExpressionException; use Recurrence\Rrule\RecurrenceProvider; -class IntervalExtractor extends atoum +class IntervalExtractor extends \atoum { /** - * Failed : Use an invalid INTERVAL value + * Failed : Use an invalid INTERVAL value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\IntervalExtractor())->extract('FREQ=MONTHLY;DTSTART=20170520;INTERVAL=WRONG'); }) ->isInstanceOf(InvalidRruleException::class) @@ -24,7 +23,7 @@ public function testInvalidValue(): void } /** - * Success : No INTERVAL option + * Success : No INTERVAL option. */ public function testNoValue(): void { @@ -37,7 +36,7 @@ public function testNoValue(): void } /** - * Success : Use a valid INTERVAL value + * Success : Use a valid INTERVAL value. */ public function testValidValue(): void { @@ -57,13 +56,13 @@ public function testValidValue(): void } /** - * Failed : Missing value for RRULE option + * Failed : Missing value for RRULE option. */ public function testMissingRruleValue(): void { // Missing INTERVAL value in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new RecurrenceProvider())->create('FREQ=MONTHLY;BYMONTHDAY=1;INTERVAL'); }) ->isInstanceOf(InvalidRruleExpressionException::class) diff --git a/tests/units/Recurrence/Rrule/Extractor/UntilExtractor.php b/tests/units/Recurrence/Rrule/Extractor/UntilExtractor.php index 95b9a6d..068ef76 100644 --- a/tests/units/Recurrence/Rrule/Extractor/UntilExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/UntilExtractor.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class UntilExtractor extends atoum +class UntilExtractor extends \atoum { /** - * Failed : Use an invalid UNTIL value + * Failed : Use an invalid UNTIL value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\UntilExtractor())->extract('FREQ=MONTHLY;UNTIL=20ERROR12'); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,7 +21,7 @@ public function testInvalidValue(): void } /** - * Success : No UNTIL option + * Success : No UNTIL option. */ public function testNoValue(): void { @@ -35,7 +34,7 @@ public function testNoValue(): void } /** - * Success : Use a valid UNTIL value + * Success : Use a valid UNTIL value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Extractor/UntilTimezonedExtractor.php b/tests/units/Recurrence/Rrule/Extractor/UntilTimezonedExtractor.php index 1e6351d..d24adcd 100644 --- a/tests/units/Recurrence/Rrule/Extractor/UntilTimezonedExtractor.php +++ b/tests/units/Recurrence/Rrule/Extractor/UntilTimezonedExtractor.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Extractor; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class UntilTimezonedExtractor extends atoum +class UntilTimezonedExtractor extends \atoum { /** - * Failed : Use an invalid UNTIL;TZID value + * Failed : Use an invalid UNTIL;TZID value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Extractor\UntilTimezonedExtractor())->extract('FREQ=MONTHLY;UNTIL;TZID=20ERROR12;COUNT=1'); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,7 +21,7 @@ public function testInvalidValue(): void } /** - * Success : No UNTIL;TZID option + * Success : No UNTIL;TZID option. */ public function testNoValue(): void { @@ -35,7 +34,7 @@ public function testNoValue(): void } /** - * Success : Use a valid UNTIL;TZID value + * Success : Use a valid UNTIL;TZID value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/RecurrenceProvider.php b/tests/units/Recurrence/Rrule/RecurrenceProvider.php index 7a6efe5..81f37d4 100644 --- a/tests/units/Recurrence/Rrule/RecurrenceProvider.php +++ b/tests/units/Recurrence/Rrule/RecurrenceProvider.php @@ -2,21 +2,19 @@ namespace Recurrence\tests\units\Rrule; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Model\Exception\InvalidRruleExpressionException; -class RecurrenceProvider extends atoum +class RecurrenceProvider extends \atoum { - /** - * Failed : Empty RRULE + * Failed : Empty RRULE. */ public function testEmptyRrule(): void { // Empty RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\RecurrenceProvider())->create(''); }) ->isInstanceOf(InvalidRruleExpressionException::class) @@ -24,13 +22,13 @@ public function testEmptyRrule(): void } /** - * Failed : Bad RRULE syntax + * Failed : Bad RRULE syntax. */ public function tesBadRruleSyntax(): void { // Wrong option syntax in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ:MONTHLY;UNTIL=20170520;BYMONTHDAY=1;INTERVAL'); }) ->isInstanceOf(InvalidRruleException::class) @@ -38,13 +36,13 @@ public function tesBadRruleSyntax(): void } /** - * Failed : Missing required value for RRULE option + * Failed : Missing required value for RRULE option. */ public function tesMissingRruleValue(): void { // Missing INTERVAL value in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL=20170520;BYMONTHDAY=1;INTERVAL'); }) ->isInstanceOf(InvalidRruleException::class) @@ -52,12 +50,12 @@ public function tesMissingRruleValue(): void } /** - * Check FREQ support + * Check FREQ support. */ public function testRruleFreqSupport(): void { // Success creation of recurrence from RRULE - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL=20170520;BYMONTHDAY=1;INTERVAL=2'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520;UNTIL=20170520;BYMONTHDAY=1;INTERVAL=2'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -66,16 +64,16 @@ public function testRruleFreqSupport(): void // Wrong frequency name in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQUENCY=MONTHLY;UNTIL=20170520;BYMONTHDAY=1;INTERVAL=2'); }) ->isInstanceOf(InvalidRruleExpressionException::class) - ->hasMessage('Frequency is required') + ->hasMessage('Missing [Freq] option.') ; // Wrong frequency option in RRULE $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=BADLY;UNTIL=20170520;BYMONTHDAY=1;INTERVAL=2'); }) ->isInstanceOf(InvalidRruleException::class) @@ -84,12 +82,12 @@ public function testRruleFreqSupport(): void } /** - * Test DTSTART support + * Test DTSTART support. */ public function testRruleDstartSupport(): void { // Success creation of recurrence from RRULE using simple date - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520;UNTIL=20170520'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520;UNTIL=20170520;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -99,7 +97,7 @@ public function testRruleDstartSupport(): void ; // Success creation of recurrence from RRULE using datetime - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520T161322;UNTIL=20170520'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520T161322;UNTIL=20170520;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -109,7 +107,7 @@ public function testRruleDstartSupport(): void ; // Success creation of recurrence from RRULE using timezoned datetime - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520T161322Z;UNTIL=20170520'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520T161322Z;UNTIL=20170520;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -121,7 +119,7 @@ public function testRruleDstartSupport(): void ; // Success creation of recurrence from RRULE using timezoned datetime with TZID option - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART;TZID=Europe/Paris:20170520T161322;UNTIL=20170520'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART;TZID=Europe/Paris:20170520T161322;UNTIL=20170520;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -134,8 +132,8 @@ public function testRruleDstartSupport(): void // Invalid datetime $this->assert - ->exception(function () { - (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART;TZID=Disneyland/Paris:20170520T161322;UNTIL=20170520'); + ->exception(static function () { + (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART;TZID=Disneyland/Paris:20170520T161322;UNTIL=20170520;INTERVAL=1'); }) ->isInstanceOf(InvalidRruleException::class) ->hasMessage('Invalid RRULE [DTSTART;TZID] option : [Disneyland/Paris]') @@ -143,12 +141,12 @@ public function testRruleDstartSupport(): void } /** - * Test UNTIL support + * Test UNTIL support. */ public function testRruleUntilSupport(): void { // Success creation of recurrence from RRULE using simple date - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL=20170520'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170520;UNTIL=20170520;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -158,7 +156,7 @@ public function testRruleUntilSupport(): void ; // Success creation of recurrence from RRULE using datetime - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL=20170520T161322'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;UNTIL=20170520T161322;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -168,7 +166,7 @@ public function testRruleUntilSupport(): void ; // Success creation of recurrence from RRULE using timezoned datetime - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL=20170520T161322Z'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;UNTIL=20170520T161322Z;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -180,7 +178,7 @@ public function testRruleUntilSupport(): void ; // Success creation of recurrence from RRULE using timezoned datetime with TZID option - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL;TZID=Europe/Paris:20170520T161322'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;UNTIL;TZID=Europe/Paris:20170520T161322;INTERVAL=1'); $this->assert ->string((string) $recurrence->getFrequency()) @@ -193,7 +191,7 @@ public function testRruleUntilSupport(): void // Invalid datetime $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL;TZID=Disneyland/Paris:20170520T161322'); }) ->isInstanceOf(InvalidRruleException::class) @@ -202,46 +200,48 @@ public function testRruleUntilSupport(): void } /** - * Check INTERVAL support + * Check INTERVAL support. */ public function testRruleIntervalSupport(): void { // Success creation of recurrence from RRULE - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;UNTIL=20170520;BYMONTHDAY=1;INTERVAL=2'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;UNTIL=20170520;BYMONTHDAY=1;INTERVAL=2'); $this->assert ->integer($recurrence->getInterval()) - ->isEqualTo(2); + ->isEqualTo(2) + ; } /** - * Check COUNT support + * Check COUNT support. */ public function testRruleCountSupport(): void { // Success creation of recurrence from RRULE - $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;BYMONTHDAY=1;COUNT=2'); + $recurrence = (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;BYMONTHDAY=1;COUNT=2;INTERVAL=1'); $this->assert ->integer($recurrence->getCount()) - ->isEqualTo(2); + ->isEqualTo(2) + ; // You can not create Recurrence with both COUNT and UNTIL option $this->assert - ->exception(function () { - (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;UNTIL=20170520;COUNT=2'); + ->exception(static function () { + (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;UNTIL=20170520;COUNT=2;INTERVAL=1'); }) ->isInstanceOf(InvalidRruleExpressionException::class) - ->hasMessage('Recurrence cannot have [COUNT] and [UNTIL] option at the same time') + ->hasMessage('Recurrence cannot have [COUNT] and [UNTIL] option at the same time.') ; // You have to set Recurrence with at least COUNT or UNTIL option $this->assert - ->exception(function () { - (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;'); + ->exception(static function () { + (new \Recurrence\Rrule\RecurrenceProvider())->create('FREQ=MONTHLY;DTSTART=20170120;INTERVAL=1'); }) ->isInstanceOf(InvalidRruleExpressionException::class) - ->hasMessage('Recurrence required [COUNT] or [UNTIL] option') + ->hasMessage('Recurrence required [COUNT] or [UNTIL] option.') ; } -} \ No newline at end of file +} diff --git a/tests/units/Recurrence/Rrule/Transformer/CountTransformer.php b/tests/units/Recurrence/Rrule/Transformer/CountTransformer.php index 46bf297..2d9bb8f 100644 --- a/tests/units/Recurrence/Rrule/Transformer/CountTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/CountTransformer.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class CountTransformer extends atoum +class CountTransformer extends \atoum { /** - * Failed : Use an invalid COUNT value + * Failed : Use an invalid COUNT value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\CountTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,12 +21,12 @@ public function testInvalidValue(): void } /** - * Success : No COUNT option + * Success : No COUNT option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\CountTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -36,7 +35,7 @@ public function testNoValue(): void } /** - * Success : Use a valid COUNT value + * Success : Use a valid COUNT value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php b/tests/units/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php index 3eedab4..b27c807 100644 --- a/tests/units/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/DtStartTimezonedTransformer.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class DtStartTimezonedTransformer extends atoum +class DtStartTimezonedTransformer extends \atoum { /** - * Failed : Use an invalid DTSTART;TZID value + * Failed : Use an invalid DTSTART;TZID value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\DtStartTimezonedTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -21,7 +20,7 @@ public function testInvalidValue(): void ; $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\DtStartTimezonedTransformer())->transform(['Miami\Vice', 'B']); }) ->isInstanceOf(InvalidRruleException::class) @@ -29,7 +28,7 @@ public function testInvalidValue(): void ; $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\DtStartTimezonedTransformer())->transform(['A', 'B']); }) ->isInstanceOf(InvalidRruleException::class) @@ -38,12 +37,12 @@ public function testInvalidValue(): void } /** - * Success : No DTSTART;TZID option + * Success : No DTSTART;TZID option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\DtStartTimezonedTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -52,7 +51,7 @@ public function testNoValue(): void } /** - * Success : Use a valid DTSTART;TZID value + * Success : Use a valid DTSTART;TZID value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Transformer/DtStartTransformer.php b/tests/units/Recurrence/Rrule/Transformer/DtStartTransformer.php index b3a9d5b..c9bb5bc 100644 --- a/tests/units/Recurrence/Rrule/Transformer/DtStartTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/DtStartTransformer.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class DtStartTransformer extends atoum +class DtStartTransformer extends \atoum { /** - * Failed : Use an invalid DTSTART value + * Failed : Use an invalid DTSTART value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\DtStartTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,12 +21,12 @@ public function testInvalidValue(): void } /** - * Success : No DTSTART option + * Success : No DTSTART option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\DtStartTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -36,7 +35,7 @@ public function testNoValue(): void } /** - * Success : Use a valid DTSTART value + * Success : Use a valid DTSTART value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Transformer/FreqTransformer.php b/tests/units/Recurrence/Rrule/Transformer/FreqTransformer.php index 3524c54..cc3295f 100644 --- a/tests/units/Recurrence/Rrule/Transformer/FreqTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/FreqTransformer.php @@ -2,19 +2,18 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; use Recurrence\Model\Frequency; -class FreqTransformer extends atoum +class FreqTransformer extends \atoum { /** - * Failed : Use an invalid FREQ value + * Failed : Use an invalid FREQ value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\FreqTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -23,12 +22,12 @@ public function testInvalidValue(): void } /** - * Success : No FREQ option + * Success : No FREQ option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\FreqTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -37,7 +36,7 @@ public function testNoValue(): void } /** - * Success : Use a valid FREQ value + * Success : Use a valid FREQ value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Transformer/IntervalTransformer.php b/tests/units/Recurrence/Rrule/Transformer/IntervalTransformer.php index 2758684..ac8c6cd 100644 --- a/tests/units/Recurrence/Rrule/Transformer/IntervalTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/IntervalTransformer.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class IntervalTransformer extends atoum +class IntervalTransformer extends \atoum { /** - * Failed : Use an invalid INTERVAL value + * Failed : Use an invalid INTERVAL value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\IntervalTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,12 +21,12 @@ public function testInvalidValue(): void } /** - * Success : No INTERVAL option + * Success : No INTERVAL option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\IntervalTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -36,7 +35,7 @@ public function testNoValue(): void } /** - * Success : Use a valid INTERVAL value + * Success : Use a valid INTERVAL value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php b/tests/units/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php index 465d1f4..8c91167 100644 --- a/tests/units/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/UntilTimezonedTransformer.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class UntilTimezonedTransformer extends atoum +class UntilTimezonedTransformer extends \atoum { /** - * Failed : Use an invalid UNTIL;TZID value + * Failed : Use an invalid UNTIL;TZID value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\UntilTimezonedTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -21,7 +20,7 @@ public function testInvalidValue(): void ; $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\UntilTimezonedTransformer())->transform(['Miami\Vice', 'B']); }) ->isInstanceOf(InvalidRruleException::class) @@ -29,7 +28,7 @@ public function testInvalidValue(): void ; $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\UntilTimezonedTransformer())->transform(['A', 'B']); }) ->isInstanceOf(InvalidRruleException::class) @@ -38,12 +37,12 @@ public function testInvalidValue(): void } /** - * Success : No UNTIL;TZID option + * Success : No UNTIL;TZID option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\UntilTimezonedTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -52,7 +51,7 @@ public function testNoValue(): void } /** - * Success : Use a valid UNTIL;TZID value + * Success : Use a valid UNTIL;TZID value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Rrule/Transformer/UntilTransformer.php b/tests/units/Recurrence/Rrule/Transformer/UntilTransformer.php index 8122685..8188f97 100644 --- a/tests/units/Recurrence/Rrule/Transformer/UntilTransformer.php +++ b/tests/units/Recurrence/Rrule/Transformer/UntilTransformer.php @@ -2,18 +2,17 @@ namespace Recurrence\tests\units\Rrule\Transformer; -use atoum; use Recurrence\Model\Exception\InvalidRruleException; -class UntilTransformer extends atoum +class UntilTransformer extends \atoum { /** - * Failed : Use an invalid UNTIL value + * Failed : Use an invalid UNTIL value. */ public function testInvalidValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\UntilTransformer())->transform(['A']); }) ->isInstanceOf(InvalidRruleException::class) @@ -22,12 +21,12 @@ public function testInvalidValue(): void } /** - * Success : No UNTIL option + * Success : No UNTIL option. */ public function testNoValue(): void { $this->assert - ->exception(function () { + ->exception(static function () { (new \Recurrence\Rrule\Transformer\UntilTransformer())->transform([]); }) ->isInstanceOf(InvalidRruleException::class) @@ -36,7 +35,7 @@ public function testNoValue(): void } /** - * Success : Use a valid UNTIL value + * Success : Use a valid UNTIL value. */ public function testValidValue(): void { diff --git a/tests/units/Recurrence/Validator/RecurrenceValidator.php b/tests/units/Recurrence/Validator/RecurrenceValidator.php deleted file mode 100644 index 41fd8d9..0000000 --- a/tests/units/Recurrence/Validator/RecurrenceValidator.php +++ /dev/null @@ -1,85 +0,0 @@ -setFrequency(new Frequency('MONTHLY')); - $recurrence->setCount(2); - - $this->assert - ->boolean(TestedRecurrenceValidator::validate($recurrence)) - ->isTrue() - ; - } - - public function testInvalidRecurrence(): void - { - // Missing FREQ option - $this->assert - ->exception(function () { - $recurrence = new Recurrence(); - $recurrence->setCount(2); - - TestedRecurrenceValidator::validate($recurrence); - }) - ->isInstanceOf(InvalidRecurrenceException::class) - ->hasMessage('Frequency is required') - ; - - // Conflict between COUNT and UNTIL option - $this->assert - ->exception(function () { - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('MONTHLY')) - ->setPeriodEndAt(new \Datetime()) - ->setCount(2); - - TestedRecurrenceValidator::validate($recurrence); - }) - ->isInstanceOf(InvalidRecurrenceException::class) - ->hasMessage('Recurrence cannot have [COUNT] and [UNTIL] option at the same time') - ; - - // Missing COUNT or UNTIL option - $this->assert - ->exception(function () { - $recurrence = new Recurrence(); - $recurrence->setFrequency(new Frequency('MONTHLY')); - - TestedRecurrenceValidator::validate($recurrence); - }) - ->isInstanceOf(InvalidRecurrenceException::class) - ->hasMessage('Recurrence required [COUNT] or [UNTIL] option') - ; - - // Conflict between constraint and frequency - $this->assert - ->exception(function () { - $recurrence = new Recurrence(); - $recurrence - ->setFrequency(new Frequency('DAILY')) - ->addConstraint(new EndOfMonthConstraint()) - ->setCount(2) - ->setInterval(2) - ; - - TestedRecurrenceValidator::validate($recurrence); - }) - ->isInstanceOf(InvalidRecurrenceException::class) - ->hasMessage('End of month constraint can be applied only with monthly frequency') - ; - } -} \ No newline at end of file