Completed
Push — master ( 89343c...3e93d4 )
by
unknown
36s queued 25s
created

CellTest::appliedStylingProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpOffice\PhpSpreadsheetTests\Cell;
6
7
use PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder;
8
use PhpOffice\PhpSpreadsheet\Cell\Cell;
9
use PhpOffice\PhpSpreadsheet\Cell\DataType;
10
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
11
use PhpOffice\PhpSpreadsheet\Cell\StringValueBinder;
12
use PhpOffice\PhpSpreadsheet\Exception;
13
use PhpOffice\PhpSpreadsheet\Spreadsheet;
14
use PhpOffice\PhpSpreadsheet\Style\Color;
15
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
16
use PhpOffice\PhpSpreadsheet\Style\Fill;
17
use PhpOffice\PhpSpreadsheet\Style\Style;
18
use PHPUnit\Framework\Attributes\DataProvider;
19
use PHPUnit\Framework\TestCase;
20
21
class CellTest extends TestCase
22
{
23
    private ?Spreadsheet $spreadsheet = null;
24
25
    protected function setUp(): void
26
    {
27
        Cell::setValueBinder(new DefaultValueBinder());
28
    }
29
30
    protected function tearDown(): void
31
    {
32
        Cell::setValueBinder(new DefaultValueBinder());
33
        if ($this->spreadsheet !== null) {
34
            $this->spreadsheet->disconnectWorksheets();
35
            $this->spreadsheet = null;
36
        }
37
    }
38
39
    public function testSetValueBinderOverride(): void
40
    {
41
        $value = '12.5%';
42
        $spreadsheet = new Spreadsheet();
43
44
        $cell = $spreadsheet->getActiveSheet()->getCell('A1');
45
        $cell->setValue($value); // Using the Default Value Binder
46
47
        self::assertSame('12.5%', $cell->getValue());
48
        self::assertSame('General', $cell->getStyle()->getNumberFormat()->getFormatCode());
49
50
        $cell = $spreadsheet->getActiveSheet()->getCell('A2');
51
        $cell->setValue($value, new AdvancedValueBinder()); // Overriding the Default Value Binder
52
53
        self::assertSame(0.125, $cell->getValue());
54
        self::assertSame('0.00%', $cell->getStyle()->getNumberFormat()->getFormatCode());
55
56
        $spreadsheet->disconnectWorksheets();
57
    }
58
59
    public function testSetValueBinderOverride2(): void
60
    {
61
        $value = '12.5%';
62
        $spreadsheet = new Spreadsheet();
63
        Cell::setValueBinder(new AdvancedValueBinder());
64
65
        $cell = $spreadsheet->getActiveSheet()->getCell('A1');
66
        $cell->setValue($value); // Using the Advanced Value Binder
67
68
        self::assertSame(0.125, $cell->getValue());
69
        self::assertSame('0.00%', $cell->getStyle()->getNumberFormat()->getFormatCode());
70
71
        $cell = $spreadsheet->getActiveSheet()->getCell('A2');
72
        $cell->setValue($value, new StringValueBinder()); // Overriding the Advanced Value Binder
73
74
        self::assertSame('12.5%', $cell->getValue());
75
        self::assertSame('General', $cell->getStyle()->getNumberFormat()->getFormatCode());
76
77
        $spreadsheet->disconnectWorksheets();
78
    }
79
80
    #[DataProvider('providerSetValueExplicit')]
81
    public function testSetValueExplicit(mixed $expected, mixed $value, string $dataType): void
82
    {
83
        $spreadsheet = new Spreadsheet();
84
        $cell = $spreadsheet->getActiveSheet()->getCell('A1');
85
        $cell->setValueExplicit($value, $dataType);
86
87
        self::assertSame($expected, $cell->getValue());
88
        $spreadsheet->disconnectWorksheets();
89
    }
90
91
    public static function providerSetValueExplicit(): array
92
    {
93
        return require 'tests/data/Cell/SetValueExplicit.php';
94
    }
95
96
    public function testInvalidIsoDateSetValueExplicit(): void
97
    {
98
        $this->spreadsheet = new Spreadsheet();
99
        $cell = $this->spreadsheet->getActiveSheet()->getCell('A1');
100
101
        $dateValue = '2022-02-29'; // Invalid leap year
102
        $this->expectException(Exception::class);
103
        $this->expectExceptionMessage("Invalid string {$dateValue} supplied for datatype Date");
104
        $cell->setValueExplicit($dateValue, DataType::TYPE_ISO_DATE);
105
    }
106
107
    #[DataProvider('providerSetValueExplicitException')]
108
    public function testSetValueExplicitException(mixed $value, string $dataType): void
109
    {
110
        $this->expectException(Exception::class);
111
112
        $this->spreadsheet = new Spreadsheet();
113
        $cell = $this->spreadsheet->getActiveSheet()->getCell('A1');
114
        $cell->setValueExplicit($value, $dataType);
115
    }
116
117
    public static function providerSetValueExplicitException(): array
118
    {
119
        return require 'tests/data/Cell/SetValueExplicitException.php';
120
    }
121
122
    public function testNoChangeToActiveSheet(): void
123
    {
124
        $spreadsheet = new Spreadsheet();
125
        $sheet1 = $spreadsheet->getActiveSheet();
126
        $sheet1->setTitle('Sheet 1');
127
        $sheet3 = $spreadsheet->createSheet();
128
        $sheet3->setTitle('Sheet 3');
129
        $sheet1->setCellValue('C1', 123);
130
        $sheet1->setCellValue('D1', 124);
131
        $sheet3->setCellValue('A1', "='Sheet 1'!C1+'Sheet 1'!D1");
132
        $sheet1->setCellValue('A1', "='Sheet 3'!A1");
133
        $cell = 'A1';
134
        $spreadsheet->setActiveSheetIndex(0);
135
        self::assertEquals(0, $spreadsheet->getActiveSheetIndex());
136
        $value = $spreadsheet->getActiveSheet()->getCell($cell)->getCalculatedValue();
137
        self::assertEquals(0, $spreadsheet->getActiveSheetIndex());
138
        self::assertEquals(247, $value);
139
        $spreadsheet->disconnectWorksheets();
140
    }
141
142
    public function testDestroyWorksheet(): void
143
    {
144
        $spreadsheet = new Spreadsheet();
145
        $sheet = $spreadsheet->getActiveSheet();
146
        $cell = $sheet->getCell('A1');
147
        self::assertSame($sheet, $cell->getWorksheet());
148
        $this->expectException(Exception::class);
149
        $this->expectExceptionMessage('Worksheet no longer exists');
150
        $spreadsheet->disconnectWorksheets();
151
        $cell->getWorksheet();
152
    }
153
154
    public function testDestroyCell1(): void
155
    {
156
        $spreadsheet = new Spreadsheet();
157
        $sheet = $spreadsheet->getActiveSheet();
158
        $cell = $sheet->getCell('A1');
159
        self::assertSame('A1', $cell->getCoordinate());
160
        $this->expectException(Exception::class);
161
        $this->expectExceptionMessage('Coordinate no longer exists');
162
        $spreadsheet->disconnectWorksheets();
163
        $cell->getCoordinate();
164
    }
165
166
    public function testDestroyCell2(): void
167
    {
168
        $this->spreadsheet = new Spreadsheet();
169
        $sheet = $this->spreadsheet->getActiveSheet();
170
        $cell = $sheet->getCell('A1');
171
        self::assertSame('A1', $cell->getCoordinate());
172
        $this->expectException(Exception::class);
173
        $this->expectExceptionMessage('Coordinate no longer exists');
174
        $parent = $cell->getParent();
175
        if ($parent === null) {
176
            self::fail('Unexpected null parent');
177
        } else {
178
            $parent->delete('A1');
179
            $cell->getCoordinate();
180
        }
181
    }
182
183
    public function testAppliedStyleWithRange(): void
184
    {
185
        $spreadsheet = new Spreadsheet();
186
        $sheet = $spreadsheet->getActiveSheet();
187
        $sheet->setCellValue('A1', -1);
188
        $sheet->setCellValue('A2', 0);
189
        $sheet->setCellValue('A3', 1);
190
191
        $cellRange = 'A1:A3';
192
        $sheet->getStyle($cellRange)->getFont()->setBold(true);
193
194
        $yellowStyle = new Style(false, true);
195
        $yellowStyle->getFill()
196
            ->setFillType(Fill::FILL_SOLID)
197
            ->getStartColor()->setARGB(Color::COLOR_YELLOW);
198
        $greenStyle = new Style(false, true);
199
        $greenStyle->getFill()
200
            ->setFillType(Fill::FILL_SOLID)
201
            ->getStartColor()->setARGB(Color::COLOR_GREEN);
202
        $redStyle = new Style(false, true);
203
        $redStyle->getFill()
204
            ->setFillType(Fill::FILL_SOLID)
205
            ->getStartColor()->setARGB(Color::COLOR_RED);
206
207
        $conditionalStyles = [];
208
        $wizardFactory = new Wizard($cellRange);
209
        /** @var Wizard\CellValue $cellWizard */
210
        $cellWizard = $wizardFactory->newRule(Wizard::CELL_VALUE);
211
212
        $cellWizard->equals(0)
213
            ->setStyle($yellowStyle);
214
        $conditionalStyles[] = $cellWizard->getConditional();
215
216
        $cellWizard->greaterThan(0)
217
            ->setStyle($greenStyle);
218
        $conditionalStyles[] = $cellWizard->getConditional();
219
220
        $cellWizard->lessThan(0)
221
            ->setStyle($redStyle);
222
        $conditionalStyles[] = $cellWizard->getConditional();
223
224
        $sheet->getStyle($cellWizard->getCellRange())
225
            ->setConditionalStyles($conditionalStyles);
226
227
        $style = $sheet->getCell('A1')->getAppliedStyle();
228
        self::assertTrue($style->getFont()->getBold());
229
        self::assertEquals($redStyle->getFill()->getFillType(), $style->getFill()->getFillType());
230
        self::assertEquals($redStyle->getFill()->getStartColor()->getARGB(), $style->getFill()->getStartColor()->getARGB());
231
232
        $style = $sheet->getCell('A2')->getAppliedStyle();
233
        self::assertTrue($style->getFont()->getBold());
234
        self::assertEquals($yellowStyle->getFill()->getFillType(), $style->getFill()->getFillType());
235
        self::assertEquals(
236
            $yellowStyle->getFill()->getStartColor()->getARGB(),
237
            $style->getFill()->getStartColor()->getARGB()
238
        );
239
240
        $style = $sheet->getCell('A3')->getAppliedStyle();
241
        self::assertTrue($style->getFont()->getBold());
242
        self::assertEquals($greenStyle->getFill()->getFillType(), $style->getFill()->getFillType());
243
        self::assertEquals(
244
            $greenStyle->getFill()->getStartColor()->getARGB(),
245
            $style->getFill()->getStartColor()->getARGB()
246
        );
247
        $spreadsheet->disconnectWorksheets();
248
    }
249
250
    #[DataProvider('appliedStylingProvider')]
251
    public function testAppliedStyleSingleCell(string $cellAddress, string $fillStyle, ?string $fillColor): void
252
    {
253
        $spreadsheet = new Spreadsheet();
254
        $sheet = $spreadsheet->getActiveSheet();
255
        $sheet->setCellValue('A1', -1);
256
        $sheet->setCellValue('A2', 0);
257
        $sheet->setCellValue('B1', 0);
258
        $sheet->setCellValue('C1', 1);
259
        $sheet->setCellValue('C2', -1);
260
261
        $cellRange = 'A1:C2';
262
        $sheet->getStyle($cellRange)->getFont()->setBold(true);
263
264
        $yellowStyle = new Style(false, true);
265
        $yellowStyle->getFill()
266
            ->setFillType(Fill::FILL_SOLID)
267
            ->getStartColor()->setARGB(Color::COLOR_YELLOW);
268
        $redStyle = new Style(false, true);
269
        $redStyle->getFill()
270
            ->setFillType(Fill::FILL_SOLID)
271
            ->getStartColor()->setARGB(Color::COLOR_RED);
272
273
        $conditionalCellRange = 'A1:C1';
274
        $conditionalStyles = [];
275
        $wizardFactory = new Wizard($conditionalCellRange);
276
        /** @var Wizard\CellValue $cellWizard */
277
        $cellWizard = $wizardFactory->newRule(Wizard::CELL_VALUE);
278
279
        $cellWizard->equals(0)
280
            ->setStyle($yellowStyle);
281
        $conditionalStyles[] = $cellWizard->getConditional();
282
283
        $cellWizard->lessThan(0)
284
            ->setStyle($redStyle);
285
        $conditionalStyles[] = $cellWizard->getConditional();
286
287
        $sheet->getStyle($cellWizard->getCellRange())
288
            ->setConditionalStyles($conditionalStyles);
289
290
        $style = $sheet->getCell($cellAddress)->getAppliedStyle();
291
292
        self::assertTrue($style->getFont()->getBold());
293
        self::assertEquals($fillStyle, $style->getFill()->getFillType());
294
        if ($fillStyle === Fill::FILL_SOLID) {
295
            self::assertEquals($fillColor, $style->getFill()->getStartColor()->getARGB());
296
        }
297
        $spreadsheet->disconnectWorksheets();
298
    }
299
300
    public static function appliedStylingProvider(): array
301
    {
302
        return [
303
            'A1 - Conditional with Match' => ['A1', Fill::FILL_SOLID, Color::COLOR_RED],
304
            'A2 - No Conditionals' => ['A2', Fill::FILL_NONE, null],
305
            'B1 - Conditional with Match' => ['B1', Fill::FILL_SOLID, Color::COLOR_YELLOW],
306
            'C1 - Conditionals, but No Match' => ['C1', Fill::FILL_NONE, null],
307
            'C2 - No Conditionals' => ['C2', Fill::FILL_NONE, null],
308
        ];
309
    }
310
}
311