PhpQuickProfilerTest   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 338
Duplicated Lines 9.47 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 10
Bugs 1 Features 8
Metric Value
wmc 26
c 10
b 1
f 8
lcom 1
cbo 5
dl 32
loc 338
rs 10

23 Methods

Rating   Name   Duplication   Size   Complexity  
A tearDownAfterClass() 0 4 1
A setUpBeforeClass() 0 20 1
A testConstruct() 0 10 1
A testSetConsole() 8 8 1
A testSetDisplay() 0 8 1
A testGatherFileData() 0 16 2
A testGatherMemoryData() 0 14 1
A testSetProfiledQueries() 0 8 1
B testGatherQueryData() 0 27 3
A testGatherQueryDataInternalProfiler() 0 10 1
A testExplainQuery() 0 12 1
A testExplainQueryBadQueryException() 0 11 1
A testExplainQueryBadParametersException() 12 12 1
A testGetExplainQuery() 0 15 1
A testGetExplainQueryUnsupportedDriver() 12 12 1
A testGatherSpeedData() 0 15 1
B testDisplay() 0 30 1
A testDisplayNothingSetException() 0 5 1
A testDisplayNoConsoleException() 0 7 1
A testDisplayNoDisplayException() 0 7 1
A dataProfiledQueries() 0 15 1
A dataConnectionDrivers() 0 13 1
A getAccessibleMethod() 0 7 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Particletree\Pqp;
4
5
use PHPUnit_Framework_Testcase;
6
use ReflectionClass;
7
8
class PhpQuickProfilerTest extends PHPUnit_Framework_TestCase
9
{
10
11
    protected static $dbConnection;
12
13
    public static function setUpBeforeClass()
14
    {
15
        self::$dbConnection = new LoggingPdo('sqlite::memory:');
16
        $createTable = "
17
            CREATE TABLE IF NOT EXISTS `testing` (
18
                `id` integer PRIMARY KEY AUTOINCREMENT,
19
                `title` varchar(60) NOT NULL
20
            );";
21
        self::$dbConnection->exec($createTable);
22
23
        $hydrateTable = "
24
            INSERT INTO `testing`
25
                (`title`)
26
            VALUES
27
                ('alpha'),
28
                ('beta'),
29
                ('charlie'),
30
                ('delta');";
31
        self::$dbConnection->exec($hydrateTable);
32
    }
33
34
    public function testConstruct()
35
    {
36
        $startTime = microtime(true);
37
38
        $profiler = new PhpQuickProfiler();
39
        $this->assertAttributeEquals($startTime, 'startTime', $profiler);
40
41
        $profiler = new PhpQuickProfiler($startTime);
42
        $this->assertAttributeEquals($startTime, 'startTime', $profiler);
43
    }
44
45 View Code Duplication
    public function testSetConsole()
46
    {
47
        $console = new Console();
48
        $profiler = new PhpQuickProfiler();
49
        $profiler->setConsole($console);
50
51
        $this->assertAttributeSame($console, 'console', $profiler);
52
    }
53
54
    public function testSetDisplay()
55
    {
56
        $display = new Display();
57
        $profiler = new PhpQuickProfiler();
58
        $profiler->setDisplay($display);
59
60
        $this->assertAttributeSame($display, 'display', $profiler);
61
    }
62
63
    public function testGatherFileData()
64
    {
65
        $files = get_included_files();
66
        $profiler = new PhpQuickProfiler();
67
        $gatheredFileData = $profiler->gatherFileData();
68
69
        $this->assertInternalType('array', $gatheredFileData);
70
        $this->assertEquals(count($files), count($gatheredFileData));
71
        foreach ($gatheredFileData as $fileData) {
72
            $this->assertInternalType('array', $fileData);
73
            $this->assertArrayHasKey('name', $fileData);
74
            $this->assertContains($fileData['name'], $files);
75
            $this->assertArrayHasKey('size', $fileData);
76
            $this->assertEquals($fileData['size'], filesize($fileData['name']));
77
        }
78
    }
79
80
    public function testGatherMemoryData()
81
    {
82
        $memoryUsage = memory_get_peak_usage();
83
        $allowedLimit = ini_get('memory_limit');
84
        $profiler = new PhpQuickProfiler();
85
        $gatheredMemoryData = $profiler->gatherMemoryData();
86
87
        $this->assertInternalType('array', $gatheredMemoryData);
88
        $this->assertEquals(2, count($gatheredMemoryData));
89
        $this->assertArrayHasKey('used', $gatheredMemoryData);
90
        $this->assertEquals($memoryUsage, $gatheredMemoryData['used']);
91
        $this->assertArrayHasKey('allowed', $gatheredMemoryData);
92
        $this->assertEquals($allowedLimit, $gatheredMemoryData['allowed']);
93
    }
94
95
    public function testSetProfiledQueries()
96
    {
97
        $profiledQueries = $this->dataProfiledQueries();
98
        $profiler = new PhpQuickProfiler();
99
        $profiler->setProfiledQueries($profiledQueries);
100
101
        $this->assertAttributeEquals($profiledQueries, 'profiledQueries', $profiler);
102
    }
103
104
    public function testGatherQueryData()
105
    {
106
        $profiledQueries = $this->dataProfiledQueries();
107
        $profiledQueriesSql = array();
108
        $profiledQueriesTime = array();
109
        foreach ($profiledQueries as $queryData) {
110
            array_push($profiledQueriesSql, $queryData['sql']);
111
            array_push($profiledQueriesTime, $queryData['time']);
112
        }
113
114
        $profiler = new PhpQuickProfiler();
115
        $profiler->setProfiledQueries($profiledQueries);
116
        $gatheredQueryData = $profiler->gatherQueryData(self::$dbConnection);
117
118
        $this->assertInternalType('array', $gatheredQueryData);
119
        $this->assertEquals(count($profiledQueries), count($gatheredQueryData));
120
        foreach ($gatheredQueryData as $queryData) {
121
            $this->assertInternalType('array', $queryData);
122
            $this->assertArrayHasKey('sql', $queryData);
123
            $this->assertContains($queryData['sql'], $profiledQueriesSql);
124
            $this->assertArrayHasKey('explain', $queryData);
125
            $this->assertInternaltype('array', $queryData['explain']);
126
            $this->assertGreaterThan(0, count($queryData['explain']));
127
            $this->assertArrayHasKey('time', $queryData);
128
            $this->assertContains($queryData['time'], $profiledQueriesTime);
129
        }
130
    }
131
132
    public function testGatherQueryDataInternalProfiler()
133
    {
134
        $profiledQueries = $this->dataProfiledQueries();
135
        $dbConnection = self::$dbConnection;
136
        $dbConnection->queries = $profiledQueries;
137
        $profiler = new PhpQuickProfiler();
138
        $profiler->gatherQueryData($dbConnection);
139
140
        $this->assertAttributeSame($profiledQueries, 'profiledQueries', $profiler);
141
    }
142
143
    /**
144
     * @dataProvider dataProfiledQueries
145
     */
146
    public function testExplainQuery($sql, $parameters)
147
    {
148
        $profiler = new PhpQuickProfiler();
149
        $reflectedMethod = $this->getAccessibleMethod($profiler, 'explainQuery');
150
151
        $explainedQuery = $reflectedMethod->invokeArgs(
152
            $profiler,
153
            array(self::$dbConnection, $sql, $parameters)
154
        );
155
        $this->assertInternalType('array', $explainedQuery);
156
        $this->assertGreaterThan(0, count($explainedQuery));
157
    }
158
159
    /**
160
     * @expectedException Exception
161
     */
162
    public function testExplainQueryBadQueryException()
163
    {
164
        $invalidQuery = 'SELECT * FROM `fake_table`';
165
        $profiler = new PhpQuickProfiler();
166
        $reflectedMethod = $this->getAccessibleMethod($profiler, 'explainQuery');
167
168
        $reflectedMethod->invokeArgs(
169
            $profiler,
170
            array(self::$dbConnection, $invalidQuery)
171
        );
172
    }
173
174
    /**
175
     * @expectedException Exception
176
     */
177 View Code Duplication
    public function testExplainQueryBadParametersException()
178
    {
179
        $query = 'SELECT * FROM `testing` WHERE `title` = :title';
180
        $invalidParams = array('id' => 1);
181
        $profiler = new PhpQuickProfiler();
182
        $reflectedMethod = $this->getAccessibleMethod($profiler, 'explainQuery');
183
184
        $reflectedMethod->invokeArgs(
185
            $profiler,
186
            array(self::$dbConnection, $query, $invalidParams)
187
        );
188
    }
189
190
    /**
191
     * @dataProvider dataConnectionDrivers
192
     */
193
    public function testGetExplainQuery($driver, $prefix)
194
    {
195
        $query = 'SELECT * FROM `testing`';
196
        $profiler = new PhpQuickProfiler();
197
        $reflectedMethod = $this->getAccessibleMethod($profiler, 'getExplainQuery');
198
199
        $explainQuery = $reflectedMethod->invokeArgs(
200
            $profiler,
201
            array($query, $driver)
202
        );
203
204
        $explainPrefix = str_replace($query, '', $explainQuery);
205
        $explainPrefix = trim($explainPrefix);
206
        $this->assertEquals($prefix, $explainPrefix);
207
    }
208
209
    /**
210
     * @expectedException Exception
211
     */
212 View Code Duplication
    public function testGetExplainQueryUnsupportedDriver()
213
    {
214
        $query = 'SELECT * FROM `testing`';
215
        $unsupportedDriver = 'zz';
216
        $profiler = new PhpQuickProfiler();
217
        $reflectedMethod = $this->getAccessibleMethod($profiler, 'getExplainQuery');
218
219
        $reflectedMethod->invokeArgs(
220
            $profiler,
221
            array($query, $unsupportedDriver)
222
        );
223
    }
224
225
    public function testGatherSpeedData()
226
    {
227
        $elapsedTime = 1.234;
228
        $startTime = microtime(true) - $elapsedTime;
229
        $allowedTime = ini_get('max_execution_time');
230
        $profiler = new PhpQuickProfiler($startTime);
231
        $gatheredSpeedData = $profiler->gatherSpeedData();
232
233
        $this->assertInternalType('array', $gatheredSpeedData);
234
        $this->assertEquals(2, count($gatheredSpeedData));
235
        $this->assertArrayHasKey('elapsed', $gatheredSpeedData);
236
        $this->assertEquals($elapsedTime, $gatheredSpeedData['elapsed']);
237
        $this->assertArrayHasKey('allowed', $gatheredSpeedData);
238
        $this->assertEquals($allowedTime, $gatheredSpeedData['allowed']);
239
    }
240
241
    public function testDisplay()
242
    {
243
        $console = new Console();
244
        $profiler = new PhpQuickProfiler();
245
246
        $reflectedProfiler = new ReflectionClass(get_class($profiler));
247
        $reflectedProperty = $reflectedProfiler->getProperty('startTime');
248
        $reflectedProperty->setAccessible(true);
249
        $startTime = $reflectedProperty->getValue($profiler);
250
251
        $expectedDisplay = new Display();
252
        $expectedDisplay->setStartTime($startTime);
253
        $expectedDisplay->setConsole($console);
254
        $expectedDisplay->setFileData($profiler->gatherFileData());
255
        $expectedDisplay->setMemoryData($profiler->gatherMemoryData());
256
        $expectedDisplay->setQueryData($profiler->gatherQueryData());
257
        $expectedDisplay->setSpeedData($profiler->gatherSpeedData());
258
        ob_start();
259
        $expectedDisplay->__invoke();
260
        ob_end_clean();
261
262
        $display = new Display();
263
        $profiler->setConsole($console);
264
        $profiler->setDisplay($display);
265
        ob_start();
266
        $profiler->display();
267
        ob_end_clean();
268
269
        $this->assertAttributeEquals($expectedDisplay, 'display', $profiler);
270
    }
271
272
    /**
273
     * @expectedException Exception
274
     */
275
    public function testDisplayNothingSetException()
276
    {
277
        $profiler = new PhpQuickProfiler();
278
        $profiler->display();
279
    }
280
281
    /**
282
     * @expectedException Exception
283
     */
284
    public function testDisplayNoConsoleException()
285
    {
286
        $display = new Display();
287
        $profiler = new PhpQuickProfiler();
288
        $profiler->setDisplay($display);
289
        $profiler->display();
290
    }
291
292
    /**
293
     * @expectedException Exception
294
     */
295
    public function testDisplayNoDisplayException()
296
    {
297
        $console = new Console();
298
        $profiler = new PhpQuickProfiler();
299
        $profiler->setConsole($console);
300
        $profiler->display();
301
    }
302
303
    public function dataProfiledQueries()
304
    {
305
        return array(
306
            array(
307
              'sql' => "SELECT * FROM testing",
308
              'parameters' => array(),
309
              'time' => 25
310
            ),
311
            array(
312
              'sql' => "SELECT id FROM testing WHERE title = :title",
313
              'parameters' => array('title' => 'beta'),
314
              'time' => 5
315
            )
316
        );
317
    }
318
319
    public function dataConnectionDrivers()
320
    {
321
        return array(
322
            array(
323
                'driver' => 'mysql',
324
                'prefix' => 'EXPLAIN'
325
            ),
326
            array(
327
                'driver' => 'sqlite',
328
                'prefix' => 'EXPLAIN QUERY PLAN'
329
            )
330
        );
331
    }
332
333
    protected function getAccessibleMethod(PhpQuickProfiler $profiler, $methodName)
334
    {
335
        $reflectedConsole = new ReflectionClass(get_class($profiler));
336
        $reflectedMethod = $reflectedConsole->getMethod($methodName);
337
        $reflectedMethod->setAccessible(true);
338
        return $reflectedMethod;
339
    }
340
341
    public static function tearDownAfterClass()
342
    {
343
        self::$dbConnection = null;
344
    }
345
}
346