• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MyIntervals / PHP-CSS-Parser / 19810899568

01 Dec 2025 04:07AM UTC coverage: 59.658%. Remained the same
19810899568

Pull #1399

github

web-flow
Merge 8502a50f6 into c29c15a56
Pull Request #1399: [BUGFIX] Parse calc split over multiple lines

0 of 2 new or added lines in 1 file covered. (0.0%)

15 existing lines in 1 file now uncovered.

1118 of 1874 relevant lines covered (59.66%)

25.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Value/CalcFunction.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Sabberworm\CSS\Value;
6

7
use Sabberworm\CSS\Parsing\ParserState;
8
use Sabberworm\CSS\Parsing\UnexpectedEOFException;
9
use Sabberworm\CSS\Parsing\UnexpectedTokenException;
10

11
class CalcFunction extends CSSFunction
12
{
13
    private const T_OPERAND = 1;
14
    private const T_OPERATOR = 2;
15

16
    /**
17
     * @throws UnexpectedTokenException
18
     * @throws UnexpectedEOFException
19
     *
20
     * @internal since V8.8.0
21
     */
UNCOV
22
    public static function parse(ParserState $parserState, bool $ignoreCase = false): CSSFunction
×
23
    {
24
        $operators = ['+', '-', '*', '/'];
×
UNCOV
25
        $function = $parserState->parseIdentifier();
×
26
        if ($parserState->peek() !== '(') {
×
27
            // Found ; or end of line before an opening bracket
28
            throw new UnexpectedTokenException('(', $parserState->peek(), 'literal', $parserState->currentLine());
×
UNCOV
29
        } elseif ($function !== 'calc') {
×
30
            // Found invalid calc definition. Example calc (...
31
            throw new UnexpectedTokenException('calc', $function, 'literal', $parserState->currentLine());
×
32
        }
33
        $parserState->consume('(');
×
UNCOV
34
        $calcRuleValueList = new CalcRuleValueList($parserState->currentLine());
×
35
        $list = new RuleValueList(',', $parserState->currentLine());
×
36
        $nestingLevel = 0;
×
37
        $lastComponentType = null;
×
38
        while (!$parserState->comes(')') || $nestingLevel > 0) {
×
39
            if ($parserState->isEnd() && $nestingLevel === 0) {
×
40
                break;
×
41
            }
42

UNCOV
43
            $parserState->consumeWhiteSpace();
×
UNCOV
44
            if ($parserState->comes('(')) {
×
45
                $nestingLevel++;
×
46
                $calcRuleValueList->addListComponent($parserState->consume(1));
×
47
                $parserState->consumeWhiteSpace();
×
48
                continue;
×
49
            } elseif ($parserState->comes(')')) {
×
50
                $nestingLevel--;
×
51
                $calcRuleValueList->addListComponent($parserState->consume(1));
×
52
                $parserState->consumeWhiteSpace();
×
53
                continue;
×
54
            }
55
            if ($lastComponentType !== CalcFunction::T_OPERAND) {
×
UNCOV
56
                $value = Value::parsePrimitiveValue($parserState);
×
57
                $calcRuleValueList->addListComponent($value);
×
58
                $lastComponentType = CalcFunction::T_OPERAND;
×
59
            } else {
60
                if (\in_array($parserState->peek(), $operators, true)) {
×
UNCOV
61
                    if (($parserState->comes('-') || $parserState->comes('+'))) {
×
NEW
62
                        $nextChar = $parserState->peek(1, 1);
×
63
                        if (
UNCOV
64
                            $parserState->peek(1, -1) !== ' '
×
NEW
65
                            || !($nextChar === ' ' || $nextChar === "\n" || $nextChar === "\r")
×
66
                        ) {
67
                            throw new UnexpectedTokenException(
×
68
                                " {$parserState->peek()} ",
×
69
                                $parserState->peek(1, -1) . $parserState->peek(2),
×
70
                                'literal',
×
71
                                $parserState->currentLine()
×
72
                            );
73
                        }
74
                    }
UNCOV
75
                    $calcRuleValueList->addListComponent($parserState->consume(1));
×
76
                    $lastComponentType = CalcFunction::T_OPERATOR;
×
77
                } else {
UNCOV
78
                    throw new UnexpectedTokenException(
×
79
                        \sprintf(
×
80
                            'Next token was expected to be an operand of type %s. Instead "%s" was found.',
×
81
                            \implode(', ', $operators),
×
82
                            $parserState->peek()
×
83
                        ),
UNCOV
84
                        '',
×
85
                        'custom',
×
86
                        $parserState->currentLine()
×
87
                    );
88
                }
89
            }
UNCOV
90
            $parserState->consumeWhiteSpace();
×
91
        }
UNCOV
92
        $list->addListComponent($calcRuleValueList);
×
93
        if (!$parserState->isEnd()) {
×
94
            $parserState->consume(')');
×
95
        }
UNCOV
96
        return new CalcFunction($function, $list, ',', $parserState->currentLine());
×
97
    }
98
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc