Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.27% covered (warning)
86.27%
44 / 51
61.54% covered (warning)
61.54%
8 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
Less_Tree_Unit
86.27% covered (warning)
86.27%
44 / 51
61.54% covered (warning)
61.54%
8 / 13
39.35
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 clone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 genCSS
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
6.10
 toString
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 compare
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 is
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isLength
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 isAngle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isEmpty
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 isSingular
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 usedUnits
80.00% covered (warning)
80.00%
8 / 10
0.00% covered (danger)
0.00%
0 / 1
8.51
 cancel
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
8
1<?php
2declare( strict_types = 1 );
3
4/**
5 * @private
6 * @see less-2.5.3.js#Unit.prototype
7 */
8class Less_Tree_Unit extends Less_Tree {
9
10    /** @var string[] */
11    public $numerator = [];
12    /** @var string[] */
13    public $denominator = [];
14    /** @var string|null */
15    public $backupUnit;
16
17    public function __construct( $numerator = [], $denominator = [], $backupUnit = null ) {
18        $this->numerator = $numerator;
19        $this->denominator = $denominator;
20        sort( $this->numerator );
21        sort( $this->denominator );
22        $this->backupUnit = $backupUnit ?? $numerator[0] ?? null;
23    }
24
25    public function clone() {
26        // we are recreating a new object to trigger logic from constructor
27        return new Less_Tree_Unit( $this->numerator, $this->denominator, $this->backupUnit );
28    }
29
30    /**
31     * @see Less_Tree::genCSS
32     */
33    public function genCSS( $output ) {
34        $strictUnits = Less_Parser::$options['strictUnits'];
35
36        if ( count( $this->numerator ) === 1 ) {
37            $output->add( $this->numerator[0] ); // the ideal situation
38        } elseif ( !$strictUnits && $this->backupUnit ) {
39            $output->add( $this->backupUnit );
40        } elseif ( !$strictUnits && $this->denominator ) {
41            $output->add( $this->denominator[0] );
42        }
43    }
44
45    public function toString() {
46        $returnStr = implode( '*', $this->numerator );
47        foreach ( $this->denominator as $d ) {
48            $returnStr .= '/' . $d;
49        }
50        return $returnStr;
51    }
52
53    public function __toString() {
54        return $this->toString();
55    }
56
57    /**
58     * @param self $other
59     */
60    public function compare( $other ) {
61        return $this->is( $other->toString() ) ? 0 : -1;
62    }
63
64    public function is( $unitString ) {
65        return strtoupper( $this->toString() ) === strtoupper( $unitString );
66    }
67
68    public function isLength() {
69        $css = $this->toCSS();
70        return (bool)preg_match( '/px|em|%|in|cm|mm|pc|pt|ex/', $css );
71    }
72
73    // TODO: Remove unused method
74    public function isAngle() {
75        return isset( Less_Tree_UnitConversions::$angle[$this->toCSS()] );
76    }
77
78    public function isEmpty() {
79        return !$this->numerator && !$this->denominator;
80    }
81
82    public function isSingular() {
83        return count( $this->numerator ) <= 1 && !$this->denominator;
84    }
85
86    public function usedUnits() {
87        $result = [];
88
89        foreach ( Less_Tree_UnitConversions::$groups as $groupName ) {
90            $group = Less_Tree_UnitConversions::${$groupName};
91
92            foreach ( $this->numerator as $atomicUnit ) {
93                if ( isset( $group[$atomicUnit] ) && !isset( $result[$groupName] ) ) {
94                    $result[$groupName] = $atomicUnit;
95                }
96            }
97
98            foreach ( $this->denominator as $atomicUnit ) {
99                if ( isset( $group[$atomicUnit] ) && !isset( $result[$groupName] ) ) {
100                    $result[$groupName] = $atomicUnit;
101                }
102            }
103        }
104
105        return $result;
106    }
107
108    /**
109     * @see less-2.5.3.js#Unit.prototype.cancel
110     */
111    public function cancel() {
112        $counter = [];
113
114        foreach ( $this->numerator as $atomicUnit ) {
115            $counter[$atomicUnit] = ( $counter[$atomicUnit] ?? 0 ) + 1;
116        }
117
118        foreach ( $this->denominator as $atomicUnit ) {
119            $counter[$atomicUnit] = ( $counter[$atomicUnit] ?? 0 ) - 1;
120        }
121
122        $this->numerator = [];
123        $this->denominator = [];
124
125        foreach ( $counter as $atomicUnit => $count ) {
126            if ( $count > 0 ) {
127                for ( $i = 0; $i < $count; $i++ ) {
128                    $this->numerator[] = $atomicUnit;
129                }
130            } elseif ( $count < 0 ) {
131                for ( $i = 0; $i < -$count; $i++ ) {
132                    $this->denominator[] = $atomicUnit;
133                }
134            }
135        }
136
137        sort( $this->numerator );
138        sort( $this->denominator );
139    }
140
141}