From 78d17f18c5a8bc3fbda9869f7340d66204de53ec Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Tue, 22 Oct 2024 23:56:35 -0500 Subject: [PATCH] Test with PostgreSQL --- .github/workflows/php.yml | 14 +++++++++- composer.json | 6 +++-- test/DbTestCase.php | 46 +++++++++++++++++++++---------- test/PgsqlDbTest.php | 57 +++++++++++++++++++++++++++++++++++++++ test/src/Config.php | 15 +++++++++++ 5 files changed, 121 insertions(+), 17 deletions(-) create mode 100644 test/PgsqlDbTest.php diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 584fdc2..09e4ad9 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -19,6 +19,16 @@ jobs: # map port 3306 on service container to the host - 3306:3306 options: --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 5 + postgres: + image: postgres + env: + POSTGRES_HOST: localhost + POSTGRES_PASSWORD: postgres + # Set health checks to wait until postgres has started + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + ports: + # Maps tcp port 5432 on service container to the host + - 5432:5432 steps: - name: Checkout @@ -43,7 +53,9 @@ jobs: if: ${{ matrix.php == '8.3' }} - name: Run PHPUnit - run: composer test-mysql + run: composer test-without-mssql + env: + POSTGRES_HOST: localhost - name: Check Formatting run: vendor/bin/php-cs-fixer fix -v --dry-run --stop-on-violation --using-cache=no diff --git a/composer.json b/composer.json index 28ec953..1fde685 100644 --- a/composer.json +++ b/composer.json @@ -47,8 +47,10 @@ "analyze": "psalm", "cs-fix": "php-cs-fixer fix -v", "test": "phpunit", - "test-mssql": "phpunit --exclude-group mysql", - "test-mysql": "phpunit --exclude-group mssql", + "test-mssql": "phpunit --exclude-group mysql,pgsql", + "test-mysql": "phpunit --exclude-group mssql,pgsql", + "test-pgsql": "phpunit --exclude-group mssql,mysql", + "test-without-mssql": "phpunit --exclude-group mssql", "test-without-db": "phpunit --exclude-group mssql,mysql" } } diff --git a/test/DbTestCase.php b/test/DbTestCase.php index 4d561e6..15daef8 100644 --- a/test/DbTestCase.php +++ b/test/DbTestCase.php @@ -33,7 +33,8 @@ public static function legacyUsersProvider(): LegacyUsers public function testAddEntities(): void { - $entities = static::entitiesProvider(); + $db = static::dbProvider(); + $entities = new Users($db); try { $entities->addEntities([[ @@ -63,15 +64,20 @@ public function testAddEntities(): void $ids = $entities->addEntities($users); - $users[0] = array_merge(['id' => $ids[0]], $users[0], ['isDisabled' => false]); - $users[1] = array_merge(['id' => $ids[1]], $users[1]); + $expected = array_map(function ($u, $i) use ($db) { + return array_merge(['id' => $i], $u, [ + 'weight' => $db->options->floatSelectedAsString ? (string) $u['weight'] : $u['weight'], + 'isDisabled' => $u['isDisabled'] ?? false, + ]); + }, $users, $ids); - $this->assertSame($users, $entities->getEntitiesByIds($ids)); + $this->assertSame($expected, $entities->getEntitiesByIds($ids)); } public function testUpdateById(): void { - $entities = static::entitiesProvider(); + $db = static::dbProvider(); + $entities = new Users($db); try { // optional properties should still be required when replacing an entity @@ -103,13 +109,18 @@ public function testUpdateById(): void 'isDisabled' => false, ]; + if ($db->options->floatSelectedAsString) { + $newUser['weight'] = (string) $newUser['weight']; + } + $entities->updateById($id, $newUser); $this->assertSame($newUser, $entities->getEntityById($id)); } public function testPatchByIds(): void { - $entities = static::entitiesProvider(); + $db = static::dbProvider(); + $entities = new Users($db); $users = [ [ @@ -126,8 +137,11 @@ public function testPatchByIds(): void $ids = $entities->addEntities($users); - $expected = array_map(function ($u, $i) { - return array_merge(['id' => $i], $u, ['isDisabled' => false]); + $expected = array_map(function ($u, $i) use ($db) { + return array_merge(['id' => $i], $u, [ + 'weight' => $db->options->floatSelectedAsString ? (string) $u['weight'] : $u['weight'], + 'isDisabled' => false, + ]); }, $users, $ids); $this->assertSame($expected, $entities->getEntitiesByIds($ids)); @@ -136,8 +150,10 @@ public function testPatchByIds(): void 'weight' => 125.0, ]); - $newExpected = array_map(function ($u) { - return array_merge($u, ['weight' => 125.0]); + $newExpected = array_map(function ($u) use ($db) { + return array_merge($u, [ + 'weight' => $db->options->floatSelectedAsString ? '125' : 125.0, + ]); }, $expected); $this->assertSame($newExpected, $entities->getEntitiesByIds($ids)); @@ -204,7 +220,8 @@ public function testConstraintError(): void public function testGetEntities(): void { - $entities = static::entitiesProvider(); + $db = static::dbProvider(); + $entities = new Users($db); $users = []; for ($i = 1; $i <= 50; $i++) { @@ -225,10 +242,11 @@ public function testGetEntities(): void $expected = []; for ($j = 40; $j > 35; $j--) { + $weight = $j * 10.0; $expected[] = [ 'name' => "User {$j}", 'birthday' => '2000-02-04', - 'weight' => $j * 10.0, + 'weight' => $db->options->floatSelectedAsString ? (string) $weight : $weight, 'isDisabled' => false, ]; } @@ -314,7 +332,7 @@ public function testModernUsers(): void 'name' => 'Modern user 4', 'isDisabled' => false, 'computed' => 41.0, - 'weight' => 40.0, + 'weight' => $db->options->floatSelectedAsString ? '40' : 40.0, 'thing' => [ 'uid' => $ids[3], ], @@ -324,7 +342,7 @@ public function testModernUsers(): void 'name' => 'Modern user 3 modified', 'isDisabled' => false, 'computed' => 31.0, - 'weight' => 30.0, + 'weight' => $db->options->floatSelectedAsString ? '30' : 30.0, 'thing' => null, ], ]; diff --git a/test/PgsqlDbTest.php b/test/PgsqlDbTest.php new file mode 100644 index 0000000..189dd32 --- /dev/null +++ b/test/PgsqlDbTest.php @@ -0,0 +1,57 @@ +getPgsqlDsn($dbName), $c->getPgsqlUser(), $c->getPgsqlPassword(), [ + PDO::ATTR_EMULATE_PREPARES => false, + ]); + + self::$db = new PeachySql($pdo); + self::createTestTable(self::$db); + } + + return self::$db; + } + + private static function createTestTable(PeachySql $db): void + { + self::tearDownAfterClass(); + + $sql = " + CREATE TABLE Users ( + user_id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL UNIQUE, + dob DATE NOT NULL, + weight REAL NOT NULL, + is_disabled BOOLEAN NOT NULL + )"; + + $db->query($sql); + + $sql = " + CREATE TABLE UserThings ( + thing_id SERIAL PRIMARY KEY, + user_id INT NOT NULL, + FOREIGN KEY (user_id) REFERENCES Users(user_id) + )"; + + $db->query($sql); + } +} diff --git a/test/src/Config.php b/test/src/Config.php index 052222f..1889046 100644 --- a/test/src/Config.php +++ b/test/src/Config.php @@ -22,6 +22,21 @@ public function getMysqlPassword(): string return ''; } + public function getPgsqlDsn(string $database): string + { + return "pgsql:host=localhost;dbname=$database"; + } + + public function getPgsqlUser(): string + { + return 'postgres'; + } + + public function getPgsqlPassword(): string + { + return 'postgres'; + } + public function getSqlsrvServer(): string { return '(local)\SQLEXPRESS';