Failed Conditions
Pull Request — master (#3261)
by Mark
15:21
created

structuredReferenceProviderColumnData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 24
rs 9.6666
cc 1
nc 1
nop 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Engine;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Engine\Operands\StructuredReference;
6
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8
use PhpOffice\PhpSpreadsheet\Worksheet\Table;
9
use PHPUnit\Framework\TestCase;
10
11
class StructuredReferenceTest extends TestCase
12
{
13
    protected Spreadsheet $spreadSheet;
14
15
    protected const COLUMN_FORMULA = '=[@Sales Amount]*[@[% Commission]]';
16
17
    // Note that column headings may contain a non-breaking space, while the formula may not;
18
    // these still need to match.
19
    protected array $tableData = [
20
        ["Sales\u{a0}Person", 'Region', "Sales\u{a0}Amount", "%\u{a0}Commission", "Commission\u{a0}Amount"],
21
        ['Joe', 'North', 260, '10%', self::COLUMN_FORMULA],
22
        ['Robert', 'South', 660, '15%', self::COLUMN_FORMULA],
23
        ['Michelle', 'East', 940, '15%', self::COLUMN_FORMULA],
24
        ['Erich', 'West', 410, '12%', self::COLUMN_FORMULA],
25
        ['Dafna', 'North', 800, '15%', self::COLUMN_FORMULA],
26
        ['Rob', 'South', 900, '15%', self::COLUMN_FORMULA],
27
        ['Total'],
28
    ];
29
30
    protected function setUp(): void
31
    {
32
        parent::setUp();
33
34
        $this->spreadSheet = new Spreadsheet();
35
        $workSheet = $this->spreadSheet->getActiveSheet();
36
        $workSheet->fromArray($this->tableData, null, 'A1');
37
38
        $table = new Table('A1:E8', 'DeptSales');
39
        $table->setShowTotalsRow(true);
40
        $table->getColumn('A')->setTotalsRowLabel('Total');
41
        $workSheet->addTable($table);
42
    }
43
44
    protected function tearDown(): void
45
    {
46
        $this->spreadSheet->disconnectWorksheets();
47
48
        parent::tearDown();
49
    }
50
51
    public function testStructuredReferenceInvalidTable(): void
52
    {
53
        $cell = $this->spreadSheet->getActiveSheet()->getCell('H5');
54
55
        $this->expectException(Exception::class);
56
        $this->expectExceptionMessage('Table SalesResults for Structured Reference cannot be located');
57
        $structuredReferenceObject = new StructuredReference('SalesResults[@[% Commission]]');
58
        $structuredReferenceObject->parse($cell);
59
    }
60
61
    public function testStructuredReferenceInvalidCellForTable(): void
62
    {
63
        $cell = $this->spreadSheet->getActiveSheet()->getCell('H99');
64
65
        $this->expectException(Exception::class);
66
        $this->expectExceptionMessage('Table for Structured Reference cannot be identified');
67
        $structuredReferenceObject = new StructuredReference('[@[% Commission]]');
68
        $structuredReferenceObject->parse($cell);
69
    }
70
71
    /**
72
     * @dataProvider structuredReferenceProviderColumnData
73
     */
74
    public function testStructuredReferenceColumns(string $expectedCellRange, string $structuredReference): void
75
    {
76
        $cell = $this->spreadSheet->getActiveSheet()->getCell('E5');
77
78
        $structuredReferenceObject = new StructuredReference($structuredReference);
79
        $cellRange = $structuredReferenceObject->parse($cell);
80
        self::assertSame($expectedCellRange, $cellRange);
81
    }
82
83
    /**
84
     * @dataProvider structuredReferenceProviderRowData
85
     */
86
    public function testStructuredReferenceRows(string $expectedCellRange, string $structuredReference): void
87
    {
88
        $cell = $this->spreadSheet->getActiveSheet()->getCell('E5');
89
90
        $structuredReferenceObject = new StructuredReference($structuredReference);
91
        $cellRange = $structuredReferenceObject->parse($cell);
92
        self::assertSame($expectedCellRange, $cellRange);
93
    }
94
95
    public function structuredReferenceProviderColumnData(): array
96
    {
97
        return [
98
            // Full table, with no column specified,  means data only, not headers or totals
99
            'Full table Unqualified' => ['A2:E7', '[]'],
100
            'Full table Qualified' => ['A2:E7', 'DeptSales[]'],
101
            // No item identifier, but with a column identifier, means data and header for the column, but no totals
102
            'Column with no Item Identifier #1' => ['A2:A7', 'DeptSales[[Sales Person]]'],
103
            'Column with no Item Identifier #2' => ['B2:B7', 'DeptSales[Region]'],
104
            // Item identifier with no column specified
105
            'Item Identifier only #1' => ['A1:E1', 'DeptSales[#Headers]'],
106
            'Item Identifier only #2' => ['A1:E1', 'DeptSales[[#Headers]]'],
107
            'Item Identifier only #3' => ['A8:E8', 'DeptSales[#Totals]'],
108
            'Item Identifier only #4' => ['A2:E7', 'DeptSales[#Data]'],
109
            // Item identifiers and column identifiers
110
            'Full column' => ['C1:C8', 'DeptSales[[#All],[Sales Amount]]'],
111
            'Column Header' => ['D1', 'DeptSales[[#Headers],[% Commission]]'],
112
            'Column Total' => ['B8', 'DeptSales[[#Totals],[Region]]'],
113
            'Column Range All' => ['C1:D8', 'DeptSales[[#All],[Sales Amount]:[% Commission]]'],
114
            'Column Range Data' => ['D2:E7', 'DeptSales[[#Data],[% Commission]:[Commission Amount]]'],
115
            'Column Range Headers' => ['B1:E1', 'DeptSales[[#Headers],[Region]:[Commission Amount]]'],
116
            'Column Range Totals' => ['C8:E8', 'DeptSales[[#Totals],[Sales Amount]:[Commission Amount]]'],
117
            'Column Range Headers and Data' => ['D1:D7', 'DeptSales[[#Headers],[#Data],[% Commission]]'],
118
            'Column Range No Item Identifier' => ['A2:B7', 'DeptSales[[Sales Person]:[Region]]'],
119
            //            ['C2:C7,E2:E7', 'DeptSales[Sales Amount],DeptSales[Commission Amount]'],
120
            //            ['B2:C7', 'DeptSales[[Sales Person]:[Sales Amount]] DeptSales[[Region]:[% Commission]]'],
121
        ];
122
    }
123
124
    public function structuredReferenceProviderRowData(): array
125
    {
126
        return [
127
            ['E5', 'DeptSales[[#This Row], [Commission Amount]]'],
128
            ['E5', 'DeptSales[@Commission Amount]'],
129
            ['E5', 'DeptSales[@[Commission Amount]]'],
130
            ['C5:D5', 'DeptSales[@[Sales Amount]:[% Commission]]'],
131
        ];
132
    }
133
}
134