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
|
from scss.expression import Calculator
from scss.rule import Namespace
from scss.types import NumberValue
from scss.util import to_str
import pytest
def test_reference_operations():
"""Test the example expressions in the reference document:
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#operations
"""
# TODO: break this into its own file and add the entire reference guide
ns = Namespace()
calc = lambda expr: Calculator(ns).evaluate_expression(expr).render()
# Simple example
assert calc('1in + 8pt') == '1.11111in'
# Division
ns.set_variable('$width', '1000px')
ns.set_variable('$font-size', '12px')
ns.set_variable('$line-height', '30px')
assert calc('10px/8px') == '10px / 8px' # plain CSS; no division
assert calc('$width/2') == '500px' # uses a variable; does division
assert calc('(500px/2)') == '250px' # uses parens; does division
assert calc('5px + 8px/2px') == '9px' # uses +; does division
assert calc('#{$font-size}/#{$line-height}') == '12px/30px'
# uses #{}; does no division
# Color operations
ns.set_variable('$translucent-red', 'rgba(255, 0, 0, 0.5)')
ns.set_variable('$green', '#00ff00')
assert calc('#010203 + #040506') == '#050709'
assert calc('#010203 * 2') == '#020406'
assert calc('rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75)') == 'rgba(255, 255, 0, 0.75)'
assert calc('opacify($translucent-red, 0.3)') == 'rgba(255, 0, 0, 0.9)'
assert calc('transparentize($translucent-red, 0.25)') == 'rgba(255, 0, 0, 0.25)'
assert calc("progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}')"
) == "progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr=#FF00FF00, endColorstr=#80FF0000)"
# String operations
ns.set_variable('$value', 'null')
assert calc('e + -resize') == 'e-resize'
assert calc('"Foo " + Bar') == '"Foo Bar"'
assert calc('sans- + "serif"') == 'sans-serif'
assert calc('3px + 4px auto') == '7px auto'
assert calc('"I ate #{5 + 10} pies!"') == '"I ate 15 pies!"'
assert calc('"I ate #{$value} pies!"') == '"I ate pies!"'
# Operators: arithmetic (+ - * / %), unary (+ -), comparison (== != < > <= >=), boolean
# Types: numbers, colors, strings, booleans, lists
# Test them all!
def test_addition():
calc = lambda expr: to_str(Calculator(Namespace()).calculate(expr))
assert calc('123 + 456') == '579'
assert calc('1px + 2px') == '3px'
assert calc('123 + abc') == '123abc'
assert calc('abc + 123') == 'abc123'
assert calc('abc + def') == 'abcdef'
assert calc('abc + "def"') == 'abcdef'
assert calc('"abc" + def') == '"abcdef"'
assert calc('"abc" + "def"') == '"abcdef"'
assert calc('#010305 + #050301') == '#060606'
assert calc('#ffffff + #ffffff') == '#ffffff'
def test_subtraction():
calc = lambda expr: to_str(Calculator(Namespace()).calculate(expr))
assert calc('123 - 456') == '-333'
assert calc('456 - 123') == '333'
# TODO test that subtracting e.g. strings doesn't work
assert calc('#0f0f0f - #050505') == '#0a0a0a'
def test_division():
calc = Calculator(Namespace()).calculate
assert calc('(5px / 5px)') == NumberValue(1)
def test_comparison_numeric():
calc = Calculator(Namespace()).calculate
assert calc('123 < 456')
assert calc('123 <= 456')
assert calc('123 <= 123')
assert calc('456 > 123')
assert calc('456 >= 123')
assert calc('456 >= 456')
assert calc('123 == 123')
assert calc('123 != 456')
# Same tests, negated
assert not calc('123 > 456')
assert not calc('123 >= 456')
assert not calc('456 < 123')
assert not calc('456 <= 123')
assert not calc('123 != 123')
assert not calc('123 == 456')
def test_comparison_stringerific():
calc = Calculator(Namespace()).calculate
assert calc('"abc" == "abc"')
assert calc('"abc" != "xyz"')
# Same tests, negated
assert not calc('"abc" != "abc"')
assert not calc('"abc" == "xyz"')
# Interaction with other types
assert calc('123 != "123"')
# Sass strings don't support ordering
for expression in (
'"abc" < "xyz"',
'"abc" <= "xyz"',
'"abc" <= "abc"',
'"xyz" > "abc"',
'"xyz" >= "abc"',
'"xyz" >= "xyz"',
'123 < "456"'):
with pytest.raises(TypeError):
calc(expression)
def test_comparison_null():
calc = Calculator(Namespace()).calculate
assert calc('null == null')
assert calc('null != 0')
with pytest.raises(TypeError):
calc('null < null')
# TODO write more! i'm lazy.
|