Skip to content

Commit

Permalink
PHP 8.1 compatibility (#72)
Browse files Browse the repository at this point in the history
* PHP 8.1 compatibility

* update github action to run tests for php 8.1

* Force the version of CS Fixer

* Update PHPUnit before running tests
  • Loading branch information
courtney-miles authored Oct 29, 2023
1 parent a2e8df0 commit 64d4bd8
Show file tree
Hide file tree
Showing 17 changed files with 408 additions and 50 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.1', '7.2', '7.3', '7.4', '8.0']
php-version: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
composer-prefer:
- '--prefer-dist'
- '--prefer-stable --prefer-lowest'
Expand Down Expand Up @@ -39,7 +39,9 @@ jobs:
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
run: composer update ${{ matrix.composer-prefer }} --no-progress
run: |
composer update ${{ matrix.composer-prefer }} --no-progress
composer update phpunit/phpunit --no-progress
- name: Run Code Style Check for PHP ${{ matrix.php-version }}
run: composer run-script style-check
Expand Down
2 changes: 1 addition & 1 deletion .install-cs-fixer.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash

if [ ! -f ./php-cs-fixer ]; then
wget https://cs.symfony.com/download/php-cs-fixer-v3.phar -O php-cs-fixer
wget https://cs.symfony.com/download/v3.4.0/php-cs-fixer.phar -O php-cs-fixer
chmod +x php-cs-fixer
fi
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM php:8.0-cli
FROM php:8.1-cli

RUN apt-get update
RUN apt-get update -y

## PHP dependencies
RUN pecl install xdebug \
Expand All @@ -11,4 +11,4 @@ RUN curl -sS https://getcomposer.org/installer | php \
&& apt-get install git unzip -y
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV XDEBUG_MODE=coverage
WORKDIR /src
WORKDIR /src
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"jmikola/geojson": "^1.0"
},
"require-dev": {
"phpunit/phpunit": ">=7.5",
"phpunit/phpunit": ">=7.5 <10.0",
"php-coveralls/php-coveralls": "^2.4",
"psy/psysh": "@stable",
"roave/security-advisories": "dev-latest"
Expand Down
3 changes: 3 additions & 0 deletions src/Fields/BaseField.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

abstract class BaseField
{
/**
* @param object $descriptor
*/
public function __construct($descriptor = null)
{
$this->descriptor = empty($descriptor) ? (object) [] : $descriptor;
Expand Down
7 changes: 4 additions & 3 deletions src/Fields/DateField.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace frictionlessdata\tableschema\Fields;

use Carbon\Carbon;
use frictionlessdata\tableschema\Utility\StrptimeFormatTransformer;

class DateField extends BaseField
{
Expand All @@ -21,13 +22,13 @@ protected function validateCastValue($val)
}
} else {
$format = 'default' === $this->format() ? self::DEFAULT_FORMAT : $this->format();
$date = strptime($val, $format);
$date = date_parse_from_format(StrptimeFormatTransformer::transform($format), $val);

if (false === $date || '' != $date['unparsed']) {
if ($date['error_count'] > 0) {
throw $this->getValidationException("couldn't parse date/time according to given strptime format '{$format}''", $val);
} else {
return Carbon::create(
(int) $date['tm_year'] + 1900, (int) $date['tm_mon'] + 1, (int) $date['tm_mday'],
(int) $date['year'], (int) $date['month'], (int) $date['day'],
0, 0, 0
);
}
Expand Down
9 changes: 5 additions & 4 deletions src/Fields/DatetimeField.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace frictionlessdata\tableschema\Fields;

use Carbon\Carbon;
use frictionlessdata\tableschema\Utility\StrptimeFormatTransformer;

class DatetimeField extends BaseField
{
Expand Down Expand Up @@ -33,13 +34,13 @@ protected function validateCastValue($val)
throw $this->getValidationException($e->getMessage(), $val);
}
default:
$date = strptime($val, $this->format());
if (false === $date || '' != $date['unparsed']) {
$date = date_parse_from_format(StrptimeFormatTransformer::transform($this->format()), $val);
if ($date['error_count'] > 0) {
throw $this->getValidationException("couldn't parse date/time according to given strptime format '{$this->format()}''", $val);
} else {
return Carbon::create(
(int) $date['tm_year'] + 1900, (int) $date['tm_mon'] + 1, (int) $date['tm_mday'],
(int) $date['tm_hour'], (int) $date['tm_min'], (int) $date['tm_sec']
(int) $date['year'], (int) $date['month'], (int) $date['day'],
(int) $date['hour'], (int) $date['minute'], (int) $date['second']
);
}
}
Expand Down
11 changes: 8 additions & 3 deletions src/Fields/TimeField.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace frictionlessdata\tableschema\Fields;

use Carbon\Carbon;
use frictionlessdata\tableschema\Utility\StrptimeFormatTransformer;

/**
* Class TimeField
Expand Down Expand Up @@ -32,11 +33,15 @@ protected function validateCastValue($val)

return $this->getNativeTime($dt->hour, $dt->minute, $dt->second);
default:
$date = strptime($val, $this->format());
if (false === $date || '' != $date['unparsed']) {
$date = date_parse_from_format(
StrptimeFormatTransformer::transform($this->format()),
$val
);

if ($date['error_count'] > 0) {
throw $this->getValidationException(null, $val);
} else {
return $this->getNativeTime($date['tm_hour'], $date['tm_min'], $date['tm_sec']);
return $this->getNativeTime($date['hour'], $date['minute'], $date['second']);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ public function save($outputDataSource)
* @throws Exceptions\FieldValidationException
* @throws Exceptions\DataSourceException
*/
#[\ReturnTypeWillChange]
public function current()
{
if (count($this->castRows) > 0) {
Expand Down Expand Up @@ -213,6 +214,7 @@ public function __destruct()
$this->dataSource->close();
}

#[\ReturnTypeWillChange]
public function rewind()
{
if (0 == $this->currentLine) {
Expand All @@ -223,18 +225,21 @@ public function rewind()
}
}

#[\ReturnTypeWillChange]
public function key()
{
return $this->currentLine - count($this->castRows);
}

#[\ReturnTypeWillChange]
public function next()
{
if (0 == count($this->castRows)) {
++$this->currentLine;
}
}

#[\ReturnTypeWillChange]
public function valid()
{
return count($this->castRows) > 0 || !$this->dataSource->isEof();
Expand Down
53 changes: 53 additions & 0 deletions src/Utility/StrptimeFormatTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace frictionlessdata\tableschema\Utility;

final class StrptimeFormatTransformer
{
public static function transform(string $strptimeFormat): string
{
return strtr(
$strptimeFormat,
[
// Day
'%d' => 'd', // 09
'%e' => 'j', // 9

// Month
'%m' => 'm', // 02
'%b' => 'M', // Feb
'%B' => 'F', // February

// Year
'%Y' => 'Y', // 2023
'%y' => 'y', // 23

// Hour
'%H' => 'H', // 00 to 23
'%k' => 'G', // 0 to 23
'%I' => 'h', // 00 to 12
'%l' => 'h', // 0 to 12
'%p' => 'A', // AM / PM
'%P' => 'a', // am / pm

// Minute
'%M' => 'i',

// Second
'%S' => 's',

// Date
'%D' => 'm/d/y',
'%F' => 'Y-m-d',

// Time
'%r' => 'h:i:s A',
'%R' => 'H:i',
'%T' => 'H:i:s',
'%s' => 'U',
]
);
}
}
20 changes: 10 additions & 10 deletions tests/FieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function testType(string $expectedType, array $fieldDescriptor): void
);
}

public function provideFieldWithType(): array
public static function provideFieldWithType(): array
{
return [
[
Expand All @@ -104,7 +104,7 @@ public function testFormat(string $expectedFormat, array $fieldDescriptor): void
);
}

public function provideFieldDescriptorFormat(): array
public static function provideFieldDescriptorFormat(): array
{
return [
[
Expand All @@ -129,7 +129,7 @@ public function testConstraints(\stdClass $expectedConstraint, array $fieldDescr
);
}

public function provideFieldConstraintsTestData(): array
public static function provideFieldConstraintsTestData(): array
{
return [
[
Expand Down Expand Up @@ -158,7 +158,7 @@ public function testRequired(bool $expectedRequired, array $fieldDescriptor): vo
);
}

public function provideFieldRequiredTestData(): array
public static function provideFieldRequiredTestData(): array
{
return [
[
Expand Down Expand Up @@ -231,7 +231,7 @@ public function testDisableConstraints($expectedCastValue, $valueToCast, array $
);
}

public function provideDisableConstraintTestData(): array
public static function provideDisableConstraintTestData(): array
{
return [
[
Expand Down Expand Up @@ -285,7 +285,7 @@ public function testValidateValue(string $expectedError, array $fieldDescriptor,
$this->assertFieldValidateValue($expectedError, $fieldDescriptor, $value);
}

public function provideValidateValueTestData(): array
public static function provideValidateValueTestData(): array
{
return [
[
Expand Down Expand Up @@ -321,7 +321,7 @@ public function testValidateValueDisableConstraints(array $fieldDescriptor, $val
);
}

public function provideValidateValueDisableConstraintsTestData(): array
public static function provideValidateValueDisableConstraintsTestData(): array
{
return [
[
Expand All @@ -347,7 +347,7 @@ public function testMissingValues(string $fieldType): void
$this->assertMissingValues(['type' => $fieldType], ['', 'NA', 'N/A']);
}

public function provideMissingDataFieldType(): array
public static function provideMissingDataFieldType(): array
{
return [
['string'],
Expand Down Expand Up @@ -427,7 +427,7 @@ public function testValidValueForConstraint(string $type, array $constraintDefin
$this->assertFieldValidateValue('', $descriptor, $validValue);
}

public function provideValidDataForConstraint(): array
public static function provideValidDataForConstraint(): array
{
return [
['string', ['pattern' => '3.*'], '3'],
Expand Down Expand Up @@ -471,7 +471,7 @@ public function testInvalidValueForConstraint(
$this->assertFieldValidateValue($expectedError, $descriptor, $invalidValue);
}

public function provideInvalidDataForConstraint(): array
public static function provideInvalidDataForConstraint(): array
{
return [
['name: value does not match pattern ("123")', 'string', ['pattern' => '3.*'], '123'],
Expand Down
38 changes: 38 additions & 0 deletions tests/Fields/DateFieldTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace frictionlessdata\tableschema\tests\Fields;

use Carbon\Carbon;
use DateTime;
use DateTimeInterface;
use frictionlessdata\tableschema\Fields\DateField;
use PHPUnit\Framework\TestCase;

/**
* @covers \frictionlessdata\tableschema\Fields\DateField
*/
class DateFieldTest extends TestCase
{
/**
* @dataProvider provideDateFormatTestData
*/
public function testParseDateFormat(DateTimeInterface $expectedDateTime, string $format, $dateValue): void
{
$descriptor = (object) ['format' => $format];
$sut = new DateField($descriptor);

$castValue = $sut->castValue($dateValue);
self::assertInstanceOf(Carbon::class, $castValue);

self::assertTrue(
$castValue->eq($expectedDateTime)
);
}

public static function provideDateFormatTestData(): iterable
{
yield [new DateTime('2023-02-28'), '%Y-%m-%d', '2023-02-28'];
}
}
Loading

0 comments on commit 64d4bd8

Please sign in to comment.