1from fontTools.varLib.models import (
2    normalizeLocation, supportScalar, VariationModel, VariationModelError)
3import pytest
4
5
6def test_normalizeLocation():
7    axes = {"wght": (100, 400, 900)}
8    assert normalizeLocation({"wght": 400}, axes) == {'wght': 0.0}
9    assert normalizeLocation({"wght": 100}, axes) == {'wght': -1.0}
10    assert normalizeLocation({"wght": 900}, axes) == {'wght': 1.0}
11    assert normalizeLocation({"wght": 650}, axes) == {'wght': 0.5}
12    assert normalizeLocation({"wght": 1000}, axes) == {'wght': 1.0}
13    assert normalizeLocation({"wght": 0}, axes) == {'wght': -1.0}
14
15    axes = {"wght": (0, 0, 1000)}
16    assert normalizeLocation({"wght": 0}, axes) == {'wght': 0.0}
17    assert normalizeLocation({"wght": -1}, axes) == {'wght': 0.0}
18    assert normalizeLocation({"wght": 1000}, axes) == {'wght': 1.0}
19    assert normalizeLocation({"wght": 500}, axes) == {'wght': 0.5}
20    assert normalizeLocation({"wght": 1001}, axes) == {'wght': 1.0}
21
22    axes = {"wght": (0, 1000, 1000)}
23    assert normalizeLocation({"wght": 0}, axes) == {'wght': -1.0}
24    assert normalizeLocation({"wght": -1}, axes) == {'wght': -1.0}
25    assert normalizeLocation({"wght": 500}, axes) == {'wght': -0.5}
26    assert normalizeLocation({"wght": 1000}, axes) == {'wght': 0.0}
27    assert normalizeLocation({"wght": 1001}, axes) == {'wght': 0.0}
28
29
30def test_supportScalar():
31    assert supportScalar({}, {}) == 1.0
32    assert supportScalar({'wght':.2}, {}) == 1.0
33    assert supportScalar({'wght':.2}, {'wght':(0,2,3)}) == 0.1
34    assert supportScalar({'wght':2.5}, {'wght':(0,2,4)}) == 0.75
35
36
37class VariationModelTest(object):
38
39    @pytest.mark.parametrize(
40        "locations, axisOrder, sortedLocs, supports, deltaWeights",
41        [
42            (
43                [
44                    {'wght': 0.55, 'wdth': 0.0},
45                    {'wght': -0.55, 'wdth': 0.0},
46                    {'wght': -1.0, 'wdth': 0.0},
47                    {'wght': 0.0, 'wdth': 1.0},
48                    {'wght': 0.66, 'wdth': 1.0},
49                    {'wght': 0.66, 'wdth': 0.66},
50                    {'wght': 0.0, 'wdth': 0.0},
51                    {'wght': 1.0, 'wdth': 1.0},
52                    {'wght': 1.0, 'wdth': 0.0},
53                ],
54                ["wght"],
55                [
56                    {},
57                    {'wght': -0.55},
58                    {'wght': -1.0},
59                    {'wght': 0.55},
60                    {'wght': 1.0},
61                    {'wdth': 1.0},
62                    {'wdth': 1.0, 'wght': 1.0},
63                    {'wdth': 1.0, 'wght': 0.66},
64                    {'wdth': 0.66, 'wght': 0.66}
65                ],
66                [
67                    {},
68                    {'wght': (-1.0, -0.55, 0)},
69                    {'wght': (-1.0, -1.0, -0.55)},
70                    {'wght': (0, 0.55, 1.0)},
71                    {'wght': (0.55, 1.0, 1.0)},
72                    {'wdth': (0, 1.0, 1.0)},
73                    {'wdth': (0, 1.0, 1.0), 'wght': (0, 1.0, 1.0)},
74                    {'wdth': (0, 1.0, 1.0), 'wght': (0, 0.66, 1.0)},
75                    {'wdth': (0, 0.66, 1.0), 'wght': (0, 0.66, 1.0)}
76                ],
77                [
78                    {},
79                    {0: 1.0},
80                    {0: 1.0},
81                    {0: 1.0},
82                    {0: 1.0},
83                    {0: 1.0},
84                    {0: 1.0,
85                     4: 1.0,
86                     5: 1.0},
87                    {0: 1.0,
88                     3: 0.7555555555555555,
89                     4: 0.24444444444444444,
90                     5: 1.0,
91                     6: 0.66},
92                    {0: 1.0,
93                     3: 0.7555555555555555,
94                     4: 0.24444444444444444,
95                     5: 0.66,
96                     6: 0.43560000000000006,
97                     7: 0.66}
98                ]
99            ),
100            (
101                [
102                    {},
103                    {'bar': 0.5},
104                    {'bar': 1.0},
105                    {'foo': 1.0},
106                    {'bar': 0.5, 'foo': 1.0},
107                    {'bar': 1.0, 'foo': 1.0},
108                ],
109                None,
110                [
111                    {},
112                    {'bar': 0.5},
113                    {'bar': 1.0},
114                    {'foo': 1.0},
115                    {'bar': 0.5, 'foo': 1.0},
116                    {'bar': 1.0, 'foo': 1.0},
117                ],
118                [
119                    {},
120                    {'bar': (0, 0.5, 1.0)},
121                    {'bar': (0.5, 1.0, 1.0)},
122                    {'foo': (0, 1.0, 1.0)},
123                    {'bar': (0, 0.5, 1.0), 'foo': (0, 1.0, 1.0)},
124                    {'bar': (0.5, 1.0, 1.0), 'foo': (0, 1.0, 1.0)},
125                ],
126                [
127                    {},
128                    {0: 1.0},
129                    {0: 1.0},
130                    {0: 1.0},
131                    {0: 1.0, 1: 1.0, 3: 1.0},
132                    {0: 1.0, 2: 1.0, 3: 1.0},
133                ],
134            )
135        ]
136    )
137    def test_init(
138        self, locations, axisOrder, sortedLocs, supports, deltaWeights
139    ):
140        model = VariationModel(locations, axisOrder=axisOrder)
141
142        assert model.locations == sortedLocs
143        assert model.supports == supports
144        assert model.deltaWeights == deltaWeights
145
146    def test_init_duplicate_locations(self):
147        with pytest.raises(VariationModelError, match="Locations must be unique."):
148            VariationModel(
149                [
150                    {"foo": 0.0, "bar": 0.0},
151                    {"foo": 1.0, "bar": 1.0},
152                    {"bar": 1.0, "foo": 1.0},
153                ]
154            )
155