diff --git a/.github/workflows/published.yml b/.github/workflows/published.yml
index ffa8190..c0c0460 100644
--- a/.github/workflows/published.yml
+++ b/.github/workflows/published.yml
@@ -34,12 +34,9 @@ jobs:
run: vendor/bin/psalm --stats --shepherd
- name: Generate Coverage
- run: vendor/bin/phpunit --configuration phpunit.xml.dist \
- --coverage-xml=build/coverage-xml \
- --coverage-clover=build/clover.xml \
- --log-junit=build/phpunit.junit.xml
+ run: vendor/bin/testo --coverage --log-junit=runtime/coverage/phpunit.junit.xml
- name: Infection Mutation Testing
env:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
- run: vendor/bin/infection --coverage=build --threads=max --logger-github --no-progress --skip-initial-tests
+ run: vendor/bin/infection --coverage=runtime/coverage --threads=max --logger-github --no-progress --skip-initial-tests
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 703dbe5..c4d7c8c 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -36,6 +36,6 @@ jobs:
composer-options: "--optimize-autoloader"
- name: PHPUnit
- run: vendor/bin/phpunit --configuration phpunit.xml.dist --coverage-clover ./coverage.xml
+ run: vendor/bin/testo
env:
XDEBUG_MODE: coverage
diff --git a/.gitignore b/.gitignore
index c356681..aecd873 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
# phpstorm project files
.idea
.zed
+.claude
# Mac DS_Store Files
.DS_Store
@@ -18,4 +19,5 @@ phpunit.phar
# local
*.local.php
+*.env
.auth.json
diff --git a/Makefile b/Makefile
index ff42b7b..9adf694 100644
--- a/Makefile
+++ b/Makefile
@@ -41,10 +41,10 @@ phpstan: ## phpstan
ghcr.io/kuaukutsu/php:${PHP_VERSION}-cli \
./vendor/bin/phpstan analyse -c phpstan.neon
-phpunit: ## phpunit
+testo: ## testo
$(DOCKER_RUN) \
ghcr.io/kuaukutsu/php:${PHP_VERSION}-cli \
- ./vendor/bin/phpunit
+ ./vendor/bin/testo
phpcs: ## php code snifferphp: detect violations of a defined coding standard
$(DOCKER_RUN) \
@@ -78,11 +78,13 @@ infection:
--target tests \
-t app_cli .docker/php/cli
- docker run --init -it --rm \
- --add-host=host.docker.internal:host-gateway \
-u $(USER) \
-v "$$(pwd):/app" \
-w /app \
- app_cli ./vendor/bin/infection
+ app_cli ./vendor/bin/infection \
+ --coverage=/app/runtime/coverage \
+ --threads=max \
+ --skip-initial-tests
docker image rm -f app_cli
tests:
@@ -93,17 +95,12 @@ tests:
--target tests \
-t app_cli .docker/php/cli
- docker run --init -it --rm \
- --add-host=host.docker.internal:host-gateway \
-u $(USER) \
-v "$$(pwd):/app" \
-w /app \
- app_cli ./vendor/bin/phpunit \
- --configuration phpunit.xml.dist \
- --coverage-xml=/app/runtime/coverage/coverage-xml \
- --coverage-clover=/app/runtime/coverage/clover.xml \
- --log-junit=/app/runtime/coverage/phpunit.junit.xml
+ app_cli ./vendor/bin/testo \
+ --coverage --log-junit=/app/runtime/coverage/junit.xml
- docker run --init -it --rm \
- --add-host=host.docker.internal:host-gateway \
-u $(USER) \
-v "$$(pwd):/app" \
-w /app \
@@ -119,3 +116,10 @@ app:
$(DOCKER_RUN) -w /app/example \
ghcr.io/kuaukutsu/php:${PHP_VERSION}-cli \
sh -l
+
+## AI
+-include .claude/Makefile
+
+# Спец-правило, чтобы Makefile не ругался на неизвестные команды (аргументы)
+%:
+ @:
diff --git a/composer.json b/composer.json
index 883b3c0..22595f5 100644
--- a/composer.json
+++ b/composer.json
@@ -20,14 +20,15 @@
},
"require-dev": {
"buggregator/trap": "^1.15",
- "infection/infection": "^0.32.4",
+ "infection/infection": "^0.32.7",
"php-di/php-di": "^7.1",
"phpstan/phpstan": "^2.0",
- "phpunit/phpunit": "^12.5",
"rector/rector": "^2.0",
"roave/security-advisories": "dev-latest",
"slevomat/coding-standard": "^8.7",
"squizlabs/php_codesniffer": "^3.7",
+ "testo/bridge-infection": "^0.1.3",
+ "testo/testo": "^0.10.10",
"vimeo/psalm": "^6.13"
},
"autoload": {
diff --git a/infection.json5.dist b/infection.json5.dist
index 05d6aa0..07e646c 100644
--- a/infection.json5.dist
+++ b/infection.json5.dist
@@ -1,14 +1,12 @@
{
+ "$schema": "vendor/infection/infection/resources/schema.json",
"source": {
- "directories": [
- "src"
- ]
+ "directories": ["src"]
},
+ "testFramework": "testo",
"threads": "max",
+ "tmpDir": "runtime",
"minCoveredMsi": 99,
- "phpUnit": {
- "configDir": "."
- },
"mutators": {
"@default": true
},
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
deleted file mode 100644
index 5347843..0000000
--- a/phpunit.xml.dist
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
- tests
-
-
-
-
- ./
-
-
- ./tests
- ./vendor
-
-
-
diff --git a/testo.dist.xml b/testo.dist.xml
new file mode 100644
index 0000000..15805ee
--- /dev/null
+++ b/testo.dist.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/testo.php b/testo.php
new file mode 100644
index 0000000..98cc41d
--- /dev/null
+++ b/testo.php
@@ -0,0 +1,24 @@
+getName());
- self::assertEquals('main', $driver->getSourceName());
+ Assert::same($driver->getName(), 'pgsql');
+ Assert::same($driver->getSourceName(), 'main');
$driver = new Driver(
dsn: 'MYSQL:host=mysql;dbname=copyDb',
);
- self::assertEquals('mysql', $driver->getName());
- self::assertEquals('copydb', $driver->getSourceName());
+ Assert::same($driver->getName(), 'mysql');
+ Assert::same($driver->getSourceName(), 'copydb');
$driver = new Driver(
dsn: 'sqlite::memory:',
);
- self::assertEquals('sqlite', $driver->getName());
- self::assertEquals('memory', $driver->getSourceName());
+ Assert::same($driver->getName(), 'sqlite');
+ Assert::same($driver->getSourceName(), 'memory');
$driver = new Driver(
dsn: 'sqlite:tests/data/sqlite/db.sqlite3',
);
- self::assertEquals('sqlite', $driver->getName());
- self::assertEquals('db', $driver->getSourceName());
+ Assert::same($driver->getName(), 'sqlite');
+ Assert::same($driver->getSourceName(), 'db');
}
- public function testConfigurationException(): void
+ public function configurationException(): void
{
- $this->expectException(ConfigurationException::class);
+ Expect::exception(ConfigurationException::class);
new Driver(
dsn: 'unknown:',
);
}
- public function testDSNConfigurationException(): void
+ public function dsnConfigurationException(): void
{
- $this->expectException(ConfigurationException::class);
- $this->expectExceptionMessage('PDODriver: dsn is incorrect.');
+ Expect::exception(ConfigurationException::class)
+ ->withMessage('PDODriver: dsn is incorrect.');
new Driver(
dsn: 'mysql::memory:',
);
}
- public function testDSNEmptyConfigurationException(): void
+ public function dsnEmptyConfigurationException(): void
{
- $this->expectException(ConfigurationException::class);
- $this->expectExceptionMessage('PDODriver: dsn is incorrect.');
+ Expect::exception(ConfigurationException::class)
+ ->withMessage('PDODriver: dsn is incorrect.');
new Driver(
dsn: 'sqlite:',
diff --git a/tests/workflow/MigrationTest.php b/tests/workflow/MigrationTest.php
index e164f96..1b1b5f5 100644
--- a/tests/workflow/MigrationTest.php
+++ b/tests/workflow/MigrationTest.php
@@ -4,28 +4,29 @@
namespace dbschemix\pdo\tests\workflow;
-use Override;
use Throwable;
-use PHPUnit\Framework\Attributes\Depends;
-use PHPUnit\Framework\TestCase;
-use dbschemix\pdo\Driver;
-use dbschemix\pdo\tests\MigratorFactory;
+use Testo\Assert;
+use Testo\Lifecycle\BeforeTest;
+use Testo\Test;
use dbschemix\core\command\CommandInterface;
use dbschemix\core\Config;
use dbschemix\core\InputOptions;
use dbschemix\core\MigratorInterface;
+use dbschemix\pdo\tests\MigratorFactory;
+use dbschemix\pdo\Driver;
/**
* Верхнеуровневая работа приложения.
*/
-final class MigrationTest extends TestCase
+#[Test]
+final class MigrationTest
{
private MigratorInterface $migrator;
private CommandInterface $command;
- #[Override]
- protected function setUp(): void
+ #[BeforeTest]
+ public function prepare(): void
{
$driver = new Driver(
dsn: 'sqlite::memory:',
@@ -38,124 +39,119 @@ protected function setUp(): void
/**
* @throws Throwable
*/
- public function testInit(): void
+ public function init(): void
{
$this->migrator->init();
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
}
/**
* @throws Throwable
*/
- #[Depends('testInit')]
- public function testUp(): void
+ public function up(): void
{
$this->migrator->init();
$this->migrator->up();
$data = $this->command->fetchApplied();
$countMigration = count($data);
- self::assertGreaterThanOrEqual(3, $countMigration);
+ Assert::int($countMigration)->greaterThanOrEqual(3);
// sort order
$names = array_keys($data);
- self::assertEquals('202501021025_account_email.sql', $names[0]);
- self::assertEquals('202501021024_account_create.sql', $names[1]);
- self::assertEquals('202501011024_entity_create.sql', $names[2]);
+ Assert::same($names[0], '202501021025_account_email.sql');
+ Assert::same($names[1], '202501021024_account_create.sql');
+ Assert::same($names[2], '202501011024_entity_create.sql');
$this->migrator->up();
$data = $this->command->fetchApplied();
- self::assertCount($countMigration, $data);
+ Assert::count($data, $countMigration);
}
/**
* @throws Throwable
*/
- #[Depends('testInit')]
- public function testDown(): void
+ public function down(): void
{
$this->migrator->init();
$this->migrator->up();
$data = $this->command->fetchApplied();
- self::assertGreaterThanOrEqual(3, $data);
+ Assert::int(count($data))->greaterThanOrEqual(3);
$this->migrator->down();
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
}
/**
* @throws Throwable
*/
- #[Depends('testInit')]
- public function testRedo(): void
+ public function redo(): void
{
$this->migrator->init();
$this->migrator->up();
$data = $this->command->fetchApplied();
- self::assertGreaterThanOrEqual(3, $data);
+ Assert::int(count($data))->greaterThanOrEqual(3);
$version = (int)current($data);
- self::assertGreaterThan(0, $version);
+ Assert::int($version)->greaterThan(0);
usleep(10_000);
$this->migrator->redo();
$data = $this->command->fetchApplied();
- self::assertGreaterThanOrEqual(3, $data);
+ Assert::int(count($data))->greaterThanOrEqual(3);
$versionNew = (int)current($data);
- self::assertGreaterThan(0, $versionNew);
+ Assert::int($versionNew)->greaterThan(0);
// новая версия больше старой
- self::assertGreaterThan($version, $versionNew);
+ Assert::int($versionNew)->greaterThan($version);
}
/**
* @throws Throwable
*/
- #[Depends('testInit')]
- public function testVerify(): void
+ public function verify(): void
{
$this->migrator->init();
$this->migrator->up(new InputOptions(limit: 1));
$data = $this->command->fetchApplied();
- self::assertCount(1, $data);
+ Assert::count($data, 1);
$version = (int)current($data);
- self::assertGreaterThan(0, $version);
+ Assert::int($version)->greaterThan(0);
usleep(10_000);
$this->migrator->verify();
$data = $this->command->fetchApplied();
- self::assertCount(1, $data);
+ Assert::count($data, 1);
$versionNew = (int)current($data);
- self::assertEquals($version, $versionNew);
+ Assert::equals($versionNew, $version);
}
/**
* @throws Throwable
*/
- #[Depends('testInit')]
- public function testFixture(): void
+ public function fixture(): void
{
$this->migrator->init();
$this->migrator->up();
$data = $this->command->fetchApplied();
$countMigration = count($data);
- self::assertGreaterThan(0, $countMigration);
+ Assert::int($countMigration)->greaterThan(0);
// applied fixture no saved
$this->migrator->fixture();
$data = $this->command->fetchApplied();
- self::assertCount($countMigration, $data);
+ Assert::count($data, $countMigration);
}
}
diff --git a/tests/workflow/StatementMysqlTest.php b/tests/workflow/StatementMysqlTest.php
index 76add99..105fb3e 100644
--- a/tests/workflow/StatementMysqlTest.php
+++ b/tests/workflow/StatementMysqlTest.php
@@ -4,21 +4,23 @@
namespace dbschemix\pdo\tests\workflow;
-use Override;
use Throwable;
use PDO;
-use PHPUnit\Framework\Attributes\DataProvider;
-use PHPUnit\Framework\TestCase;
+use Testo\Assert;
+use Testo\Data\DataProvider;
+use Testo\Lifecycle\BeforeTest;
+use Testo\Test;
use dbschemix\core\connection\TransactionInterface;
use dbschemix\pdo\internal\Connection;
use dbschemix\pdo\Type;
-final class StatementMysqlTest extends TestCase
+#[Test]
+final class StatementMysqlTest
{
private TransactionInterface $transaction;
- #[Override]
- protected function setUp(): void
+ #[BeforeTest]
+ public function init(): void
{
$pdo = new PDO(dsn: 'sqlite::memory:');
$pdo->exec(
@@ -31,40 +33,69 @@ protected function setUp(): void
/**
* @throws Throwable
*/
- public function testExecActiveTransaction(): void
+ public function execActiveTransaction(): void
{
// default: false
- self::assertFalse($this->transaction->isActive());
+ Assert::false($this->transaction->isActive());
$this->transaction->exec(
"INSERT INTO migration (name, version, atime) VALUES ('v1', 1, '2026-01-01 00:00:00')"
);
// statement INSERT: true
- self::assertTrue($this->transaction->isActive());
+ Assert::true($this->transaction->isActive());
$state = $this->transaction->commit();
- self::assertTrue($state);
- self::assertFalse($this->transaction->isActive());
+ Assert::true($state);
+ Assert::false($this->transaction->isActive());
// not active
$state = $this->transaction->commit();
- self::assertTrue($state);
+ Assert::true($state);
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertCount(1, $data);
+ Assert::count($data, 1);
}
/**
- * @return iterable
+ * Non-parameterized DDL case.
+ *
+ * Testo's coverage bridge does not attribute per-line coverage to
+ * #[DataProvider] methods, so {@see execNotActiveTransaction} is invisible
+ * to Infection and the DDL detection in tryBeginTransaction() would stay
+ * uncovered. This plain test pins the "DDL does not open a transaction"
+ * contract so the preg_match guard is mutation-covered.
+ *
+ * @throws Throwable
+ */
+ public function execSchemaQueryNotActiveTransaction(): void
+ {
+ // default: false
+ Assert::false($this->transaction->isActive());
+
+ $this->transaction->exec(
+ 'CREATE TABLE IF NOT EXISTS test (name TEXT PRIMARY KEY, version INTEGER DEFAULT 0, atime TEXT)'
+ );
+
+ // statement CREATE TABLE: still not active, DDL must not open a transaction
+ Assert::false($this->transaction->isActive());
+
+ $state = $this->transaction->commit();
+ Assert::true($state);
+ }
+
+ /**
+ * @return iterable
*/
public static function additionSchemaQuery(): iterable
{
- yield ['CREATE TABLE IF NOT EXISTS test (name TEXT PRIMARY KEY, version INTEGER DEFAULT 0, atime TEXT)'];
- yield ['ALTER TABLE migration ADD COLUMN test TEXT DEFAULT NULL'];
- yield ['CREATE UNIQUE INDEX IF NOT EXISTS `UI_migration_name` ON migration (name)'];
- yield ['DROP INDEX IF EXISTS `UI_migration_name`'];
- yield ['DROP TABLE IF EXISTS test'];
+ yield 'create table' => [
+ 'CREATE TABLE IF NOT EXISTS test (name TEXT PRIMARY KEY, version INTEGER DEFAULT 0, atime TEXT)',
+ ];
+ yield 'alter table' => ['ALTER TABLE migration ADD COLUMN test TEXT DEFAULT NULL'];
+ yield 'create index' => ['CREATE UNIQUE INDEX IF NOT EXISTS `UI_migration_name` ON migration (name)'];
+ yield 'drop index' => ['DROP INDEX IF EXISTS `UI_migration_name`'];
+ yield 'drop table' => ['DROP TABLE IF EXISTS test'];
}
/**
@@ -72,17 +103,17 @@ public static function additionSchemaQuery(): iterable
* @throws Throwable
*/
#[DataProvider('additionSchemaQuery')]
- public function testExecNotActiveTransaction(string $query): void
+ public function execNotActiveTransaction(string $query): void
{
// default: false
- self::assertFalse($this->transaction->isActive());
+ Assert::false($this->transaction->isActive());
$this->transaction->exec($query);
// statement CREATE TABLE: false
- self::assertFalse($this->transaction->isActive());
+ Assert::false($this->transaction->isActive());
$state = $this->transaction->commit();
- self::assertTrue($state);
+ Assert::true($state);
}
}
diff --git a/tests/workflow/StatementTest.php b/tests/workflow/StatementTest.php
index 8d88ce8..99a3131 100644
--- a/tests/workflow/StatementTest.php
+++ b/tests/workflow/StatementTest.php
@@ -4,21 +4,24 @@
namespace dbschemix\pdo\tests\workflow;
-use Override;
use Throwable;
use PDO;
-use PHPUnit\Framework\TestCase;
+use Testo\Assert;
+use Testo\Lifecycle\AfterTest;
+use Testo\Lifecycle\BeforeTest;
+use Testo\Test;
use dbschemix\core\connection\TransactionInterface;
use dbschemix\pdo\internal\Transaction;
-final class StatementTest extends TestCase
+#[Test]
+final class StatementTest
{
private PDO $pdo;
private TransactionInterface $transaction;
- #[Override]
- protected function setUp(): void
+ #[BeforeTest]
+ public function init(): void
{
$this->pdo = new PDO(dsn: 'sqlite::memory:');
$this->pdo->exec(
@@ -28,8 +31,8 @@ protected function setUp(): void
$this->transaction = Transaction::begin($this->pdo);
}
- #[Override]
- protected function tearDown(): void
+ #[AfterTest]
+ public function clean(): void
{
$this->transaction->rollback();
}
@@ -37,67 +40,67 @@ protected function tearDown(): void
/**
* @throws Throwable
*/
- public function testExecWithoutParams(): void
+ public function execWithoutParams(): void
{
$this->transaction->exec(
"INSERT INTO migration (name, version, atime) VALUES ('v1', 1, '2026-01-01 00:00:00')"
);
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertCount(1, $data);
- self::assertArrayHasKey('v1', $data);
+ Assert::count($data, 1);
+ Assert::array($data)->hasKeys('v1');
}
/**
* @throws Throwable
*/
- public function testExecCommitTransaction(): void
+ public function execCommitTransaction(): void
{
- self::assertTrue($this->transaction->isActive());
+ Assert::true($this->transaction->isActive());
$this->transaction->exec(
"INSERT INTO migration (name, version, atime) VALUES ('v1', 1, '2026-01-01 00:00:00')"
);
$state = $this->transaction->commit();
- self::assertTrue($state);
- self::assertFalse($this->transaction->isActive());
+ Assert::true($state);
+ Assert::false($this->transaction->isActive());
// not active
$state = $this->transaction->commit();
- self::assertTrue($state);
+ Assert::true($state);
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertCount(1, $data);
+ Assert::count($data, 1);
}
/**
* @throws Throwable
*/
- public function testExecRollbackTransaction(): void
+ public function execRollbackTransaction(): void
{
- self::assertTrue($this->transaction->isActive());
+ Assert::true($this->transaction->isActive());
$this->transaction->exec(
"INSERT INTO migration (name, version, atime) VALUES ('v1', 1, '2026-01-01 00:00:00')"
);
$state = $this->transaction->rollback();
- self::assertTrue($state);
- self::assertFalse($this->transaction->isActive());
+ Assert::true($state);
+ Assert::false($this->transaction->isActive());
// not active
$state = $this->transaction->rollback();
- self::assertTrue($state);
+ Assert::true($state);
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertEmpty($data);
+ Assert::blank($data);
}
/**
* @throws Throwable
*/
- public function testExecWithNamedParams(): void
+ public function execWithNamedParams(): void
{
$this->transaction->exec(
'INSERT INTO migration (name, version, atime) VALUES (:name, :version, :atime)',
@@ -105,9 +108,9 @@ public function testExecWithNamedParams(): void
);
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertCount(1, $data);
- self::assertArrayHasKey('202501010000_create_users', $data);
- self::assertEquals(42, $data['202501010000_create_users']);
+ Assert::count($data, 1);
+ Assert::array($data)->hasKeys('202501010000_create_users');
+ Assert::equals($data['202501010000_create_users'], 42);
}
/**
@@ -115,7 +118,7 @@ public function testExecWithNamedParams(): void
*
* @throws Throwable
*/
- public function testExecParamsAreNotInterpolated(): void
+ public function execParamsAreNotInterpolated(): void
{
$maliciousName = "'); DROP TABLE migration; --";
@@ -125,14 +128,14 @@ public function testExecParamsAreNotInterpolated(): void
);
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertCount(1, $data);
- self::assertArrayHasKey($maliciousName, $data);
+ Assert::count($data, 1);
+ Assert::array($data)->hasKeys($maliciousName);
}
/**
* @throws Throwable
*/
- public function testExecMultipleRowsWithParams(): void
+ public function execMultipleRowsWithParams(): void
{
$rows = [
['name' => '202501010000_first', 'version' => 1, 'atime' => '2026-01-01 00:00:00'],
@@ -148,16 +151,16 @@ public function testExecMultipleRowsWithParams(): void
}
$data = $this->transaction->fetchRecord('SELECT name, version FROM migration');
- self::assertCount(3, $data);
- self::assertEquals(1, $data['202501010000_first']);
- self::assertEquals(2, $data['202501010001_second']);
- self::assertEquals(3, $data['202501010002_third']);
+ Assert::count($data, 3);
+ Assert::equals($data['202501010000_first'], 1);
+ Assert::equals($data['202501010001_second'], 2);
+ Assert::equals($data['202501010002_third'], 3);
}
/**
* @throws Throwable
*/
- public function testFetchRecordWithParams(): void
+ public function fetchRecordWithParams(): void
{
$this->pdo->exec("INSERT INTO migration (name, version, atime) VALUES ('v1', 10, '2026-01-01 00:00:00')");
$this->pdo->exec("INSERT INTO migration (name, version, atime) VALUES ('v2', 20, '2026-01-02 00:00:00')");
@@ -168,16 +171,15 @@ public function testFetchRecordWithParams(): void
['version' => 10],
);
- self::assertCount(2, $data);
- self::assertArrayHasKey('v1', $data);
- self::assertArrayHasKey('v3', $data);
- self::assertArrayNotHasKey('v2', $data);
+ Assert::count($data, 2);
+ Assert::array($data)->hasKeys('v1', 'v3');
+ Assert::array($data)->doesNotHaveKeys('v2');
}
/**
* @throws Throwable
*/
- public function testFetchRecordWithParamsNoMatch(): void
+ public function fetchRecordWithParamsNoMatch(): void
{
$this->pdo->exec("INSERT INTO migration (name, version, atime) VALUES ('v1', 1, '2026-01-01 00:00:00')");
@@ -186,6 +188,6 @@ public function testFetchRecordWithParamsNoMatch(): void
['version' => 999],
);
- self::assertEmpty($data);
+ Assert::blank($data);
}
}
diff --git a/tests/workflow/UpExactlyTest.php b/tests/workflow/UpExactlyTest.php
index c1a6d4a..a0e3c50 100644
--- a/tests/workflow/UpExactlyTest.php
+++ b/tests/workflow/UpExactlyTest.php
@@ -4,25 +4,28 @@
namespace dbschemix\pdo\tests\workflow;
-use Override;
use Throwable;
-use PHPUnit\Framework\TestCase;
-use dbschemix\pdo\Driver;
-use dbschemix\pdo\tests\MigratorFactory;
+use Testo\Assert;
+use Testo\Expect;
+use Testo\Lifecycle\BeforeTest;
+use Testo\Test;
use dbschemix\core\command\CommandInterface;
use dbschemix\core\exception\ActionException;
use dbschemix\core\Config;
use dbschemix\core\InputOptions;
use dbschemix\core\MigratorInterface;
+use dbschemix\pdo\Driver;
+use dbschemix\pdo\tests\MigratorFactory;
-final class UpExactlyTest extends TestCase
+#[Test]
+final class UpExactlyTest
{
private MigratorInterface $migrator;
private CommandInterface $command;
- #[Override]
- protected function setUp(): void
+ #[BeforeTest]
+ public function prepare(): void
{
$driver = new Driver(
dsn: 'sqlite::memory:',
@@ -35,19 +38,19 @@ protected function setUp(): void
/**
* @throws Throwable
*/
- public function testUpExactlyAll(): void
+ public function upExactlyAll(): void
{
$this->migrator->init();
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
$this->migrator->up(new InputOptions(limit: 1));
$data = $this->command->fetchApplied();
- self::assertCount(1, $data);
+ Assert::count($data, 1);
$this->migrator->down();
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
try {
$this->migrator->up();
@@ -56,11 +59,11 @@ public function testUpExactlyAll(): void
// только первая миграция успешно
$data = $this->command->fetchApplied();
- self::assertCount(1, $data);
+ Assert::count($data, 1);
$this->migrator->down();
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
try {
$this->migrator->up(new InputOptions(exactlyAll: true));
@@ -69,17 +72,15 @@ public function testUpExactlyAll(): void
// всё или ничего
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
}
- public function testUpExactlyAllException(): void
+ public function upExactlyAllException(): void
{
$this->migrator->init();
- $this->expectException(ActionException::class);
- $this->expectExceptionMessage(
- 'SQLSTATE[HY000]: General error: 1 no such table:'
- );
+ Expect::exception(ActionException::class)
+ ->withMessageContaining('SQLSTATE[HY000]: General error: 1 no such table:');
$this->migrator->up(new InputOptions(exactlyAll: true));
}
@@ -87,15 +88,15 @@ public function testUpExactlyAllException(): void
/**
* @throws Throwable
*/
- public function testVerify(): void
+ public function verify(): void
{
$this->migrator->init();
$data = $this->command->fetchApplied();
- self::assertEmpty($data);
+ Assert::blank($data);
$this->migrator->up(new InputOptions(limit: 1));
$data = $this->command->fetchApplied();
- self::assertCount(1, $data);
+ Assert::count($data, 1);
// точность версионирования
usleep(10_000);
@@ -107,17 +108,15 @@ public function testVerify(): void
// только первая миграция успешно
$data = $this->command->fetchApplied();
- self::assertCount(1, $data);
+ Assert::count($data, 1);
}
- public function testVerifyException(): void
+ public function verifyException(): void
{
$this->migrator->init();
- $this->expectException(ActionException::class);
- $this->expectExceptionMessage(
- 'SQLSTATE[HY000]: General error: 1 no such table:'
- );
+ Expect::exception(ActionException::class)
+ ->withMessageContaining('SQLSTATE[HY000]: General error: 1 no such table:');
$this->migrator->verify();
}