diff --git a/.cz.yaml b/.cz.yaml
index 8a44208..245146b 100644
--- a/.cz.yaml
+++ b/.cz.yaml
@@ -2,4 +2,4 @@
commitizen:
name: cz_conventional_commits
tag_format: $version
- version: 0.6.2
+ version: 1.0.0
diff --git a/.github/workflows/php-latest.yml b/.github/workflows/php-latest.yml
index 19744fb..6fa64bb 100644
--- a/.github/workflows/php-latest.yml
+++ b/.github/workflows/php-latest.yml
@@ -33,7 +33,7 @@ jobs:
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
- run: composer update --no-ansi --no-interaction --prefer-dist --no-progress --ignore-platform-req=ext-ast
+ run: composer install --no-ansi --no-interaction --prefer-dist --no-progress --ignore-platform-req=ext-ast
- name: Run test suite
run: composer ci:test-build
diff --git a/.github/workflows/pr-quality.yml b/.github/workflows/pr-quality.yml
index 8372eb2..26d468f 100644
--- a/.github/workflows/pr-quality.yml
+++ b/.github/workflows/pr-quality.yml
@@ -17,7 +17,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
- php-version: 8.1
+ php-version: 8.2
- name: Validate composer.json and composer.lock
run: composer validate --strict
@@ -31,7 +31,7 @@ jobs:
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
- run: composer update --no-ansi --no-interaction --prefer-dist --no-progress --ignore-platform-req=ext-ast && composer dumpautoload
+ run: composer install --no-ansi --no-interaction --prefer-dist --no-progress --ignore-platform-req=ext-ast && composer dumpautoload
- name: Scanning for lint errors
run: composer ci:lint
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f71054..c75261a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 1.0.0 (2025-01-19)
+
+### BREAKING CHANGE
+
+- CsvFileStorage::getByKey now returns ItemFound instead of Item.
+
+### Feat
+
+- use phpolar/storage 3.0
+
## 0.6.2 (2025-01-01)
## 0.6.1 (2023-07-03)
diff --git a/README.md b/README.md
index 3bd313c..648d764 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,9 @@
-
+
# PHPolar CSV File Storage
-
-[](https://packagist.org/packages/phpolar/csv-file-storage) [](https://packagist.org/packages/phpolar/csv-file-storage) [](https://packagist.org/packages/phpolar/csv-file-storage) [](https://github.com/phpolar/csv-file-storage/actions/workflows/phpmd.yml) [](https://github.com/phpolar/csv-file-storage/actions/workflows/php-latest.yml)
+[](https://coveralls.io/github/phpolar/csv-file-storage?branch=main) [](https://packagist.org/packages/phpolar/csv-file-storage) [](https://packagist.org/packages/phpolar/csv-file-storage) [](https://packagist.org/packages/phpolar/csv-file-storage) [](https://github.com/phpolar/csv-file-storage/actions/workflows/phpmd.yml) [](https://github.com/phpolar/csv-file-storage/actions/workflows/php-latest.yml)
## Adds support for storing data on disk in CSV format
diff --git a/composer.json b/composer.json
index ca66c1f..5d82bb0 100644
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,4 @@
{
- "$schema": "https://getcomposer.org/schema.json",
"name": "phpolar/csv-file-storage",
"description": "Adds support for storing data on disk in CSV format.",
"type": "library",
@@ -30,8 +29,8 @@
}
},
"require": {
- "php": ">=8.1",
- "phpolar/storage": "^2.0"
+ "php": ">= 8.2",
+ "phpolar/storage": "^3.0"
},
"license": "MIT",
"scripts": {
diff --git a/composer.lock b/composer.lock
index 56fb6dd..8ee2725 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "fda532158d89dc655e12e8bf1f5a7a75",
+ "content-hash": "ade786ee9a5b80457ab0a8c897eb6fbc",
"packages": [
{
"name": "phpolar/storage",
- "version": "2.0.0",
+ "version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/phpolar/storage.git",
- "reference": "0c72e6ec91d7be7fd3f60adc1064949c54567c4c"
+ "reference": "eb2716c49a938b952d2787ca397dd643962491bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpolar/storage/zipball/0c72e6ec91d7be7fd3f60adc1064949c54567c4c",
- "reference": "0c72e6ec91d7be7fd3f60adc1064949c54567c4c",
+ "url": "https://api.github.com/repos/phpolar/storage/zipball/eb2716c49a938b952d2787ca397dd643962491bd",
+ "reference": "eb2716c49a938b952d2787ca397dd643962491bd",
"shasum": ""
},
"require": {
@@ -27,11 +27,11 @@
"ext-ast": "*",
"ext-openssl": "*",
"phan/phan": "^5.4",
- "php-coveralls/php-coveralls": "^2.5",
- "phpmd/phpmd": "^2.13",
+ "php-coveralls/php-coveralls": "^2.7.0",
+ "phpmd/phpmd": "^2.15.0",
"phpstan/phpstan": "^1.9",
- "phpunit/phpunit": "^10.0",
- "squizlabs/php_codesniffer": "^3.7"
+ "phpunit/phpunit": "^11.4.4",
+ "squizlabs/php_codesniffer": "^3.11.1"
},
"type": "library",
"autoload": {
@@ -46,9 +46,9 @@
"description": "A convenient tool to speed up the creation of data storage for application development.",
"support": {
"issues": "https://github.com/phpolar/storage/issues",
- "source": "https://github.com/phpolar/storage/tree/2.0.0"
+ "source": "https://github.com/phpolar/storage/tree/3.0.0"
},
- "time": "2023-09-02T23:34:51+00:00"
+ "time": "2025-01-19T01:50:21+00:00"
}
],
"packages-dev": [
@@ -4805,7 +4805,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=8.1"
+ "php": ">= 8.2"
},
"platform-dev": {
"ext-ast": "*",
diff --git a/phpunit.ci.xml b/phpunit.ci.xml
index 9b09c6f..73f4adb 100644
--- a/phpunit.ci.xml
+++ b/phpunit.ci.xml
@@ -1,26 +1,18 @@
+ cacheDirectory=".phpunit.cache">
-
- tests/unit
-
tests/unit
-
+
- src
+ src
-
+
+
diff --git a/phpunit.dev.xml b/phpunit.dev.xml
index 6a5711a..da40d44 100644
--- a/phpunit.dev.xml
+++ b/phpunit.dev.xml
@@ -1,19 +1,15 @@
-
- tests/unit
-
tests/acceptance
@@ -24,7 +20,7 @@
-
+
diff --git a/src/CsvFileStorage.php b/src/CsvFileStorage.php
index 92f4afd..d95085b 100644
--- a/src/CsvFileStorage.php
+++ b/src/CsvFileStorage.php
@@ -34,7 +34,7 @@ final class CsvFileStorage extends AbstractStorage implements Countable
*/
private $writeStream;
- private int|false $fileSize = 0;
+ private int $fileSize = 0;
/**
* The first line of the CSV file.
@@ -107,7 +107,14 @@ public function commit(): void
fputcsv($this->writeStream, [$record]);
break;
case is_array($record):
- fputcsv($this->writeStream, $record);
+ /**
+ * @var array
+ */
+ $arr = $record;
+ fputcsv(
+ $this->writeStream,
+ $arr,
+ );
break;
default:
throw new DomainException(self::INVALID_VALUE_MSG);
@@ -137,7 +144,8 @@ private function convertObjVars(array $objVars): array
*/
public function count(): int
{
- return $this->getCount();
+ $result = $this->getCount();
+ return max($result, 0);
}
protected function load(): void
@@ -162,11 +170,12 @@ protected function load(): void
/**
* @param string $needle
- * @param ReflectionNamedType[] $namedTypes
+ * @param ReflectionNamedType[]|\ReflectionIntersectionType[] $types
*/
- private function containsType(string $needle, array $namedTypes): bool
+ private function containsType(string $needle, array $types): bool
{
- $haystack = array_map(static fn (ReflectionNamedType $type) => $type->getName(), $namedTypes);
+ /** @phan-suppress-next-line PhanPartialTypeMismatchArgument */
+ $haystack = array_map(static fn (ReflectionNamedType $type) => $type->getName(), array_filter($types, static fn ($type) => $type instanceof ReflectionNamedType));
return in_array($needle, $haystack);
}
diff --git a/tests/unit/CsvFileStorageTest.php b/tests/unit/CsvFileStorageTest.php
index 2835c28..59ae5f7 100644
--- a/tests/unit/CsvFileStorageTest.php
+++ b/tests/unit/CsvFileStorageTest.php
@@ -13,8 +13,8 @@
use Phpolar\Phpolar\Storage\ItemKey;
use Phpolar\Phpolar\Storage\ItemNotFound;
use PHPUnit\Framework\Attributes\CoversClass;
-use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\TestDox;
+use PHPUnit\Framework\Attributes\WithoutErrorHandler;
use PHPUnit\Framework\TestCase;
#[CoversClass(CsvFileStorage::class)]
@@ -44,7 +44,7 @@ static function (string $filename): void {
file_exists($filename) && unlink($filename);
},
);
- unset(self::$filenames);
+ self::$filenames = [];
}
#[TestDox("Shall save objects to file")]
@@ -62,7 +62,6 @@ public function test1a()
}
#[TestDox("Shall save objects with primary key to file")]
- #[Group("me")]
public function test1b()
{
$givenPrimaryKey = uniqid();
@@ -124,7 +123,7 @@ public function test4()
#[TestDox("Shall not clear the internal data if data is on file, no headers exist, and load is called")]
public function test5()
{
- $sut = new CsvFileStorage("tests/__fakes__/without-headers.csv");
+ $sut = new CsvFileStorage(__DIR__ . "/../__fakes__/without-headers.csv");
$fromFile = $sut->getAll();
$this->assertNotEmpty($fromFile);
}
@@ -133,40 +132,37 @@ public function test5()
public function test6()
{
$this->expectException(DomainException::class);
- new CsvFileStorage("tests/__fakes__/empty-headers.csv");
+ new CsvFileStorage(__DIR__ . "/../__fakes__/empty-headers.csv");
}
#[TestDox("Shall throw an exception if storage contains object types but file has no headers")]
public function test7()
{
$this->expectException(DomainException::class);
- new CsvFileStorage("tests/__fakes__/empty-headers.csv", FakeValueObject::class);
+ new CsvFileStorage(__DIR__ . "/../__fakes__/empty-headers.csv", FakeValueObject::class);
}
#[TestDox("Shall throw an exception if stream does not exist")]
+ #[WithoutErrorHandler]
public function test8()
{
- $warningHandler = static fn () => true;
- set_error_handler($warningHandler, E_WARNING);
$this->expectException(FileNotExistsException::class);
- new CsvFileStorage("php://non-existing-stream-handle");
- restore_error_handler();
+ @new CsvFileStorage("php://non-existing-stream-handle");
}
#[TestDox("Shall load objects from file")]
public function testaa()
{
- $sut = new CsvFileStorage("tests/__fakes__/object.csv", FakeValueObject::class);
+ $sut = new CsvFileStorage(__DIR__ . "/../__fakes__/object.csv", FakeValueObject::class);
$itemKey = new ItemKey(0);
$item = $sut->getByKey($itemKey);
$this->assertNotInstanceOf(ItemNotFound::class, $item);
}
#[TestDox("Shall load objects with primary key from file")]
- #[Group("me")]
public function testab()
{
- $sut = new CsvFileStorage("tests/__fakes__/object-with-pkey.csv", FakeValueObjectWithPrimaryKey::class);
+ $sut = new CsvFileStorage(__DIR__ . "/../__fakes__/object-with-pkey.csv", FakeValueObjectWithPrimaryKey::class);
$primaryKey = "123";
$itemKey = new ItemKey($primaryKey);
$item = $sut->getByKey($itemKey);
@@ -176,7 +172,7 @@ public function testab()
#[TestDox("Shall load more than one object from file")]
public function testb()
{
- $sut = new CsvFileStorage("tests/__fakes__/object-2.csv", FakeValueObject::class);
+ $sut = new CsvFileStorage(__DIR__ . "/../__fakes__/object-2.csv", FakeValueObject::class);
$this->assertCount(2, $sut);
}
@@ -184,7 +180,7 @@ public function testb()
public function testc()
{
$this->expectException(DomainException::class);
- new CsvFileStorage("tests/__fakes__/object-malformed.csv", FakeValueObject::class);
+ new CsvFileStorage(__DIR__ . "/../__fakes__/object-malformed.csv", FakeValueObject::class);
}
#[TestDox("Shall not set first line when file is empty")]
@@ -197,7 +193,7 @@ public function testd()
#[TestDox("Shall parse into target object having union types")]
public function teste()
{
- $sut = new CsvFileStorage("tests/__fakes__/object-unions.csv", FakeValueObjectWithUnions::class);
+ $sut = new CsvFileStorage(__DIR__ . "/../__fakes__/object-unions.csv", FakeValueObjectWithUnions::class);
$this->assertContainsOnlyInstancesOf(FakeValueObjectWithUnions::class, $sut->getAll());
}
@@ -205,7 +201,7 @@ public function teste()
public function testf()
{
$this->expectException(AmbiguousUnionTypeException::class);
- new CsvFileStorage("tests/__fakes__/object-unions-malformed.csv", FakeValueObjectWithUnionsError::class);
+ new CsvFileStorage(__DIR__ . "/../__fakes__/object-unions-malformed.csv", FakeValueObjectWithUnionsError::class);
}
#[TestDox("Shall throw an exception when an invalid value is commited")]