Skip to content

Commit c8dd058

Browse files
committed
improved Writer unit testing
1 parent c2a7c63 commit c8dd058

File tree

5 files changed

+88
-30
lines changed

5 files changed

+88
-30
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66

77
### Added
88
- Added new config param `queries.exclude_pattern` (env var `SQL_REPORTER_QUERIES_EXCLUDE_PATTERN`) to narrow down queries to be logged without bloating include pattern regex.
9+
- Added unit tests for `Writer`, testing query include/exclude patterns and min exec time.
910

1011
### Changed
1112
- Renamed `SQL_REPORTER_QUERIES_PATTERN` env var to `SQL_REPORTER_QUERIES_INCLUDE_PATTERN`
13+
- Renamed methods in `Writer` for clarity.
14+
- Improved testability of `Writer::writeQuery()` by returning true if query was written to log.
1215

1316
## [v0.9 (2021-06-02)](https://github.com/onlime/laravel-sql-reporter/releases/tag/v0.9)
1417

src/SqlLogger.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function log()
2929
{
3030
foreach (DB::getQueryLog() as $query) {
3131
$sqlQuery = new SqlQuery(++$this->queryNumber, $query['query'], $query['bindings'], $query['time']);
32-
$this->writer->save($sqlQuery);
32+
$this->writer->writeQuery($sqlQuery);
3333
}
3434
}
3535
}

src/Writer.php

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,47 +26,52 @@ public function __construct(
2626
) {}
2727

