diff --git a/src/PhpSpreadsheet/Settings.php b/src/PhpSpreadsheet/Settings.php index 0baf44637..d8007fd00 100644 --- a/src/PhpSpreadsheet/Settings.php +++ b/src/PhpSpreadsheet/Settings.php @@ -155,7 +155,7 @@ class Settings /** * Sets the implementation of cache that should be used for cell collection. */ - public static function setCache(CacheInterface $cache): void + public static function setCache(?CacheInterface $cache): void { self::$cache = $cache; } diff --git a/src/PhpSpreadsheet/Shared/Font.php b/src/PhpSpreadsheet/Shared/Font.php index 9d160537a..90c1992a3 100644 --- a/src/PhpSpreadsheet/Shared/Font.php +++ b/src/PhpSpreadsheet/Shared/Font.php @@ -380,15 +380,15 @@ class Font $approximate = self::$autoSizeMethod === self::AUTOSIZE_METHOD_APPROX; $columnWidth = 0; if (!$approximate) { - $columnWidthAdjust = ceil( - self::getTextWidthPixelsExact( - str_repeat('n', 1 * (($filterAdjustment ? 3 : 1) + ($indentAdjustment * 2))), - $font, - 0 - ) * 1.07 - ); - try { + $columnWidthAdjust = ceil( + self::getTextWidthPixelsExact( + str_repeat('n', 1 * (($filterAdjustment ? 3 : 1) + ($indentAdjustment * 2))), + $font, + 0 + ) * 1.07 + ); + // Width of text in pixels excl. padding // and addition because Excel adds some padding, just use approx width of 'n' glyph $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + $columnWidthAdjust; @@ -561,10 +561,13 @@ class Font if (mb_strlen(self::$trueTypeFontPath) > 1 && mb_substr(self::$trueTypeFontPath, -1) !== '/' && mb_substr(self::$trueTypeFontPath, -1) !== '\\') { $separator = DIRECTORY_SEPARATOR; } - $fontFile = self::$trueTypeFontPath . $separator . $fontFile; + $fontFileAbsolute = preg_match('~^([A-Za-z]:)?[/\\\\]~', $fontFile) === 1; + if (!$fontFileAbsolute) { + $fontFile = self::$trueTypeFontPath . $separator . $fontFile; + } // Check if file actually exists - if ($checkPath && !file_exists($fontFile)) { + if ($checkPath && !file_exists($fontFile) && !$fontFileAbsolute) { $alternateName = $name; if ($index !== 'x' && $fontArray[$name][$index] !== $fontArray[$name]['x']) { // Bold but no italic: diff --git a/src/PhpSpreadsheet/Worksheet/PageMargins.php b/src/PhpSpreadsheet/Worksheet/PageMargins.php index 34e1145e0..d51023fcc 100644 --- a/src/PhpSpreadsheet/Worksheet/PageMargins.php +++ b/src/PhpSpreadsheet/Worksheet/PageMargins.php @@ -197,21 +197,6 @@ class PageMargins return $this; } - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } - public static function fromCentimeters(float $value): float { return $value / 2.54; diff --git a/src/PhpSpreadsheet/Worksheet/PageSetup.php b/src/PhpSpreadsheet/Worksheet/PageSetup.php index 22c99ff3b..72c8958c8 100644 --- a/src/PhpSpreadsheet/Worksheet/PageSetup.php +++ b/src/PhpSpreadsheet/Worksheet/PageSetup.php @@ -885,19 +885,4 @@ class PageSetup return $this; } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } } diff --git a/src/PhpSpreadsheet/Worksheet/SheetView.php b/src/PhpSpreadsheet/Worksheet/SheetView.php index 13464c997..697f11c2a 100644 --- a/src/PhpSpreadsheet/Worksheet/SheetView.php +++ b/src/PhpSpreadsheet/Worksheet/SheetView.php @@ -175,19 +175,4 @@ class SheetView return $this; } - - /** - * Implement PHP __clone to create a deep clone, not just a shallow copy. - */ - public function __clone() - { - $vars = get_object_vars($this); - foreach ($vars as $key => $value) { - if (is_object($value)) { - $this->$key = clone $value; - } else { - $this->$key = $value; - } - } - } } diff --git a/tests/PhpSpreadsheetTests/CellReferenceHelperTest.php b/tests/PhpSpreadsheetTests/CellReferenceHelperTest.php index 79172c9cc..15f02d756 100644 --- a/tests/PhpSpreadsheetTests/CellReferenceHelperTest.php +++ b/tests/PhpSpreadsheetTests/CellReferenceHelperTest.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests; use PhpOffice\PhpSpreadsheet\CellReferenceHelper; +use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException; use PHPUnit\Framework\TestCase; class CellReferenceHelperTest extends TestCase @@ -63,6 +64,14 @@ class CellReferenceHelperTest extends TestCase self::assertSame($expectedResult, $result); } + public function testCantUseRange(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Only single cell references'); + $cellReferenceHelper = new CellReferenceHelper('E5', 2, 0); + $cellReferenceHelper->updateCellReference('A1:A6'); + } + public function cellReferenceHelperDeleteColumnsProvider(): array { return [ @@ -252,4 +261,10 @@ class CellReferenceHelperTest extends TestCase 'issue3363 $Z$5' => ['$Z$3', '$Z$5'], ]; } + + public function testCellReferenceHelperDeleteColumnAltogether(): void + { + $cellReferenceHelper = new CellReferenceHelper('E5', -4, 0); + self::assertTrue($cellReferenceHelper->cellAddressInDeleteRange('A5')); + } } diff --git a/tests/PhpSpreadsheetTests/Collection/CellsTest.php b/tests/PhpSpreadsheetTests/Collection/CellsTest.php index 9e662b928..9a59458ae 100644 --- a/tests/PhpSpreadsheetTests/Collection/CellsTest.php +++ b/tests/PhpSpreadsheetTests/Collection/CellsTest.php @@ -79,6 +79,7 @@ class CellsTest extends TestCase $cell3 = $sheet->getCell('C3'); self::assertSame($cell3, $collection->update($cell3), 'should silently add non-existing C3 cell'); self::assertEquals(['A1', 'Z1', 'AA1', 'C3'], $collection->getCoordinates(), 'cell list should contains the C3 cell'); + $spreadsheet->disconnectWorksheets(); } public function testCacheLastCell(): void @@ -89,6 +90,7 @@ class CellsTest extends TestCase $sheet->setCellValue('A1', 1); $sheet->setCellValue('A2', 2); self::assertEquals($cells, $sheet->getCoordinates(), 'list should include last added cell'); + $workbook->disconnectWorksheets(); } public function testCanGetCellAfterAnotherIsDeleted(): void @@ -101,6 +103,7 @@ class CellsTest extends TestCase $collection->delete('A1'); $sheet->setCellValue('A3', 1); self::assertNotNull($collection->get('A2'), 'should be able to get back the cell even when another cell was deleted while this one was the current one'); + $workbook->disconnectWorksheets(); } public function testThrowsWhenCellCannotBeRetrievedFromCache(): void @@ -153,5 +156,31 @@ class CellsTest extends TestCase self::assertEquals('C', $collection->getHighestColumn()); self::assertEquals('A', $collection->getHighestColumn(1)); self::assertEquals('C', $collection->getHighestColumn(4)); + $workbook->disconnectWorksheets(); + } + + public function testGetHighestColumnBad(): void + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + $this->expectExceptionMessage('Row number must be a positive integer'); + $workbook = new Spreadsheet(); + $sheet = $workbook->getActiveSheet(); + $collection = $sheet->getCellCollection(); + + // check for empty sheet + self::assertEquals('A', $collection->getHighestColumn()); + $collection->getHighestColumn(0); + $workbook->disconnectWorksheets(); + } + + public function testRemoveRowBad(): void + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + $this->expectExceptionMessage('Row number must be a positive integer'); + $workbook = new Spreadsheet(); + $sheet = $workbook->getActiveSheet(); + $collection = $sheet->getCellCollection(); + $collection->removeRow(0); + $workbook->disconnectWorksheets(); } } diff --git a/tests/PhpSpreadsheetTests/ReferenceHelper2Test.php b/tests/PhpSpreadsheetTests/ReferenceHelper2Test.php new file mode 100644 index 000000000..076ed1b6f --- /dev/null +++ b/tests/PhpSpreadsheetTests/ReferenceHelper2Test.php @@ -0,0 +1,49 @@ +expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cloning a Singleton'); + $referenceHelper = ReferenceHelper::getInstance(); + clone $referenceHelper; + } + + public function testRenamedWorksheetInFormula(): void + { + $spreadsheet = new Spreadsheet(); + $sheet1 = $spreadsheet->getActiveSheet(); + $referenceHelper = ReferenceHelper::getInstance(); + $referenceHelper->updateNamedFormulae($spreadsheet); // no-op + $sheet2 = $spreadsheet->createSheet(); + $sheet2->setTitle('Sheet2'); + $title2 = $sheet2->getTitle(); + $sheet2->getCell('A1')->setValue(10); + $sheet2->getCell('A2')->setValue(20); + $sheet3 = $spreadsheet->createSheet(); + $sheet3->setTitle('Sheet3'); + $title3 = $sheet3->getTitle(); + $sheet3->getCell('A1')->setValue(30); + $sheet3->getCell('A2')->setValue(40); + $sheet1->getCell('A1')->setValue("=$title2!A1"); + $sheet1->getCell('A2')->setValue("='$title2'!A2"); + $sheet1->getCell('B1')->setValue("=$title3!A1"); + $sheet1->getCell('B2')->setValue("='$title3'!A2"); + $newTitle2 = 'renamedSheet2'; + $sheet2->setTitle($newTitle2); + self::assertSame("=$newTitle2!A1", $sheet1->getCell('A1')->getValue()); + self::assertSame("='$newTitle2'!A2", $sheet1->getCell('A2')->getValue()); + self::assertSame("=$title3!A1", $sheet1->getCell('B1')->getValue()); + self::assertSame("='$title3'!A2", $sheet1->getCell('B2')->getValue()); + self::assertSame([[10, 30], [20, 40]], $sheet1->toArray(null, true, false)); + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php index ac686a298..8b3c4ee9b 100644 --- a/tests/PhpSpreadsheetTests/ReferenceHelperTest.php +++ b/tests/PhpSpreadsheetTests/ReferenceHelperTest.php @@ -16,10 +16,6 @@ use PHPUnit\Framework\TestCase; class ReferenceHelperTest extends TestCase { - protected function setUp(): void - { - } - public function testColumnSort(): void { $columnBase = $columnExpectedResult = [ diff --git a/tests/PhpSpreadsheetTests/SettingsTest.php b/tests/PhpSpreadsheetTests/SettingsTest.php index 532d55b8a..a27bb8d09 100644 --- a/tests/PhpSpreadsheetTests/SettingsTest.php +++ b/tests/PhpSpreadsheetTests/SettingsTest.php @@ -28,6 +28,7 @@ class SettingsTest extends TestCase if (\PHP_VERSION_ID < 80000) { libxml_disable_entity_loader($this->prevValue); } + Settings::setCache(null); } public function testGetXMLSettings(): void @@ -59,4 +60,28 @@ class SettingsTest extends TestCase $this->expectExceptionMessage('Chart renderer must implement'); Settings::setChartRenderer(self::class); } + + public function testInvalidRequestFactory(): void + { + $this->expectException(SpException::class); + $this->expectExceptionMessage('HTTP client must be configured'); + Settings::getRequestFactory(); + } + + public function testCache(): void + { + $cache1 = Settings::getCache(); + self::assertNotNull($cache1); + Settings::setCache(null); + $cache2 = Settings::getCache(); + self::assertEquals($cache1, $cache2); + self::assertNotSame($cache1, $cache2); + $array = ['A1' => 10, 'B2' => 20]; + $cache2->setMultiple($array); + self::assertSame($array, $cache2->getMultiple(array_keys($array))); + self::assertNull($cache2->get('C3')); + $cache2->clear(); + self::assertNull($cache2->get('A1')); + self::assertNull($cache2->get('B2')); + } } diff --git a/tests/PhpSpreadsheetTests/Shared/ExactFontTest.php b/tests/PhpSpreadsheetTests/Shared/ExactFontTest.php new file mode 100644 index 000000000..cbc051b40 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Shared/ExactFontTest.php @@ -0,0 +1,133 @@ + [ + 'x' => 'DejaVuSans.ttf', + 'xb' => 'DejaVuSans-Bold.ttf', + 'xi' => 'DejaVuSans-Oblique.ttf', + 'xbi' => 'DejaVuSans-BoldOblique.ttf', + ], + 'DejaVu Sans Mono' => [ + 'x' => 'DejaVuSansMono.ttf', + 'xb' => 'DejaVuSansMono-Bold.ttf', + 'xi' => 'DejaVuSansMono-Oblique.ttf', + 'xbi' => 'DejaVuSansMono-BoldOblique.ttf', + ], + 'DejaVu Serif Condensed' => [ + 'x' => 'DejaVuSerifCondensed.ttf', + 'xb' => 'DejaVuSerifCondensed-Bold.ttf', + 'xi' => 'DejaVuSerifCondensed-Italic.ttf', + 'xbi' => 'DejaVuSerifCondensed-BoldItalic.ttf', + ], + ]; + + /** @var string */ + private $holdDirectory; + + /** @var string */ + private $holdAutoSizeMethod; + + /** @var string */ + private $directoryName = ''; + + /** @var string */ + private $incompleteMessage = ''; + + protected function setUp(): void + { + $this->holdDirectory = Font::getTrueTypeFontPath(); + $this->holdAutoSizeMethod = Font::getAutoSizeMethod(); + $direc = realpath('vendor/mpdf/mpdf/ttfonts') . DIRECTORY_SEPARATOR; + $fontFile = 'DejaVuSans.ttf'; + $fontPath = $direc . $fontFile; + $this->incompleteMessage = ''; + if (@is_readable($fontPath)) { + if ('6a15e0a7c0367ba77a959ea27ebf11cf' !== md5_file($fontPath)) { + $this->incompleteMessage = 'Font file MD5 hash has changed'; + } + } else { + $this->incompleteMessage = 'Unable to locate font file'; + } + $this->directoryName = $direc; + } + + protected function tearDown(): void + { + Font::setTrueTypeFontPath($this->holdDirectory); + Font::setAutoSizeMethod($this->holdAutoSizeMethod); + $this->directoryName = ''; + } + + /** @dataProvider providerFontData */ + public function testExact(string $fontName, float $excelWidth, float $xmlWidth, float $winWidth, float $ubuntuWidth): void + { + if ($this->incompleteMessage !== '') { + self::markTestIncomplete($this->incompleteMessage); + } + $font = new StyleFont(); + $font->setName($fontName); + $font->setSize(11); + Font::setTrueTypeFontPath($this->directoryName); + Font::setExtraFontArray(self::EXTRA_FONTS); + Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_EXACT); + $exactWidth = Font::calculateColumnWidth($font, "This is $fontName"); + Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_APPROX); + $approxWidth = Font::calculateColumnWidth($font, "This is $fontName"); + if ($excelWidth > 0) { + self::assertGreaterThanOrEqual(max($excelWidth, $xmlWidth), $exactWidth); + // Give ourselves a little wiggle room on upper bound. + self::assertLessThanOrEqual(1.05 * max($winWidth, $ubuntuWidth), $exactWidth); + self::assertNotEquals($exactWidth, $approxWidth); + } else { + self::assertEquals($exactWidth, $approxWidth, 'Use approx when exact font file not found'); + } + } + + public function providerFontData(): array + { + return [ + ['DejaVu Sans', 19.82, 20.453125, 22.5659, 21.709], + ['DejaVu Sans Mono', 29.18, 29.81640625, 31.9922, 31.8494], + ['DejaVu Serif Condensed', 29.55, 30.1796875, 31.9922, 31.1353], + ['Arial', -29.55, 30.1796875, 31.9922, 31.1353], + ]; + } + + public function testRichText(): void + { + // RichText treated as text, using Cell font, not Run Font + $courier = new StyleFont(); + $courier->setName('Courier New'); + $courier->setSize(11); + Font::setAutoSizeMethod(Font::AUTOSIZE_METHOD_APPROX); + $element1 = new Run('A'); + $element2 = new Run('B'); + $element3 = new Run('C'); + $element1->setFont($courier); + $element2->setFont($courier); + $element3->setFont($courier); + $richText = new RichText(); + $richText->setRichTextElements([$element1, $element2, $element3]); + $arial = new StyleFont(); + $arial->setName('Arial'); + $arial->setSize(9); + $widthRich = Font::calculateColumnWidth($arial, $richText); + $widthText = Font::calculateColumnWidth($arial, 'ABC'); + self::assertSame($widthRich, $widthText); + } +} diff --git a/tests/PhpSpreadsheetTests/Shared/FontFileNameTest.php b/tests/PhpSpreadsheetTests/Shared/FontFileNameTest.php index bf12287b3..4f8df7c82 100644 --- a/tests/PhpSpreadsheetTests/Shared/FontFileNameTest.php +++ b/tests/PhpSpreadsheetTests/Shared/FontFileNameTest.php @@ -151,4 +151,35 @@ class FontFileNameTest extends TestCase ['cour.ttf', ['name' => 'Courier New']], ]; } + + /** + * @dataProvider providerOverrideAbsolute + */ + public function testOverrideFilenamesAbsolute(string $expected, array $fontArray): void + { + $realPath = realpath(self::MAC_DIRECTORY) . DIRECTORY_SEPARATOR; + Font::setTrueTypeFontPath(self::DEFAULT_DIRECTORY); + Font::setExtraFontArray([ + 'Arial' => [ + 'x' => $realPath . 'Arial.ttf', + 'xb' => $realPath . 'Arial Bold.ttf', + 'xi' => $realPath . 'Arial Italic.ttf', + 'xbi' => $realPath . 'Arial Bold Italic.ttf', + ], + ]); + $font = (new StyleFont())->applyFromArray($fontArray); + $result = Font::getTrueTypeFontFileFromFont($font); + self::assertSame($expected, basename($result)); + } + + public function providerOverrideAbsolute(): array + { + return [ + 'absolute path normal' => ['Arial.ttf', ['name' => 'Arial']], + 'absolute path bold' => ['Arial Bold.ttf', ['name' => 'Arial', 'bold' => true]], + 'absolute path italic' => ['Arial Italic.ttf', ['name' => 'Arial', 'italic' => true]], + 'absolute path bold italic' => ['Arial Bold Italic.ttf', ['name' => 'Arial', 'bold' => true, 'italic' => true]], + 'non-absolute path uses TrueTypeFontPath' => ['cour.ttf', ['name' => 'Courier New']], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Worksheet/SheetViewTest.php b/tests/PhpSpreadsheetTests/Worksheet/SheetViewTest.php new file mode 100644 index 000000000..f37c79581 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Worksheet/SheetViewTest.php @@ -0,0 +1,44 @@ +getView()); + $sheetView->setView(SheetView::SHEETVIEW_PAGE_LAYOUT); + self::assertSame(SheetView::SHEETVIEW_PAGE_LAYOUT, $sheetView->getView()); + $sheetView->setView(null); + self::assertSame(SheetView::SHEETVIEW_NORMAL, $sheetView->getView()); + } + + public function testBadView(): void + { + $this->expectException(PhpSpreadsheetException::class); + $this->expectExceptionMessage('Invalid sheetview layout type.'); + $sheetView = new SheetView(); + $sheetView->setView('unknown'); + } + + public function testBadZoomScaleNormal(): void + { + $this->expectException(PhpSpreadsheetException::class); + $this->expectExceptionMessage('Scale must be greater than or equal to 1.'); + $sheetView = new SheetView(); + $sheetView->setZoomScaleNormal(0); + } + + public function testBadZoomScale(): void + { + $this->expectException(PhpSpreadsheetException::class); + $this->expectExceptionMessage('Scale must be greater than or equal to 1.'); + $sheetView = new SheetView(); + $sheetView->setZoomScale(0); + } +} diff --git a/tests/PhpSpreadsheetTests/Worksheet/Worksheet2Test.php b/tests/PhpSpreadsheetTests/Worksheet/Worksheet2Test.php new file mode 100644 index 000000000..519852eb6 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Worksheet/Worksheet2Test.php @@ -0,0 +1,210 @@ +getStyles()); + $worksheet->disconnectCells(); + self::assertSame([], $worksheet->getCoordinates()); + } + + public function testHighestColumn(): void + { + $worksheet = new Worksheet(); + $worksheet->getCell('A1')->setValue(1); + $worksheet->getCell('B1')->setValue(2); + $worksheet->getCell('A2')->setValue(3); + self::assertSame('B', $worksheet->getHighestColumn(1)); + self::assertSame('A', $worksheet->getHighestColumn(2)); + } + + public function testHighestRow(): void + { + $worksheet = new Worksheet(); + $worksheet->getCell('A1')->setValue(1); + $worksheet->getCell('B1')->setValue(2); + $worksheet->getCell('B2')->setValue(3); + self::assertSame(1, $worksheet->getHighestRow('A')); + self::assertSame(2, $worksheet->getHighestRow('B')); + self::assertSame(['row' => 2, 'column' => 'B'], $worksheet->getHighestRowAndColumn()); + } + + public function testUnmergeNonRange(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Merge can only be removed from a range'); + $worksheet = new Worksheet(); + $worksheet->unmergeCells('A1'); + } + + public function testUnprotectNotProtected(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell range A1:B2 not known as protected'); + $worksheet = new Worksheet(); + $worksheet->unprotectCells('A1:B2'); + } + + public function testFreezeRange(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Freeze pane can not be set on a range'); + $worksheet = new Worksheet(); + $worksheet->freezePane('A1:B2'); + } + + private function getPane(Worksheet $sheet): ?string + { + return $sheet->getFreezePane(); + } + + public function testFreeze(): void + { + $worksheet = new Worksheet(); + $worksheet->freezePane('A1'); + $freeze = $this->getPane($worksheet); + self::assertSame('A1', $freeze); + $worksheet->unfreezePane(); + // Scrutinizer is an idiot. If it still complains, I give up. + self::assertNull($this->getPane($worksheet)); + } + + public function testInsertBeforeRowOne(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Rows can only be inserted before at least row 1'); + $worksheet = new Worksheet(); + $worksheet->insertNewRowBefore(0); + } + + public function testRemoveBeforeRowOne(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Rows to be deleted should at least start from row 1'); + $worksheet = new Worksheet(); + $worksheet->removeRow(0); + } + + public function testInsertNumericColumn(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Column references should not be numeric'); + $worksheet = new Worksheet(); + $worksheet->insertNewColumnBefore('0'); + } + + public function testRemoveNumericColumn(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Column references should not be numeric'); + $worksheet = new Worksheet(); + $worksheet->removeColumn('0'); + } + + public function testInsertColumnByIndexBeforeOne(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Columns can only be inserted before at least column A (1)'); + $worksheet = new Worksheet(); + $worksheet->insertNewColumnBeforeByIndex(0); + } + + public function testRemoveColumnByIndexBeforeOne(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Columns to be deleted should at least start from column A (1)'); + $worksheet = new Worksheet(); + $worksheet->removeColumnByIndex(0); + } + + public function testInsertColumnByIndex(): void + { + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->getCell('A1')->setValue(10); + $worksheet->insertNewColumnBeforeByIndex(1); + self::assertSame(10, $worksheet->getCell('B1')->getValue()); + self::assertNull($worksheet->getCell('A1')->getValue()); + $spreadsheet->disconnectWorksheets(); + } + + public function testRemoveColumnByIndex(): void + { + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->getCell('B1')->setValue(10); + $worksheet->removeColumnByIndex(1); + self::assertSame(10, $worksheet->getCell('A1')->getValue()); + self::assertNull($worksheet->getCell('B1')->getValue()); + $spreadsheet->disconnectWorksheets(); + } + + public function testRemoveCommentInvalid1(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell coordinate string can not be a range'); + $worksheet = new Worksheet(); + $worksheet->removeComment('A1:B2'); + } + + public function testRemoveCommentInvalid2(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell coordinate string must not be absolute'); + $worksheet = new Worksheet(); + $worksheet->removeComment('$A$1'); + } + + public function testRemoveCommentInvalid3(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell coordinate can not be zero-length string'); + $worksheet = new Worksheet(); + $worksheet->removeComment(''); + } + + public function testGetCommentInvalid1(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell coordinate string can not be a range'); + $worksheet = new Worksheet(); + $worksheet->getComment('A1:B2'); + } + + public function testGetCommentInvalid2(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell coordinate string must not be absolute'); + $worksheet = new Worksheet(); + $worksheet->getComment('$A$1'); + } + + public function testGetCommentInvalid3(): void + { + $this->expectException(SpreadsheetException::class); + $this->expectExceptionMessage('Cell coordinate can not be zero-length string'); + $worksheet = new Worksheet(); + $worksheet->getComment(''); + } + + public function testResetTabColor(): void + { + $worksheet = new Worksheet(); + self::assertSame('FF000000', $worksheet->getTabColor()->getArgb()); + $worksheet->getTabColor()->setArgb('FF800000'); + self::assertSame('FF800000', $worksheet->getTabColor()->getArgb()); + $worksheet->resetTabColor(); + self::assertSame('FF000000', $worksheet->getTabColor()->getArgb()); + } +} diff --git a/tests/PhpSpreadsheetTests/Worksheet/Worksheet3Test.php b/tests/PhpSpreadsheetTests/Worksheet/Worksheet3Test.php new file mode 100644 index 000000000..04320cb83 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Worksheet/Worksheet3Test.php @@ -0,0 +1,61 @@ +getPageSetup()->setOrientation('landscape'); + $pageSetup = clone $worksheet1->getPageSetup(); + $worksheet2 = new Worksheet(); + $worksheet2->setPageSetup($pageSetup); + self::assertSame('landscape', $worksheet2->getPageSetup()->getOrientation()); + } + + public function testPageMargins(): void + { + $worksheet1 = new Worksheet(); + $worksheet1->getPageMargins()->setLeft(0.75); + $pageMargins = clone $worksheet1->getPageMargins(); + $worksheet2 = new Worksheet(); + $worksheet2->setPageMargins($pageMargins); + self::assertSame(0.75, $worksheet2->getPageMargins()->getLeft()); + } + + public function testHeaderFooter(): void + { + $worksheet1 = new Worksheet(); + $worksheet1->getHeaderFooter()->setDifferentOddEven(true); + $headerFooter = clone $worksheet1->getHeaderFooter(); + $worksheet2 = new Worksheet(); + $worksheet2->setHeaderFooter($headerFooter); + self::assertTrue($worksheet2->getHeaderFooter()->getDifferentOddEven()); + } + + public function testSheetView(): void + { + $worksheet1 = new Worksheet(); + $worksheet1->getSheetView()->setView('pageLayout'); + $sheetView = clone $worksheet1->getSheetView(); + $worksheet2 = new Worksheet(); + $worksheet2->setSheetView($sheetView); + self::assertSame('pageLayout', $worksheet2->getSheetView()->getView()); + } + + public function testProtection(): void + { + $worksheet1 = new Worksheet(); + $worksheet1->getProtection()->setSpinCount(4321); + $protection = clone $worksheet1->getProtection(); + $worksheet2 = new Worksheet(); + $worksheet2->setProtection($protection); + self::assertSame(4321, $worksheet2->getProtection()->getSpinCount()); + } +} diff --git a/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php b/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php index 6458c4c30..4f2c33d18 100644 --- a/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php +++ b/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php @@ -86,6 +86,7 @@ class WorksheetTest extends TestCase return [ [str_repeat('a', 32), 'Maximum 31 characters allowed in sheet code name.'], ['invalid*code*name', 'Invalid character found in sheet code name'], + ['', 'Sheet code name cannot be empty'], ]; }