From 84d6d983482adfc094cca24087cac454244c2d11 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 16 Sep 2022 01:55:36 +0200 Subject: [PATCH] Unit tests for correctly handling hidden merged cells in Readers --- .../Reader/Ods/HiddenMergeCellsTest.php | 48 ++++++++++++++++++ .../Reader/Xls/HiddenMergeCellsTest.php | 48 ++++++++++++++++++ .../Reader/Xlsx/HiddenMergeCellsTest.php | 48 ++++++++++++++++++ .../data/Reader/Ods/HiddenMergeCellsTest.ods | Bin 0 -> 8045 bytes .../data/Reader/XLS/HiddenMergeCellsTest.xls | Bin 0 -> 5632 bytes .../Reader/XLSX/HiddenMergeCellsTest.xlsx | Bin 0 -> 4576 bytes 6 files changed, 144 insertions(+) create mode 100644 tests/PhpSpreadsheetTests/Reader/Ods/HiddenMergeCellsTest.php create mode 100644 tests/PhpSpreadsheetTests/Reader/Xls/HiddenMergeCellsTest.php create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/HiddenMergeCellsTest.php create mode 100644 tests/data/Reader/Ods/HiddenMergeCellsTest.ods create mode 100644 tests/data/Reader/XLS/HiddenMergeCellsTest.xls create mode 100644 tests/data/Reader/XLSX/HiddenMergeCellsTest.xlsx diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/HiddenMergeCellsTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/HiddenMergeCellsTest.php new file mode 100644 index 00000000..710b292a --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Ods/HiddenMergeCellsTest.php @@ -0,0 +1,48 @@ +spreadsheet = $reader->load($filename); + } + + public function testHiddenMergeCells(): void + { + $c2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('C2')->isInMergeRange(); + self::assertTrue($c2InMergeRange); + $a2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('A2')->isInMergeRange(); + self::assertTrue($a2InMergeRange); + $a2MergeRangeValue = $this->spreadsheet->getActiveSheet()->getCell('A2')->isMergeRangeValueCell(); + self::assertTrue($a2MergeRangeValue); + + $cellArray = $this->spreadsheet->getActiveSheet()->rangeToArray('A2:C2'); + self::assertSame([[12, 4, 3]], $cellArray); + } + + public function testUnmergeHiddenMergeCells(): void + { + $this->spreadsheet->getActiveSheet()->unmergeCells('A2:C2'); + + $c2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('C2')->isInMergeRange(); + self::assertFalse($c2InMergeRange); + $a2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('A2')->isInMergeRange(); + self::assertFalse($a2InMergeRange); + + $cellArray = $this->spreadsheet->getActiveSheet()->rangeToArray('A2:C2', null, false, false, false); + self::assertSame([[12, '=6-B1', '=A2/B2']], $cellArray); + } +} diff --git a/tests/PhpSpreadsheetTests/Reader/Xls/HiddenMergeCellsTest.php b/tests/PhpSpreadsheetTests/Reader/Xls/HiddenMergeCellsTest.php new file mode 100644 index 00000000..c7085281 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xls/HiddenMergeCellsTest.php @@ -0,0 +1,48 @@ +spreadsheet = $reader->load($filename); + } + + public function testHiddenMergeCells(): void + { + $c2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('C2')->isInMergeRange(); + self::assertTrue($c2InMergeRange); + $a2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('A2')->isInMergeRange(); + self::assertTrue($a2InMergeRange); + $a2MergeRangeValue = $this->spreadsheet->getActiveSheet()->getCell('A2')->isMergeRangeValueCell(); + self::assertTrue($a2MergeRangeValue); + + $cellArray = $this->spreadsheet->getActiveSheet()->rangeToArray('A2:C2'); + self::assertSame([[12, 4, 3]], $cellArray); + } + + public function testUnmergeHiddenMergeCells(): void + { + $this->spreadsheet->getActiveSheet()->unmergeCells('A2:C2'); + + $c2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('C2')->isInMergeRange(); + self::assertFalse($c2InMergeRange); + $a2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('A2')->isInMergeRange(); + self::assertFalse($a2InMergeRange); + + $cellArray = $this->spreadsheet->getActiveSheet()->rangeToArray('A2:C2', null, false, false, false); + self::assertSame([[12, '=6-B1', '=A2/B2']], $cellArray); + } +} diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/HiddenMergeCellsTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/HiddenMergeCellsTest.php new file mode 100644 index 00000000..4919cd27 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/HiddenMergeCellsTest.php @@ -0,0 +1,48 @@ +spreadsheet = $reader->load($filename); + } + + public function testHiddenMergeCells(): void + { + $c2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('C2')->isInMergeRange(); + self::assertTrue($c2InMergeRange); + $a2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('A2')->isInMergeRange(); + self::assertTrue($a2InMergeRange); + $a2MergeRangeValue = $this->spreadsheet->getActiveSheet()->getCell('A2')->isMergeRangeValueCell(); + self::assertTrue($a2MergeRangeValue); + + $cellArray = $this->spreadsheet->getActiveSheet()->rangeToArray('A2:C2'); + self::assertSame([[12, 4, 3]], $cellArray); + } + + public function testUnmergeHiddenMergeCells(): void + { + $this->spreadsheet->getActiveSheet()->unmergeCells('A2:C2'); + + $c2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('C2')->isInMergeRange(); + self::assertFalse($c2InMergeRange); + $a2InMergeRange = $this->spreadsheet->getActiveSheet()->getCell('A2')->isInMergeRange(); + self::assertFalse($a2InMergeRange); + + $cellArray = $this->spreadsheet->getActiveSheet()->rangeToArray('A2:C2', null, false, false, false); + self::assertSame([[12, '=6-B1', '=A2/B2']], $cellArray); + } +} diff --git a/tests/data/Reader/Ods/HiddenMergeCellsTest.ods b/tests/data/Reader/Ods/HiddenMergeCellsTest.ods new file mode 100644 index 0000000000000000000000000000000000000000..b8beb972c568a6702fa7e36c61d245776fa8c798 GIT binary patch literal 8045 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 literal 0 HcmV?d00001 diff --git a/tests/data/Reader/XLS/HiddenMergeCellsTest.xls b/tests/data/Reader/XLS/HiddenMergeCellsTest.xls new file mode 100644 index 0000000000000000000000000000000000000000..fefbcecc802d7aafa01a4321bd6667e1a9adcfc5 GIT binary patch literal 5632 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