Passed
Pull Request — master (#3275)
by Mark
13:53
created

testStructuredReferenceHeadersHidden()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
c 0
b 0
f 0
dl 0
loc 15
rs 9.9332
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 testStructuredReferenceHeadersHidden(): void
96
    {
97
        $cell = $this->spreadSheet->getActiveSheet()->getCell('K1');
98
        $table = $this->spreadSheet->getActiveSheet()->getTableByName('DeptSales');
1 ignored issue
show
Bug introduced by
Are you sure the assignment to $table is correct as $this->spreadSheet->getA...ableByName('DeptSales') targeting PhpOffice\PhpSpreadsheet...sheet::getTableByName() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
99
        /** @var Table $table */
100
        $structuredReferenceObject = new StructuredReference('DeptSales[[#Headers],[% Commission]]');
101
        $cellRange = $structuredReferenceObject->parse($cell);
102
        self::assertSame('D1', $cellRange);
103
104
        $table->setShowHeaderRow(false);
105
106
        self::expectException(Exception::class);
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCase::expectException() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

106
        self::/** @scrutinizer ignore-call */ 
107
              expectException(Exception::class);
Loading history...
107
        self::expectExceptionMessage('Table Headers are Hidden, and should not be Referenced');
0 ignored issues
show
Bug Best Practice introduced by
The method PHPUnit\Framework\TestCa...xpectExceptionMessage() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
        self::/** @scrutinizer ignore-call */ 
108
              expectExceptionMessage('Table Headers are Hidden, and should not be Referenced');
Loading history...
108
        $structuredReferenceObject = new StructuredReference('DeptSales[[#Headers],[% Commission]]');
109
        $cellRange = $structuredReferenceObject->parse($cell);
0 ignored issues
show
Unused Code introduced by
The assignment to $cellRange is dead and can be removed.
Loading history...
110
    }
111
112
    public function structuredReferenceProviderColumnData(): array
113
    {
114
        return [
115
            // Full table, with no column specified,  means data only, not headers or totals
116
            'Full table Unqualified' => ['A2:E7', '[]'],
117
            'Full table Qualified' => ['A2:E7', 'DeptSales[]'],
118
            // No item identifier, but with a column identifier, means data and header for the column, but no totals
119
            'Column with no Item Identifier #1' => ['A2:A7', 'DeptSales[[Sales Person]]'],
120
            'Column with no Item Identifier #2' => ['B2:B7', 'DeptSales[Region]'],
121
            // Item identifier with no column specified
122
            'Item Identifier only #1' => ['A1:E1', 'DeptSales[#Headers]'],
123
            'Item Identifier only #2' => ['A1:E1', 'DeptSales[[#Headers]]'],
124
            'Item Identifier only #3' => ['A8:E8', 'DeptSales[#Totals]'],
125
            'Item Identifier only #4' => ['A2:E7', 'DeptSales[#Data]'],
126
            // Item identifiers and column identifiers
127
            'Full column' => ['C1:C8', 'DeptSales[[#All],[Sales Amount]]'],
128
            'Column Header' => ['D1', 'DeptSales[[#Headers],[% Commission]]'],
129
            'Column Total' => ['B8', 'DeptSales[[#Totals],[Region]]'],
130
            'Column Range All' => ['C1:D8', 'DeptSales[[#All],[Sales Amount]:[% Commission]]'],
131
            'Column Range Data' => ['D2:E7', 'DeptSales[[#Data],[% Commission]:[Commission Amount]]'],
132
            'Column Range Headers' => ['B1:E1', 'DeptSales[[#Headers],[Region]:[Commission Amount]]'],
133
            'Column Range Totals' => ['C8:E8', 'DeptSales[[#Totals],[Sales Amount]:[Commission Amount]]'],
134
            'Column Range Headers and Data' => ['D1:D7', 'DeptSales[[#Headers],[#Data],[% Commission]]'],
135
            'Column Range No Item Identifier' => ['A2:B7', 'DeptSales[[Sales Person]:[Region]]'],
136
            //            ['C2:C7,E2:E7', 'DeptSales[Sales Amount],DeptSales[Commission Amount]'],
137
            //            ['B2:C7', 'DeptSales[[Sales Person]:[Sales Amount]] DeptSales[[Region]:[% Commission]]'],
138
        ];
139
    }
140
141
    public function structuredReferenceProviderRowData(): array
142
    {
143
        return [
144
            ['E5', 'DeptSales[[#This Row], [Commission Amount]]'],
145
            ['E5', 'DeptSales[@Commission Amount]'],
146
            ['E5', 'DeptSales[@[Commission Amount]]'],
147
            ['C5:D5', 'DeptSales[@[Sales Amount]:[% Commission]]'],
148
        ];
149
    }
150
}
151