1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
"""Tests for the type system."""
from scss.types import Color, Null, Number, String
import pytest
# Operators: arithmetic (+ - * / %), unary (+ -), comparison (== != < > <= >=), boolean
# Types: numbers, colors, strings, booleans, lists
# Test them all!
def test_addition():
# Numbers are a little complicated, what with all the units
# Simple case
assert Number(123) + Number(456) == Number(579)
# Simple equal units
assert Number(1, "px") + Number(2, "px") == Number(3, "px")
# Unitless values inherit units of the other operand
assert Number(5) + Number(6, "px") == Number(11, "px")
# Zero values can cast to any units
assert Number(0, "in") + Number(24, "deg") == Number(24, "deg")
# With different units, the left operand wins
assert Number(10, "cm") + Number(100, "mm") == Number(20, "cm")
assert Number(100, "mm") + Number(10, "cm") == Number(200, "mm")
# Unconvertible units raise an error
with pytest.raises(ValueError):
Number(1, "px") + Number(1, "em")
# Adding anything to a string makes a string
assert Number(123) + String('abc') == String('123abc')
assert String('abc') + Number(123) == String('abc123')
ret = String('abc', quotes=None) + String('def', quotes=None)
assert ret == String('abcdef')
assert ret.quotes is None
ret = String('abc', quotes='"') + String('def', quotes=None)
assert ret == String('abcdef')
assert ret.quotes is '"'
ret = String('abc', quotes=None) + String('def', quotes='"')
assert ret == String('abcdef')
assert ret.quotes is None
assert Color.from_hex('#010305') + Color.from_hex('#050301') == Color.from_hex('#060606')
assert Color.from_name('white') + Color.from_name('white') == Color.from_name('white')
def test_subtraction():
assert Number(123) - Number(456) == Number(-333)
assert Number(456) - Number(123) == Number(333)
# TODO test that subtracting e.g. strings doesn't work
assert Color.from_hex('#0f0f0f') - Color.from_hex('#050505') == Color.from_hex('#0a0a0a')
def test_division():
assert Number(5, "px") / Number(5, "px") == Number(1)
assert Number(1, "in") / Number(6, "pt") == Number(12)
def test_comparison_numeric():
lo = Number(123)
hi = Number(456)
assert lo < hi
assert lo <= hi
assert lo <= lo
assert hi > lo
assert hi >= lo
assert hi >= hi
assert lo == lo
assert lo != hi
# Same tests, negated
assert not lo > hi
assert not lo >= hi
assert not hi < lo
assert not hi <= lo
assert not lo != lo
assert not lo == hi
# Numbers with units should also auto-cast numbers with units
units = Number(123, "px")
plain = Number(123)
assert units == plain
assert units <= plain
assert units >= plain
assert not units != plain
assert not units < plain
assert not units > plain
# Incompatible units have... rules.
ems = Number(100, "em")
pxs = Number(100, "px")
with pytest.raises(ValueError):
ems < pxs
with pytest.raises(ValueError):
ems > pxs
with pytest.raises(ValueError):
ems <= pxs
with pytest.raises(ValueError):
ems >= pxs
assert not ems == pxs
assert ems != pxs
def test_comparison_stringerific():
abc = String('abc')
xyz = String('xyz')
assert abc == abc
assert abc != xyz
assert not abc == xyz
assert not abc != abc
# Interaction with other types
assert Number(123) != String('123')
assert String('123') != Number(123)
# Sass strings don't support ordering
with pytest.raises(TypeError):
abc < xyz
with pytest.raises(TypeError):
abc <= xyz
with pytest.raises(TypeError):
abc > xyz
with pytest.raises(TypeError):
abc >= xyz
with pytest.raises(TypeError):
Number(123) < String('123')
def test_comparison_null():
null = Null()
assert null == null
assert null != Number(0)
with pytest.raises(TypeError):
null < null
# TODO write more! i'm lazy.
|