Skip to content

Commit ea49eb4

Browse files
authored
Merge pull request #151 from kylekatarnls/feature/support-year-multiple-condition
Support year condition with multiple clauses joined with "and" operator
2 parents fcf655f + 7596dde commit ea49eb4

15 files changed

+137
-70
lines changed

.github/workflows/tests.yml

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
name: PHP ${{ matrix.php }} - ${{ matrix.setup }}
2020

2121
steps:
22-
- uses: actions/checkout@v4
22+
- uses: actions/checkout@v5
2323

2424
- name: Setup PHP
2525
uses: shivammathur/setup-php@v2
@@ -46,48 +46,45 @@ jobs:
4646
- name: Install dependencies
4747
if: steps.composer-cache.outputs.cache-hit != 'true'
4848
run: |
49-
${{ matrix.php >= 8.1 && 'composer require --no-update phpunit/phpunit:^8.5.14 --no-interaction' || '' }}
50-
composer update --prefer-dist ${{ matrix.setup != 'next' && matrix.setup != 'no-calendar' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress --no-suggest ${{ matrix.php >= 8.1 && '--ignore-platform-req=php' || '' }}
51-
52-
- name: Code Climate Test Reporter Preparation
53-
if: matrix.php == '7.4' && matrix.setup == 'stable'
54-
run: |
55-
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter;
56-
chmod +x ./cc-test-reporter;
57-
./cc-test-reporter before-build;
58-
env:
59-
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
49+
composer update --prefer-dist ${{ matrix.setup != 'next' && matrix.setup != 'no-calendar' && format('--prefer-{0}', matrix.setup) || '' }} --no-progress --no-suggest
6050
6151
- name: Fix PHP compatibility
6252
if: matrix.php >= '8.1'
6353
run: php tests/fix-php-compatibility.php
6454

6555
- name: Run test suite
6656
run: |
67-
if [[ ${MATRIX_CONFIG} == "7.4-stable" ]]; then
57+
if [[ ${MATRIX_CONFIG} == "8.4-stable" ]]; then
6858
vendor/bin/phpunit --coverage-text --coverage-clover=clover.xml;
59+
cp clover.xml coverage.xml
6960
else
7061
vendor/bin/phpunit --no-coverage;
7162
fi;
7263
env:
7364
MATRIX_CONFIG: ${{ matrix.php }}-${{ matrix.setup }}
7465

7566
- name: Code Climate Test Reporter
76-
if: ${{ matrix.php == '7.4' && matrix.setup == 'stable' && env.CC_TEST_REPORTER_ID != '' }}
77-
run: ./cc-test-reporter after-build --exit-code 0
67+
if: matrix.php == '8.4' && matrix.setup == 'stable'
68+
uses: aktions/codeclimate-test-reporter@v1
69+
with:
70+
codeclimate-test-reporter-id: ${{ secrets.CC_TEST_REPORTER_ID }}
71+
command: after-build -t clover
7872
env:
79-
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
73+
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
74+
continue-on-error: true
8075

81-
- name: Coverage
82-
if: matrix.php == '7.4' && matrix.setup == 'stable'
83-
run: bash <(curl -s https://codecov.io/bash)
76+
- name: Upload coverage reports to Codecov
77+
if: matrix.php == '8.4' && matrix.setup == 'stable'
78+
uses: codecov/codecov-action@v5.5.1
79+
with:
80+
token: ${{ secrets.CODECOV_TOKEN }}
8481

8582
multitest:
8683
runs-on: ubuntu-latest
8784

8885
strategy:
8986
matrix:
90-
php: ['7.4']
87+
php: ['8.4']
9188
setup: ['stable']
9289

9390
name: Multitest
@@ -114,7 +111,7 @@ jobs:
114111
- name: Install dependencies
115112
if: steps.composer-cache.outputs.cache-hit != 'true'
116113
run: |
117-
composer require kylekatarnls/multi-tester:^1.1 --no-update;
114+
composer require kylekatarnls/multi-tester:^2.5.3 --no-update;
118115
composer update --prefer-dist --prefer-${{ matrix.setup }} --no-progress --no-suggest ${{ matrix.composerOptions }};
119116
120117
- name: Run test suites

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"nesbot/carbon": "^2.29 || ^3.0.1"
88
},
99
"require-dev": {
10-
"phpunit/phpunit": "^7.5.20 || ^8.5.31",
10+
"phpunit/phpunit": "^7.5.20 || ^8.5.31 || ^9.6.27 || ^10.5.55",
1111
"phpstan/phpstan": "1.* || 2.*",
1212
"phpstan/extension-installer": "*"
1313
},

phpunit.xml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
4+
bootstrap="tests/bootstrap.php"
5+
cacheDirectory=".phpunit.cache"
6+
executionOrder="depends,defects"
7+
beStrictAboutOutputDuringTests="true"
8+
displayDetailsOnPhpunitDeprecations="true"
9+
failOnPhpunitDeprecation="true"
10+
failOnRisky="true"
11+
failOnWarning="true">
12+
<testsuites>
13+
<testsuite name="default">
14+
<directory>tests</directory>
15+
</testsuite>
16+
</testsuites>
17+
18+
<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
19+
<include>
20+
<directory>src/Cmixin</directory>
21+
</include>
22+
</source>
23+
</phpunit>

phpunit.xml.dist

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/Cmixin/BusinessDay/PHPStan/BusinessDayMethodReflection.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
/**
2828
* PHPStan method reflection for cmixin/business-day methods.
29+
*
30+
* @codeCoverageIgnore
2931
*/
3032
final class BusinessDayMethodReflection implements MethodReflection
3133
{

src/Cmixin/BusinessDay/PHPStan/BusinessDayMethodsClassReflectionExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
/**
2323
* PHPStan extension for cmixin/business-day methods.
24+
*
25+
* @codeCoverageIgnore
2426
*/
2527
final class BusinessDayMethodsClassReflectionExtension implements MethodsClassReflectionExtension
2628
{

src/Cmixin/BusinessDay/Util/YearCondition.php

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Cmixin\BusinessDay\Util;
66

77
use DateTime;
8+
use InvalidArgumentException;
89

910
trait YearCondition
1011
{
@@ -17,16 +18,25 @@ trait YearCondition
1718
protected function matchYearCondition($dateTime, ?string &$condition): bool
1819
{
1920
$value = (int) $dateTime->format('Y');
21+
$subConditions = $this->getYearConditions($condition);
2022

21-
if (!$condition || !preg_match(
22-
'/^\s*year(?:\s*%\s*(?<modulo>\d+))?\s*(?<operator>>=?|<=?|={1,3}|!={1,2}|<>)\s*(?<expected>\d+)/',
23-
$condition,
24-
$match
25-
)) {
23+
if ($subConditions === []) {
2624
return $this->year === $value;
2725
}
2826

2927
$condition = null;
28+
29+
foreach ($subConditions as $subCondition) {
30+
if (!$this->matchYearSubCondition($value, $subCondition)) {
31+
return false;
32+
}
33+
}
34+
35+
return true;
36+
}
37+
38+
private function matchYearSubCondition(int $value, array $match): bool
39+
{
3040
$expected = (int) $match['expected'];
3141

3242
if (!empty($match['modulo'])) {
@@ -55,4 +65,34 @@ protected function matchYearCondition($dateTime, ?string &$condition): bool
5565
return $value === $expected;
5666
}
5767
}
68+
69+
private function getYearConditions(?string $condition): array
70+
{
71+
if ($condition === null) {
72+
return [];
73+
}
74+
75+
$subConditions = explode(' and ', $condition);
76+
$conditionMatches = [];
77+
78+
foreach ($subConditions as $subCondition) {
79+
if (preg_match(
80+
'/^\s*year(?:\s*%\s*(?<modulo>\d+))?\s*(?<operator>>=?|<=?|={1,3}|!={1,2}|<>)\s*(?<expected>\d+)/',
81+
$subCondition,
82+
$match
83+
)) {
84+
$conditionMatches[] = $match;
85+
}
86+
}
87+
88+
$finalCount = \count($conditionMatches);
89+
90+
if ($finalCount === 0 || $finalCount === \count($subConditions)) {
91+
return $conditionMatches;
92+
}
93+
94+
throw new InvalidArgumentException(
95+
'Mixed conditions are not supported for now, they must all target the same unit (for example: year)'
96+
);
97+
}
5898
}

src/Cmixin/Holidays/sk-national.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
'2nd-sunday-of-may' => '= second Sunday of May',
1212
'07-05' => '07-05',
1313
'08-29' => '08-29',
14-
'09-01' => '09-01',
14+
'09-01' => '= 09-01 if year >= 1992 and year < 2024',
1515
'09-15' => '09-15',
1616
'11-01' => '11-01',
1717
'11-17' => '11-17',

tests/Cmixin/BusinessDayTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,21 @@ public function testExtraWorkDays()
753753
self::assertFalse($carbon::parse('2021-07-14')->isBusinessDay());
754754
}
755755

756+
public function testMixedConditionsNotYetSupported()
757+
{
758+
self::expectExceptionObject(
759+
new InvalidArgumentException(
760+
'Mixed conditions are not supported for now, they must all target the same unit (for example: year)'
761+
)
762+
);
763+
$carbon = static::CARBON_CLASS;
764+
BusinessDay::enable($carbon, 'fr-national', null, [
765+
'mixed' => '= 09-01 if year > 1991 and day = Monday',
766+
]);
767+
768+
$carbon::parse('2024-09-01')->isBusinessDay();
769+
}
770+
756771
public function testSetExtraWorkdayGetter()
757772
{
758773
$carbon = static::CARBON_CLASS;

tests/Cmixin/Holidays/SkTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Tests\Cmixin\Holidays;
4+
5+
use Cmixin\BusinessDay;
6+
use PHPUnit\Framework\TestCase;
7+
8+
class SkTest extends TestCase
9+
{
10+
const CARBON_CLASS = 'Carbon\Carbon';
11+
12+
public function testHolidays(): void
13+
{
14+
BusinessDay::enable(static::CARBON_CLASS);
15+
$carbon = static::CARBON_CLASS;
16+
$carbon::resetHolidays();
17+
$carbon::setHolidaysRegion('sk-national');
18+
19+
self::assertFalse($carbon::parse('1991-09-01')->isHoliday());
20+
self::assertTrue($carbon::parse('1992-09-01')->isHoliday());
21+
self::assertTrue($carbon::parse('2023-09-01')->isHoliday());
22+
self::assertFalse($carbon::parse('2024-09-01')->isHoliday());
23+
self::assertFalse($carbon::parse('2025-09-01')->isHoliday());
24+
}
25+
}

0 commit comments

Comments
 (0)