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