diff --git a/.editorconfig b/.editorconfig
index 3faf149..5e5b915 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,6 +11,6 @@ indent_style = tab
indent_size = tab
tab_width = 4
-[{*.json, *.yaml, *.yml, *.md}]
+[*.{json,yaml,yml,md}]
indent_style = space
indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index c52e7b9..aad8529 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,10 +1,10 @@
-# Not archived
.docs export-ignore
-tests export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
-phpstan.neon export-ignore
+Makefile export-ignore
README.md export-ignore
+phpstan.neon export-ignore
ruleset.xml export-ignore
+tests export-ignore
diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml
deleted file mode 100644
index 60c34b6..0000000
--- a/.github/.kodiak.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-version = 1
-
-[merge]
-automerge_label = "automerge"
-blacklist_title_regex = "^WIP.*"
-blacklist_labels = ["WIP"]
-method = "rebase"
-delete_branch_on_merge = true
-notify_on_conflict = true
-optimistic_updates = false
diff --git a/.github/workflows/codesniffer.yml b/.github/workflows/codesniffer.yml
index 69d3d77..a58ac4f 100644
--- a/.github/workflows/codesniffer.yml
+++ b/.github/workflows/codesniffer.yml
@@ -2,6 +2,7 @@ name: "Codesniffer"
on:
pull_request:
+ workflow_dispatch:
push:
branches: ["*"]
@@ -10,8 +11,8 @@ on:
- cron: "0 8 * * 1"
jobs:
- build:
+ codesniffer:
name: "Codesniffer"
- uses: contributte/.github/.github/workflows/codesniffer.yml@v1
+ uses: contributte/.github/.github/workflows/codesniffer.yml@master
with:
php: "8.2"
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 0000000..fac01f8
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,18 @@
+name: "Coverage"
+
+on:
+ pull_request:
+ workflow_dispatch:
+
+ push:
+ branches: ["*"]
+
+ schedule:
+ - cron: "0 9 * * 1"
+
+jobs:
+ coverage:
+ name: "Nette Tester"
+ uses: contributte/.github/.github/workflows/nette-tester-coverage-v2.yml@master
+ with:
+ php: "8.2"
diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
index 7cd7dc2..13ceb07 100644
--- a/.github/workflows/phpstan.yml
+++ b/.github/workflows/phpstan.yml
@@ -2,16 +2,17 @@ name: "Phpstan"
on:
pull_request:
+ workflow_dispatch:
push:
branches: ["*"]
schedule:
- - cron: "0 8 * * 1"
+ - cron: "0 10 * * 1"
jobs:
- build:
+ phpstan:
name: "Phpstan"
- uses: contributte/.github/.github/workflows/phpstan.yml@v1
+ uses: contributte/.github/.github/workflows/phpstan.yml@master
with:
php: "8.2"
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 768684a..ac636ef 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -2,28 +2,36 @@ name: "Nette Tester"
on:
pull_request:
+ workflow_dispatch:
push:
branches: ["*"]
schedule:
- - cron: "0 8 * * 1"
+ - cron: "0 10 * * 1"
jobs:
- build84:
+ test85:
name: "Nette Tester"
- uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@v1
+ uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@master
with:
- php: "8.4"
+ php: "8.5"
- build83:
+ test84:
name: "Nette Tester"
- uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@v1
+ uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@master
with:
- php: "8.3"
+ php: "8.4"
- build82:
+ test83:
name: "Nette Tester"
- uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@v1
+ uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@master
with:
- php: "8.2"
+ php: "8.3"
+
+ test82:
+ name: "Nette Tester"
+ uses: contributte/.github/.github/workflows/nette-tester-mysql.yml@master
+ with:
+ php: "8.2"
+ composer: "composer update --no-interaction --no-progress --prefer-dist --prefer-stable --prefer-lowest"
diff --git a/.gitignore b/.gitignore
index b1b6f4d..f0b3670 100755
--- a/.gitignore
+++ b/.gitignore
@@ -6,5 +6,9 @@
/composer.lock
# Tests
-/temp
-/coverage.xml
+/tests/tmp
+/coverage.*
+/tests/**/*.log
+/tests/**/*.html
+/tests/**/*.expected
+/tests/**/*.actual
diff --git a/composer.json b/composer.json
index 710aa48..2734155 100755
--- a/composer.json
+++ b/composer.json
@@ -15,15 +15,12 @@
"nextras/dbal": "^5.0.0"
},
"require-dev": {
- "contributte/qa": "^0.4.0",
- "contributte/tester": "^0.3.0",
- "nette/di": "^3.0.1",
- "nextras/orm": "^5.0.0",
- "mockery/mockery": "^1.3.0",
- "phpstan/phpstan": "^1.0.0",
- "phpstan/phpstan-strict-rules": "^1.0.0",
- "phpstan/phpstan-deprecation-rules": "^1.0.0",
- "phpstan/phpstan-nette": "^1.0.0"
+ "contributte/phpstan": "~0.2.0",
+ "contributte/qa": "~0.4.0",
+ "contributte/tester": "~0.3.0",
+ "mockery/mockery": "^1.6.0",
+ "nette/di": "^3.2.0",
+ "nextras/orm": "^5.0.0"
},
"autoload": {
"psr-4": {
@@ -37,14 +34,15 @@
},
"minimum-stability": "dev",
"prefer-stable": true,
- "extra": {
- "branch-alias": {
- "dev-master": "0.7.x-dev"
- }
- },
"config": {
+ "sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.7.x-dev"
+ }
}
}
diff --git a/phpstan.neon b/phpstan.neon
index b84b608..ced0e50 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,12 +1,18 @@
includes:
- - vendor/phpstan/phpstan-deprecation-rules/rules.neon
- - vendor/phpstan/phpstan-nette/extension.neon
- - vendor/phpstan/phpstan-nette/rules.neon
- - vendor/phpstan/phpstan-strict-rules/rules.neon
+ - vendor/contributte/phpstan/phpstan.neon
parameters:
level: 9
phpVersion: 80200
+
+ scanDirectories:
+ - src
+
+ fileExtensions:
+ - php
+
paths:
- src
+ ignoreErrors:
+ - identifier: trait.unused
diff --git a/ruleset.xml b/ruleset.xml
index bee4c4f..d26d240 100644
--- a/ruleset.xml
+++ b/ruleset.xml
@@ -10,10 +10,17 @@
+
+
+
+
-
+
+
+ /tests/Cases
+
/tests/Cases
@@ -23,9 +30,6 @@
/tests/Cases
-
- /tests/Cases
-
/tests/tmp
diff --git a/tests/.coveralls.yml b/tests/.coveralls.yml
deleted file mode 100644
index 403f48b..0000000
--- a/tests/.coveralls.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-# for php-coveralls
-service_name: github-actions
-coverage_clover: coverage.xml
-json_path: coverage.json
\ No newline at end of file
diff --git a/tests/.gitignore b/tests/.gitignore
deleted file mode 100644
index f0d3402..0000000
--- a/tests/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-# Folders - recursive
-*.expected
-*.actual
-
-# Folders
-/tmp
-
-# Files
-/*.log
-/*.html
diff --git a/tests/Cases/E2E/BooksTest.phpt b/tests/Cases/E2E/BooksTest.phpt
index 2f2fc82..b95dbef 100644
--- a/tests/Cases/E2E/BooksTest.phpt
+++ b/tests/Cases/E2E/BooksTest.phpt
@@ -6,10 +6,12 @@ use Contributte\Nextras\Orm\QueryObject\Queryable;
use Contributte\Nextras\Orm\QueryObject\QueryObjectContextAwareManager;
use Contributte\Nextras\Orm\QueryObject\QueryObjectManager;
use Nette\DI\Container;
+use Nextras\Dbal\Drivers\Exception\ConnectionException;
use Nextras\Dbal\IConnection;
use Nextras\Dbal\Result\Result;
use Nextras\Orm\Collection\ICollection;
use Tester\Assert;
+use Tester\Environment;
use Tester\TestCase;
use Tests\Mocks\Model\Book\AllBooksExecutableQueryObject;
use Tests\Mocks\Model\Book\AllBooksQueryObject;
@@ -17,8 +19,24 @@ use Tests\Mocks\Model\Book\Book;
use Tests\Mocks\Model\Book\BookRepository;
use Tests\Mocks\Model\User\User;
+require_once __DIR__ . '/../../bootstrap.php';
+
+// nextras/orm 5.0.x is not yet compatible with PHP 8.5 (null array offset in AbstractEntity)
+if (PHP_VERSION_ID >= 80500) {
+ Environment::skip('nextras/orm is not yet compatible with PHP 8.5');
+}
+
$container = require_once __DIR__ . '/../../bootstrap.container.php';
+/** @var IConnection $connection */
+$connection = $container->getByType(IConnection::class);
+
+try {
+ $connection->connect();
+} catch (ConnectionException $e) {
+ Environment::skip('MySQL connection not available: ' . $e->getMessage());
+}
+
final class BooksTest extends TestCase
{
@@ -124,8 +142,8 @@ final class BooksTest extends TestCase
$sql = file_get_contents(__DIR__ . '/../../Fixtures/mysql.sql');
assert($sql !== false);
- foreach (array_filter(array_map('trim', explode(';', $sql))) as $query) {
- $connection->query('%raw', $query);
+ foreach (array_filter(array_map('trim', explode(';', $sql))) as $statement) {
+ $connection->query('%raw', $statement);
}
}
diff --git a/tests/Cases/Exceptions.phpt b/tests/Cases/Exceptions.phpt
index d882805..b51c2ce 100644
--- a/tests/Cases/Exceptions.phpt
+++ b/tests/Cases/Exceptions.phpt
@@ -2,32 +2,37 @@
use Contributte\Nextras\Orm\QueryObject\Exception\InvalidHydrationModeException;
use Contributte\Nextras\Orm\QueryObject\Exception\InvalidObjectCreationException;
+use Contributte\Tester\Toolkit;
use Tester\Assert;
require_once __DIR__ . '/../bootstrap.php';
-test('InvalidHydrationModeException extends LogicException', function (): void {
+// Test: InvalidHydrationModeException extends LogicException
+Toolkit::test(static function (): void {
$exception = new InvalidHydrationModeException('Test message');
Assert::type(LogicException::class, $exception);
Assert::same('Test message', $exception->getMessage());
});
-test('InvalidObjectCreationException extends LogicException', function (): void {
+// Test: InvalidObjectCreationException extends LogicException
+Toolkit::test(static function (): void {
$exception = new InvalidObjectCreationException('Creation failed');
Assert::type(LogicException::class, $exception);
Assert::same('Creation failed', $exception->getMessage());
});
-test('InvalidHydrationModeException can be thrown and caught', function (): void {
- Assert::exception(function (): void {
+// Test: InvalidHydrationModeException can be thrown and caught
+Toolkit::test(static function (): void {
+ Assert::exception(static function (): void {
throw new InvalidHydrationModeException('Invalid hydration mode "99"');
}, InvalidHydrationModeException::class, 'Invalid hydration mode "99"');
});
-test('InvalidObjectCreationException can be thrown and caught', function (): void {
- Assert::exception(function (): void {
+// Test: InvalidObjectCreationException can be thrown and caught
+Toolkit::test(static function (): void {
+ Assert::exception(static function (): void {
throw new InvalidObjectCreationException('Created object must be typed of QueryObject');
}, InvalidObjectCreationException::class, 'Created object must be typed of QueryObject');
});
diff --git a/tests/Cases/ExecutableQueryObject.phpt b/tests/Cases/ExecutableQueryObject.phpt
index ab1860e..9e0731d 100644
--- a/tests/Cases/ExecutableQueryObject.phpt
+++ b/tests/Cases/ExecutableQueryObject.phpt
@@ -1,6 +1,7 @@
fetch(new QueryBuilder($platform));
diff --git a/tests/Cases/QueryObjectContextAwareManager.phpt b/tests/Cases/QueryObjectContextAwareManager.phpt
index 6089b32..35a4180 100644
--- a/tests/Cases/QueryObjectContextAwareManager.phpt
+++ b/tests/Cases/QueryObjectContextAwareManager.phpt
@@ -3,6 +3,7 @@
use Contributte\Nextras\Orm\QueryObject\Exception\InvalidObjectCreationException;
use Contributte\Nextras\Orm\QueryObject\QueryObject;
use Contributte\Nextras\Orm\QueryObject\QueryObjectContextAwareManager;
+use Contributte\Tester\Toolkit;
use Nette\DI\Container;
use Nextras\Dbal\Connection;
use Nextras\Dbal\QueryBuilder\QueryBuilder;
@@ -12,7 +13,8 @@ use Tests\Mocks\SimpleQueryObject;
require_once __DIR__ . '/../bootstrap.php';
-test('QueryObjectContextAwareManager create returns QueryObject', function (): void {
+// Test: QueryObjectContextAwareManager create returns QueryObject
+Toolkit::test(static function (): void {
$queryObject = new SimpleQueryObject();
$container = Mockery::mock(Container::class);
@@ -30,7 +32,8 @@ test('QueryObjectContextAwareManager create returns QueryObject', function (): v
Mockery::close();
});
-test('QueryObjectContextAwareManager create throws InvalidObjectCreationException for non-QueryObject', function (): void {
+// Test: QueryObjectContextAwareManager create throws InvalidObjectCreationException for non-QueryObject
+Toolkit::test(static function (): void {
$nonQueryObject = new stdClass();
$container = Mockery::mock(Container::class);
@@ -41,14 +44,15 @@ test('QueryObjectContextAwareManager create throws InvalidObjectCreationExceptio
$manager = new QueryObjectContextAwareManager($container);
- Assert::exception(function () use ($manager): void {
+ Assert::exception(static function () use ($manager): void {
$manager->create(stdClass::class);
}, InvalidObjectCreationException::class);
Mockery::close();
});
-test('QueryObjectContextAwareManager fetch returns Result', function (): void {
+// Test: QueryObjectContextAwareManager fetch returns Result
+Toolkit::test(static function (): void {
$connection = Mockery::mock(Connection::class);
$queryBuilder = Mockery::mock(QueryBuilder::class);
$result = Mockery::mock(Result::class);
diff --git a/tests/Cases/QueryObjectExtension.phpt b/tests/Cases/QueryObjectExtension.phpt
index 46f5f6d..2e16551 100644
--- a/tests/Cases/QueryObjectExtension.phpt
+++ b/tests/Cases/QueryObjectExtension.phpt
@@ -2,6 +2,8 @@
use Contributte\Nextras\Orm\QueryObject\DI\NextrasQueryObjectExtension;
use Contributte\Nextras\Orm\QueryObject\QueryObjectManager;
+use Contributte\Tester\Environment;
+use Contributte\Tester\Toolkit;
use Nette\DI\Compiler;
use Nette\DI\Container;
use Nette\DI\ContainerLoader;
@@ -9,9 +11,9 @@ use Tester\Assert;
require_once __DIR__ . '/../bootstrap.php';
-test('NextrasQueryObjectExtension registers QueryObjectManager service', function (): void {
- $loader = new ContainerLoader(TEMP_DIR);
- $class = $loader->load(function (Compiler $compiler): void {
+Toolkit::test(static function (): void {
+ $loader = new ContainerLoader(Environment::getTestDir());
+ $class = $loader->load(static function (Compiler $compiler): void {
$compiler->addExtension('nextrasqueryobject', new NextrasQueryObjectExtension());
}, microtime());
diff --git a/tests/Cases/Queryable.phpt b/tests/Cases/Queryable.phpt
index 5039d4e..2d4d473 100644
--- a/tests/Cases/Queryable.phpt
+++ b/tests/Cases/Queryable.phpt
@@ -1,14 +1,17 @@
getProperty('connection');
- $property->setAccessible(true);
Assert::same($connection, $property->getValue($repo));
Mockery::close();
});
-test('TRepositoryQueryable fetch with HYDRATION_RESULTSET returns Result', function (): void {
+// Test: TRepositoryQueryable fetch with HYDRATION_RESULTSET returns Result
+Toolkit::test(static function (): void {
$connection = Mockery::mock(Connection::class);
$queryBuilder = Mockery::mock(QueryBuilder::class);
$result = Mockery::mock(Result::class);
@@ -85,11 +87,13 @@ test('TRepositoryQueryable fetch with HYDRATION_RESULTSET returns Result', funct
Mockery::close();
});
-test('TRepositoryQueryable fetch with HYDRATION_ENTITY returns ICollection', function (): void {
+// Test: TRepositoryQueryable fetch with HYDRATION_ENTITY returns ICollection
+Toolkit::test(static function (): void {
$connection = Mockery::mock(Connection::class);
$queryBuilder = Mockery::mock(QueryBuilder::class);
$mapper = Mockery::mock(DbalMapper::class);
- $collection = new StubCollection();
+
+ $collection = new EmptyCollection();
$queryBuilder->shouldReceive('select')
->with('*')
@@ -122,7 +126,8 @@ test('TRepositoryQueryable fetch with HYDRATION_ENTITY returns ICollection', fun
Mockery::close();
});
-test('TRepositoryQueryable fetch throws InvalidHydrationModeException for invalid mode', function (): void {
+// Test: TRepositoryQueryable fetch throws InvalidHydrationModeException for invalid mode
+Toolkit::test(static function (): void {
$connection = Mockery::mock(Connection::class);
$queryBuilder = Mockery::mock(QueryBuilder::class);
@@ -145,7 +150,7 @@ test('TRepositoryQueryable fetch throws InvalidHydrationModeException for invali
$queryObject = new SimpleQueryObject();
- Assert::exception(function () use ($repo, $queryObject): void {
+ Assert::exception(static function () use ($repo, $queryObject): void {
$repo->fetch($queryObject, 999);
}, InvalidHydrationModeException::class, 'Invalid hydration mode "999"');
diff --git a/tests/Mocks/Model/Book/BookMapper.php b/tests/Mocks/Model/Book/BookMapper.php
index df2e0b7..ce5238d 100644
--- a/tests/Mocks/Model/Book/BookMapper.php
+++ b/tests/Mocks/Model/Book/BookMapper.php
@@ -4,6 +4,9 @@
use Nextras\Orm\Mapper\Dbal\DbalMapper;
+/**
+ * @extends DbalMapper
+ */
final class BookMapper extends DbalMapper
{
diff --git a/tests/Mocks/Model/User/UserMapper.php b/tests/Mocks/Model/User/UserMapper.php
index ce5f45d..779594b 100644
--- a/tests/Mocks/Model/User/UserMapper.php
+++ b/tests/Mocks/Model/User/UserMapper.php
@@ -4,6 +4,9 @@
use Nextras\Orm\Mapper\Dbal\DbalMapper;
+/**
+ * @extends DbalMapper
+ */
final class UserMapper extends DbalMapper
{
diff --git a/tests/Mocks/SimpleConnection.php b/tests/Mocks/SimpleConnection.php
index 4faa165..410e1f7 100644
--- a/tests/Mocks/SimpleConnection.php
+++ b/tests/Mocks/SimpleConnection.php
@@ -2,9 +2,7 @@
namespace Tests\Mocks;
-use Mockery;
use Nextras\Dbal\Connection;
-use Nextras\Dbal\Platforms\IPlatform;
use Nextras\Dbal\QueryBuilder\QueryBuilder;
final class SimpleConnection extends Connection
@@ -12,9 +10,7 @@ final class SimpleConnection extends Connection
public function createQueryBuilder(): QueryBuilder
{
- $platform = Mockery::mock(IPlatform::class);
-
- return new QueryBuilder($platform);
+ return new QueryBuilder($this->getPlatform());
}
}
diff --git a/tests/bootstrap.container.php b/tests/bootstrap.container.php
index e202da8..94c14e0 100644
--- a/tests/bootstrap.container.php
+++ b/tests/bootstrap.container.php
@@ -1,6 +1,7 @@
load(function (Compiler $compiler): void {
$compiler->addExtension('inject', new InjectExtension());
$compiler->addExtension('di', new DIExtension());