Skip to content

Commit ebf9027

Browse files
committed
fix: Correct line endings in test files
1 parent 8ff9b51 commit ebf9027

4 files changed

Lines changed: 199 additions & 0 deletions

File tree

tests/Connection/ConnectionTest.php

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,151 @@ public function test_connection_exception_is_thrown_for_bad_credentials(): void
292292
$this->expectException(ConnectionException::class);
293293
$connection->getPDO();
294294
}
295+
296+
/**
297+
* Regression for BUG-3: when no driver is configured, `connect()` should
298+
* read the actual driver name from the live PDO instance.
299+
*/
300+
public function test_connect_reads_driver_name_from_pdo_when_unset(): void
301+
{
302+
$connection = new Connection([
303+
'dsn' => 'sqlite::memory:',
304+
'driver' => '',
305+
'charset' => '',
306+
]);
307+
308+
$connection->getPDO();
309+
self::assertSame('sqlite', $connection->getDriver());
310+
}
311+
312+
public function test_trivial_setters_and_getters_round_trip(): void
313+
{
314+
$connection = SqliteHelper::makeConnection();
315+
316+
$connection->setHost('h')
317+
->setPort(1234)
318+
->setDsn('sqlite::memory:')
319+
->setUsername('u')
320+
->setPassword('p')
321+
->setDriver('mysql')
322+
->setCharset('utf8mb4', 'utf8mb4_unicode_ci')
323+
->setDebug(true);
324+
325+
self::assertSame('h', $connection->getHost());
326+
self::assertSame(1234, $connection->getPort());
327+
self::assertSame('sqlite::memory:', $connection->getDsn());
328+
self::assertSame('u', $connection->getUsername());
329+
self::assertSame('p', $connection->getPassword());
330+
self::assertSame('mysql', $connection->getDriver());
331+
self::assertSame('utf8mb4', $connection->getCharset());
332+
self::assertSame('utf8mb4_unicode_ci', $connection->getCollation());
333+
self::assertTrue($connection->getDebug());
334+
}
335+
336+
public function test_setDriver_rejects_unsafe_identifier(): void
337+
{
338+
$connection = SqliteHelper::makeConnection();
339+
340+
$this->expectException(ConnectionInvalidArgumentException::class);
341+
$connection->setDriver("mysql'; --");
342+
}
343+
344+
public function test_setCharset_rejects_unsafe_collation(): void
345+
{
346+
$connection = SqliteHelper::makeConnection();
347+
348+
$this->expectException(ConnectionInvalidArgumentException::class);
349+
$connection->setCharset('utf8', "utf8'; DROP");
350+
}
351+
352+
public function test_getDatabase_returns_null_for_empty_string(): void
353+
{
354+
$connection = SqliteHelper::makeConnection(['database' => '']);
355+
356+
self::assertNull($connection->getDatabase());
357+
}
358+
359+
/**
360+
* Run the MySQL-only charset branch by spoofing the credentials driver
361+
* to 'mysql' after the underlying PDO has been opened against SQLite.
362+
* SQLite rejects `SET NAMES`, so the method bubbles a PDOException —
363+
* but every branch up to the `exec()` call is exercised.
364+
*/
365+
public function test_applyCharsetAndCollation_mysql_branch_with_collation(): void
366+
{
367+
$connection = SqliteHelper::makeConnection([
368+
'charset' => 'utf8mb4',
369+
'collation' => 'utf8mb4_unicode_ci',
370+
]);
371+
$connection->getPDO();
372+
$this->spoofDriver($connection, 'mysql');
373+
374+
$this->expectException(\PDOException::class);
375+
$this->invokePrivate($connection, 'applyCharsetAndCollation');
376+
}
377+
378+
public function test_applyCharsetAndCollation_mysql_branch_without_collation(): void
379+
{
380+
$connection = SqliteHelper::makeConnection([
381+
'charset' => 'utf8mb4',
382+
'collation' => null,
383+
]);
384+
$connection->getPDO();
385+
$this->spoofDriver($connection, 'mysql');
386+
387+
$this->expectException(\PDOException::class);
388+
$this->invokePrivate($connection, 'applyCharsetAndCollation');
389+
}
390+
391+
public function test_applyCharsetAndCollation_returns_early_for_empty_charset(): void
392+
{
393+
$connection = SqliteHelper::makeConnection(['charset' => '']);
394+
$connection->getPDO();
395+
$this->spoofDriver($connection, 'mysql');
396+
397+
// No exception — early return path.
398+
$this->invokePrivate($connection, 'applyCharsetAndCollation');
399+
self::assertTrue(true);
400+
}
401+
402+
public function test_applyCharsetAndCollation_returns_early_for_unsafe_charset(): void
403+
{
404+
$connection = SqliteHelper::makeConnection(['charset' => 'utf8']);
405+
$connection->getPDO();
406+
$this->spoofDriver($connection, 'mysql');
407+
// Bypass the setter validation by spoofing the charset directly.
408+
$this->spoofCredential($connection, 'charset', "utf8' --");
409+
410+
// No exception — the regex guard catches it before exec.
411+
$this->invokePrivate($connection, 'applyCharsetAndCollation');
412+
self::assertTrue(true);
413+
}
414+
415+
private function spoofDriver(Connection $connection, string $driver): void
416+
{
417+
$this->spoofCredential($connection, 'driver', $driver);
418+
}
419+
420+
private function spoofCredential(Connection $connection, string $key, $value): void
421+
{
422+
$ref = new \ReflectionObject($connection);
423+
$prop = $ref->getProperty('credentials');
424+
$prop->setAccessible(true);
425+
$creds = $prop->getValue($connection);
426+
$creds[$key] = $value;
427+
$prop->setValue($connection, $creds);
428+
}
429+
430+
/**
431+
* @param array<int, mixed> $args
432+
* @return mixed
433+
*/
434+
private function invokePrivate(Connection $connection, string $method, array $args = [])
435+
{
436+
$ref = new \ReflectionObject($connection);
437+
$m = $ref->getMethod($method);
438+
$m->setAccessible(true);
439+
440+
return $m->invokeArgs($connection, $args);
441+
}
295442
}

