Total Complexity | 51 |
Total Lines | 580 |
Duplicated Lines | 0 % |
Changes | 9 | ||
Bugs | 0 | Features | 0 |
Complex classes like TableTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use TableTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class TableTest extends SetupTeardown |
||
14 | { |
||
15 | private const INITIAL_RANGE = 'H2:O256'; |
||
16 | |||
17 | public function testToString(): void |
||
18 | { |
||
19 | $expectedResult = self::INITIAL_RANGE; |
||
20 | $table = new Table(self::INITIAL_RANGE); |
||
21 | |||
22 | // magic __toString should return the active table range |
||
23 | $result = (string) $table; |
||
24 | self::assertEquals($expectedResult, $result); |
||
25 | } |
||
26 | |||
27 | /** |
||
28 | * @dataProvider validTableNamesProvider |
||
29 | */ |
||
30 | public function testValidTableNames(string $name, string $expected): void |
||
31 | { |
||
32 | $table = new Table(self::INITIAL_RANGE); |
||
33 | |||
34 | $result = $table->setName($name); |
||
35 | self::assertInstanceOf(Table::class, $result); |
||
36 | self::assertEquals($expected, $table->getName()); |
||
37 | } |
||
38 | |||
39 | public function validTableNamesProvider(): array |
||
40 | { |
||
41 | return [ |
||
42 | ['', ''], |
||
43 | ['Table_1', 'Table_1'], |
||
44 | ['_table_2', '_table_2'], |
||
45 | ['\table_3', '\table_3'], |
||
46 | [" Table_4 \n", 'Table_4'], |
||
47 | ['table.5', 'table.5'], |
||
48 | ['தமிழ்', 'தமிழ்'], // UTF-8 letters with combined character |
||
49 | ]; |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * @dataProvider invalidTableNamesProvider |
||
54 | */ |
||
55 | public function testInvalidTableNames(string $name): void |
||
62 | } |
||
63 | |||
64 | public function invalidTableNamesProvider(): array |
||
80 | ]; |
||
81 | } |
||
82 | |||
83 | public function testUniqueTableNameOnBindToWorksheet(): void |
||
84 | { |
||
85 | $this->expectException(PhpSpreadsheetException::class); |
||
86 | $sheet = $this->getSheet(); |
||
87 | |||
88 | $table1 = new Table(); |
||
89 | $table1->setName('Table_1'); |
||
90 | $sheet->addTable($table1); |
||
91 | |||
92 | $table2 = new Table(); |
||
93 | $table2->setName('tABlE_1'); // case insensitive |
||
94 | $sheet->addTable($table2); |
||
95 | } |
||
96 | |||
97 | public function testUniqueTableNameOnNameChange(): void |
||
98 | { |
||
99 | $this->expectException(PhpSpreadsheetException::class); |
||
100 | $sheet = $this->getSheet(); |
||
101 | |||
102 | $table1 = new Table(); |
||
103 | $table1->setName('Table_1'); |
||
104 | $sheet->addTable($table1); |
||
105 | |||
106 | $table2 = new Table(); |
||
107 | $table2->setName('table_2'); // case insensitive |
||
108 | $sheet->addTable($table2); |
||
109 | $table2->setName('tAbLe_1'); |
||
110 | } |
||
111 | |||
112 | public function testVariousSets(): void |
||
113 | { |
||
114 | $table = new Table(self::INITIAL_RANGE); |
||
115 | |||
116 | $result = $table->setShowHeaderRow(false); |
||
117 | self::assertInstanceOf(Table::class, $result); |
||
118 | self::assertFalse($table->getShowHeaderRow()); |
||
119 | |||
120 | $result = $table->setShowTotalsRow(true); |
||
121 | self::assertInstanceOf(Table::class, $result); |
||
122 | self::assertTrue($table->getShowTotalsRow()); |
||
123 | } |
||
124 | |||
125 | public function testGetWorksheet(): void |
||
126 | { |
||
127 | $sheet = $this->getSheet(); |
||
128 | $table = new Table(self::INITIAL_RANGE); |
||
129 | $sheet->addTable($table); |
||
130 | $result = $table->getWorksheet(); |
||
131 | self::assertSame($sheet, $result); |
||
132 | } |
||
133 | |||
134 | public function testSetWorksheet(): void |
||
135 | { |
||
136 | $table = new Table(self::INITIAL_RANGE); |
||
137 | $spreadsheet = $this->getSpreadsheet(); |
||
138 | $sheet2 = $spreadsheet->createSheet(); |
||
139 | // Setters return the instance to implement the fluent interface |
||
140 | $result = $table->setWorksheet($sheet2); |
||
141 | self::assertInstanceOf(Table::class, $result); |
||
142 | } |
||
143 | |||
144 | public function testGetRange(): void |
||
145 | { |
||
146 | $expectedResult = self::INITIAL_RANGE; |
||
147 | $table = new Table(self::INITIAL_RANGE); |
||
148 | |||
149 | // Result should be the active table range |
||
150 | $result = $table->getRange(); |
||
151 | self::assertEquals($expectedResult, $result); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * @dataProvider validTableRangeProvider |
||
156 | * |
||
157 | * @param AddressRange|array<int>|string $fullRange |
||
158 | * @param string $fullRange |
||
159 | */ |
||
160 | public function testSetRangeValidRange($fullRange, string $actualRange): void |
||
161 | { |
||
162 | $table = new Table(self::INITIAL_RANGE); |
||
163 | |||
164 | $result = $table->setRange($fullRange); |
||
165 | self::assertInstanceOf(Table::class, $result); |
||
166 | self::assertEquals($actualRange, $table->getRange()); |
||
167 | } |
||
168 | |||
169 | public function validTableRangeProvider(): array |
||
170 | { |
||
171 | $sheet = $this->getSheet(); |
||
172 | $title = $sheet->getTitle(); |
||
173 | |||
174 | return [ |
||
175 | ["$title!G1:J512", 'G1:J512'], |
||
176 | ['K1:N20', 'K1:N20'], |
||
177 | [[3, 5, 6, 8], 'C5:F8'], |
||
178 | [new CellRange(new CellAddress('C5', $sheet), new CellAddress('F8', $sheet)), 'C5:F8'], |
||
179 | ]; |
||
180 | } |
||
181 | |||
182 | public function testClearRange(): void |
||
183 | { |
||
184 | $expectedResult = ''; |
||
185 | $table = new Table(self::INITIAL_RANGE); |
||
186 | |||
187 | // Setters return the instance to implement the fluent interface |
||
188 | $result = $table->setRange(''); |
||
189 | self::assertInstanceOf(Table::class, $result); |
||
190 | |||
191 | // Result should be a clear range |
||
192 | $result = $table->getRange(); |
||
193 | self::assertEquals($expectedResult, $result); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * @dataProvider invalidTableRangeProvider |
||
198 | */ |
||
199 | public function testSetRangeInvalidRange(string $range): void |
||
200 | { |
||
201 | $this->expectException(PhpSpreadsheetException::class); |
||
202 | |||
203 | new Table($range); |
||
204 | } |
||
205 | |||
206 | public function invalidTableRangeProvider(): array |
||
207 | { |
||
208 | return [ |
||
209 | ['A1'], |
||
210 | ['A1:A1'], |
||
211 | ['B1:A4'], |
||
212 | ['A1:D1'], |
||
213 | ['D1:A1'], |
||
214 | ]; |
||
215 | } |
||
216 | |||
217 | public function testGetColumnsEmpty(): void |
||
224 | } |
||
225 | |||
226 | public function testGetColumnOffset(): void |
||
227 | { |
||
228 | $columnIndexes = [ |
||
229 | 'H' => 0, |
||
230 | 'K' => 3, |
||
231 | 'M' => 5, |
||
232 | ]; |
||
233 | $table = new Table(self::INITIAL_RANGE); |
||
234 | |||
235 | // If we request a specific column by its column ID, we should get an |
||
236 | // integer returned representing the column offset within the range |
||
237 | foreach ($columnIndexes as $columnIndex => $columnOffset) { |
||
238 | $result = $table->getColumnOffset($columnIndex); |
||
239 | self::assertEquals($columnOffset, $result); |
||
240 | } |
||
241 | } |
||
242 | |||
243 | public function testRemoveColumns(): void |
||
244 | { |
||
245 | $sheet = $this->getSheet(); |
||
246 | $sheet->fromArray(range('H', 'O'), null, 'H2'); |
||
247 | $table = new Table(self::INITIAL_RANGE); |
||
248 | $table->getColumn('L')->setShowFilterButton(false); |
||
249 | $sheet->addTable($table); |
||
250 | |||
251 | $sheet->removeColumn('K', 2); |
||
252 | $result = $table->getRange(); |
||
253 | self::assertEquals('H2:M256', $result); |
||
254 | |||
255 | // Check that the prop that was set for column L is no longer set |
||
256 | self::assertTrue($table->getColumn('L')->getShowFilterButton()); |
||
257 | } |
||
258 | |||
259 | public function testRemoveRows(): void |
||
260 | { |
||
261 | $sheet = $this->getSheet(); |
||
262 | $sheet->fromArray(range('H', 'O'), null, 'H2'); |
||
263 | $table = new Table(self::INITIAL_RANGE); |
||
264 | $sheet->addTable($table); |
||
265 | |||
266 | $sheet->removeRow(42, 128); |
||
267 | $result = $table->getRange(); |
||
268 | self::assertEquals('H2:O128', $result); |
||
269 | } |
||
270 | |||
271 | public function testInsertColumns(): void |
||
272 | { |
||
273 | $sheet = $this->getSheet(); |
||
274 | $sheet->fromArray(range('H', 'O'), null, 'H2'); |
||
275 | $table = new Table(self::INITIAL_RANGE); |
||
276 | $table->getColumn('N')->setShowFilterButton(false); |
||
277 | $sheet->addTable($table); |
||
278 | |||
279 | $sheet->insertNewColumnBefore('N', 3); |
||
280 | $result = $table->getRange(); |
||
281 | self::assertEquals('H2:R256', $result); |
||
282 | |||
283 | // Check that column N no longer has a prop |
||
284 | self::assertTrue($table->getColumn('N')->getShowFilterButton()); |
||
285 | // Check that the prop originally set in column N has been moved to column Q |
||
286 | self::assertFalse($table->getColumn('Q')->getShowFilterButton()); |
||
287 | } |
||
288 | |||
289 | public function testInsertRows(): void |
||
290 | { |
||
291 | $sheet = $this->getSheet(); |
||
292 | $sheet->fromArray(range('H', 'O'), null, 'H2'); |
||
293 | $table = new Table(self::INITIAL_RANGE); |
||
294 | $sheet->addTable($table); |
||
295 | |||
296 | $sheet->insertNewRowBefore(3, 4); |
||
297 | $result = $table->getRange(); |
||
298 | self::assertEquals('H2:O260', $result); |
||
299 | } |
||
300 | |||
301 | public function testGetInvalidColumnOffset(): void |
||
302 | { |
||
303 | $this->expectException(PhpSpreadsheetException::class); |
||
304 | |||
305 | $invalidColumn = 'G'; |
||
306 | $sheet = $this->getSheet(); |
||
307 | $table = new Table(); |
||
308 | $table->setWorksheet($sheet); |
||
309 | |||
310 | $table->getColumnOffset($invalidColumn); |
||
311 | } |
||
312 | |||
313 | public function testSetColumnWithString(): void |
||
314 | { |
||
315 | $expectedResult = 'L'; |
||
316 | $table = new Table(self::INITIAL_RANGE); |
||
317 | |||
318 | // Setters return the instance to implement the fluent interface |
||
319 | $result = $table->setColumn($expectedResult); |
||
320 | self::assertInstanceOf(Table::class, $result); |
||
321 | |||
322 | $result = $table->getColumns(); |
||
323 | // Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\Table\Column |
||
324 | // objects for each column we set indexed by the column ID |
||
325 | self::assertIsArray($result); |
||
326 | self::assertCount(1, $result); |
||
327 | self::assertArrayHasKey($expectedResult, $result); |
||
328 | self::assertInstanceOf(Column::class, $result[$expectedResult]); |
||
329 | } |
||
330 | |||
331 | public function testSetInvalidColumnWithString(): void |
||
332 | { |
||
333 | $this->expectException(PhpSpreadsheetException::class); |
||
334 | $table = new Table(self::INITIAL_RANGE); |
||
335 | |||
336 | $invalidColumn = 'A'; |
||
337 | $table->setColumn($invalidColumn); |
||
338 | } |
||
339 | |||
340 | public function testSetColumnWithColumnObject(): void |
||
357 | } |
||
358 | |||
359 | public function testSetInvalidColumnWithObject(): void |
||
360 | { |
||
361 | $this->expectException(PhpSpreadsheetException::class); |
||
362 | |||
363 | $invalidColumn = 'E'; |
||
364 | $table = new Table(self::INITIAL_RANGE); |
||
365 | $table->setColumn($invalidColumn); |
||
366 | } |
||
367 | |||
368 | public function testSetColumnWithInvalidDataType(): void |
||
369 | { |
||
370 | $this->expectException(PhpSpreadsheetException::class); |
||
371 | |||
372 | $table = new Table(self::INITIAL_RANGE); |
||
373 | $invalidColumn = 123.456; |
||
374 | // @phpstan-ignore-next-line |
||
375 | $table->setColumn($invalidColumn); |
||
376 | } |
||
377 | |||
378 | public function testGetColumns(): void |
||
379 | { |
||
380 | $table = new Table(self::INITIAL_RANGE); |
||
381 | |||
382 | $columnIndexes = ['L', 'M']; |
||
383 | |||
384 | foreach ($columnIndexes as $columnIndex) { |
||
385 | $table->setColumn($columnIndex); |
||
386 | } |
||
387 | |||
388 | $result = $table->getColumns(); |
||
389 | // Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\Table\Column |
||
390 | // objects for each column we set indexed by the column ID |
||
391 | self::assertIsArray($result); |
||
392 | self::assertCount(count($columnIndexes), $result); |
||
393 | foreach ($columnIndexes as $columnIndex) { |
||
394 | self::assertArrayHasKey($columnIndex, $result); |
||
395 | self::assertInstanceOf(Column::class, $result[$columnIndex]); |
||
396 | } |
||
397 | |||
398 | $table->setRange(''); |
||
399 | self::assertCount(0, $table->getColumns()); |
||
400 | self::assertSame('', $table->getRange()); |
||
401 | } |
||
402 | |||
403 | public function testGetColumn(): void |
||
418 | } |
||
419 | } |
||
420 | |||
421 | public function testGetColumnByOffset(): void |
||
422 | { |
||
423 | $table = new Table(self::INITIAL_RANGE); |
||
424 | |||
425 | $columnIndexes = [ |
||
426 | 0 => 'H', |
||
427 | 3 => 'K', |
||
428 | 5 => 'M', |
||
429 | ]; |
||
430 | |||
431 | // If we request a specific column by its offset, we should |
||
432 | // get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\Table\Column object returned |
||
433 | foreach ($columnIndexes as $columnIndex => $columnID) { |
||
434 | $result = $table->getColumnByOffset($columnIndex); |
||
435 | self::assertInstanceOf(Column::class, $result); |
||
436 | self::assertEquals($result->getColumnIndex(), $columnID); |
||
437 | } |
||
438 | } |
||
439 | |||
440 | public function testGetColumnIfNotSet(): void |
||
441 | { |
||
442 | $table = new Table(self::INITIAL_RANGE); |
||
443 | // If we request a specific column by its column ID, we should |
||
444 | // get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\Table\Column object returned |
||
445 | $result = $table->getColumn('K'); |
||
446 | self::assertInstanceOf(Column::class, $result); |
||
447 | } |
||
448 | |||
449 | public function testGetColumnWithoutRangeSet(): void |
||
450 | { |
||
451 | $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); |
||
452 | $table = new Table(self::INITIAL_RANGE); |
||
453 | |||
454 | // Clear the range |
||
455 | $table->setRange(''); |
||
456 | $table->getColumn('A'); |
||
457 | } |
||
458 | |||
459 | public function testClearRangeWithExistingColumns(): void |
||
481 | } |
||
482 | |||
483 | public function testSetRangeWithExistingColumns(): void |
||
484 | { |
||
485 | $table = new Table(self::INITIAL_RANGE); |
||
486 | $expectedResult = 'G1:J512'; |
||
487 | |||
488 | // These columns should be retained |
||
489 | $columnIndexes1 = ['I', 'J']; |
||
490 | foreach ($columnIndexes1 as $columnIndex) { |
||
491 | $table->setColumn($columnIndex); |
||
492 | } |
||
493 | // These columns should be discarded |
||
494 | $columnIndexes2 = ['K', 'L', 'M']; |
||
495 | foreach ($columnIndexes2 as $columnIndex) { |
||
496 | $table->setColumn($columnIndex); |
||
497 | } |
||
498 | |||
499 | // Setters return the instance to implement the fluent interface |
||
500 | $result = $table->setRange($expectedResult); |
||
501 | self::assertInstanceOf(Table::class, $result); |
||
502 | |||
503 | // Range should be correctly set |
||
504 | $result = $table->getRange(); |
||
505 | self::assertEquals($expectedResult, $result); |
||
506 | |||
507 | // Only columns that existed in the original range and that |
||
508 | // still fall within the new range should be retained |
||
509 | $result = $table->getColumns(); |
||
510 | self::assertIsArray($result); |
||
511 | self::assertCount(count($columnIndexes1), $result); |
||
512 | } |
||
513 | |||
514 | public function testClone(): void |
||
545 | } |
||
546 | |||
547 | public function testNoWorksheet(): void |
||
548 | { |
||
549 | $table = new Table(); |
||
550 | self::assertNull($table->getWorksheet()); |
||
551 | } |
||
552 | |||
553 | public function testClearColumn(): void |
||
554 | { |
||
555 | $table = new Table(self::INITIAL_RANGE); |
||
556 | $columnIndexes = ['J', 'K', 'L', 'M']; |
||
557 | |||
558 | foreach ($columnIndexes as $columnIndex) { |
||
559 | $table->setColumn($columnIndex); |
||
560 | } |
||
561 | $columns = $table->getColumns(); |
||
562 | self::assertCount(4, $columns); |
||
563 | self::assertArrayHasKey('J', $columns); |
||
564 | self::assertArrayHasKey('K', $columns); |
||
565 | self::assertArrayHasKey('L', $columns); |
||
566 | self::assertArrayHasKey('M', $columns); |
||
567 | $table->clearColumn('K'); |
||
568 | $columns = $table->getColumns(); |
||
569 | self::assertCount(3, $columns); |
||
570 | self::assertArrayHasKey('J', $columns); |
||
571 | self::assertArrayHasKey('L', $columns); |
||
572 | self::assertArrayHasKey('M', $columns); |
||
573 | } |
||
574 | |||
575 | public function testAutoFilterRule(): void |
||
593 | } |
||
594 | } |
||
595 | } |
||
596 |