Passed
Pull Request — master (#3448)
by Mark
22:11
created

DateValueTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
4
5
use DateTimeImmutable;
6
use DateTimeInterface;
7
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
8
use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue;
9
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
10
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
11
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate;
12
use PhpOffice\PhpSpreadsheet\Spreadsheet;
13
use PhpOffice\PhpSpreadsheetTests\Calculation\Functions\FormulaArguments;
14
use PHPUnit\Framework\TestCase;
15
16
class DateValueTest extends TestCase
17
{
18
    /**
19
     * @var int
20
     */
21
    private $excelCalendar;
22
23
    /**
24
     * @var string
25
     */
26
    private $returnDateType;
27
28
    protected function setUp(): void
29
    {
30
        parent::setUp();
31
32
        $this->excelCalendar = SharedDate::getExcelCalendar();
33
        $this->returnDateType = Functions::getReturnDateType();
34
    }
35
36
    protected function tearDown(): void
37
    {
38
        parent::tearDown();
39
40
        SharedDate::setExcelCalendar($this->excelCalendar);
41
        Functions::setReturnDateType($this->returnDateType);
42
    }
43
44
    private function expectationIsTemplate(string $expectedResult): bool
45
    {
46
        return is_string($expectedResult) && substr($expectedResult, 0, 2) === 'Y-';
47
    }
48
49
    private function parseTemplatedExpectation(string $expectedResult): string
50
    {
51
        return (string) DateValue::fromString(
52
            (new DateTimeImmutable(
53
                str_replace('Y', (new DateTimeImmutable('now'))->format('Y'), $expectedResult)
54
            ))->format('Y-m-d')
55
        );
56
    }
57
58
    /**
59
     * @dataProvider providerDATEVALUE
60
     *
61
     * @param mixed $expectedResult
62
     */
63
    public function testDirectCallToDATEVALUE($expectedResult, ...$args): void
64
    {
65
        if ($this->expectationIsTemplate($expectedResult)) {
66
            $expectedResult = $this->parseTemplatedExpectation($expectedResult);
67
        }
68
69
        /** @scrutinizer ignore-call */
70
        $result = DateValue::fromString(...$args);
71
        self::assertEqualsWithDelta($expectedResult, $result, 1.0e-8);
72
    }
73
74
    /**
75
     * @dataProvider providerDATEVALUE
76
     *
77
     * @param mixed $expectedResult
78
     */
79
    public function testDATEVALUEAsFormula($expectedResult, ...$args): void
80
    {
81
        if ($this->expectationIsTemplate($expectedResult)) {
82
            $expectedResult = $this->parseTemplatedExpectation($expectedResult);
83
        }
84
85
        $arguments = new FormulaArguments(...$args);
86
87
        $calculation = Calculation::getInstance();
88
        $formula = "=DATEVALUE({$arguments})";
89
90
        $result = $calculation->_calculateFormulaValue($formula);
91
        self::assertEqualsWithDelta($expectedResult, $result, 1.0e-8);
92
    }
93
94
    /**
95
     * @dataProvider providerDATEVALUE
96
     *
97
     * @param mixed $expectedResult
98
     */
99
    public function testDATEVALUEInWorksheet($expectedResult, ...$args): void
100
    {
101
        if ($this->expectationIsTemplate($expectedResult)) {
102
            $expectedResult = $this->parseTemplatedExpectation($expectedResult);
103
        }
104
105
        $arguments = new FormulaArguments(...$args);
106
107
        $spreadsheet = new Spreadsheet();
108
        $worksheet = $spreadsheet->getActiveSheet();
109
        $argumentCells = $arguments->populateWorksheet($worksheet);
110
        $formula = "=DATEVALUE({$argumentCells})";
111
112
        $result = $worksheet->setCellValue('A1', $formula)
113
            ->getCell('A1')
114
            ->getCalculatedValue();
115
        self::assertEqualsWithDelta($expectedResult, $result, 1.0e-8);
116
117
        $spreadsheet->disconnectWorksheets();
118
    }
119
120
    public function providerDATEVALUE(): array
121
    {
122
        return require 'tests/data/Calculation/DateTime/DATEVALUE.php';
123
    }
124
125
    /**
126
     * @dataProvider providerUnhappyDATEVALUE
127
     */
128
    public function testDATEVALUEUnhappyPath(string $expectedException, ...$args): void
129
    {
130
        $arguments = new FormulaArguments(...$args);
131
132
        $spreadsheet = new Spreadsheet();
133
        $worksheet = $spreadsheet->getActiveSheet();
134
        $argumentCells = $arguments->populateWorksheet($worksheet);
135
        $formula = "=DATEVALUE({$argumentCells})";
136
137
        $this->expectException(CalculationException::class);
138
        $this->expectExceptionMessage($expectedException);
139
        $worksheet->setCellValue('A1', $formula)
140
            ->getCell('A1')
141
            ->getCalculatedValue();
142
143
        $spreadsheet->disconnectWorksheets();
144
    }
145
146
    public function providerUnhappyDATEVALUE(): array
147
    {
148
        return [
149
            ['Formula Error: Wrong number of arguments for DATEVALUE() function'],
150
        ];
151
    }
152
153
    public function testDATEVALUEtoUnixTimestamp(): void
154
    {
155
        Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
156
157
        $result = DateValue::fromString('2012-1-31');
158
        self::assertEquals(1327968000, $result);
159
        self::assertEqualsWithDelta(1327968000, $result, 1E-8);
160
    }
161
162
    public function testDATEVALUEtoDateTimeObject(): void
163
    {
164
        Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
165
166
        $result = DateValue::fromString('2012-1-31');
167
        //    Must return an object...
168
        self::assertIsObject($result);
169
        //    ... of the correct type
170
        self::assertTrue(is_a($result, DateTimeInterface::class));
171
        //    ... with the correct value
172
        self::assertEquals($result->format('d-M-Y'), '31-Jan-2012');
173
    }
174
175
    public function testDATEVALUEWith1904Calendar(): void
176
    {
177
        SharedDate::setExcelCalendar(SharedDate::CALENDAR_MAC_1904);
178
179
        self::assertEquals(5428, DateValue::fromString('1918-11-11'));
180
        self::assertEquals(0, DateValue::fromString('1904-01-01'));
181
        self::assertEquals('#VALUE!', DateValue::fromString('1903-12-31'));
182
        self::assertEquals('#VALUE!', DateValue::fromString('1900-02-29'));
183
    }
184
185
    /**
186
     * @dataProvider providerDateValueArray
187
     */
188
    public function testDateValueArray(array $expectedResult, string $array): void
189
    {
190
        $calculation = Calculation::getInstance();
191
192
        $formula = "=DATEVALUE({$array})";
193
        $result = $calculation->_calculateFormulaValue($formula);
194
        self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
195
    }
196
197
    public function providerDateValueArray(): array
198
    {
199
        return [
200
            'row vector' => [[[44562, 44724, 45129]], '{"2022-01-01", "2022-06-12", "2023-07-22"}'],
201
            'column vector' => [[[44562], [44564], [44567]], '{"2022-01-01"; "2022-01-03"; "2022-01-06"}'],
202
            'matrix' => [[[44562, 44571], [44788, 44926]], '{"2022-01-01", "2022-01-10"; "2022-08-15", "2022-12-31"}'],
203
        ];
204
    }
205
}
206