PhpSpreadsheet/tests/PhpSpreadsheetTests/Style/StyleTest.php

161 lines
6.0 KiB
PHP
Raw Permalink Normal View History

Add exportArray Method for Styles (#1580) Issue #580 has gone stale since I started work on this. Nevertheless, this implements an exportArray function as an exact counterpart of applyFromArry. I chose the name exportArray to avoid confusion with the existing method getStyleArray, which does something completely different. This change also increases coverage for all the Style classes to 100%, with the exception of Style.php itself. There were several (unchanged) places in Style.php where I did not have sufficient understanding of what was supposed to be happening, so could not create tests. All properties used by applyFromArray are exported by this method. Note that conditional styles are not covered; this is consistent with the fact that they are not covered by applyFromArray. The method is implemented as a final public function in Style/Supervisor, which calls abstract protected function exportArray1, which is implemented in each of the subclasses, and which calls final protected function exportArray2 in Style/Supervisor. So exportArray is usable for any of the subclasses as well. The new method is added to the documentation. The existing documentation for applyFromArray was alphabetized to make it easier to follow. One property (Style quotePrefix) was added to the documentation. Some Borders pseudo-properties (vertical, horizontal, and outline) were documented as usable by applyFromArray, but aren't actually supported - they were removed. The documentation of the properties seemed to use setProperty and getProperty fairly randomly - it now uses setProperty exclusively. New constants were added for the textRotation "angles" used to create a "stacked" cell. I felt that changing the readers and writers to use these constants was beyond the scope of this change, but it is on my to-do list.
2020-10-26 19:56:24 +00:00
<?php
namespace PhpOffice\PhpSpreadsheetTests\Style;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
Apply Column and Row Styles to Existing Cells (#1721) * Apply Column and Row Styles to Existing Cells This is a fix for issue #1712. When a style is applied to an entire row or column, it is currently only effective for cells which don't already contain a value. The code needs to iterate through existing cells in the row/column in order to apply the style to them. This could be considered a breaking change, however, I believe that the change makes things operate as users would expect, and that the existing implementation is incomplete. The change also removes protected element conditionalStyles from the Style class. That element is an unused remnant, and can no longer be set or retrieved - methods getConditionalStyles and setConditionalStyles actually act on an element in the Worksheet class. Finally, additional tests are added so that Style, and in fact the entire Style directory, now has 100% test coverage. * Scrutinizer Changes Scrutinizer flagged 6 statements. 5 can be easily corrected. One is absolutely wrong (it thinks iterating through cells in column can return null). Let's see if we can satisfy it. * Remove Exception For CellIterator on Empty Row/Column For my first attempt at this change, which corrects a bug by updating styles for non-empty cells when a style is set on a row or column, I wished to make things more efficient by using setIterateOnlyExistingCells, something which the existing documentation recommends. This caused an exception to be generated when the row or column is empty. So I removed that part of the change while I researched what was going on. I have completed that research. The existing code does throw an exception when the row/column is empty and iterateOnlyExistingCells is true. However, that does not seem like a reasonable action. This situation is analagous to iterating over an empty array, and that action is legal and does not throw. The same should apply here. There were no tests for this situation, and now there are. I have added additional tests, and coverage for all of RowCellIterator, ColumnCellIterator, and CellIterator are all now 100%. Some of my new tests were added in new members, because the existing tests all relied on mocking, which was not the best choice for the new tests. One of the existing tests for RowCellIteratorTest (testSeekOutOfRange) was wrong; it issued the expected exception, but for the wrong reason. I have added an additional test to ensure that it fails "correctly". The existing documentation says that the default value for IterateOnlyExistingCells is true. In fact, the default value is false. I have corrected the documentation. * More Scrutinizer I believe its analysis is incorrect, but this should silence it. * DocBlock Correction ColumnCellIterator DocBlock for current indicated it could return null or Cell, but it can really return only Cell. This had caused Scrutinizer to complain earlier. * PHP8 Environment Appears to be Fixed Cosmetic change to Doc member. I suspect there is a way to rerun all the tests without another push, but I have been unable to figure out how.
2020-12-10 17:19:56 +00:00
use PhpOffice\PhpSpreadsheet\Style\Fill;
Add exportArray Method for Styles (#1580) Issue #580 has gone stale since I started work on this. Nevertheless, this implements an exportArray function as an exact counterpart of applyFromArry. I chose the name exportArray to avoid confusion with the existing method getStyleArray, which does something completely different. This change also increases coverage for all the Style classes to 100%, with the exception of Style.php itself. There were several (unchanged) places in Style.php where I did not have sufficient understanding of what was supposed to be happening, so could not create tests. All properties used by applyFromArray are exported by this method. Note that conditional styles are not covered; this is consistent with the fact that they are not covered by applyFromArray. The method is implemented as a final public function in Style/Supervisor, which calls abstract protected function exportArray1, which is implemented in each of the subclasses, and which calls final protected function exportArray2 in Style/Supervisor. So exportArray is usable for any of the subclasses as well. The new method is added to the documentation. The existing documentation for applyFromArray was alphabetized to make it easier to follow. One property (Style quotePrefix) was added to the documentation. Some Borders pseudo-properties (vertical, horizontal, and outline) were documented as usable by applyFromArray, but aren't actually supported - they were removed. The documentation of the properties seemed to use setProperty and getProperty fairly randomly - it now uses setProperty exclusively. New constants were added for the textRotation "angles" used to create a "stacked" cell. I felt that changing the readers and writers to use these constants was beyond the scope of this change, but it is on my to-do list.
2020-10-26 19:56:24 +00:00
use PHPUnit\Framework\TestCase;
class StyleTest extends TestCase
{
public function testStyleOddMethods(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$cellCoordinate = 'A1';
$cell1 = $sheet->getCell($cellCoordinate);
$cell1style = $cell1->getStyle();
self::assertSame($spreadsheet, $cell1style->getParent());
$styleArray = ['alignment' => ['textRotation' => 45]];
$outArray = $cell1style->getStyleArray($styleArray);
self::assertEquals($styleArray, $outArray['quotePrefix']);
}
Apply Column and Row Styles to Existing Cells (#1721) * Apply Column and Row Styles to Existing Cells This is a fix for issue #1712. When a style is applied to an entire row or column, it is currently only effective for cells which don't already contain a value. The code needs to iterate through existing cells in the row/column in order to apply the style to them. This could be considered a breaking change, however, I believe that the change makes things operate as users would expect, and that the existing implementation is incomplete. The change also removes protected element conditionalStyles from the Style class. That element is an unused remnant, and can no longer be set or retrieved - methods getConditionalStyles and setConditionalStyles actually act on an element in the Worksheet class. Finally, additional tests are added so that Style, and in fact the entire Style directory, now has 100% test coverage. * Scrutinizer Changes Scrutinizer flagged 6 statements. 5 can be easily corrected. One is absolutely wrong (it thinks iterating through cells in column can return null). Let's see if we can satisfy it. * Remove Exception For CellIterator on Empty Row/Column For my first attempt at this change, which corrects a bug by updating styles for non-empty cells when a style is set on a row or column, I wished to make things more efficient by using setIterateOnlyExistingCells, something which the existing documentation recommends. This caused an exception to be generated when the row or column is empty. So I removed that part of the change while I researched what was going on. I have completed that research. The existing code does throw an exception when the row/column is empty and iterateOnlyExistingCells is true. However, that does not seem like a reasonable action. This situation is analagous to iterating over an empty array, and that action is legal and does not throw. The same should apply here. There were no tests for this situation, and now there are. I have added additional tests, and coverage for all of RowCellIterator, ColumnCellIterator, and CellIterator are all now 100%. Some of my new tests were added in new members, because the existing tests all relied on mocking, which was not the best choice for the new tests. One of the existing tests for RowCellIteratorTest (testSeekOutOfRange) was wrong; it issued the expected exception, but for the wrong reason. I have added an additional test to ensure that it fails "correctly". The existing documentation says that the default value for IterateOnlyExistingCells is true. In fact, the default value is false. I have corrected the documentation. * More Scrutinizer I believe its analysis is incorrect, but this should silence it. * DocBlock Correction ColumnCellIterator DocBlock for current indicated it could return null or Cell, but it can really return only Cell. This had caused Scrutinizer to complain earlier. * PHP8 Environment Appears to be Fixed Cosmetic change to Doc member. I suspect there is a way to rerun all the tests without another push, but I have been unable to figure out how.
2020-12-10 17:19:56 +00:00
public function testStyleColumn(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$cellCoordinates = 'A:B';
$styleArray = [
'font' => [
'bold' => true,
],
];
$sheet->getStyle($cellCoordinates)->applyFromArray($styleArray);
$sheet->setCellValue('A1', 'xxxa1');
$sheet->setCellValue('A2', 'xxxa2');
$sheet->setCellValue('A3', 'xxxa3');
$sheet->setCellValue('B1', 'xxxa1');
$sheet->setCellValue('B2', 'xxxa2');
$sheet->setCellValue('B3', 'xxxa3');
$sheet->setCellValue('C1', 'xxxc1');
$sheet->setCellValue('C2', 'xxxc2');
$sheet->setCellValue('C3', 'xxxc3');
$styleArray = [
'font' => [
'italic' => true,
],
];
$sheet->getStyle($cellCoordinates)->applyFromArray($styleArray);
self::assertTrue($sheet->getStyle('A1')->getFont()->getBold());
self::assertTrue($sheet->getStyle('B2')->getFont()->getBold());
self::assertFalse($sheet->getStyle('C3')->getFont()->getBold());
self::assertTrue($sheet->getStyle('A1')->getFont()->getItalic());
self::assertTrue($sheet->getStyle('B2')->getFont()->getItalic());
self::assertFalse($sheet->getStyle('C3')->getFont()->getItalic());
}
public function testStyleRow(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$cellCoordinates = '2:3';
$styleArray = [
'font' => [
'bold' => true,
],
];
$sheet->getStyle($cellCoordinates)->applyFromArray($styleArray);
$sheet->setCellValue('A1', 'xxxa1');
$sheet->setCellValue('A2', 'xxxa2');
$sheet->setCellValue('A3', 'xxxa3');
$sheet->setCellValue('B1', 'xxxa1');
$sheet->setCellValue('B2', 'xxxa2');
$sheet->setCellValue('B3', 'xxxa3');
$sheet->setCellValue('C1', 'xxxc1');
$sheet->setCellValue('C2', 'xxxc2');
$sheet->setCellValue('C3', 'xxxc3');
$styleArray = [
'font' => [
'italic' => true,
],
];
$sheet->getStyle($cellCoordinates)->applyFromArray($styleArray);
self::assertFalse($sheet->getStyle('A1')->getFont()->getBold());
self::assertTrue($sheet->getStyle('B2')->getFont()->getBold());
self::assertTrue($sheet->getStyle('C3')->getFont()->getBold());
self::assertFalse($sheet->getStyle('A1')->getFont()->getItalic());
self::assertTrue($sheet->getStyle('B2')->getFont()->getItalic());
self::assertTrue($sheet->getStyle('C3')->getFont()->getItalic());
}
public function testIssue1712A(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$rgb = '4467b8';
$sheet->fromArray(['OK', 'KO']);
$spreadsheet->getActiveSheet()
->getStyle('A1')
->getFill()
->setFillType(Fill::FILL_SOLID)
->getStartColor()
->setRGB($rgb);
$spreadsheet->getActiveSheet()
->getStyle('B')
->getFill()
->setFillType(Fill::FILL_SOLID)
->getStartColor()
->setRGB($rgb);
self::assertEquals($rgb, $sheet->getCell('A1')->getStyle()->getFill()->getStartColor()->getRGB());
self::assertEquals($rgb, $sheet->getCell('B1')->getStyle()->getFill()->getStartColor()->getRGB());
}
public function testIssue1712B(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$rgb = '4467b8';
$spreadsheet->getActiveSheet()
->getStyle('A1')
->getFill()
->setFillType(Fill::FILL_SOLID)
->getStartColor()
->setRGB($rgb);
$spreadsheet->getActiveSheet()
->getStyle('B')
->getFill()
->setFillType(Fill::FILL_SOLID)
->getStartColor()
->setRGB($rgb);
$sheet->fromArray(['OK', 'KO']);
self::assertEquals($rgb, $sheet->getCell('A1')->getStyle()->getFill()->getStartColor()->getRGB());
self::assertEquals($rgb, $sheet->getCell('B1')->getStyle()->getFill()->getStartColor()->getRGB());
}
public function testStyleLoopUpwards(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$cellCoordinates = 'C5:A3';
$styleArray = [
'font' => [
'bold' => true,
],
];
$sheet->getStyle($cellCoordinates)->applyFromArray($styleArray);
$sheet->setCellValue('A1', 'xxxa1');
$sheet->setCellValue('A2', 'xxxa2');
$sheet->setCellValue('A3', 'xxxa3');
$sheet->setCellValue('B1', 'xxxa1');
$sheet->setCellValue('B2', 'xxxa2');
$sheet->setCellValue('B3', 'xxxa3');
$sheet->setCellValue('C1', 'xxxc1');
$sheet->setCellValue('C2', 'xxxc2');
$sheet->setCellValue('C3', 'xxxc3');
self::assertFalse($sheet->getStyle('A1')->getFont()->getBold());
self::assertFalse($sheet->getStyle('B2')->getFont()->getBold());
self::assertTrue($sheet->getStyle('C3')->getFont()->getBold());
}
Add exportArray Method for Styles (#1580) Issue #580 has gone stale since I started work on this. Nevertheless, this implements an exportArray function as an exact counterpart of applyFromArry. I chose the name exportArray to avoid confusion with the existing method getStyleArray, which does something completely different. This change also increases coverage for all the Style classes to 100%, with the exception of Style.php itself. There were several (unchanged) places in Style.php where I did not have sufficient understanding of what was supposed to be happening, so could not create tests. All properties used by applyFromArray are exported by this method. Note that conditional styles are not covered; this is consistent with the fact that they are not covered by applyFromArray. The method is implemented as a final public function in Style/Supervisor, which calls abstract protected function exportArray1, which is implemented in each of the subclasses, and which calls final protected function exportArray2 in Style/Supervisor. So exportArray is usable for any of the subclasses as well. The new method is added to the documentation. The existing documentation for applyFromArray was alphabetized to make it easier to follow. One property (Style quotePrefix) was added to the documentation. Some Borders pseudo-properties (vertical, horizontal, and outline) were documented as usable by applyFromArray, but aren't actually supported - they were removed. The documentation of the properties seemed to use setProperty and getProperty fairly randomly - it now uses setProperty exclusively. New constants were added for the textRotation "angles" used to create a "stacked" cell. I felt that changing the readers and writers to use these constants was beyond the scope of this change, but it is on my to-do list.
2020-10-26 19:56:24 +00:00
}