Migrate tests to Pest #8
|
@ -40,7 +40,7 @@
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Test\\": "./tests",
|
"Test\\": "./tests",
|
||||||
"Test\\Integration\\": "./tests/integration",
|
"Test\\Integration\\": "./tests/integration",
|
||||||
"Test\\Integration\\PostgreSQL\\": "./tests/integration/postgresql",
|
"Test\\Integration\\PostgreSQL\\": "./tests/Integration/PostgreSQL",
|
||||||
"Test\\Integration\\SQLite\\": "./tests/integration/sqlite"
|
"Test\\Integration\\SQLite\\": "./tests/integration/sqlite"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
86
composer.lock
generated
86
composer.lock
generated
|
@ -1234,16 +1234,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpdocumentor/reflection-docblock",
|
"name": "phpdocumentor/reflection-docblock",
|
||||||
"version": "5.5.1",
|
"version": "5.6.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||||
"reference": "0c70d2c566e899666f367ab7b80986beb3581e6f"
|
"reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/0c70d2c566e899666f367ab7b80986beb3581e6f",
|
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c",
|
||||||
"reference": "0c70d2c566e899666f367ab7b80986beb3581e6f",
|
"reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1252,7 +1252,7 @@
|
||||||
"php": "^7.4 || ^8.0",
|
"php": "^7.4 || ^8.0",
|
||||||
"phpdocumentor/reflection-common": "^2.2",
|
"phpdocumentor/reflection-common": "^2.2",
|
||||||
"phpdocumentor/type-resolver": "^1.7",
|
"phpdocumentor/type-resolver": "^1.7",
|
||||||
"phpstan/phpdoc-parser": "^1.7",
|
"phpstan/phpdoc-parser": "^1.7|^2.0",
|
||||||
"webmozart/assert": "^1.9.1"
|
"webmozart/assert": "^1.9.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
@ -1292,9 +1292,9 @@
|
||||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
|
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
|
||||||
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.5.1"
|
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0"
|
||||||
},
|
},
|
||||||
"time": "2024-11-06T11:58:54+00:00"
|
"time": "2024-11-12T11:25:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpdocumentor/type-resolver",
|
"name": "phpdocumentor/type-resolver",
|
||||||
|
@ -1356,30 +1356,30 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpdoc-parser",
|
"name": "phpstan/phpdoc-parser",
|
||||||
"version": "1.33.0",
|
"version": "2.0.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||||
"reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140"
|
"reference": "c00d78fb6b29658347f9d37ebe104bffadf36299"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140",
|
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299",
|
||||||
"reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140",
|
"reference": "c00d78fb6b29658347f9d37ebe104bffadf36299",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2 || ^8.0"
|
"php": "^7.4 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/annotations": "^2.0",
|
"doctrine/annotations": "^2.0",
|
||||||
"nikic/php-parser": "^4.15",
|
"nikic/php-parser": "^5.3.0",
|
||||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||||
"phpstan/extension-installer": "^1.0",
|
"phpstan/extension-installer": "^1.0",
|
||||||
"phpstan/phpstan": "^1.5",
|
"phpstan/phpstan": "^2.0",
|
||||||
"phpstan/phpstan-phpunit": "^1.1",
|
"phpstan/phpstan-phpunit": "^2.0",
|
||||||
"phpstan/phpstan-strict-rules": "^1.0",
|
"phpstan/phpstan-strict-rules": "^2.0",
|
||||||
"phpunit/phpunit": "^9.5",
|
"phpunit/phpunit": "^9.6",
|
||||||
"symfony/process": "^5.2"
|
"symfony/process": "^5.2"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
@ -1397,9 +1397,9 @@
|
||||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0"
|
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0"
|
||||||
},
|
},
|
||||||
"time": "2024-10-13T11:25:22+00:00"
|
"time": "2024-10-13T11:29:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan",
|
"name": "phpstan/phpstan",
|
||||||
|
@ -3009,16 +3009,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v7.1.7",
|
"version": "v7.2.0-RC1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "3284aafcac338b6e86fd955ee4d794cbe434151a"
|
"reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/3284aafcac338b6e86fd955ee4d794cbe434151a",
|
"url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf",
|
||||||
"reference": "3284aafcac338b6e86fd955ee4d794cbe434151a",
|
"reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3082,7 +3082,7 @@
|
||||||
"terminal"
|
"terminal"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v7.1.7"
|
"source": "https://github.com/symfony/console/tree/v7.2.0-RC1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3098,7 +3098,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-05T15:34:55+00:00"
|
"time": "2024-11-06T14:24:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
|
@ -3169,16 +3169,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/finder",
|
"name": "symfony/finder",
|
||||||
"version": "v7.1.6",
|
"version": "v7.2.0-RC1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/finder.git",
|
"url": "https://github.com/symfony/finder.git",
|
||||||
"reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8"
|
"reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8",
|
"url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49",
|
||||||
"reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8",
|
"reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3213,7 +3213,7 @@
|
||||||
"description": "Finds files and directories via an intuitive fluent interface",
|
"description": "Finds files and directories via an intuitive fluent interface",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/finder/tree/v7.1.6"
|
"source": "https://github.com/symfony/finder/tree/v7.2.0-RC1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3229,7 +3229,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-10-01T08:31:23+00:00"
|
"time": "2024-10-23T06:56:12+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
|
@ -3551,16 +3551,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v7.1.7",
|
"version": "v7.2.0-RC1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "9b8a40b7289767aa7117e957573c2a535efe6585"
|
"reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/9b8a40b7289767aa7117e957573c2a535efe6585",
|
"url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e",
|
||||||
"reference": "9b8a40b7289767aa7117e957573c2a535efe6585",
|
"reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3592,7 +3592,7 @@
|
||||||
"description": "Executes commands in sub-processes",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v7.1.7"
|
"source": "https://github.com/symfony/process/tree/v7.2.0-RC1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3608,7 +3608,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-06T09:25:12+00:00"
|
"time": "2024-11-06T14:24:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
|
@ -3695,16 +3695,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/string",
|
"name": "symfony/string",
|
||||||
"version": "v7.1.6",
|
"version": "v7.2.0-RC1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/string.git",
|
"url": "https://github.com/symfony/string.git",
|
||||||
"reference": "61b72d66bf96c360a727ae6232df5ac83c71f626"
|
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626",
|
"url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82",
|
||||||
"reference": "61b72d66bf96c360a727ae6232df5ac83c71f626",
|
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3762,7 +3762,7 @@
|
||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/string/tree/v7.1.6"
|
"source": "https://github.com/symfony/string/tree/v7.2.0-RC1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -3778,7 +3778,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-09-25T14:20:29+00:00"
|
"time": "2024-11-13T13:31:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ta-tikoma/phpunit-architecture-test",
|
"name": "ta-tikoma/phpunit-architecture-test",
|
||||||
|
|
|
@ -8,8 +8,8 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use BitBadger\PDODocument\{AutoId, Configuration, Custom, Document, DocumentException, Field, Find, Query};
|
use BitBadger\PDODocument\{AutoId, Configuration, Custom, Document, DocumentException, Field, Find, Query};
|
||||||
use BitBadger\PDODocument\Mapper\ArrayMapper;
|
use BitBadger\PDODocument\Mapper\ArrayMapper;
|
||||||
use Test\Integration\PostgreSQL\ThrowawayDb;
|
|
||||||
use Test\Integration\{NumDocument, SubDocument, TestDocument};
|
use Test\Integration\{NumDocument, SubDocument, TestDocument};
|
||||||
|
use Test\Integration\PostgreSQL\ThrowawayDb;
|
||||||
|
|
||||||
pest()->group('integration', 'postgresql');
|
pest()->group('integration', 'postgresql');
|
||||||
|
|
||||||
|
|
48
tests/Integration/PostgreSQL/ExistsTest.php
Normal file
48
tests/Integration/PostgreSQL/ExistsTest.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use BitBadger\PDODocument\{Exists, Field};
|
||||||
|
use Test\Integration\PostgreSQL\ThrowawayDb;
|
||||||
|
|
||||||
|
pest()->group('integration', 'postgresql');
|
||||||
|
|
||||||
|
describe('::byId()', function () {
|
||||||
|
test('returns true when a document exists', function () {
|
||||||
|
expect(Exists::byId(ThrowawayDb::TABLE, 'three'))->toBeTrue();
|
||||||
|
});
|
||||||
|
test('returns false when a document does not exist', function () {
|
||||||
|
expect(Exists::byId(ThrowawayDb::TABLE, 'seven'))->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byFields()', function () {
|
||||||
|
test('returns true when matching documents exist', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 10)]))->toBeTrue();
|
||||||
|
});
|
||||||
|
test('returns false when no matching documents exist', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::less('nothing', 'none')]))->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byContains()', function () {
|
||||||
|
test('returns true when matching documents exist', function () {
|
||||||
|
expect(Exists::byContains(ThrowawayDb::TABLE, ['value' => 'purple']))->toBeTrue();
|
||||||
|
});
|
||||||
|
test('returns false when no matching documents exist', function () {
|
||||||
|
expect(Exists::byContains(ThrowawayDb::TABLE, ['value' => 'violet']))->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byJsonPath()', function () {
|
||||||
|
test('returns true when matching documents exist', function () {
|
||||||
|
expect(Exists::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ == 10)'))->toBeTrue();
|
||||||
|
});
|
||||||
|
test('returns false when no matching documents exist', function () {
|
||||||
|
expect(Exists::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ == 10.1)'))->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
216
tests/Integration/PostgreSQL/FindTest.php
Normal file
216
tests/Integration/PostgreSQL/FindTest.php
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use BitBadger\PDODocument\{Custom, Delete, Document, Field, FieldMatch, Find};
|
||||||
|
use Test\Integration\{ArrayDocument, NumDocument, TestDocument};
|
||||||
|
use Test\Integration\PostgreSQL\ThrowawayDb;
|
||||||
|
|
||||||
|
pest()->group('integration', 'postgresql');
|
||||||
|
|
||||||
|
describe('::all()', function () {
|
||||||
|
test('retrieves data', function () {
|
||||||
|
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull();
|
||||||
|
$count = 0;
|
||||||
|
foreach ($docs->items() as $ignored) $count++;
|
||||||
|
expect($count)->toBe(5);
|
||||||
|
});
|
||||||
|
test('sorts data ascending', function () {
|
||||||
|
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class, [Field::named('id')]);
|
||||||
|
expect($docs)->not->toBeNull()
|
||||||
|
->and(iterator_to_array($docs->map(fn ($it) => $it->id), false))
|
||||||
|
->toBe(['five', 'four', 'one', 'three', 'two']);
|
||||||
|
});
|
||||||
|
test('sorts data descending', function () {
|
||||||
|
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class, [Field::named('id DESC')]);
|
||||||
|
expect($docs)->not->toBeNull()
|
||||||
|
->and(iterator_to_array($docs->map(fn ($it) => $it->id), false))
|
||||||
|
->toBe(['two', 'three', 'one', 'four', 'five']);
|
||||||
|
});
|
||||||
|
test('sorts data numerically', function () {
|
||||||
|
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class,
|
||||||
|
[Field::named('sub.foo NULLS LAST'), Field::named('n:num_value')]);
|
||||||
|
expect($docs)->not->toBeNull()
|
||||||
|
->and(iterator_to_array($docs->map(fn ($it) => $it->id), false))
|
||||||
|
->toBe(['two', 'four', 'one', 'three', 'five']);
|
||||||
|
});
|
||||||
|
test('retrieves empty results', function () {
|
||||||
|
Custom::nonQuery('DELETE FROM ' . ThrowawayDb::TABLE, []);
|
||||||
|
expect(Find::all(ThrowawayDb::TABLE, TestDocument::class))
|
||||||
|
->not->toBeNull()
|
||||||
|
->hasItems()->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byId()', function () {
|
||||||
|
test('retrieves a document via string ID', function () {
|
||||||
|
expect(Find::byId(ThrowawayDb::TABLE, 'two', TestDocument::class))
|
||||||
|
->isSome()->toBeTrue()
|
||||||
|
->get()->id->toBe('two');
|
||||||
|
});
|
||||||
|
test('retrieves a document via numeric ID', function () {
|
||||||
|
Delete::byFields(ThrowawayDb::TABLE, [Field::notExists('absent')]);
|
||||||
|
Document::insert(ThrowawayDb::TABLE, ['id' => 18, 'value' => 'howdy']);
|
||||||
|
expect(Find::byId(ThrowawayDb::TABLE, 18, NumDocument::class))
|
||||||
|
->isSome()->toBeTrue()
|
||||||
|
->get()->id->toBe(18);
|
||||||
|
});
|
||||||
|
test('returns None when a document is not found', function () {
|
||||||
|
expect(Find::byId(ThrowawayDb::TABLE, 'seventy-five', TestDocument::class))->isNone()->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byFields()', function () {
|
||||||
|
test('retrieves matching documents', function () {
|
||||||
|
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::in('value', ['blue', 'purple']), Field::exists('sub')],
|
||||||
|
TestDocument::class, FieldMatch::All);
|
||||||
|
expect($docs)->not->toBeNull();
|
||||||
|
$count = 0;
|
||||||
|
foreach ($docs->items() as $ignored) $count++;
|
||||||
|
expect($count)->toBe(1);
|
||||||
|
});
|
||||||
|
test('retrieves ordered matching documents', function () {
|
||||||
|
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::equal('value', 'purple')], TestDocument::class,
|
||||||
|
FieldMatch::All, [Field::named('id')]);
|
||||||
|
expect($docs)->not->toBeNull()
|
||||||
|
->and(iterator_to_array($docs->map(fn ($it) => $it->id), false))->toBe(['five', 'four']);
|
||||||
|
});
|
||||||
|
test('retrieves documents matching a numeric IN clause', function () {
|
||||||
|
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::in('num_value', [2, 4, 6, 8])], TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull();
|
||||||
|
$count = 0;
|
||||||
|
foreach ($docs->items() as $ignored) $count++;
|
||||||
|
expect($count)->toBe(1);
|
||||||
|
});
|
||||||
|
test('returns an empty list when no matching documents are found', function () {
|
||||||
|
expect(Find::byFields(ThrowawayDb::TABLE, [Field::greater('num_value', 100)], TestDocument::class))
|
||||||
|
->not->toBeNull()
|
||||||
|
->hasItems()->toBeFalse();
|
||||||
|
});
|
||||||
|
test('retrieves documents matching an inArray condition', function () {
|
||||||
|
Delete::byFields(ThrowawayDb::TABLE, [Field::notExists('absentField')]);
|
||||||
|
foreach (ArrayDocument::testDocuments() as $doc) Document::insert(ThrowawayDb::TABLE, $doc);
|
||||||
|
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::inArray('values', ThrowawayDb::TABLE, ['c'])],
|
||||||
|
ArrayDocument::class);
|
||||||
|
expect($docs)->not->toBeNull();
|
||||||
|
$count = 0;
|
||||||
|
foreach ($docs->items() as $ignored) $count++;
|
||||||
|
expect($count)->toBe(2);
|
||||||
|
});
|
||||||
|
test('returns an empty list when no documents match an inArray condition', function () {
|
||||||
|
Delete::byFields(ThrowawayDb::TABLE, [Field::notExists('absentField')]);
|
||||||
|
foreach (ArrayDocument::testDocuments() as $doc) Document::insert(ThrowawayDb::TABLE, $doc);
|
||||||
|
expect(Find::byFields(ThrowawayDb::TABLE, [Field::inArray('values', ThrowawayDb::TABLE, ['j'])],
|
||||||
|
ArrayDocument::class))
|
||||||
|
->not->toBeNull()
|
||||||
|
->hasItems()->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byContains()', function () {
|
||||||
|
test('retrieves matching documents', function () {
|
||||||
|
$docs = Find::byContains(ThrowawayDb::TABLE, ['value' => 'purple'], TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull();
|
||||||
|
$count = 0;
|
||||||
|
foreach ($docs->items() as $ignored) $count++;
|
||||||
|
expect($count)->toBe(2);
|
||||||
|
});
|
||||||
|
test('retrieves ordered matching documents', function () {
|
||||||
|
$docs = Find::byContains(ThrowawayDb::TABLE, ['sub' => ['foo' => 'green']], TestDocument::class,
|
||||||
|
[Field::named('value')]);
|
||||||
|
expect($docs)
|
||||||
|
->not->toBeNull()
|
||||||
|
->and(iterator_to_array($docs->map(fn ($it) => $it->id), false))->toBe(['two', 'four']);
|
||||||
|
});
|
||||||
|
test('returns an empty list when no documents match', function () {
|
||||||
|
expect(Find::byContains(ThrowawayDb::TABLE, ['value' => 'indigo'], TestDocument::class))
|
||||||
|
->not->toBeNull()
|
||||||
|
->hasItems()->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byJsonPath()', function () {
|
||||||
|
test('retrieves matching documents', function () {
|
||||||
|
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull();
|
||||||
|
$count = 0;
|
||||||
|
foreach ($docs->items() as $ignored) $count++;
|
||||||
|
expect($count)->toBe(2);
|
||||||
|
});
|
||||||
|
test('retrieves ordered matching documents', function () {
|
||||||
|
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class,
|
||||||
|
[Field::named('id')]);
|
||||||
|
expect($docs)->not->toBeNull()
|
||||||
|
->and(iterator_to_array($docs->map(fn ($it) => $it->id), false))->toBe(['five', 'four']);
|
||||||
|
});
|
||||||
|
test('returns an empty list when no documents match', function () {
|
||||||
|
expect(Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 100)', TestDocument::class))
|
||||||
|
->not->toBeNull()
|
||||||
|
->hasItems()->toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::firstByFields()', function () {
|
||||||
|
test('retrieves a matching document', function () {
|
||||||
|
expect(Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('value', 'another')], TestDocument::class))
|
||||||
|
->isSome()->toBeTrue()->get()->id->toBe('two');
|
||||||
|
});
|
||||||
|
test('retrieves a document for multiple results', function () {
|
||||||
|
$doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('sub.foo', 'green')], TestDocument::class);
|
||||||
|
expect($doc)->isSome()->toBeTrue()->and(['two', 'four'])->toContain($doc->get()->id);
|
||||||
|
});
|
||||||
|
test('retrieves a document for multiple ordered results', function () {
|
||||||
|
expect(Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('sub.foo', 'green')], TestDocument::class,
|
||||||
|
orderBy: [Field::named('n:num_value DESC')]))
|
||||||
|
->isSome()->toBeTrue()->get()->id->toBe('four');
|
||||||
|
});
|
||||||
|
test('returns None when no documents match', function () {
|
||||||
|
expect(Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('value', 'absent')], TestDocument::class))
|
||||||
|
->isNone()->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::firstByContains()', function () {
|
||||||
|
test('retrieves a matching document', function () {
|
||||||
|
expect(Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'FIRST!'], TestDocument::class))
|
||||||
|
->isSome()->toBeTrue()->get()->id->toBe('one');
|
||||||
|
});
|
||||||
|
test('retrieves a document for multiple results', function () {
|
||||||
|
$doc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'purple'], TestDocument::class);
|
||||||
|
expect($doc)->isSome()->toBeTrue()->and(['four', 'five'])->toContain($doc->get()->id);
|
||||||
|
});
|
||||||
|
test('retrieves a document for multiple ordered results', function () {
|
||||||
|
expect(Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'purple'], TestDocument::class,
|
||||||
|
[Field::named('sub.bar NULLS FIRST')]))
|
||||||
|
->isSome()->toBeTrue()->get()->id->toBe('five');
|
||||||
|
});
|
||||||
|
test('returns None when no documents match', function () {
|
||||||
|
expect(Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'indigo'], TestDocument::class))
|
||||||
|
->isNone()->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::firstByJsonPath()', function () {
|
||||||
|
test('retrieves a matching document', function () {
|
||||||
|
expect(Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ == 10)', TestDocument::class))
|
||||||
|
->isSome()->toBeTrue()->get()->id->toBe('two');
|
||||||
|
});
|
||||||
|
test('retrieves a document for multiple results', function () {
|
||||||
|
$doc = Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class);
|
||||||
|
expect($doc)->isSome()->toBeTrue()->and(['four', 'five'])->toContain($doc->get()->id);
|
||||||
|
});
|
||||||
|
test('retrieves a document for multiple ordered results', function () {
|
||||||
|
expect(Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class,
|
||||||
|
[Field::named('id DESC')]))
|
||||||
|
->isSome()->toBeTrue()->get()->id->toBe('four');
|
||||||
|
});
|
||||||
|
test('returns None when no documents match', function () {
|
||||||
|
expect(Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 100)', TestDocument::class))
|
||||||
|
->isNone()->toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
72
tests/Integration/PostgreSQL/PatchTest.php
Normal file
72
tests/Integration/PostgreSQL/PatchTest.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use BitBadger\PDODocument\{Count, Exists, Field, Find, Patch};
|
||||||
|
use Test\Integration\PostgreSQL\ThrowawayDb;
|
||||||
|
use Test\Integration\TestDocument;
|
||||||
|
|
||||||
|
pest()->group('integration', 'postgresql');
|
||||||
|
|
||||||
|
describe('::byId()', function () {
|
||||||
|
test('updates an existing document', function () {
|
||||||
|
Patch::byId(ThrowawayDb::TABLE, 'one', ['num_value' => 44]);
|
||||||
|
expect(Find::byId(ThrowawayDb::TABLE, 'one', TestDocument::class))
|
||||||
|
->isSome()->toBeTrue()
|
||||||
|
->get()->num_value->toBe(44);
|
||||||
|
});
|
||||||
|
test('does nothing when a document does not exist', function () {
|
||||||
|
$id = 'forty-seven';
|
||||||
|
expect(Exists::byId(ThrowawayDb::TABLE, $id))->toBeFalse();
|
||||||
|
Patch::byId(ThrowawayDb::TABLE, $id, ['foo' => 'green']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byFields()', function () {
|
||||||
|
test('updates existing documents', function () {
|
||||||
|
Patch::byFields(ThrowawayDb::TABLE, [Field::equal('value', 'purple')], ['num_value' => 77]);
|
||||||
|
expect(Count::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 77)]))->toBe(2);
|
||||||
|
});
|
||||||
|
test('does nothing when no matching documents exist', function () {
|
||||||
|
$fields = [Field::equal('value', 'burgundy')];
|
||||||
|
expect(Count::byFields(ThrowawayDb::TABLE, $fields))->toBe(0);
|
||||||
|
Patch::byFields(ThrowawayDb::TABLE, $fields, ['foo' => 'green']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byContains()', function () {
|
||||||
|
test('updates existing documents', function () {
|
||||||
|
Patch::byContains(ThrowawayDb::TABLE, ['value' => 'another'], ['num_value' => 12]);
|
||||||
|
$tryDoc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'another'], TestDocument::class);
|
||||||
|
expect($tryDoc)->isSome()->toBeTrue()
|
||||||
|
->and($tryDoc->get())
|
||||||
|
->id->toBe('two')
|
||||||
|
->num_value->toBe(12);
|
||||||
|
});
|
||||||
|
test('does nothing when no matching documents exist', function () {
|
||||||
|
$criteria = ['value' => 'updated'];
|
||||||
|
expect(Count::byContains(ThrowawayDb::TABLE, $criteria))->toBe(0);
|
||||||
|
Patch::byContains(ThrowawayDb::TABLE, $criteria, ['sub.foo' => 'green']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byJsonPath()', function () {
|
||||||
|
test('updates existing documents', function () {
|
||||||
|
Patch::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', ['value' => 'blue']);
|
||||||
|
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull()->hasItems()->toBeTrue();
|
||||||
|
foreach ($docs->items() as $item) {
|
||||||
|
expect(['four', 'five'])->toContain($item->id)
|
||||||
|
->and($item->value)->toBe('blue');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
test('does nothing when no matching documents exist', function () {
|
||||||
|
$path = '$.num_value ? (@ > 100)';
|
||||||
|
expect(Count::byJsonPath(ThrowawayDb::TABLE, $path))->toBe(0);
|
||||||
|
Patch::byJsonPath(ThrowawayDb::TABLE, $path, ['value' => 'blue']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
91
tests/Integration/PostgreSQL/RemoveFieldsTest.php
Normal file
91
tests/Integration/PostgreSQL/RemoveFieldsTest.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use BitBadger\PDODocument\{Exists, Field, Find, RemoveFields};
|
||||||
|
use Test\Integration\PostgreSQL\ThrowawayDb;
|
||||||
|
use Test\Integration\TestDocument;
|
||||||
|
|
||||||
|
pest()->group('integration', 'postgresql');
|
||||||
|
|
||||||
|
describe('::byId()', function () {
|
||||||
|
test('removes fields', function () {
|
||||||
|
RemoveFields::byId(ThrowawayDb::TABLE, 'two', ['sub', 'value']);
|
||||||
|
$tryDoc = Find::byId(ThrowawayDb::TABLE, 'two', TestDocument::class);
|
||||||
|
expect($tryDoc)->isSome()->toBeTrue();
|
||||||
|
$doc = $tryDoc->get();
|
||||||
|
expect($doc)->sub->toBeNull()
|
||||||
|
->and($doc->value)->toBeEmpty();
|
||||||
|
});
|
||||||
|
test('does nothing when the field to remove does not exist', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::exists('a_field_that_does_not_exist')]))->toBeFalse();
|
||||||
|
RemoveFields::byId(ThrowawayDb::TABLE, 'one', ['a_field_that_does_not_exist']); // no exception = pass
|
||||||
|
});
|
||||||
|
test('does nothing when the document does not exist', function () {
|
||||||
|
expect(Exists::byId(ThrowawayDb::TABLE, 'fifty'))->toBeFalse();
|
||||||
|
RemoveFields::byId(ThrowawayDb::TABLE, 'fifty', ['sub']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byFields()', function () {
|
||||||
|
test('removes fields from matching documents', function () {
|
||||||
|
RemoveFields::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], ['sub']);
|
||||||
|
expect(Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], TestDocument::class))
|
||||||
|
->isSome()->toBeTrue()
|
||||||
|
->get()->sub->toBeNull();
|
||||||
|
});
|
||||||
|
test('does nothing when the field to remove does not exist', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::exists('nada')]))->toBeFalse();
|
||||||
|
RemoveFields::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], ['nada']); // no exception = pass
|
||||||
|
});
|
||||||
|
test('does nothing when no documents match', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::notEqual('missing', 'nope')]))->toBeFalse();
|
||||||
|
RemoveFields::byFields(ThrowawayDb::TABLE, [Field::notEqual('missing', 'nope')], ['value']); // no exn = pass
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byContains()', function () {
|
||||||
|
test('removes fields from matching documents', function () {
|
||||||
|
$criteria = ['sub' => ['foo' => 'green']];
|
||||||
|
RemoveFields::byContains(ThrowawayDb::TABLE, $criteria, ['value']);
|
||||||
|
$docs = Find::byContains(ThrowawayDb::TABLE, $criteria, TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull()->hasItems()->toBeTrue();
|
||||||
|
foreach ($docs->items() as $item) {
|
||||||
|
expect(['two', 'four'])->toContain($item->id)
|
||||||
|
->and($item->value)->toBeEmpty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
test('does nothing when the field to remove does not exist', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::exists('invalid_field')]))->toBeFalse();
|
||||||
|
RemoveFields::byContains(ThrowawayDb::TABLE, ['sub' => ['foo' => 'green']], ['invalid_field']); // no exn = pass
|
||||||
|
});
|
||||||
|
test('does nothing when no documents match', function () {
|
||||||
|
expect(Exists::byContains(ThrowawayDb::TABLE, ['value' => 'substantial']))->toBeFalse();
|
||||||
|
RemoveFields::byContains(ThrowawayDb::TABLE, ['value' => 'substantial'], ['num_value']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('::byJsonPath()', function () {
|
||||||
|
test('removes fields from matching documents', function () {
|
||||||
|
$path = '$.value ? (@ == "purple")';
|
||||||
|
RemoveFields::byJsonPath(ThrowawayDb::TABLE, $path, ['sub']);
|
||||||
|
$docs = Find::byJsonPath(ThrowawayDb::TABLE, $path, TestDocument::class);
|
||||||
|
expect($docs)->not->toBeNull()->hasItems()->toBeTrue();
|
||||||
|
foreach ($docs->items() as $item) {
|
||||||
|
expect(['four', 'five'])->toContain($item->id)
|
||||||
|
->and($item->sub)->toBeNull();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
test('does nothing when the field to remove does not exist', function () {
|
||||||
|
expect(Exists::byFields(ThrowawayDb::TABLE, [Field::exists('submarine')]))->toBeFalse();
|
||||||
|
RemoveFields::byJsonPath(ThrowawayDb::TABLE, '$.value ? (@ == "purple")', ['submarine']); // no exception = pass
|
||||||
|
});
|
||||||
|
test('does nothing when no documents match', function () {
|
||||||
|
expect(Exists::byJsonPath(ThrowawayDb::TABLE, '$.value ? (@ == "mauve")'))->toBeFalse();
|
||||||
|
RemoveFields::byJsonPath(ThrowawayDb::TABLE, '$.value ? (@ == "mauve")', ['value']); // no exception = pass
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,90 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Test\Integration\PostgreSQL;
|
|
||||||
|
|
||||||
use BitBadger\PDODocument\{Exists, Field};
|
|
||||||
use PHPUnit\Framework\Attributes\TestDox;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PostgreSQL integration tests for the Exists class
|
|
||||||
*/
|
|
||||||
#[TestDox('Exists (PostgreSQL integration)')]
|
|
||||||
class ExistsTest extends TestCase
|
|
||||||
{
|
|
||||||
/** @var string Database name for throwaway database */
|
|
||||||
private string $dbName;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->dbName = ThrowawayDb::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown(): void
|
|
||||||
{
|
|
||||||
ThrowawayDb::destroy($this->dbName);
|
|
||||||
parent::tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a document exists')]
|
|
||||||
public function testByIdSucceedsWhenADocumentExists(): void
|
|
||||||
{
|
|
||||||
$this->assertTrue(Exists::byId(ThrowawayDb::TABLE, 'three'), 'There should have been an existing document');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a document does not exist')]
|
|
||||||
public function testByIdSucceedsWhenADocumentDoesNotExist(): void
|
|
||||||
{
|
|
||||||
$this->assertFalse(Exists::byId(ThrowawayDb::TABLE, 'seven'),
|
|
||||||
'There should not have been an existing document');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when documents exist')]
|
|
||||||
public function testByFieldsSucceedsWhenDocumentsExist(): void
|
|
||||||
{
|
|
||||||
$this->assertTrue(Exists::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 10)]),
|
|
||||||
'There should have been existing documents');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when no matching documents exist')]
|
|
||||||
public function testByFieldsSucceedsWhenNoMatchingDocumentsExist(): void
|
|
||||||
{
|
|
||||||
$this->assertFalse(Exists::byFields(ThrowawayDb::TABLE, [Field::less('nothing', 'none')]),
|
|
||||||
'There should not have been any existing documents');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when documents exist')]
|
|
||||||
public function testByContainsSucceedsWhenDocumentsExist(): void
|
|
||||||
{
|
|
||||||
$this->assertTrue(Exists::byContains(ThrowawayDb::TABLE, ['value' => 'purple']),
|
|
||||||
'There should have been existing documents');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when no matching documents exist')]
|
|
||||||
public function testByContainsSucceedsWhenNoMatchingDocumentsExist(): void
|
|
||||||
{
|
|
||||||
$this->assertFalse(Exists::byContains(ThrowawayDb::TABLE, ['value' => 'violet']),
|
|
||||||
'There should not have been existing documents');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when documents exist')]
|
|
||||||
public function testByJsonPathSucceedsWhenDocumentsExist(): void
|
|
||||||
{
|
|
||||||
$this->assertTrue(Exists::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ == 10)'),
|
|
||||||
'There should have been existing documents');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when no matching documents exist')]
|
|
||||||
public function testByJsonPathSucceedsWhenNoMatchingDocumentsExist(): void
|
|
||||||
{
|
|
||||||
$this->assertFalse(Exists::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ == 10.1)'),
|
|
||||||
'There should have been existing documents');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,323 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Test\Integration\PostgreSQL;
|
|
||||||
|
|
||||||
use BitBadger\PDODocument\{Custom, Delete, Document, Field, FieldMatch, Find};
|
|
||||||
use PHPUnit\Framework\Attributes\TestDox;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Test\Integration\{ArrayDocument, NumDocument, TestDocument};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PostgreSQL integration tests for the Find class
|
|
||||||
*/
|
|
||||||
#[TestDox('Find (PostgreSQL integration)')]
|
|
||||||
class FindTest extends TestCase
|
|
||||||
{
|
|
||||||
/** @var string Database name for throwaway database */
|
|
||||||
private string $dbName;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->dbName = ThrowawayDb::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown(): void
|
|
||||||
{
|
|
||||||
ThrowawayDb::destroy($this->dbName);
|
|
||||||
parent::tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('all() succeeds when there is data')]
|
|
||||||
public function testAllSucceedsWhenThereIsData(): void
|
|
||||||
{
|
|
||||||
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$count = 0;
|
|
||||||
foreach ($docs->items() as $ignored) $count++;
|
|
||||||
$this->assertEquals(5, $count, 'There should have been 5 documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('all() succeeds when ordering data ascending')]
|
|
||||||
public function testAllSucceedsWhenOrderingDataAscending(): void
|
|
||||||
{
|
|
||||||
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class, [Field::named('id')]);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$ids = iterator_to_array($docs->map(fn ($it) => $it->id), false);
|
|
||||||
$this->assertEquals(['five', 'four', 'one', 'three', 'two'], $ids, 'The documents were not ordered correctly');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('all() succeeds when ordering data descending')]
|
|
||||||
public function testAllSucceedsWhenOrderingDataDescending(): void
|
|
||||||
{
|
|
||||||
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class, [Field::named('id DESC')]);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$ids = iterator_to_array($docs->map(fn ($it) => $it->id), false);
|
|
||||||
$this->assertEquals(['two', 'three', 'one', 'four', 'five'], $ids, 'The documents were not ordered correctly');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('all() succeeds when ordering data numerically')]
|
|
||||||
public function testAllSucceedsWhenOrderingDataNumerically(): void
|
|
||||||
{
|
|
||||||
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class,
|
|
||||||
[Field::named('sub.foo NULLS LAST'), Field::named('n:num_value')]);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$ids = iterator_to_array($docs->map(fn ($it) => $it->id), false);
|
|
||||||
$this->assertEquals(['two', 'four', 'one', 'three', 'five'], $ids, 'The documents were not ordered correctly');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('all() succeeds when there is no data')]
|
|
||||||
public function testAllSucceedsWhenThereIsNoData(): void
|
|
||||||
{
|
|
||||||
Custom::nonQuery('DELETE FROM ' . ThrowawayDb::TABLE, []);
|
|
||||||
$docs = Find::all(ThrowawayDb::TABLE, TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertFalse($docs->hasItems(), 'There should have been no documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a document is found')]
|
|
||||||
public function testByIdSucceedsWhenADocumentIsFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::byId(ThrowawayDb::TABLE, 'two', TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('two', $doc->get()->id, 'An incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a document is found with numeric ID')]
|
|
||||||
public function testByIdSucceedsWhenADocumentIsFoundWithNumericId(): void
|
|
||||||
{
|
|
||||||
Delete::byFields(ThrowawayDb::TABLE, [Field::notExists('absent')]);
|
|
||||||
Document::insert(ThrowawayDb::TABLE, ['id' => 18, 'value' => 'howdy']);
|
|
||||||
$doc = Find::byId(ThrowawayDb::TABLE, 18, NumDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals(18, $doc->get()->id, 'An incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a document is not found')]
|
|
||||||
public function testByIdSucceedsWhenADocumentIsNotFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::byId(ThrowawayDb::TABLE, 'seventy-five', TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isNone(), 'There should not have been a document returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when documents are found')]
|
|
||||||
public function testByFieldsSucceedsWhenDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::in('value', ['blue', 'purple']), Field::exists('sub')],
|
|
||||||
TestDocument::class, FieldMatch::All);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$count = 0;
|
|
||||||
foreach ($docs->items() as $ignored) $count++;
|
|
||||||
$this->assertEquals(1, $count, 'There should have been 1 document in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when documents are found and ordered')]
|
|
||||||
public function testByFieldsSucceedsWhenDocumentsAreFoundAndOrdered(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::equal('value', 'purple')], TestDocument::class,
|
|
||||||
FieldMatch::All, [Field::named('id')]);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$ids = iterator_to_array($docs->map(fn ($it) => $it->id), false);
|
|
||||||
$this->assertEquals(['five', 'four'], $ids, 'The documents were not ordered correctly');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when documents are found using IN with numeric field')]
|
|
||||||
public function testByFieldsSucceedsWhenDocumentsAreFoundUsingInWithNumericField(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::in('num_value', [2, 4, 6, 8])], TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$count = 0;
|
|
||||||
foreach ($docs->items() as $ignored) $count++;
|
|
||||||
$this->assertEquals(1, $count, 'There should have been 1 document in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when no documents are found')]
|
|
||||||
public function testByFieldsSucceedsWhenNoDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::greater('num_value', 100)], TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertFalse($docs->hasItems(), 'There should have been no documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds for inArray when matching documents exist')]
|
|
||||||
public function testByFieldsSucceedsForInArrayWhenMatchingDocumentsExist(): void
|
|
||||||
{
|
|
||||||
Delete::byFields(ThrowawayDb::TABLE, [Field::notExists('absentField')]);
|
|
||||||
foreach (ArrayDocument::testDocuments() as $doc) Document::insert(ThrowawayDb::TABLE, $doc);
|
|
||||||
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::inArray('values', ThrowawayDb::TABLE, ['c'])],
|
|
||||||
ArrayDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$count = 0;
|
|
||||||
foreach ($docs->items() as $ignored) $count++;
|
|
||||||
$this->assertEquals(2, $count, 'There should have been 2 documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds for inArray when no matching documents exist')]
|
|
||||||
public function testByFieldsSucceedsForInArrayWhenNoMatchingDocumentsExist(): void
|
|
||||||
{
|
|
||||||
Delete::byFields(ThrowawayDb::TABLE, [Field::notExists('absentField')]);
|
|
||||||
foreach (ArrayDocument::testDocuments() as $doc) Document::insert(ThrowawayDb::TABLE, $doc);
|
|
||||||
$docs = Find::byFields(ThrowawayDb::TABLE, [Field::inArray('values', ThrowawayDb::TABLE, ['j'])],
|
|
||||||
ArrayDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertFalse($docs->hasItems(), 'There should have been no documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when documents are found')]
|
|
||||||
public function testByContainsSucceedsWhenDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byContains(ThrowawayDb::TABLE, ['value' => 'purple'], TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$count = 0;
|
|
||||||
foreach ($docs->items() as $ignored) $count++;
|
|
||||||
$this->assertEquals(2, $count, 'There should have been 2 documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when documents are found and ordered')]
|
|
||||||
public function testByContainsSucceedsWhenDocumentsAreFoundAndOrdered(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byContains(ThrowawayDb::TABLE, ['sub' => ['foo' => 'green']], TestDocument::class,
|
|
||||||
[Field::named('value')]);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$ids = iterator_to_array($docs->map(fn ($it) => $it->id), false);
|
|
||||||
$this->assertEquals(['two', 'four'], $ids, 'The documents were not ordered correctly');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when no documents are found')]
|
|
||||||
public function testByContainsSucceedsWhenNoDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byContains(ThrowawayDb::TABLE, ['value' => 'indigo'], TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertFalse($docs->hasItems(), 'The document list should be empty');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when documents are found')]
|
|
||||||
public function testByJsonPathSucceedsWhenDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$count = 0;
|
|
||||||
foreach ($docs->items() as $ignored) $count++;
|
|
||||||
$this->assertEquals(2, $count, 'There should have been 2 documents in the list');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when documents are found and ordered')]
|
|
||||||
public function testByJsonPathSucceedsWhenDocumentsAreFoundAndOrdered(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class,
|
|
||||||
[Field::named('id')]);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$ids = iterator_to_array($docs->map(fn ($it) => $it->id), false);
|
|
||||||
$this->assertEquals(['five', 'four'], $ids, 'The documents were not ordered correctly');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when no documents are found')]
|
|
||||||
public function testByJsonPathSucceedsWhenNoDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 100)', TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertFalse($docs->hasItems(), 'The document list should be empty');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByFields() succeeds when a document is found')]
|
|
||||||
public function testFirstByFieldsSucceedsWhenADocumentIsFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('value', 'another')], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('two', $doc->get()->id, 'The incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByFields() succeeds when multiple documents are found')]
|
|
||||||
public function testFirstByFieldsSucceedsWhenMultipleDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('sub.foo', 'green')], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertContains($doc->get()->id, ['two', 'four'], 'An incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByFields() succeeds when multiple ordered documents are found')]
|
|
||||||
public function testFirstByFieldsSucceedsWhenMultipleOrderedDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('sub.foo', 'green')], TestDocument::class,
|
|
||||||
orderBy: [Field::named('n:num_value DESC')]);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('four', $doc->get()->id, 'The incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByFields() succeeds when a document is not found')]
|
|
||||||
public function testFirstByFieldsSucceedsWhenADocumentIsNotFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('value', 'absent')], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isNone(), 'There should not have been a document returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByContains() succeeds when a document is found')]
|
|
||||||
public function testFirstByContainsSucceedsWhenADocumentIsFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'FIRST!'], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('one', $doc->get()->id, 'The incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByContains() succeeds when multiple documents are found')]
|
|
||||||
public function testFirstByContainsSucceedsWhenMultipleDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'purple'], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertContains($doc->get()->id, ['four', 'five'], 'An incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByContains() succeeds when multiple ordered documents are found')]
|
|
||||||
public function testFirstByContainsSucceedsWhenMultipleOrderedDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'purple'], TestDocument::class,
|
|
||||||
[Field::named('sub.bar NULLS FIRST')]);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('five', $doc->get()->id, 'The incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByContains() succeeds when a document is not found')]
|
|
||||||
public function testFirstByContainsSucceedsWhenADocumentIsNotFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'indigo'], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isNone(), 'There should not have been a document returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByJsonPath() succeeds when a document is found')]
|
|
||||||
public function testFirstByJsonPathSucceedsWhenADocumentIsFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ == 10)', TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('two', $doc->get()->id, 'The incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByJsonPath() succeeds when multiple documents are found')]
|
|
||||||
public function testFirstByJsonPathSucceedsWhenMultipleDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertContains($doc->get()->id, ['four', 'five'], 'An incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByJsonPath() succeeds when multiple ordered documents are found')]
|
|
||||||
public function testFirstByJsonPathSucceedsWhenMultipleOrderedDocumentsAreFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class,
|
|
||||||
[Field::named('id DESC')]);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals('four', $doc->get()->id, 'The incorrect document was returned');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('firstByJsonPath() succeeds when a document is not found')]
|
|
||||||
public function testFirstByJsonPathSucceedsWhenADocumentIsNotFound(): void
|
|
||||||
{
|
|
||||||
$doc = Find::firstByJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 100)', TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isNone(), 'There should not have been a document returned');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Test\Integration\PostgreSQL;
|
|
||||||
|
|
||||||
use BitBadger\PDODocument\{Count, Exists, Field, Find, Patch};
|
|
||||||
use PHPUnit\Framework\Attributes\TestDox;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Test\Integration\TestDocument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PostgreSQL integration tests for the Patch class
|
|
||||||
*/
|
|
||||||
#[TestDox('Patch (PostgreSQL integration)')]
|
|
||||||
class PatchTest extends TestCase
|
|
||||||
{
|
|
||||||
/** @var string Database name for throwaway database */
|
|
||||||
private string $dbName;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->dbName = ThrowawayDb::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown(): void
|
|
||||||
{
|
|
||||||
ThrowawayDb::destroy($this->dbName);
|
|
||||||
parent::tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a document is updated')]
|
|
||||||
public function testByIdSucceedsWhenADocumentIsUpdated(): void
|
|
||||||
{
|
|
||||||
Patch::byId(ThrowawayDb::TABLE, 'one', ['num_value' => 44]);
|
|
||||||
$doc = Find::byId(ThrowawayDb::TABLE, 'one', TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertEquals(44, $doc->get()->num_value, 'The updated document is not correct');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when no document is updated')]
|
|
||||||
public function testByIdSucceedsWhenNoDocumentIsUpdated(): void
|
|
||||||
{
|
|
||||||
$id = 'forty-seven';
|
|
||||||
$this->assertFalse(Exists::byId(ThrowawayDb::TABLE, $id), 'The document should not exist');
|
|
||||||
Patch::byId(ThrowawayDb::TABLE, $id, ['foo' => 'green']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when a document is updated')]
|
|
||||||
public function testByFieldsSucceedsWhenADocumentIsUpdated(): void
|
|
||||||
{
|
|
||||||
Patch::byFields(ThrowawayDb::TABLE, [Field::equal('value', 'purple')], ['num_value' => 77]);
|
|
||||||
$after = Count::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 77)]);
|
|
||||||
$this->assertEquals(2, $after, 'There should have been 2 documents updated');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when no document is updated')]
|
|
||||||
public function testByFieldsSucceedsWhenNoDocumentIsUpdated(): void
|
|
||||||
{
|
|
||||||
$fields = [Field::equal('value', 'burgundy')];
|
|
||||||
$this->assertEquals(0, Count::byFields(ThrowawayDb::TABLE, $fields), 'There should be no matching documents');
|
|
||||||
Patch::byFields(ThrowawayDb::TABLE, $fields, ['foo' => 'green']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when documents are updated')]
|
|
||||||
public function testByContainsSucceedsWhenDocumentsAreUpdated(): void
|
|
||||||
{
|
|
||||||
Patch::byContains(ThrowawayDb::TABLE, ['value' => 'another'], ['num_value' => 12]);
|
|
||||||
$tryDoc = Find::firstByContains(ThrowawayDb::TABLE, ['value' => 'another'], TestDocument::class);
|
|
||||||
$this->assertTrue($tryDoc->isSome(), 'There should have been a document returned');
|
|
||||||
$doc = $tryDoc->get();
|
|
||||||
$this->assertEquals('two', $doc->id, 'An incorrect document was returned');
|
|
||||||
$this->assertEquals(12, $doc->num_value, 'The document was not patched');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when no documents are updated')]
|
|
||||||
public function testByContainsSucceedsWhenNoDocumentsAreUpdated(): void
|
|
||||||
{
|
|
||||||
$criteria = ['value' => 'updated'];
|
|
||||||
$this->assertEquals(0, Count::byContains(ThrowawayDb::TABLE, $criteria),
|
|
||||||
'There should be no matching documents');
|
|
||||||
Patch::byContains(ThrowawayDb::TABLE, $criteria, ['sub.foo' => 'green']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when documents are updated')]
|
|
||||||
public function testByJsonPathSucceedsWhenDocumentsAreUpdated(): void
|
|
||||||
{
|
|
||||||
Patch::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', ['value' => 'blue']);
|
|
||||||
$docs = Find::byJsonPath(ThrowawayDb::TABLE, '$.num_value ? (@ > 10)', TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertTrue($docs->hasItems(), 'The document list should not be empty');
|
|
||||||
foreach ($docs->items() as $item) {
|
|
||||||
$this->assertContains($item->id, ['four', 'five'], 'An incorrect document was returned');
|
|
||||||
$this->assertEquals('blue', $item->value, 'The document was not patched');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when documents are not updated')]
|
|
||||||
public function testByJsonPathSucceedsWhenDocumentsAreNotUpdated(): void
|
|
||||||
{
|
|
||||||
$path = '$.num_value ? (@ > 100)';
|
|
||||||
$this->assertEquals(0, Count::byJsonPath(ThrowawayDb::TABLE, $path),
|
|
||||||
'There should be no documents matching this path');
|
|
||||||
Patch::byJsonPath(ThrowawayDb::TABLE, $path, ['value' => 'blue']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Test\Integration\PostgreSQL;
|
|
||||||
|
|
||||||
use BitBadger\PDODocument\{Field, Find, RemoveFields};
|
|
||||||
use PHPUnit\Framework\Attributes\TestDox;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Test\Integration\TestDocument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PostgreSQL integration tests for the RemoveFields class
|
|
||||||
*/
|
|
||||||
#[TestDox('Remove Fields (PostgreSQL integration)')]
|
|
||||||
class RemoveFieldsTest extends TestCase
|
|
||||||
{
|
|
||||||
/** @var string Database name for throwaway database */
|
|
||||||
private string $dbName;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
$this->dbName = ThrowawayDb::create();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function tearDown(): void
|
|
||||||
{
|
|
||||||
ThrowawayDb::destroy($this->dbName);
|
|
||||||
parent::tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when fields are removed')]
|
|
||||||
public function testByIdSucceedsWhenFieldsAreRemoved(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byId(ThrowawayDb::TABLE, 'two', ['sub', 'value']);
|
|
||||||
$tryDoc = Find::byId(ThrowawayDb::TABLE, 'two', TestDocument::class);
|
|
||||||
$this->assertTrue($tryDoc->isSome(), 'There should have been a document returned');
|
|
||||||
$doc = $tryDoc->get();
|
|
||||||
$this->assertEquals('', $doc->value, 'Value should have been blank (its default value)');
|
|
||||||
$this->assertNull($doc->sub, 'Sub-document should have been null');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when a field is not removed')]
|
|
||||||
public function testByIdSucceedsWhenAFieldIsNotRemoved(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byId(ThrowawayDb::TABLE, 'one', ['a_field_that_does_not_exist']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byId() succeeds when no document is matched')]
|
|
||||||
public function testByIdSucceedsWhenNoDocumentIsMatched(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byId(ThrowawayDb::TABLE, 'fifty', ['sub']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when a field is removed')]
|
|
||||||
public function testByFieldsSucceedsWhenAFieldIsRemoved(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], ['sub']);
|
|
||||||
$doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], TestDocument::class);
|
|
||||||
$this->assertTrue($doc->isSome(), 'There should have been a document returned');
|
|
||||||
$this->assertNull($doc->get()->sub, 'Sub-document should have been null');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when a field is not removed')]
|
|
||||||
public function testByFieldsSucceedsWhenAFieldIsNotRemoved(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], ['nada']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byFields() succeeds when no document is matched')]
|
|
||||||
public function testByFieldsSucceedsWhenNoDocumentIsMatched(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byFields(ThrowawayDb::TABLE, [Field::notEqual('missing', 'nope')], ['value']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when a field is removed')]
|
|
||||||
public function testByContainsSucceedsWhenAFieldIsRemoved(): void
|
|
||||||
{
|
|
||||||
$criteria = ['sub' => ['foo' => 'green']];
|
|
||||||
RemoveFields::byContains(ThrowawayDb::TABLE, $criteria, ['value']);
|
|
||||||
$docs = Find::byContains(ThrowawayDb::TABLE, $criteria, TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertTrue($docs->hasItems(), 'The document list should not have been empty');
|
|
||||||
foreach ($docs->items() as $item) {
|
|
||||||
$this->assertContains($item->id, ['two', 'four'], 'An incorrect document was returned');
|
|
||||||
$this->assertEquals('', $item->value, 'The value field was not removed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when a field is not removed')]
|
|
||||||
public function testByContainsSucceedsWhenAFieldIsNotRemoved(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byContains(ThrowawayDb::TABLE, ['sub' => ['foo' => 'green']], ['invalid_field']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byContains() succeeds when no document is matched')]
|
|
||||||
public function testByContainsSucceedsWhenNoDocumentIsMatched(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byContains(ThrowawayDb::TABLE, ['value' => 'substantial'], ['num_value']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when a field is removed')]
|
|
||||||
public function testByJsonPathSucceedsWhenAFieldIsRemoved(): void
|
|
||||||
{
|
|
||||||
$path = '$.value ? (@ == "purple")';
|
|
||||||
RemoveFields::byJsonPath(ThrowawayDb::TABLE, $path, ['sub']);
|
|
||||||
$docs = Find::byJsonPath(ThrowawayDb::TABLE, $path, TestDocument::class);
|
|
||||||
$this->assertNotNull($docs, 'There should have been a document list returned');
|
|
||||||
$this->assertTrue($docs->hasItems(), 'The document list should not have been empty');
|
|
||||||
foreach ($docs->items() as $item) {
|
|
||||||
$this->assertContains($item->id, ['four', 'five'], 'An incorrect document was returned');
|
|
||||||
$this->assertNull($item->sub, 'The sub field was not removed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when a field is not removed')]
|
|
||||||
public function testByJsonPathSucceedsWhenAFieldIsNotRemoved(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byJsonPath(ThrowawayDb::TABLE, '$.value ? (@ == "purple")', ['submarine']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
|
|
||||||
#[TestDox('byJsonPath() succeeds when no document is matched')]
|
|
||||||
public function testByJsonPathSucceedsWhenNoDocumentIsMatched(): void
|
|
||||||
{
|
|
||||||
RemoveFields::byJsonPath(ThrowawayDb::TABLE, '$.value ? (@ == "mauve")', ['value']);
|
|
||||||
$this->assertTrue(true, 'The above not throwing an exception is the test');
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user