tests/Connection/Support/LoggerTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ public function test_writes_to_a_file_path_with_placeholders(): void
109109
@rmdir($dir);
110110
}
111111

112+
public function test_returns_false_when_sink_is_an_unsupported_type(): void
113+
{
114+
// Integers, floats and plain objects without `critical()` fall through
115+
// to the final `return false`.
116+
self::assertFalse((new Logger(123))->write('boom'));
117+
self::assertFalse((new Logger(new \stdClass()))->write('boom'));
118+
}
119+
112120
public function test_interpolation_skips_array_and_object_context_values(): void
113121
{
114122
$captured = null;

tests/Connection/Support/QueryLoggerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,19 @@ public function test_clear_empties_the_buffer(): void
4848

4949
self::assertSame([], $logger->all());
5050
}
51+
52+
public function test_isEnabled_reflects_constructor_argument(): void
53+
{
54+
self::assertFalse((new QueryLogger())->isEnabled());
55+
self::assertFalse((new QueryLogger(false))->isEnabled());
56+
self::assertTrue((new QueryLogger(true))->isEnabled());
57+
}
58+
59+
public function test_add_with_null_start_time_records_zero_timer(): void
60+
{
61+
$logger = new QueryLogger(true);
62+
$logger->add('SELECT 1', null, null);
63+
64+
self::assertSame(0.0, $logger->all()[0]['timer']);
65+
}
5166
}

tests/DataMapper/DataMapperTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,35 @@ public function test_getQuery_returns_the_prepared_sql(): void
164164

165165
self::assertSame($sql, $mapper->getQuery());
166166
}
167+
168+
public function test_get_magic_forwards_to_statement_properties(): void
169+
{
170+
$stmt = $this->pdo->prepare('SELECT 1');
171+
$mapper = new DataMapper($stmt);
172+
173+
self::assertSame('SELECT 1', $mapper->queryString);
174+
}
175+
176+
public function test_isset_magic_forwards_to_statement_properties(): void
177+
{
178+
$stmt = $this->pdo->prepare('SELECT 1');
179+
$mapper = new DataMapper($stmt);
180+
181+
self::assertTrue(isset($mapper->queryString));
182+
}
183+
184+
public function test_asLazy_sets_fetch_mode_to_lazy(): void
185+
{
186+
$stmt = $this->pdo->prepare('SELECT id, name FROM users WHERE id = :id');
187+
$mapper = new DataMapper($stmt);
188+
$mapper->bindValue('id', 1);
189+
$mapper->execute();
190+
$mapper->asLazy();
191+
192+
$row = $mapper->row();
193+
// PDORow exposes the columns as properties.
194+
self::assertSame('Alice', $row->name);
195+
}
167196
}
168197

169198
final class UserRow

0 commit comments

Comments
 (0)