- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
129 lines
5.3 KiB
PHP
129 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Framework\Database\ValueObjects;
|
|
|
|
use App\Framework\Database\ValueObjects\QueryParameters;
|
|
use App\Framework\Database\ValueObjects\SqlQuery;
|
|
use InvalidArgumentException;
|
|
|
|
describe('SqlQuery Value Object', function () {
|
|
it('can be created with SQL and parameters', function () {
|
|
$params = QueryParameters::fromArray(['id' => 123]);
|
|
$query = new SqlQuery('SELECT * FROM users WHERE id = :id', $params);
|
|
|
|
expect($query->sql)->toBe('SELECT * FROM users WHERE id = :id');
|
|
expect($query->parameters->get('id'))->toBe(123);
|
|
});
|
|
|
|
it('can be created with create factory method', function () {
|
|
$query = SqlQuery::create('SELECT * FROM users', ['limit' => 10]);
|
|
|
|
expect($query->sql)->toBe('SELECT * FROM users');
|
|
expect($query->parameters->get('limit'))->toBe(10);
|
|
});
|
|
|
|
it('can create SELECT queries', function () {
|
|
$query = SqlQuery::select('users', ['id', 'name'], 'active = 1');
|
|
|
|
expect($query->sql)->toBe('SELECT id, name FROM users WHERE active = 1');
|
|
expect($query->isSelect())->toBeTrue();
|
|
});
|
|
|
|
it('can create INSERT queries', function () {
|
|
$query = SqlQuery::insert('users', ['name' => 'John', 'email' => 'john@test.com']);
|
|
|
|
expect($query->sql)->toBe('INSERT INTO users (name, email) VALUES (:name, :email)');
|
|
expect($query->parameters->get('name'))->toBe('John');
|
|
expect($query->parameters->get('email'))->toBe('john@test.com');
|
|
expect($query->isInsert())->toBeTrue();
|
|
});
|
|
|
|
it('can create UPDATE queries', function () {
|
|
$query = SqlQuery::update('users', ['name' => 'Jane'], 'id = :id');
|
|
|
|
expect($query->sql)->toBe('UPDATE users SET name = :name WHERE id = :id');
|
|
expect($query->parameters->get('name'))->toBe('Jane');
|
|
expect($query->isUpdate())->toBeTrue();
|
|
});
|
|
|
|
it('can create DELETE queries', function () {
|
|
$query = SqlQuery::delete('users', 'id = :id');
|
|
|
|
expect($query->sql)->toBe('DELETE FROM users WHERE id = :id');
|
|
expect($query->isDelete())->toBeTrue();
|
|
});
|
|
|
|
it('can add parameters immutably', function () {
|
|
$query = SqlQuery::create('SELECT * FROM users WHERE id = :id');
|
|
$newQuery = $query->withParameter('id', 123);
|
|
|
|
expect($query->parameters->has('id'))->toBeFalse(); // Original unchanged
|
|
expect($newQuery->parameters->get('id'))->toBe(123);
|
|
});
|
|
|
|
it('can add multiple parameters', function () {
|
|
$query = SqlQuery::create('SELECT * FROM users');
|
|
$newQuery = $query->withParameters(['limit' => 10, 'offset' => 20]);
|
|
|
|
expect($newQuery->parameters->get('limit'))->toBe(10);
|
|
expect($newQuery->parameters->get('offset'))->toBe(20);
|
|
});
|
|
|
|
it('detects query types correctly', function () {
|
|
expect(SqlQuery::create('SELECT * FROM users')->isSelect())->toBeTrue();
|
|
expect(SqlQuery::create('INSERT INTO users VALUES (1)')->isInsert())->toBeTrue();
|
|
expect(SqlQuery::create('UPDATE users SET name = "test"')->isUpdate())->toBeTrue();
|
|
expect(SqlQuery::create('DELETE FROM users')->isDelete())->toBeTrue();
|
|
expect(SqlQuery::create('CREATE TABLE test (id INT)')->isDDL())->toBeTrue();
|
|
expect(SqlQuery::create('ALTER TABLE test ADD column')->isDDL())->toBeTrue();
|
|
expect(SqlQuery::create('DROP TABLE test')->isDDL())->toBeTrue();
|
|
});
|
|
|
|
it('detects modifying queries', function () {
|
|
expect(SqlQuery::create('SELECT * FROM users')->isModifying())->toBeFalse();
|
|
expect(SqlQuery::create('INSERT INTO users VALUES (1)')->isModifying())->toBeTrue();
|
|
expect(SqlQuery::create('UPDATE users SET name = "test"')->isModifying())->toBeTrue();
|
|
expect(SqlQuery::create('DELETE FROM users')->isModifying())->toBeTrue();
|
|
expect(SqlQuery::create('CREATE TABLE test (id INT)')->isModifying())->toBeTrue();
|
|
});
|
|
|
|
it('generates debug string correctly', function () {
|
|
$query = SqlQuery::create('SELECT * FROM users WHERE id = :id AND name = :name', [
|
|
'id' => 123,
|
|
'name' => 'John',
|
|
]);
|
|
|
|
$debug = $query->toDebugString();
|
|
expect($debug)->toContain('123');
|
|
expect($debug)->toContain("'John'");
|
|
expect($debug)->not->toContain(':id');
|
|
expect($debug)->not->toContain(':name');
|
|
});
|
|
|
|
it('converts to string', function () {
|
|
$query = SqlQuery::create('SELECT * FROM users');
|
|
expect($query->toString())->toBe('SELECT * FROM users');
|
|
expect($query->__toString())->toBe('SELECT * FROM users');
|
|
});
|
|
|
|
it('throws exception for empty SQL', function () {
|
|
expect(fn () => new SqlQuery(''))->toThrow(InvalidArgumentException::class);
|
|
expect(fn () => new SqlQuery(' '))->toThrow(InvalidArgumentException::class);
|
|
});
|
|
|
|
it('throws exception for too large SQL', function () {
|
|
$largeSql = str_repeat('SELECT * FROM users; ', 100000); // > 1MB
|
|
expect(fn () => new SqlQuery($largeSql))->toThrow(InvalidArgumentException::class);
|
|
});
|
|
|
|
it('throws exception for empty insert data', function () {
|
|
expect(fn () => SqlQuery::insert('users', []))->toThrow(InvalidArgumentException::class);
|
|
});
|
|
|
|
it('throws exception for empty update data', function () {
|
|
expect(fn () => SqlQuery::update('users', [], 'id = 1'))->toThrow(InvalidArgumentException::class);
|
|
});
|
|
});
|