summaryrefslogtreecommitdiff
path: root/scss/tests/test_types.py
blob: 026be02b4e42522324411cf6e0fb081630b18851 (plain)
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.