2828
/**
29-
* Save queries to log.
29+
* Write a query to log.
3030
*
3131
* @param SqlQuery $query
32+
* @return bool true if query was written to log, false if skipped
3233
*/
33-
public function save(SqlQuery $query)
34+
public function writeQuery(SqlQuery $query): bool
3435
{
3536
$this->createDirectoryIfNotExists($query->number());
3637

3738
if ($this->shouldLogQuery($query)) {
3839
if (0 === $this->logCount) {
3940
// only write header information on first query to be logged
40-
$this->saveLine(
41+
$this->writeLine(
4142
$this->formatter->getHeader(),
4243
$this->config->queriesOverrideLog()
4344
);
4445
}
45-
$this->saveLine(
46+
$this->writeLine(
4647
$this->formatter->getLine($query)
4748
);
4849
$this->logCount++;
50+
return true;
4951
}
52+
return false;
5053
}
5154

5255
/**
5356
* Create directory if it does not exist yet.
5457
*
5558
* @param int $queryNumber
59+
* @return bool true on successful directory creation
5660
*/
57-
protected function createDirectoryIfNotExists(int $queryNumber)
61+
protected function createDirectoryIfNotExists(int $queryNumber): bool
5862
{
5963
if ($queryNumber == 1 && ! file_exists($directory = $this->directory())) {
60-
mkdir($directory, 0777, true);
64+
return mkdir($directory, 0777, true);
6165
}
66+
return false;
6267
}
6368

6469
/**
6570
* Get directory where file should be located.
6671
*
6772
* @return string
6873
*/
69-
protected function directory()
74+
protected function directory(): string
7075
{
7176
return rtrim($this->config->logDirectory(), '\\/');
7277
}
@@ -75,10 +80,9 @@ protected function directory()
7580
* Verify whether query should be logged.
7681
*
7782
* @param SqlQuery $query
78-
*
7983
* @return bool
8084
*/
81-
protected function shouldLogQuery(SqlQuery $query)
85+
protected function shouldLogQuery(SqlQuery $query): bool
8286
{
8387
return $this->config->queriesEnabled() &&
8488
$query->time() >= $this->config->queriesMinExecTime() &&
@@ -87,14 +91,15 @@ protected function shouldLogQuery(SqlQuery $query)
8791
}
8892

8993
/**
90-
* Save data to log file.
94+
* Write data to log file.
9195
*
9296
* @param string $line
9397
* @param bool $override
98+
* @return int|false the number of bytes that were written to the file, or false on failure.
9499
*/
95-
protected function saveLine(string $line, bool $override = false)
100+
protected function writeLine(string $line, bool $override = false): int|false
96101
{
97-
file_put_contents(
102+
return file_put_contents(
98103
$this->directory() . DIRECTORY_SEPARATOR . $this->fileName->getLogfile(),
99104
$line . PHP_EOL,
100105
$override ? 0 : FILE_APPEND

tests/Unit/SqlLoggerTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public function it_runs_writer_with_valid_query()
3434
]);
3535

3636
$sqlQuery = new SqlQuery(1, 'anything', [], 1.23);
37-
// $this->writer->shouldReceive('save')->once()->with($sqlQuery)
38-
$this->writer->shouldReceive('save')->once()->with(Mockery::on(function($arg) use ($sqlQuery) {
37+
// $this->writer->shouldReceive('writeQuery')->once()->with($sqlQuery)
38+
$this->writer->shouldReceive('writeQuery')->once()->with(Mockery::on(function($arg) use ($sqlQuery) {
3939
return $sqlQuery == $arg;
4040
}));
4141

@@ -52,14 +52,14 @@ public function it_uses_valid_query_number_for_multiple_queries()
5252
]);
5353

5454
$sqlQuery = new SqlQuery(1, 'anything', ['one', 1], 1.23);
55-
// $this->writer->shouldReceive('save')->once()->with($sqlQuery);
56-
$this->writer->shouldReceive('save')->once()->with(Mockery::on(function($arg) use ($sqlQuery) {
55+
// $this->writer->shouldReceive('writeQuery')->once()->with($sqlQuery);
56+
$this->writer->shouldReceive('writeQuery')->once()->with(Mockery::on(function($arg) use ($sqlQuery) {
5757
return $sqlQuery == $arg;
5858
}));
5959

6060
$sqlQuery2 = new SqlQuery(2, 'anything2', ['two', 2], 4.56);
61-
// $this->writer->shouldReceive('save')->once()->with($sqlQuery2);
62-
$this->writer->shouldReceive('save')->once()->with(Mockery::on(function($arg) use ($sqlQuery2) {
61+
// $this->writer->shouldReceive('writeQuery')->once()->with($sqlQuery2);
62+
$this->writer->shouldReceive('writeQuery')->once()->with(Mockery::on(function($arg) use ($sqlQuery2) {
6363
return $sqlQuery2 == $arg;
6464
}));
6565

tests/Unit/WriterTest.php

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function it_creates_directory_if_it_does_not_exist_for_1st_query()
7373
$this->config->shouldReceive('queriesEnabled')->once()->withNoArgs()->andReturn(false);
7474
$this->config->shouldReceive('logDirectory')->once()->withNoArgs()->andReturn($this->directory);
7575
$this->assertFileDoesNotExist($this->directory);
76-
$this->writer->save($query);
76+
$this->writer->writeQuery($query);
7777
$this->assertFileExists($this->directory);
7878
$this->assertEmpty($this->filesystem->allFiles($this->directory));
7979
}
@@ -85,7 +85,7 @@ public function it_does_not_create_directory_if_it_does_not_exist_for_2nd_query(
8585
$this->config->shouldReceive('queriesEnabled')->once()->withNoArgs()->andReturn(false);
8686
$this->config->shouldNotReceive('logDirectory');
8787
$this->assertFileDoesNotExist($this->directory);
88-
$this->writer->save($query);
88+
$this->writer->writeQuery($query);
8989
$this->assertFileDoesNotExist($this->directory);
9090
}
9191

@@ -106,7 +106,7 @@ public function it_creates_log_file()
106106
$this->config->shouldReceive('queriesOverrideLog')->once()->withNoArgs()->andReturn(false);
107107
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
108108
$this->filename->shouldReceive('getLogfile')->times(2)->withNoArgs()->andReturn($expectedFileName);
109-
$this->writer->save($query);
109+
$this->writer->writeQuery($query);
110110
$this->assertFileExists($this->directory);
111111
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
112112
$this->assertFileExists($this->directory . '/' . $expectedFileName);
@@ -135,7 +135,7 @@ public function it_appends_to_existing_log_file()
135135
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
136136
$this->filename->shouldReceive('getLogfile')->times(2)->withNoArgs()->andReturn($expectedFileName);
137137
$this->assertFileExists($this->directory . '/' . $expectedFileName);
138-
$this->writer->save($query);
138+
$this->writer->writeQuery($query);
139139
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
140140
$this->assertFileExists($this->directory . '/' . $expectedFileName);
141141
$this->assertSame($expectedContent, file_get_contents($this->directory . '/' . $expectedFileName));
@@ -163,7 +163,7 @@ public function it_replaces_current_file_content_for_1st_query_when_overriding_i
163163
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
164164
$this->filename->shouldReceive('getLogfile')->times(2)->withNoArgs()->andReturn($expectedFileName);
165165
$this->assertFileExists($this->directory . '/' . $expectedFileName);
166-
$this->writer->save($query);
166+
$this->writer->writeQuery($query);
167167
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
168168
$this->assertFileExists($this->directory . '/' . $expectedFileName);
169169
$this->assertSame($expectedContent, file_get_contents($this->directory . '/' . $expectedFileName));
@@ -192,8 +192,8 @@ public function it_appends_to_current_file_content_for_2nd_query_when_overriding
192192
$this->config->shouldReceive('queriesMinExecTime')->twice()->withNoArgs()->andReturn(0);
193193
$this->filename->shouldReceive('getLogfile')->times(3)->withNoArgs()->andReturn($expectedFileName);
194194
$this->assertFileExists($this->directory . '/' . $expectedFileName);
195-
$this->writer->save($query1);
196-
$this->writer->save($query2);
195+
$this->writer->writeQuery($query1);
196+
$this->writer->writeQuery($query2);
197197
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
198198
$this->assertFileExists($this->directory . '/' . $expectedFileName);
199199
$this->assertSame($expectedContent, file_get_contents($this->directory . '/' . $expectedFileName));
@@ -216,7 +216,7 @@ public function it_saves_select_query_to_file_when_pattern_set_to_select_queries
216216
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
217217
$this->filename->shouldReceive('getLogfile')->twice()->withNoArgs()->andReturn($expectedFileName);
218218
$this->config->shouldReceive('queriesOverrideLog')->once()->withNoArgs()->andReturn(false);
219-
$this->writer->save($query);
219+
$this->writer->writeQuery($query);
220220
$this->assertFileExists($this->directory);
221221
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
222222

@@ -232,7 +232,7 @@ public function it_doesnt_save_select_query_to_file_when_pattern_set_to_insert_o
232232
$this->config->shouldReceive('queriesIncludePattern')->once()->withNoArgs()->andReturn('#^(?:UPDATE|INSERT) .*$#i');
233233
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
234234
$this->config->shouldReceive('logDirectory')->once()->withNoArgs()->andReturn($this->directory);
235-
$this->writer->save($query);
235+
$this->writer->writeQuery($query);
236236
$this->assertFileExists($this->directory);
237237
$this->assertCount(0, $this->filesystem->allFiles($this->directory));
238238
}
@@ -254,7 +254,7 @@ public function it_saves_insert_query_to_file_when_pattern_set_to_insert_or_upda
254254
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
255255
$this->filename->shouldReceive('getLogfile')->twice()->withNoArgs()->andReturn($expectedFileName);
256256
$this->config->shouldReceive('queriesOverrideLog')->once()->withNoArgs()->andReturn(false);
257-
$this->writer->save($query);
257+
$this->writer->writeQuery($query);
258258
$this->assertFileExists($this->directory);
259259
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
260260

@@ -279,11 +279,61 @@ public function it_uses_raw_query_without_bindings_when_using_query_pattern()
279279
$this->filename->shouldReceive('getLogfile')->twice()->withNoArgs()->andReturn($expectedFileName);
280280
$this->config->shouldReceive('queriesMinExecTime')->once()->withNoArgs()->andReturn(0);
281281
$this->config->shouldReceive('queriesOverrideLog')->once()->withNoArgs()->andReturn(false);
282-
$this->writer->save($query);
282+
$this->writer->writeQuery($query);
283283
$this->assertFileExists($this->directory);
284284
$this->assertCount(1, $this->filesystem->allFiles($this->directory));
285285

286286
$this->assertFileExists($this->directory . '/' . $expectedFileName);
287287
$this->assertSame($expectedContent, file_get_contents($this->directory . '/' . $expectedFileName));
288288
}
289+
290+
/** @test */
291+
public function it_only_logs_slow_queries()
292+
{
293+
$query1 = new SqlQuery(1, 'test1', [], 5.41);
294+
$query2 = new SqlQuery(2, 'test2', [], 500.5);
295+
296+
$this->config->shouldReceive('queriesEnabled')->twice()->withNoArgs()->andReturn(true);
297+
$this->config->shouldReceive('logDirectory')->once()->withNoArgs()->andReturn($this->directory);
298+
$this->config->shouldReceive('queriesMinExecTime')->twice()->withNoArgs()->andReturn(500);
299+
$this->config->shouldReceive('queriesIncludePattern')->once()->withNoArgs()->andReturn('/.*/i');
300+
$this->config->shouldReceive('queriesExcludePattern')->once()->withNoArgs()->andReturn('/^$/');
301+
$this->config->shouldReceive('queriesOverrideLog')->once()->withNoArgs()->andReturn(false);
302+
303+
$this->formatter->shouldReceive('getHeader')->once()->withNoArgs()->andReturn('');
304+
$this->formatter->shouldReceive('getLine')->once()->with($query2)->andReturn('');
305+
306+
$writer = Mockery::mock(Writer::class, [$this->formatter, $this->config, $this->filename])
307+
->makePartial()->shouldAllowMockingProtectedMethods();
308+
$writer->shouldReceive('writeLine')->twice()->andReturn(false);
309+
310+
$this->assertFalse($writer->writeQuery($query1));
311+
$this->assertTrue($writer->writeQuery($query2));
312+
}
313+
314+
/** @test */
315+
public function it_respects_query_patterns()
316+
{
317+
$query1 = new SqlQuery(1, 'select foo from bar', [], 5.41);
318+
$query2 = new SqlQuery(2, 'update bar set foo = ?', [1], 3.55);
319+
$query3 = new SqlQuery(3, 'update bar set last_visit = ?', ['2021-06-03 10:26:00'], 3.22);
320+
321+
$this->config->shouldReceive('queriesEnabled')->times(3)->withNoArgs()->andReturn(true);
322+
$this->config->shouldReceive('logDirectory')->once()->withNoArgs()->andReturn($this->directory);
323+
$this->config->shouldReceive('queriesMinExecTime')->times(3)->withNoArgs()->andReturn(0);
324+
$this->config->shouldReceive('queriesIncludePattern')->times(3)->withNoArgs()->andReturn('/^(?!SELECT).*$/i');
325+
$this->config->shouldReceive('queriesExcludePattern')->twice()->withNoArgs()->andReturn('/^UPDATE.*last_visit/i');
326+
$this->config->shouldReceive('queriesOverrideLog')->once()->withNoArgs()->andReturn(false);
327+
328+
$this->formatter->shouldReceive('getHeader')->once()->withNoArgs()->andReturn('');
329+
$this->formatter->shouldReceive('getLine')->once()->with($query2)->andReturn('');
330+
331+
$writer = Mockery::mock(Writer::class, [$this->formatter, $this->config, $this->filename])
332+
->makePartial()->shouldAllowMockingProtectedMethods();
333+
$writer->shouldReceive('writeLine')->twice()->andReturn(false);
334+
335+
$this->assertFalse($writer->writeQuery($query1));
336+
$this->assertTrue($writer->writeQuery($query2));
337+
$this->assertFalse($writer->writeQuery($query3));
338+
}
289339
}

0 commit comments

Comments
 (0)