WIP on Pest test migration
This commit is contained in:
		
							parent
							
								
									df436c9ef4
								
							
						
					
					
						commit
						b48a2a9bf9
					
				| @ -25,9 +25,9 @@ | ||||
|     "ext-pdo": "*" | ||||
|   }, | ||||
|   "require-dev": { | ||||
|     "phpunit/phpunit": "^11", | ||||
|     "square/pjson": "^0.5.0", | ||||
|     "phpstan/phpstan": "^1.12" | ||||
|     "phpstan/phpstan": "^1.12", | ||||
|     "pestphp/pest": "^3.2" | ||||
|   }, | ||||
|   "autoload": { | ||||
|     "psr-4": { | ||||
| @ -47,5 +47,10 @@ | ||||
|   }, | ||||
|   "archive": { | ||||
|     "exclude": [ "/tests", "/.gitattributes", "/.gitignore", "/.git", "/composer.lock" ] | ||||
|   }, | ||||
|   "config": { | ||||
|     "allow-plugins": { | ||||
|       "pestphp/pest-plugin": true | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										2108
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2108
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										18
									
								
								phpunit.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								phpunit.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd" | ||||
|          bootstrap="vendor/autoload.php" | ||||
|          colors="true" | ||||
| > | ||||
|     <testsuites> | ||||
|         <testsuite name="Test Suite"> | ||||
|             <directory suffix="Test.php">./tests</directory> | ||||
|         </testsuite> | ||||
|     </testsuites> | ||||
|     <source> | ||||
|         <include> | ||||
|             <directory suffix=".php">./app</directory> | ||||
|             <directory suffix=".php">./src</directory> | ||||
|         </include> | ||||
|     </source> | ||||
| </phpunit> | ||||
| @ -9,12 +9,13 @@ declare(strict_types=1); | ||||
| namespace BitBadger\PDODocument; | ||||
| 
 | ||||
| use Exception; | ||||
| use Stringable; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Exceptions occurring during document processing | ||||
|  */ | ||||
| class DocumentException extends Exception | ||||
| class DocumentException extends Exception implements Stringable | ||||
| { | ||||
|     /** | ||||
|      * Constructor | ||||
|  | ||||
							
								
								
									
										5
									
								
								tests/Feature/ExampleTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/Feature/ExampleTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| <?php | ||||
| 
 | ||||
| test('example', function () { | ||||
|     expect(true)->toBeTrue(); | ||||
| }); | ||||
							
								
								
									
										53
									
								
								tests/Pest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/Pest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
| |-------------------------------------------------------------------------- | ||||
| | Test Case | ||||
| |-------------------------------------------------------------------------- | ||||
| | | ||||
| | The closure you provide to your test functions is always bound to a specific PHPUnit test | ||||
| | case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may | ||||
| | need to change it using the "pest()" function to bind a different classes or traits. | ||||
| | | ||||
| */ | ||||
| 
 | ||||
| // pest()->extend(Tests\TestCase::class)->in('Feature');
 | ||||
| 
 | ||||
| /* | ||||
| |-------------------------------------------------------------------------- | ||||
| | Expectations | ||||
| |-------------------------------------------------------------------------- | ||||
| | | ||||
| | When you're writing tests, you often need to check that values meet certain conditions. The | ||||
| | "expect()" function gives you access to a set of "expectations" methods that you can use | ||||
| | to assert different things. Of course, you may extend the Expectation API at any time. | ||||
| | | ||||
| */ | ||||
| 
 | ||||
| expect()->extend('toBeOne', function () { | ||||
|     return $this->toBe(1); | ||||
| }); | ||||
| 
 | ||||
| /* | ||||
| |-------------------------------------------------------------------------- | ||||
| | Functions | ||||
| |-------------------------------------------------------------------------- | ||||
| | | ||||
| | While Pest is very powerful out-of-the-box, you may have some testing code specific to your | ||||
| | project that you don't want to repeat in every file. Here you can also expose helpers as | ||||
| | global functions to help you to reduce the number of lines of code in your test files. | ||||
| | | ||||
| */ | ||||
| 
 | ||||
| /** | ||||
|  * Reset the database mode | ||||
|  */ | ||||
| function reset_mode(): void | ||||
| { | ||||
|     \BitBadger\PDODocument\Configuration::overrideMode(null); | ||||
| } | ||||
| 
 | ||||
| function something() | ||||
| { | ||||
|     // ..
 | ||||
| } | ||||
							
								
								
									
										10
									
								
								tests/TestCase.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/TestCase.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Tests; | ||||
| 
 | ||||
| use PHPUnit\Framework\TestCase as BaseTestCase; | ||||
| 
 | ||||
| abstract class TestCase extends BaseTestCase | ||||
| { | ||||
|     //
 | ||||
| } | ||||
							
								
								
									
										36
									
								
								tests/Unit/ConfigurationTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								tests/Unit/ConfigurationTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\{AutoId, Configuration, DocumentException}; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('::$idField', function () { | ||||
|     test('has expected default value', function () { | ||||
|         expect(Configuration::$idField)->toBe('id'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::$autoId', function () { | ||||
|     test('has expected default value', function () { | ||||
|         expect(Configuration::$autoId)->toBe(AutoId::None); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::$idStringLength', function () { | ||||
|     test('has expected default value', function () { | ||||
|         expect(Configuration::$idStringLength)->toBe(16); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::dbConn()', function () { | ||||
|     test('throws if DSN has not been set', function () { | ||||
|         Configuration::useDSN(''); | ||||
|         expect(fn() => Configuration::dbConn())->toThrow(DocumentException::class); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										40
									
								
								tests/Unit/DocumentExceptionTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/Unit/DocumentExceptionTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\DocumentException; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('Constructor', function () { | ||||
|     test('fills code and prior exception if provided', function () { | ||||
|         $priorEx = new Exception('Uh oh'); | ||||
|         expect(new DocumentException('Test Exception', 17, $priorEx)) | ||||
|             ->not->toBeNull() | ||||
|             ->getMessage()->toBe('Test Exception') | ||||
|             ->getCode()->toBe(17) | ||||
|             ->getPrevious()->toBe($priorEx); | ||||
|     }); | ||||
|     test('uses expected code and prior exception if not provided', function () { | ||||
|         expect(new DocumentException('Oops')) | ||||
|             ->not->toBeNull() | ||||
|             ->getMessage()->toBe('Oops') | ||||
|             ->getCode()->toBe(0) | ||||
|             ->getPrevious()->toBeNull(); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('->__toString()', function () { | ||||
|     test('excludes code if 0', function () { | ||||
|         $ex = new DocumentException('Test failure'); | ||||
|         expect("$ex")->toBe("BitBadger\PDODocument\DocumentException: Test failure\n"); | ||||
|     }); | ||||
|     test('includes code if non-zero', function () { | ||||
|         $ex = new DocumentException('Oof', -6); | ||||
|         expect("$ex")->toBe("BitBadger\PDODocument\DocumentException: [-6] Oof\n"); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										20
									
								
								tests/Unit/FieldMatchTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tests/Unit/FieldMatchTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\FieldMatch; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('->toSQL()', function () { | ||||
|     test('returns AND for All', function () { | ||||
|         expect(FieldMatch::All)->toSQL()->toBe('AND'); | ||||
|     }); | ||||
|     test('returns OR for Any', function () { | ||||
|         expect(FieldMatch::Any)->toSQL()->toBe('OR'); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										418
									
								
								tests/Unit/FieldTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										418
									
								
								tests/Unit/FieldTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,418 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\{Configuration, Field, Mode, Op}; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('->appendParameter()', function () { | ||||
|     afterEach(function () { Configuration::overrideMode(null); }); | ||||
|     test('appends no parameter for exists', function () { | ||||
|         expect(Field::exists('exists')->appendParameter([]))->toBeEmpty(); | ||||
|     }); | ||||
|     test('appends no parameter for notExists', function () { | ||||
|         expect(Field::notExists('absent')->appendParameter([]))->toBeEmpty(); | ||||
|     }); | ||||
|     test('appends two parameters for between', function () { | ||||
|         expect(Field::between('exists', 5, 9, '@num')->appendParameter([])) | ||||
|             ->toHaveLength(2) | ||||
|             ->toEqual(['@nummin' => 5, '@nummax' => 9]); | ||||
|     }); | ||||
|     test('appends a parameter for each value for in', function () { | ||||
|         expect(Field::in('it', ['test', 'unit', 'great'], ':val')->appendParameter([])) | ||||
|             ->toHaveLength(3) | ||||
|             ->toEqual([':val_0' => 'test', ':val_1' => 'unit', ':val_2' => 'great']); | ||||
|     }); | ||||
|     test('appends a parameter for each value for inArray [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::inArray('it', 'table', [2, 8, 64], ':bit')->appendParameter([])) | ||||
|             ->toHaveLength(3) | ||||
|             ->toEqual([':bit_0' => '2', ':bit_1' => '8', ':bit_2' => '64']); | ||||
|     })->group('postgresql'); | ||||
|     test('appends a parameter for each value for inArray [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::inArray('it', 'table', [2, 8, 64], ':bit')->appendParameter([])) | ||||
|             ->toHaveLength(3) | ||||
|             ->toEqual([':bit_0' => 2, ':bit_1' => 8, ':bit_2' => 64]); | ||||
|     })->group('sqlite'); | ||||
|     test('appends a parameter for other operators', function () { | ||||
|         expect(Field::equal('the_field', 33, ':test')->appendParameter([])) | ||||
|             ->toHaveLength(1) | ||||
|             ->toEqual([':test' => 33]); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('->path()', function () { | ||||
|     afterEach(function () { Configuration::overrideMode(null); }); | ||||
|     test('returns simple SQL path [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::equal('it', 'that'))->path()->toBe("data->>'it'"); | ||||
|     })->group('postgresql'); | ||||
|     test('returns simple SQL path [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::equal('top', 'that'))->path()->toBe("data->>'top'"); | ||||
|     })->group('sqlite'); | ||||
|     test('returns nested SQL path [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::equal('parts.to.the.path', ''))->path()->toBe("data#>>'{parts,to,the,path}'"); | ||||
|     })->group('postgresql'); | ||||
|     test('returns nested SQL path [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::equal('one.two.three', ''))->path()->toBe("data->'one'->'two'->>'three'"); | ||||
|     })->group('sqlite'); | ||||
|     test('returns simple JSON path [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::equal('it', 'that'))->path(true)->toBe("data->'it'"); | ||||
|     })->group('postgresql'); | ||||
|     test('returns simple JSON path [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::equal('top', 'that'))->path(true)->toBe("data->'top'"); | ||||
|     })->group('sqlite'); | ||||
|     test('returns nested JSON path [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::equal('parts.to.the.path', ''))->path(true)->toBe("data#>'{parts,to,the,path}'"); | ||||
|     })->group('postgresql'); | ||||
|     test('returns nested JSON path [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::equal('one.two.three', ''))->path(true)->toBe("data->'one'->'two'->'three'"); | ||||
|     })->group('sqlite'); | ||||
| }); | ||||
| 
 | ||||
| describe('->toWhere()', function () { | ||||
|     afterEach(function () { Configuration::overrideMode(null); }); | ||||
|     test('generates IS NOT NULL for exists w/o qualifier [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::exists('that_field'))->toWhere()->toBe("data->>'that_field' IS NOT NULL"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates IS NOT NULL for exists w/o qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::exists('that_field'))->toWhere()->toBe("data->>'that_field' IS NOT NULL"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates IS NULL for notExists w/o qualifier [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::notExists('a_field'))->toWhere()->toBe("data->>'a_field' IS NULL"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates IS NULL for notExists w/o qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::notExists('a_field'))->toWhere()->toBe("data->>'a_field' IS NULL"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates BETWEEN for between w/o qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::between('age', 13, 17, '@age'))->toWhere()->toBe("data->>'age' BETWEEN @agemin AND @agemax"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates BETWEEN for between w/o qualifier, numeric range [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::between('age', 13, 17, '@age'))->toWhere() | ||||
|             ->toBe("(data->>'age')::numeric BETWEEN @agemin AND @agemax"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates BETWEEN for between w/o qualifier, non-numeric range [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::between('city', 'Atlanta', 'Chicago', ':city'))->toWhere() | ||||
|             ->toBe("data->>'city' BETWEEN :citymin AND :citymax"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates BETWEEN for between w/ qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         $field = Field::between('age', 13, 17, '@age'); | ||||
|         $field->qualifier = 'me'; | ||||
|         expect($field)->toWhere()->toBe("me.data->>'age' BETWEEN @agemin AND @agemax"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates BETWEEN for between w/ qualifier, numeric range [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         $field = Field::between('age', 13, 17, '@age'); | ||||
|         $field->qualifier = 'me'; | ||||
|         expect($field)->toWhere()->toBe("(me.data->>'age')::numeric BETWEEN @agemin AND @agemax"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates BETWEEN for between w/ qualifier, non-numeric range [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         $field = Field::between('city', 'Atlanta', 'Chicago', ':city'); | ||||
|         $field->qualifier = 'me'; | ||||
|         expect($field)->toWhere()->toBe("me.data->>'city' BETWEEN :citymin AND :citymax"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates IN for in, non-numeric values [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::in('test', ['Atlanta', 'Chicago'], ':city'))->toWhere() | ||||
|             ->toBe("data->>'test' IN (:city_0, :city_1)"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates IN for in, numeric values [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::in('even', [2, 4, 6], ':nbr'))->toWhere() | ||||
|             ->toBe("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates IN for in [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::in('test', ['Atlanta', 'Chicago'], ':city'))->toWhere() | ||||
|             ->toBe("data->>'test' IN (:city_0, :city_1)"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates clause for inArray [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::inArray('even', 'tbl', [2, 4, 6, 8], ':it'))->toWhere() | ||||
|             ->toBe("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates clause for inArray [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::inArray('test', 'tbl', ['Atlanta', 'Chicago'], ':city'))->toWhere() | ||||
|             ->toBe("EXISTS (SELECT 1 FROM json_each(tbl.data, '\$.test') WHERE value IN (:city_0, :city_1))"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates clause for other operators w/o qualifier [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Field::equal('some_field', '', ':value'))->toWhere()->toBe("data->>'some_field' = :value"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates clause for other operators w/o qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Field::equal('some_field', '', ':value'))->toWhere()->toBe("data->>'some_field' = :value"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates no-parameter clause w/ qualifier [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         $field = Field::exists('no_field'); | ||||
|         $field->qualifier = 'test'; | ||||
|         expect($field)->toWhere()->toBe("test.data->>'no_field' IS NOT NULL"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates no-parameter clause w/ qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         $field = Field::exists('no_field'); | ||||
|         $field->qualifier = 'test'; | ||||
|         expect($field)->toWhere()->toBe("test.data->>'no_field' IS NOT NULL"); | ||||
|     })->group('sqlite'); | ||||
|     test('generates parameter clause w/ qualifier [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         $field = Field::lessOrEqual('le_field', 18, ':it'); | ||||
|         $field->qualifier = 'q'; | ||||
|         expect($field)->toWhere()->toBe("(q.data->>'le_field')::numeric <= :it"); | ||||
|     })->group('postgresql'); | ||||
|     test('generates parameter clause w/ qualifier [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         $field = Field::lessOrEqual('le_field', 18, ':it'); | ||||
|         $field->qualifier = 'q'; | ||||
|         expect($field)->toWhere()->toBe("q.data->>'le_field' <= :it"); | ||||
|     })->group('sqlite'); | ||||
| }); | ||||
| 
 | ||||
| describe('::equal()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::equal('my_test', 9); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('my_test') | ||||
|             ->op->toBe(Op::Equal) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBe(9); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::equal('another_test', 'turkey', ':test'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('another_test') | ||||
|             ->op->toBe(Op::Equal) | ||||
|             ->paramName->toBe(':test') | ||||
|             ->and($field->value)->toBe('turkey'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::greater()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::greater('your_test', 4); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('your_test') | ||||
|             ->op->toBe(Op::Greater) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBe(4); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::greater('more_test', 'chicken', ':value'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('more_test') | ||||
|             ->op->toBe(Op::Greater) | ||||
|             ->paramName->toBe(':value') | ||||
|             ->and($field->value)->toBe('chicken'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::greaterOrEqual()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::greaterOrEqual('their_test', 6); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('their_test') | ||||
|             ->op->toBe(Op::GreaterOrEqual) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBe(6); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::greaterOrEqual('greater_test', 'poultry', ':cluck'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('greater_test') | ||||
|             ->op->toBe(Op::GreaterOrEqual) | ||||
|             ->paramName->toBe(':cluck') | ||||
|             ->and($field->value)->toBe('poultry'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::less()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::less('z', 32); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('z') | ||||
|             ->op->toBe(Op::Less) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBe(32); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::less('additional_test', 'fowl', ':boo'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('additional_test') | ||||
|             ->op->toBe(Op::Less) | ||||
|             ->paramName->toBe(':boo') | ||||
|             ->and($field->value)->toBe('fowl'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::lessOrEqual()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::lessOrEqual('g', 87); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('g') | ||||
|             ->op->toBe(Op::LessOrEqual) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBe(87); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::lessOrEqual('lesser_test', 'hen', ':woo'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('lesser_test') | ||||
|             ->op->toBe(Op::LessOrEqual) | ||||
|             ->paramName->toBe(':woo') | ||||
|             ->and($field->value)->toBe('hen'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::notEqual()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::notEqual('j', 65); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('j') | ||||
|             ->op->toBe(Op::NotEqual) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBe(65); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::notEqual('unequal_test', 'egg', ':zoo'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('unequal_test') | ||||
|             ->op->toBe(Op::NotEqual) | ||||
|             ->paramName->toBe(':zoo') | ||||
|             ->and($field->value)->toBe('egg'); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::between()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::between('k', 'alpha', 'zed'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('k') | ||||
|             ->op->toBe(Op::Between) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toEqual(['alpha', 'zed']); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::between('between_test', 18, 49, ':count'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('between_test') | ||||
|             ->op->toBe(Op::Between) | ||||
|             ->paramName->toBe(':count') | ||||
|             ->and($field->value)->toEqual([18, 49]); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::in()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::in('test', [1, 2, 3]); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('test') | ||||
|             ->op->toBe(Op::In) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toEqual([1, 2, 3]); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::in('unit', ['a', 'b'], ':inParam'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('unit') | ||||
|             ->op->toBe(Op::In) | ||||
|             ->paramName->toBe(':inParam') | ||||
|             ->and($field->value)->toEqual(['a', 'b']); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::inArray()', function () { | ||||
|     test('creates Field w/o parameter', function () { | ||||
|         $field = Field::inArray('test', 'tbl', [1, 2, 3]); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('test') | ||||
|             ->op->toBe(Op::InArray) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toEqual(['table' => 'tbl', 'values' => [1, 2, 3]]); | ||||
|     }); | ||||
|     test('creates Field w/ parameter', function () { | ||||
|         $field = Field::inArray('unit', 'tab', ['a', 'b'], ':inAParam'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('unit') | ||||
|             ->op->toBe(Op::InArray) | ||||
|             ->paramName->toBe(':inAParam') | ||||
|             ->and($field->value)->toEqual(['table' => 'tab', 'values' => ['a', 'b']]); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::exists()', function () { | ||||
|     test('creates Field', function () { | ||||
|         $field = Field::exists('be_there'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('be_there') | ||||
|             ->op->toBe(Op::Exists) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBeEmpty(); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::notExists()', function () { | ||||
|     test('creates Field', function () { | ||||
|         $field = Field::notExists('be_absent'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('be_absent') | ||||
|             ->op->toBe(Op::NotExists) | ||||
|             ->paramName->toBeEmpty() | ||||
|             ->and($field->value)->toBeEmpty(); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::named()', function () { | ||||
|     test('creates Field', function () { | ||||
|         $field = Field::named('the_field'); | ||||
|         expect($field) | ||||
|             ->not->toBeNull() | ||||
|             ->fieldName->toBe('the_field') | ||||
|             ->op->toBe(Op::Equal) | ||||
|             ->value->toBeEmpty() | ||||
|             ->and($field->value)->toBeEmpty(); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										23
									
								
								tests/Unit/ModeTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/Unit/ModeTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\{DocumentException, Mode}; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('::deriveFromDSN()', function () { | ||||
|     test('derives for PostgreSQL', function () { | ||||
|         expect(Mode::deriveFromDSN('pgsql:Host=localhost'))->toBe(Mode::PgSQL); | ||||
|     })->group('postgresql'); | ||||
|     test('derives for SQLite', function () { | ||||
|         expect(Mode::deriveFromDSN('sqlite:data.db'))->toBe(Mode::SQLite); | ||||
|     })->group('sqlite'); | ||||
|     test('throws for other drivers', function () { | ||||
|         expect(fn() => Mode::deriveFromDSN('mysql:Host=localhost'))->toThrow(DocumentException::class); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										47
									
								
								tests/Unit/OpTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								tests/Unit/OpTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\Op; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('->toSQL()', function () { | ||||
|     test('returns "=" for Equal', function () { | ||||
|         expect(Op::Equal)->toSQL()->toBe('='); | ||||
|     }); | ||||
|     test('returns ">" for Greater', function () { | ||||
|         expect(Op::Greater)->toSQL()->toBe('>'); | ||||
|     }); | ||||
|     test('returns ">=" for GreaterOrEqual', function () { | ||||
|         expect(Op::GreaterOrEqual)->toSQL()->toBe('>='); | ||||
|     }); | ||||
|     test('returns "<" for Less', function () { | ||||
|         expect(Op::Less)->toSQL()->toBe('<'); | ||||
|     }); | ||||
|     test('returns "<=" for LessOrEqual', function () { | ||||
|         expect(Op::LessOrEqual)->toSQL()->toBe('<='); | ||||
|     }); | ||||
|     test('returns "<>" for NotEqual', function () { | ||||
|         expect(Op::NotEqual)->toSQL()->toBe('<>'); | ||||
|     }); | ||||
|     test('returns "BETWEEN" for Between', function () { | ||||
|         expect(Op::Between)->toSQL()->toBe('BETWEEN'); | ||||
|     }); | ||||
|     test('returns "IN" for In', function () { | ||||
|         expect(Op::In)->toSQL()->toBe('IN'); | ||||
|     }); | ||||
|     test('returns "?|" (escaped) for InArray', function () { | ||||
|         expect(Op::InArray)->toSQL()->toBe('??|'); | ||||
|     }); | ||||
|     test('returns "IS NOT NULL" for Exists', function () { | ||||
|         expect(Op::Exists)->toSQL()->toBe('IS NOT NULL'); | ||||
|     }); | ||||
|     test('returns "IS NULL" for NotExists', function () { | ||||
|         expect(Op::NotExists)->toSQL()->toBe('IS NULL'); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										85
									
								
								tests/Unit/ParametersTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								tests/Unit/ParametersTest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use BitBadger\PDODocument\{Configuration, DocumentException, Field, Mode, Parameters}; | ||||
| use Test\{PjsonDocument, PjsonId}; | ||||
| 
 | ||||
| pest()->group('unit'); | ||||
| 
 | ||||
| describe('::id()', function () { | ||||
|     test('creates string ID parameter', function () { | ||||
|         expect(Parameters::id('key'))->toEqual([':id' => 'key']); | ||||
|     }); | ||||
|     test('creates string from numeric ID parameter', function () { | ||||
|         expect(Parameters::id(7))->toEqual([':id' => '7']); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::json()', function () { | ||||
|     test('serializes an array', function () { | ||||
|         expect(Parameters::json(':it', ['id' => 18, 'url' => 'https://www.unittest.com'])) | ||||
|             ->toEqual([':it' => '{"id":18,"url":"https://www.unittest.com"}']); | ||||
|     }); | ||||
|     test('serializes an array w/ an empty array value', function () { | ||||
|         expect(Parameters::json(':it', ['id' => 18, 'urls' => []]))->toEqual([':it' => '{"id":18,"urls":[]}']); | ||||
|     }); | ||||
|     test('serializes a 1-D array w/ an empty array value', function () { | ||||
|         expect(Parameters::json(':it', ['urls' => []]))->toEqual([':it' => '{"urls":[]}']); | ||||
|     }); | ||||
|     test('serializes a stdClass instance', function () { | ||||
|         $obj      = new stdClass(); | ||||
|         $obj->id  = 19; | ||||
|         $obj->url = 'https://testhere.info'; | ||||
|         expect(Parameters::json(':it', $obj))->toEqual([':it' => '{"id":19,"url":"https://testhere.info"}']); | ||||
|     }); | ||||
|     test('serializes a Pjson class instance', function () { | ||||
|         expect(Parameters::json(':it', new PjsonDocument(new PjsonId('999'), 'a test', 98, 'nothing'))) | ||||
|             ->toEqual([':it' => '{"id":"999","name":"a test","num_value":98}']); | ||||
|     }); | ||||
|     test('serializes an array of Pjson class instances', function () { | ||||
|         expect(Parameters::json(':it', | ||||
|             ['pjson' => [new PjsonDocument(new PjsonId('997'), 'another test', 94, 'nothing')]])) | ||||
|             ->toEqual([':it' => '{"pjson":[{"id":"997","name":"another test","num_value":94}]}']); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::nameFields()', function () { | ||||
|     test('provides missing parameter names', function () { | ||||
|         $named = [Field::equal('it', 17), Field::equal('also', 22, ':also'), Field::equal('other', 24)]; | ||||
|         Parameters::nameFields($named); | ||||
|         expect($named) | ||||
|             ->toHaveLength(3) | ||||
|             ->sequence( | ||||
|                 fn($it) => $it->paramName->toBe(':field0'), | ||||
|                 fn($it) => $it->paramName->toBe(':also'), | ||||
|                 fn($it) => $it->paramName->toBe(':field2')); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::addFields()', function () { | ||||
|     test('appends to an existing parameter array', function () { | ||||
|         expect(Parameters::addFields([Field::equal('b', 'two', ':b'), Field::equal('z', 18, ':z')], [':a' => 1])) | ||||
|             ->toEqual([':a' => 1, ':b' => 'two', ':z' => 18]); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| describe('::fieldNames()', function () { | ||||
|     afterEach(function () { Configuration::overrideMode(null); }); | ||||
|     test('generates names [PostgreSQL]', function () { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         expect(Parameters::fieldNames(':names', ['one', 'two', 'seven']))->toEqual([':names' => "{one,two,seven}"]); | ||||
|     })->group('postgresql'); | ||||
|     test('generates names [SQLite]', function () { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         expect(Parameters::fieldNames(':it', ['test', 'unit', 'wow'])) | ||||
|             ->toEqual([':it0' => '$.test', ':it1' => '$.unit', ':it2' => '$.wow']); | ||||
|     })->group('sqlite'); | ||||
|     test('throws when mode is not set', function () { | ||||
|         expect(fn() => Parameters::fieldNames('', []))->toThrow(DocumentException::class); | ||||
|     }); | ||||
| }); | ||||
| @ -1,58 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\{AutoId, Configuration, DocumentException}; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the Configuration class | ||||
|  */ | ||||
| #[TestDox('Configuration (Unit tests)')]
 | ||||
| class ConfigurationTest extends TestCase | ||||
| { | ||||
|     #[TestDox('id default succeeds')]
 | ||||
|     public function testIdFieldDefaultSucceeds(): void | ||||
|     { | ||||
|         $this->assertEquals('id', Configuration::$idField, 'Default ID field should be "id"'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('id change succeeds')]
 | ||||
|     public function testIdFieldChangeSucceeds(): void | ||||
|     { | ||||
|         try { | ||||
|             Configuration::$idField = 'EyeDee'; | ||||
|             $this->assertEquals('EyeDee', Configuration::$idField, 'ID field should have been updated'); | ||||
|         } finally { | ||||
|             Configuration::$idField = 'id'; | ||||
|             $this->assertEquals('id', Configuration::$idField, 'Default ID value should have been restored'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('autoId default succeeds')]
 | ||||
|     public function testAutoIdDefaultSucceeds(): void | ||||
|     { | ||||
|         $this->assertEquals(AutoId::None, Configuration::$autoId, 'Auto ID should default to None'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('idStringLength default succeeds')]
 | ||||
|     public function testIdStringLengthDefaultSucceeds(): void | ||||
|     { | ||||
|         $this->assertEquals(16, Configuration::$idStringLength, 'ID string length should default to 16'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox("dbConn() fails when no DSN specified")]
 | ||||
|     public function testDbConnFailsWhenNoDSNSpecified(): void | ||||
|     { | ||||
|         $this->expectException(DocumentException::class); | ||||
|         Configuration::useDSN(''); | ||||
|         Configuration::dbConn(); | ||||
|     } | ||||
| } | ||||
| @ -1,56 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\DocumentException; | ||||
| use Exception; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the DocumentException class | ||||
|  */ | ||||
| #[TestDox('Document Exception (Unit tests)')]
 | ||||
| class DocumentExceptionTest extends TestCase | ||||
| { | ||||
|     public function testConstructorSucceedsWithCodeAndPriorException(): void | ||||
|     { | ||||
|         $priorEx = new Exception('Uh oh'); | ||||
|         $ex = new DocumentException('Test Exception', 17, $priorEx); | ||||
|         $this->assertNotNull($ex, 'The exception should not have been null'); | ||||
|         $this->assertEquals('Test Exception', $ex->getMessage(), 'Message not filled properly'); | ||||
|         $this->assertEquals(17, $ex->getCode(), 'Code not filled properly'); | ||||
|         $this->assertSame($priorEx, $ex->getPrevious(), 'Prior exception not filled properly'); | ||||
|     } | ||||
| 
 | ||||
|     public function testConstructorSucceedsWithoutCodeAndPriorException(): void | ||||
|     { | ||||
|         $ex = new DocumentException('Oops'); | ||||
|         $this->assertNotNull($ex, 'The exception should not have been null'); | ||||
|         $this->assertEquals('Oops', $ex->getMessage(), 'Message not filled properly'); | ||||
|         $this->assertEquals(0, $ex->getCode(), 'Code not filled properly'); | ||||
|         $this->assertNull($ex->getPrevious(), 'Prior exception should have been null'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toString() succeeds without code')]
 | ||||
|     public function testToStringSucceedsWithoutCode(): void | ||||
|     { | ||||
|         $ex = new DocumentException('Test failure'); | ||||
|         $this->assertEquals("BitBadger\PDODocument\DocumentException: Test failure\n", "$ex", | ||||
|             'toString not generated correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toString() succeeds with code')]
 | ||||
|     public function testToStringSucceedsWithCode(): void | ||||
|     { | ||||
|         $ex = new DocumentException('Oof', -6); | ||||
|         $this->assertEquals("BitBadger\PDODocument\DocumentException: [-6] Oof\n", "$ex", | ||||
|             'toString not generated correctly'); | ||||
|     } | ||||
| } | ||||
| @ -1,32 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\FieldMatch; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the FieldMatch enum | ||||
|  */ | ||||
| #[TestDox('Field Match (Unit tests)')]
 | ||||
| class FieldMatchTest extends TestCase | ||||
| { | ||||
|     #[TestDox('toSQL() succeeds for All')]
 | ||||
|     public function testToSQLSucceedsForAll(): void | ||||
|     { | ||||
|         $this->assertEquals('AND', FieldMatch::All->toSQL(), 'All should have returned AND'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for Any')]
 | ||||
|     public function testToSQLSucceedsForAny(): void | ||||
|     { | ||||
|         $this->assertEquals('OR', FieldMatch::Any->toSQL(), 'Any should have returned OR'); | ||||
|     } | ||||
| } | ||||
| @ -1,683 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\{Configuration, Field, Mode, Op}; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the Field class | ||||
|  */ | ||||
| #[TestDox('Field (Unit tests)')]
 | ||||
| class FieldTest extends TestCase | ||||
| { | ||||
|     #[TestDox('appendParameter() succeeds for exists')]
 | ||||
|     public function testAppendParameterSucceedsForExists(): void | ||||
|     { | ||||
|         $this->assertEquals([], Field::exists('exists')->appendParameter([]), | ||||
|             'exists should not have appended a parameter'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('appendParameter() succeeds for notExists')]
 | ||||
|     public function testAppendParameterSucceedsForNotExists(): void | ||||
|     { | ||||
|         $this->assertEquals([], Field::notExists('absent')->appendParameter([]), | ||||
|             'notExists should not have appended a parameter'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('appendParameter() succeeds for between')]
 | ||||
|     public function testAppendParameterSucceedsForBetween(): void | ||||
|     { | ||||
|         $this->assertEquals(['@nummin' => 5, '@nummax' => 9], | ||||
|             Field::between('exists', 5, 9, '@num')->appendParameter([]), | ||||
|             'Between should have appended min and max parameters'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('appendParameter() succeeds for in')]
 | ||||
|     public function testAppendParameterSucceedsForIn(): void | ||||
|     { | ||||
|         $this->assertEquals([':val_0' => 'test', ':val_1' => 'unit', ':val_2' => 'great'], | ||||
|             Field::in('it', ['test', 'unit', 'great'], ':val')->appendParameter([]), | ||||
|             'In should have appended 3 parameters for the input values'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('appendParameter() succeeds for inArray for PostgreSQL')]
 | ||||
|     public function testAppendParameterSucceedsForInArrayForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals([':bit_0' => '2', ':bit_1' => '8', ':bit_2' => '64'], | ||||
|                 Field::inArray('it', 'table', [2, 8, 64], ':bit')->appendParameter([]), | ||||
|                 'InArray should have appended 3 string parameters for the input values'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('appendParameter() succeeds for inArray for SQLite')]
 | ||||
|     public function testAppendParameterSucceedsForInArrayForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals([':bit_0' => 2, ':bit_1' => 8, ':bit_2' => 64], | ||||
|                 Field::inArray('it', 'table', [2, 8, 64], ':bit')->appendParameter([]), | ||||
|                 'InArray should have appended 3 parameters for the input values'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('appendParameter() succeeds for others')]
 | ||||
|     public function testAppendParameterSucceedsForOthers(): void | ||||
|     { | ||||
|         $this->assertEquals(['@test' => 33], Field::equal('the_field', 33, '@test')->appendParameter([]), | ||||
|             'Field parameter not returned correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for simple SQL path for PostgreSQL')]
 | ||||
|     public function testPathSucceedsForSimpleSqlPathForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'it'", Field::equal('it', 'that')->path(), | ||||
|                 'SQL value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for simple SQL path for SQLite')]
 | ||||
|     public function testPathSucceedsForSimpleSqlPathForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'top'", Field::equal('top', 'that')->path(), | ||||
|                 'SQL value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for nested SQL path for PostgreSQL')]
 | ||||
|     public function testPathSucceedsForNestedSqlPathForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data#>>'{parts,to,the,path}'", Field::equal('parts.to.the.path', '')->path(), | ||||
|                 'SQL value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for nested SQL path for SQLite')]
 | ||||
|     public function testPathSucceedsForNestedSqlPathForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->'one'->'two'->>'three'", Field::equal('one.two.three', '')->path(), | ||||
|                 'SQL value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for simple JSON path for PostgreSQL')]
 | ||||
|     public function testPathSucceedsForSimpleJsonPathForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data->'it'", Field::equal('it', 'that')->path(true), | ||||
|                 'JSON value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for simple JSON path for SQLite')]
 | ||||
|     public function testPathSucceedsForSimpleJsonPathForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->'top'", Field::equal('top', 'that')->path(true), | ||||
|                 'JSON value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for nested JSON path for PostgreSQL')]
 | ||||
|     public function testPathSucceedsForNestedJsonPathForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data#>'{parts,to,the,path}'", Field::equal('parts.to.the.path', '')->path(true), | ||||
|                 'JSON value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('path() succeeds for nested JSON path for SQLite')]
 | ||||
|     public function testPathSucceedsForNestedJsonPathForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->'one'->'two'->'three'", Field::equal('one.two.three', '')->path(true), | ||||
|                 'SQL value path not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for exists without qualifier for PostgreSQL')]
 | ||||
|     public function testToWhereSucceedsForExistsWithoutQualifierForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'that_field' IS NOT NULL", Field::exists('that_field')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for exists without qualifier for SQLite')]
 | ||||
|     public function testToWhereSucceedsForExistsWithoutQualifierForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'that_field' IS NOT NULL", Field::exists('that_field')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for notExists without qualifier for PostgreSQL')]
 | ||||
|     public function testToWhereSucceedsForNotExistsWithoutQualifierForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'a_field' IS NULL", Field::notExists('a_field')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for notExists without qualifier for SQLite')]
 | ||||
|     public function testToWhereSucceedsForNotExistsWithoutQualifierForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'a_field' IS NULL", Field::notExists('a_field')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for between without qualifier for SQLite')]
 | ||||
|     public function testToWhereSucceedsForBetweenWithoutQualifierForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'age' BETWEEN @agemin AND @agemax", | ||||
|                 Field::between('age', 13, 17, '@age')->toWhere(), 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for between without qualifier for PostgreSQL with numeric range')]
 | ||||
|     public function testToWhereSucceedsForBetweenWithoutQualifierForPostgreSQLWithNumericRange(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax", | ||||
|                 Field::between('age', 13, 17, '@age')->toWhere(), 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for between without qualifier for PostgreSQL with non-numeric range')]
 | ||||
|     public function testToWhereSucceedsForBetweenWithoutQualifierForPostgreSQLWithNonNumericRange(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'city' BETWEEN :citymin AND :citymax", | ||||
|                 Field::between('city', 'Atlanta', 'Chicago', ':city')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for between with qualifier for SQLite')]
 | ||||
|     public function testToWhereSucceedsForBetweenWithQualifierForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $field = Field::between('age', 13, 17, '@age'); | ||||
|             $field->qualifier = 'me'; | ||||
|             $this->assertEquals("me.data->>'age' BETWEEN @agemin AND @agemax", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for between with qualifier for PostgreSQL with numeric range')]
 | ||||
|     public function testToWhereSucceedsForBetweenWithQualifierForPostgreSQLWithNumericRange(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::between('age', 13, 17, '@age'); | ||||
|             $field->qualifier = 'me'; | ||||
|             $this->assertEquals("(me.data->>'age')::numeric BETWEEN @agemin AND @agemax", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for between with qualifier for PostgreSQL with non-numeric range')]
 | ||||
|     public function testToWhereSucceedsForBetweenWithQualifierForPostgreSQLWithNonNumericRange(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::between('city', 'Atlanta', 'Chicago', ':city'); | ||||
|             $field->qualifier = 'me'; | ||||
|             $this->assertEquals("me.data->>'city' BETWEEN :citymin AND :citymax", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for in for PostgreSQL with non-numeric values')]
 | ||||
|     public function testToWhereSucceedsForInForPostgreSQLWithNonNumericValues(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::in('test', ['Atlanta', 'Chicago'], ':city'); | ||||
|             $this->assertEquals("data->>'test' IN (:city_0, :city_1)", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for in for PostgreSQL with numeric values')]
 | ||||
|     public function testToWhereSucceedsForInForPostgreSQLWithNumericValues(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::in('even', [2, 4, 6], ':nbr'); | ||||
|             $this->assertEquals("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for in for SQLite')]
 | ||||
|     public function testToWhereSucceedsForInForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $field = Field::in('test', ['Atlanta', 'Chicago'], ':city'); | ||||
|             $this->assertEquals("data->>'test' IN (:city_0, :city_1)", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for inArray for PostgreSQL')]
 | ||||
|     public function testToWhereSucceedsForInArrayForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::inArray('even', 'tbl', [2, 4, 6, 8], ':it'); | ||||
|             $this->assertEquals("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for inArray for SQLite')]
 | ||||
|     public function testToWhereSucceedsForInArrayForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $field = Field::inArray('test', 'tbl', ['Atlanta', 'Chicago'], ':city'); | ||||
|             $this->assertEquals( | ||||
|                 "EXISTS (SELECT 1 FROM json_each(tbl.data, '\$.test') WHERE value IN (:city_0, :city_1))", | ||||
|                 $field->toWhere(), 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for others without qualifier for PostgreSQL')]
 | ||||
|     public function testToWhereSucceedsForOthersWithoutQualifierForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'some_field' = @value", Field::equal('some_field', '', '@value')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds for others without qualifier for SQLite')]
 | ||||
|     public function testToWhereSucceedsForOthersWithoutQualifierForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $this->assertEquals("data->>'some_field' = @value", Field::equal('some_field', '', '@value')->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds with qualifier no parameter for PostgreSQL')]
 | ||||
|     public function testToWhereSucceedsWithQualifierNoParameterForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::exists('no_field'); | ||||
|             $field->qualifier = 'test'; | ||||
|             $this->assertEquals("test.data->>'no_field' IS NOT NULL", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds with qualifier no parameter for SQLite')]
 | ||||
|     public function testToWhereSucceedsWithQualifierNoParameterForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $field = Field::exists('no_field'); | ||||
|             $field->qualifier = 'test'; | ||||
|             $this->assertEquals("test.data->>'no_field' IS NOT NULL", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds with qualifier and parameter for PostgreSQL')]
 | ||||
|     public function testToWhereSucceedsWithQualifierAndParameterForPostgreSQL(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::PgSQL); | ||||
|         try { | ||||
|             $field = Field::lessOrEqual('le_field', 18, '@it'); | ||||
|             $field->qualifier = 'q'; | ||||
|             $this->assertEquals("(q.data->>'le_field')::numeric <= @it", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toWhere() succeeds with qualifier and parameter for SQLite')]
 | ||||
|     public function testToWhereSucceedsWithQualifierAndParameterForSQLite(): void | ||||
|     { | ||||
|         Configuration::overrideMode(Mode::SQLite); | ||||
|         try { | ||||
|             $field = Field::lessOrEqual('le_field', 18, '@it'); | ||||
|             $field->qualifier = 'q'; | ||||
|             $this->assertEquals("q.data->>'le_field' <= @it", $field->toWhere(), | ||||
|                 'WHERE fragment not generated correctly'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('equal() succeeds without parameter')]
 | ||||
|     public function testEqualSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::equal('my_test', 9); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('my_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Equal, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(9, $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('equal() succeeds with parameter')]
 | ||||
|     public function testEqualSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::equal('another_test', 'turkey', '@test'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('another_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Equal, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('turkey', $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@test', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('greater() succeeds without parameter')]
 | ||||
|     public function testGreaterSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::greater('your_test', 4); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('your_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Greater, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(4, $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('greater() succeeds with parameter')]
 | ||||
|     public function testGreaterSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::greater('more_test', 'chicken', '@value'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('more_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Greater, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('chicken', $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@value', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('greaterOrEqual() succeeds without parameter')]
 | ||||
|     public function testGreaterOrEqualSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::greaterOrEqual('their_test', 6); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('their_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::GreaterOrEqual, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(6, $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('greaterOrEqual() succeeds with parameter')]
 | ||||
|     public function testGreaterOrEqualSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::greaterOrEqual('greater_test', 'poultry', '@cluck'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('greater_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::GreaterOrEqual, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('poultry', $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@cluck', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('less() succeeds without parameter')]
 | ||||
|     public function testLessSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::less('z', 32); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('z', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Less, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(32, $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('less() succeeds with parameter')]
 | ||||
|     public function testLessSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::less('additional_test', 'fowl', '@boo'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('additional_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Less, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('fowl', $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@boo', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('lessOrEqual() succeeds without parameter')]
 | ||||
|     public function testLessOrEqualSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::lessOrEqual('g', 87); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('g', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::LessOrEqual, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(87, $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('lessOrEqual() succeeds with parameter')]
 | ||||
|     public function testLessOrEqualSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::lessOrEqual('lesser_test', 'hen', '@woo'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('lesser_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::LessOrEqual, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('hen', $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@woo', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('notEqual() succeeds without parameter')]
 | ||||
|     public function testNotEqualSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::notEqual('j', 65); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('j', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::NotEqual, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(65, $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('notEqual() succeeds with parameter')]
 | ||||
|     public function testNotEqualSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::notEqual('unequal_test', 'egg', '@zoo'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('unequal_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::NotEqual, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('egg', $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@zoo', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('between() succeeds without parameter')]
 | ||||
|     public function testBetweenSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::between('k', 'alpha', 'zed'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('k', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Between, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(['alpha', 'zed'], $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('between() succeeds with parameter')]
 | ||||
|     public function testBetweenSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::between('between_test', 18, 49, '@count'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('between_test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Between, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals([18, 49], $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@count', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('in() succeeds without parameter')]
 | ||||
|     public function testInSucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::in('test', [1, 2, 3]); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::In, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals([1, 2, 3], $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('in() succeeds with parameter')]
 | ||||
|     public function testInSucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::in('unit', ['a', 'b'], '@inParam'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('unit', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::In, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(['a', 'b'], $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@inParam', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('inArray() succeeds without parameter')]
 | ||||
|     public function testInArraySucceedsWithoutParameter(): void | ||||
|     { | ||||
|         $field = Field::inArray('test', 'tbl', [1, 2, 3]); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('test', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::InArray, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(['table' => 'tbl', 'values' => [1, 2, 3]], $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('inArray() succeeds with parameter')]
 | ||||
|     public function testInArraySucceedsWithParameter(): void | ||||
|     { | ||||
|         $field = Field::inArray('unit', 'tab', ['a', 'b'], '@inAParam'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('unit', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::InArray, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals(['table' => 'tab', 'values' => ['a', 'b']], $field->value, 'Value not filled correctly'); | ||||
|         $this->assertEquals('@inAParam', $field->paramName, 'Parameter name not filled correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('exists() succeeds')]
 | ||||
|     public function testExistsSucceeds(): void | ||||
|     { | ||||
|         $field = Field::exists('be_there'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('be_there', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Exists, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('', $field->value, 'Value should have been blank'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('notExists() succeeds')]
 | ||||
|     public function testNotExistsSucceeds(): void | ||||
|     { | ||||
|         $field = Field::notExists('be_absent'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('be_absent', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::NotExists, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('', $field->value, 'Value should have been blank'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('named() succeeds')]
 | ||||
|     public function testNamedSucceeds(): void | ||||
|     { | ||||
|         $field = Field::named('the_field'); | ||||
|         $this->assertNotNull($field, 'The field should not have been null'); | ||||
|         $this->assertEquals('the_field', $field->fieldName, 'Field name not filled correctly'); | ||||
|         $this->assertEquals(Op::Equal, $field->op, 'Operation not filled correctly'); | ||||
|         $this->assertEquals('', $field->value, 'Value should have been blank'); | ||||
|         $this->assertEquals('', $field->paramName, 'Parameter name should have been blank'); | ||||
|     } | ||||
| } | ||||
| @ -1,39 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\{DocumentException, Mode}; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the Mode enumeration | ||||
|  */ | ||||
| #[TestDox('Mode (Unit tests)')]
 | ||||
| class ModeTest extends TestCase | ||||
| { | ||||
|     #[TestDox('deriveFromDSN() succeeds for PostgreSQL')]
 | ||||
|     public function testDeriveFromDSNSucceedsForPostgreSQL(): void | ||||
|     { | ||||
|         $this->assertEquals(Mode::PgSQL, Mode::deriveFromDSN('pgsql:Host=localhost'), 'PostgreSQL mode incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('deriveFromDSN() succeeds for SQLite')]
 | ||||
|     public function testDeriveFromDSNSucceedsForSQLite(): void | ||||
|     { | ||||
|         $this->assertEquals(Mode::SQLite, Mode::deriveFromDSN('sqlite:data.db'), 'SQLite mode incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('deriveFromDSN() fails for MySQL')]
 | ||||
|     public function testDeriveFromDSNFailsForMySQL(): void | ||||
|     { | ||||
|         $this->expectException(DocumentException::class); | ||||
|         Mode::deriveFromDSN('mysql:Host=localhost'); | ||||
|     } | ||||
| } | ||||
| @ -1,86 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\Op; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the Op enumeration | ||||
|  */ | ||||
| #[TestDox('Op (Unit tests)')]
 | ||||
| class OpTest extends TestCase | ||||
| { | ||||
|     #[TestDox('toSQL() succeeds for Equal')]
 | ||||
|     public function testToSQLSucceedsForEqual(): void | ||||
|     { | ||||
|         $this->assertEquals('=', Op::Equal->toSQL(), 'Equal SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for Greater')]
 | ||||
|     public function testToSQLSucceedsForGreater(): void | ||||
|     { | ||||
|         $this->assertEquals('>', Op::Greater->toSQL(), 'Greater SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for GreaterOrEqual')]
 | ||||
|     public function testToSQLSucceedsForGreaterOrEqual(): void | ||||
|     { | ||||
|         $this->assertEquals('>=', Op::GreaterOrEqual->toSQL(), 'GreaterOrEqual SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for Less')]
 | ||||
|     public function testToSQLSucceedsForLess(): void | ||||
|     { | ||||
|         $this->assertEquals('<', Op::Less->toSQL(), 'Less SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for LessOrEqual')]
 | ||||
|     public function testToSQLSucceedsForLessOrEqual(): void | ||||
|     { | ||||
|         $this->assertEquals('<=', Op::LessOrEqual->toSQL(), 'LessOrEqual SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for NotEqual')]
 | ||||
|     public function testToSQLSucceedsForNotEqual(): void | ||||
|     { | ||||
|         $this->assertEquals('<>', Op::NotEqual->toSQL(), 'NotEqual SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for Between')]
 | ||||
|     public function testToSQLSucceedsForBetween(): void | ||||
|     { | ||||
|         $this->assertEquals('BETWEEN', Op::Between->toSQL(), 'Between SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for In')]
 | ||||
|     public function testToSQLSucceedsForIn(): void | ||||
|     { | ||||
|         $this->assertEquals('IN', Op::In->toSQL(), 'In SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for InArray')]
 | ||||
|     public function testToSQLSucceedsForInArray(): void | ||||
|     { | ||||
|         $this->assertEquals('??|', Op::InArray->toSQL(), 'InArray SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for Exists')]
 | ||||
|     public function testToSQLSucceedsForExists(): void | ||||
|     { | ||||
|         $this->assertEquals('IS NOT NULL', Op::Exists->toSQL(), 'Exists SQL operator incorrect'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('toSQL() succeeds for NotExists')]
 | ||||
|     public function testToSQLSucceedsForNEX(): void | ||||
|     { | ||||
|         $this->assertEquals('IS NULL', Op::NotExists->toSQL(), 'NotExists SQL operator incorrect'); | ||||
|     } | ||||
| } | ||||
| @ -1,134 +0,0 @@ | ||||
| <?php | ||||
| /** | ||||
|  * @author Daniel J. Summers <daniel@bitbadger.solutions> | ||||
|  * @license MIT | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace Test\Unit; | ||||
| 
 | ||||
| use BitBadger\PDODocument\{Configuration, DocumentException, Field, Mode, Parameters}; | ||||
| use PHPUnit\Framework\Attributes\TestDox; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| use stdClass; | ||||
| use Test\{PjsonDocument, PjsonId}; | ||||
| 
 | ||||
| /** | ||||
|  * Unit tests for the Parameters class | ||||
|  */ | ||||
| #[TestDox('Parameters (Unit tests)')]
 | ||||
| class ParametersTest extends TestCase | ||||
| { | ||||
|     #[TestDox('id() succeeds with string')]
 | ||||
|     public function testIdSucceedsWithString(): void | ||||
|     { | ||||
|         $this->assertEquals([':id' => 'key'], Parameters::id('key'), 'ID parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('id() succeeds with non string')]
 | ||||
|     public function testIdSucceedsWithNonString(): void | ||||
|     { | ||||
|         $this->assertEquals([':id' => '7'], Parameters::id(7), 'ID parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('json() succeeds for array')]
 | ||||
|     public function testJsonSucceedsForArray(): void | ||||
|     { | ||||
|         $this->assertEquals([':it' => '{"id":18,"url":"https://www.unittest.com"}'], | ||||
|             Parameters::json(':it', ['id' => 18, 'url' => 'https://www.unittest.com']), | ||||
|             'JSON parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('json() succeeds for array with empty array parameter')]
 | ||||
|     public function testJsonSucceedsForArrayWithEmptyArrayParameter(): void | ||||
|     { | ||||
|         $this->assertEquals([':it' => '{"id":18,"urls":[]}'], Parameters::json(':it', ['id' => 18, 'urls' => []]), | ||||
|             'JSON parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('json() succeeds for 1D array with empty array parameter')]
 | ||||
|     public function testJsonSucceedsFor1DArrayWithEmptyArrayParameter(): void | ||||
|     { | ||||
|         $this->assertEquals([':it' => '{"urls":[]}'], Parameters::json(':it', ['urls' => []]), | ||||
|             'JSON parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('json() succeeds for stdClass')]
 | ||||
|     public function testJsonSucceedsForStdClass(): void | ||||
|     { | ||||
|         $obj      = new stdClass(); | ||||
|         $obj->id  = 19; | ||||
|         $obj->url = 'https://testhere.info'; | ||||
|         $this->assertEquals([':it' => '{"id":19,"url":"https://testhere.info"}'], Parameters::json(':it', $obj), | ||||
|             'JSON parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('json() succeeds for Pjson class')]
 | ||||
|     public function testJsonSucceedsForPjsonClass(): void | ||||
|     { | ||||
|         $this->assertEquals([':it' => '{"id":"999","name":"a test","num_value":98}'], | ||||
|             Parameters::json(':it', new PjsonDocument(new PjsonId('999'), 'a test', 98, 'nothing')), | ||||
|             'JSON parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('json() succeeds for array of Pjson class')]
 | ||||
|     public function testJsonSucceedsForArrayOfPjsonClass(): void | ||||
|     { | ||||
|         $this->assertEquals([':it' => '{"pjson":[{"id":"997","name":"another test","num_value":94}]}'], | ||||
|             Parameters::json(':it', | ||||
|                 ['pjson' => [new PjsonDocument(new PjsonId('997'), 'another test', 94, 'nothing')]]), | ||||
|             'JSON parameter not constructed correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('nameFields() succeeds')]
 | ||||
|     public function testNameFieldsSucceeds(): void | ||||
|     { | ||||
|         $named = [Field::equal('it', 17), Field::equal('also', 22, ':also'), Field::equal('other', 24)]; | ||||
|         Parameters::nameFields($named); | ||||
|         $this->assertCount(3, $named, 'There should be 3 parameters in the array'); | ||||
|         $this->assertEquals(':field0', $named[0]->paramName, 'Parameter 1 not named correctly'); | ||||
|         $this->assertEquals(':also', $named[1]->paramName, 'Parameter 2 not named correctly'); | ||||
|         $this->assertEquals(':field2', $named[2]->paramName, 'Parameter 3 not named correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('addFields() succeeds')]
 | ||||
|     public function testAddFieldsSucceeds(): void | ||||
|     { | ||||
|         $this->assertEquals([':a' => 1, ':b' => 'two', ':z' => 18], | ||||
|             Parameters::addFields([Field::equal('b', 'two', ':b'), Field::equal('z', 18, ':z')], [':a' => 1]), | ||||
|             'Field parameters not added correctly'); | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('fieldNames() succeeds for PostgreSQL')]
 | ||||
|     public function testFieldNamesSucceedsForPostgreSQL(): void | ||||
|     { | ||||
|         try { | ||||
|             Configuration::overrideMode(Mode::PgSQL); | ||||
|             $this->assertEquals([':names' => "{one,two,seven}"], | ||||
|                 Parameters::fieldNames(':names', ['one', 'two', 'seven']), 'Field name parameters not correct'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('fieldNames() succeeds for SQLite')]
 | ||||
|     public function testFieldNamesSucceedsForSQLite(): void | ||||
|     { | ||||
|         try { | ||||
|             Configuration::overrideMode(Mode::SQLite); | ||||
|             $this->assertEquals([':it0' => '$.test', ':it1' => '$.unit', ':it2' => '$.wow'], | ||||
|                 Parameters::fieldNames(':it', ['test', 'unit', 'wow']), 'Field name parameters not correct'); | ||||
|         } finally { | ||||
|             Configuration::overrideMode(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[TestDox('fieldNames() fails when mode not set')]
 | ||||
|     public function testFieldNamesFailsWhenModeNotSet(): void | ||||
|     { | ||||
|         $this->expectException(DocumentException::class); | ||||
|         Configuration::overrideMode(null); | ||||
|         Parameters::fieldNames('', []); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user