summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-fonts/variations/at-font-face-descriptors.html
blob: 1935422d7c29df467a1c44bb4327e8fd79772508 (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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<!DOCTYPE html>
<html>
<head>
    <title>Testing @font-face descriptor values introduced in CSS Fonts level 4</title>
    <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-face-rule" />
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <style id="testStyle">
        @font-face { font-family: Test; src: local('Courier New'), local('Courier'); }
    </style>
</head>
<body>
    <div>@font-face descriptor tests</div>
    <script>

        function updateFontFaceRule(descriptorName, descriptorValue) {
            let testRule = document.getElementById("testStyle").sheet.cssRules[0];

            testRule.style.fontWeight = "normal";
            testRule.style.fontStyle = "normal";
            testRule.style.fontStretch = "normal";
            assert_equals(testRule.style.fontWeight, "normal", "Can't clear @font-face.");
            assert_equals(testRule.style.fontStyle, "normal", "Can't clear @font-face.");
            assert_equals(testRule.style.fontStretch,  "normal", "Can't clear @font-face.");

            testRule.style.fontWeight = "";
            testRule.style.fontStyle = "";
            testRule.style.fontStretch = "";
            assert_true(!testRule.style.fontWeight, "", "Can't clear @font-face.");
            assert_true(!testRule.style.fontStyle, "", "Can't clear @font-face.");
            assert_true(!testRule.style.fontStretch,  "", "Can't clear @font-face.");

            testRule.style[descriptorName] = descriptorValue;

            return testRule;
        }

        function testDescriptor(descriptorName, testCases) {
            var propertyName = { 'font-weight':'fontWeight', 'font-stretch':'fontStretch', 'font-style':'fontStyle' }[descriptorName];
            testCases.forEach(function (testCase) {
                test(() => {
                    let rule = updateFontFaceRule(descriptorName, testCase.value);

                    if (testCase.isValid) {
                        assert_not_equals(rule.style[propertyName], "", "Valid value should be accepted.");

                        let expectedValue = (testCase.expectedValue) ? testCase.expectedValue : testCase.value;
                        assert_equals(rule.style[propertyName], expectedValue, "Unexpected resulting value.");
                    }
                    else {
                        assert_equals(rule.style[propertyName], "", "No properties should be set.");
                    }
                }, descriptorName + (testCase.isValid ? "(valid): " : "(invalid): ") + testCase.description + ": " + testCase.value);

            });
        }

        testDescriptor("font-weight", [
            // Single value, keyword
            { value: "normal",                  isValid: true,  description: "'normal' keyword" },
            { value: "bold",                    isValid: true,  description: "'bold' keyword" },
            { value: "auto",                    isValid: true,  description: "'auto' keyword inside @font-face" },
            { value: "lighter",                 isValid: false, description: "'lighter' keyword inside @font-face" },
            { value: "bolder",                  isValid: false, description: "'bolder' keyword inside @font-face" },
            { value: "bold a",                  isValid: false, description: "Extra content after keyword" },

            // Single value, number
            { value: "401",                     isValid: true,  description: "Values that are not multiple of 100 should be parsed successfully" },
            { value: "400.1",                   isValid: true,  description: "Non-integer values should be parsed successfully" },
            { value: "1",                       isValid: true,  description: "Minimum allowed value should be parsed successfully" },
            { value: "0.999",                   isValid: false, description: "Values below minimum should be rejected" },
            { value: "-100",                    isValid: false, description: "Values below zero should be rejected" },
            { value: "1000",                    isValid: true,  description: "Maximum allowed value should be parsed successfully" },
            { value: "1000.001",                isValid: false, description: "Values above maximum should be rejected" },
            { value: "100 a",                   isValid: false, description: "Extra content after value" },

            // Single value, calc
            { value: "calc(100.5)",             isValid: true,  expectedValue: "100.5", description: "Simple calc value" },
            { value: "calc(1001)",              isValid: true, description: "Out-of-range simple calc value (should be clamped)" },
            { value: "calc(100.5*3 + 50.5)",    isValid: true,  expectedValue: "352", description: "Valid calc expression" },
            { value: "calc(100.5*3 + 800)",     isValid: true, description: "Valid calc expression with out-of-range value (should be clamped)" },
            { value: "calc(100.5px + 50.5px)",  isValid: false, description: "Valid calc expression with units" },

            // Value range
            { value: "100 900",                         isValid: true,  description: "Simple range" },
            { value: "500 500",                         isValid: true,  expectedValue: "500", description: "Simple range with equal upper and lower bounds" },
            { value: "0.9 100",                         isValid: false, description: "Lower bound out of range" },
            { value: "100 1001",                        isValid: false, description: "Upper bound out of range" },
            { value: "calc(100 + 100) 400",             isValid: true,  expectedValue: "200 400", description: "Lower bound calc()" },
            { value: "200 calc(200 + 200)",             isValid: true,  expectedValue: "200 400", description: "Upper bound calc()" },
            { value: "calc(100 + 100) calc(200 + 200)", isValid: true,  expectedValue: "200 400", description: "Both bounds are calc()" },
            { value: "400 200",                         isValid: true,  expectedValue: "400 200", description: "Bounds out of order are valid" },
            { value: "100 200 300",                     isValid: false, description: "Extra content after upper bound" },
        ]);

        testDescriptor("font-stretch", [
            // Single value, keyword
            { value: "ultra-condensed",         isValid: true,  description: "'ultra-condensed' keyword" },
            { value: "extra-condensed",         isValid: true,  description: "'extra-condensed' keyword" },
            { value: "condensed",               isValid: true,  description: "'condensed' keyword" },
            { value: "semi-condensed",          isValid: true,  description: "'semi-condensed' keyword" },
            { value: "normal",                  isValid: true,  description: "'normal' keyword" },
            { value: "semi-expanded",           isValid: true,  description: "'semi-expanded' keyword" },
            { value: "expanded",                isValid: true,  description: "'expanded' keyword" },
            { value: "extra-expanded",          isValid: true,  description: "'extra-expanded' keyword" },
            { value: "ultra-expanded",          isValid: true,  description: "'ultra-expanded' keyword" },
            { value: "expanded a",              isValid: false, description: "Extra content after value" },
            { value: "auto",                    isValid: true,  description: "'auto' keyword inside @font-face" },

            // Single value, number
            { value: "1%",                      isValid: true,  description:"Legal percentage" },
            { value: "10.5%",                   isValid: true,  description:"Legal percentage" },
            { value: "100%",                    isValid: true,  description:"Legal percentage" },
            { value: "1000%",                   isValid: true,  description:"Legal percentage" },
            { value: "100",                     isValid: false, description:"Only percentages, not numbers allowed" },
            { value: "-1%",                     isValid: false, description:"Negative values are illegal" },
            { value: "0%",                      isValid: true,  description:"Zero is legal" },
            { value: "100% a",                  isValid: false, description:"Extra content after value" },

            // Single value, calc
            { value: "calc(200.5%)",            isValid: true,  expectedValue: "200.5%", description: "Simple calc value" },
            { value: "calc(50%*2 - 20%)",       isValid: true,  expectedValue: "80%", description: "Valid calc expression" },
            { value: "calc(-100%)",             isValid: true,  description: "Negative calc value (to be clamped)" },
            { value: "calc(50% - 50%*2)",       isValid: true,  expectedValue: "calc(-50%)", description: "Negative calc expression (to be clamped)" },
            { value: "calc(100)",               isValid: false, description: "Unit-less calc value" },
            { value: "calc(100px)",             isValid: false, description: "Calc value with units" },

            // Value range
            { value: "100% 200%",                       isValid: true,  description: "Simple range" },
            { value: "100% 100%",                       isValid: true,  expectedValue: "100%", description: "Simple range with equal upper and lower bounds" },
            { value: "-100% 100%",                      isValid: false, description: "Lower bound out of range" },
            { value: "calc(10% + 10%) 30%",             isValid: true,  expectedValue: "20% 30%", description: "Lower bound calc()" },
            { value: "10% calc(10% + 10%)",             isValid: true,  expectedValue: "10% 20%", description: "Upper bound calc()" },
            { value: "calc(10% + 10%) calc(20% + 20%)", isValid: true,  expectedValue: "20% 40%", description: "Both bounds are calc()" },
            { value: "200% 100%",                       isValid: true,  expectedValue: "200% 100%", description: "Bounds out of order" },
            { value: "100% 200% 300%",                  isValid: false, description: "Extra content after upper bound" },
        ]);

        testDescriptor("font-style", [
            // Single value, keyword
            { value: "normal",                  isValid: true,  description: "'normal' keyword" },
            { value: "italic",                  isValid: true,  description: "'italic' keyword" },
            { value: "oblique",                 isValid: true,  description: "'oblique' keyword" },
            { value: "auto",                    isValid: true,  description: "'auto' keyword inside @font-face" },

            // Single value
            { value: "italic 20deg",            isValid: false, description: "'italic' followed by angle" },
            { value: "italic a",                isValid: false, description: "Extra content after keyword" },
            { value: "oblique 0deg",            isValid: true,  description: "'oblique' followed by zero degrees" },
            { value: "oblique 20deg",           isValid: true,  description: "'oblique' followed by former default 20deg angle" },
            { value: "oblique 90deg",           isValid: true,  description: "'oblique' followed by maxumum 90 degree angle" },
            { value: "oblique -90deg",          isValid: true,  description: "'oblique' followed by minimum -90 degree angle" },
            { value: "oblique calc(91deg)",     isValid: true,  description: "'oblique' followed by calc with out of range value (should be clamped)" },
            { value: "oblique calc(-91deg)",    isValid: true,  description: "'oblique' followed by calc with out of range value (should be clamped)" },
            { value: "oblique 0rad",            isValid: true,  expectedValue: "oblique 0deg", description: "'oblique' followed by angle in radians" },
            { value: "oblique 20",              isValid: false, description: "'oblique' followed by unit-less number" },
            { value: "oblique 20px",            isValid: false, description: "'oblique' followed by non-angle" },
            { value: "oblique a",               isValid: false, description: "'oblique' followed by non-number" },
            { value: "oblique -",               isValid: false, description: "'oblique' followed by isolated minus" },
            { value: "oblique - 20deg",         isValid: false, description: "'oblique' followed by minus and angle separated by space" },
            { value: "oblique -a",              isValid: false, description: "'oblique' followed by minus and non-number" },

            // Value range
            { value: "oblique 10deg 20deg",         isValid: true,  description: "Simple range" },
            { value: "oblique 10deg 10deg",         isValid: true,  expectedValue: "oblique 10deg", description: "Simple range with equal upper and lower bounds" },
            { value: "oblique 20deg 20deg",         isValid: true,  description: "Simple range with former default angle for both bounds" },
            { value: "oblique 20deg 10deg",         isValid: true,  expectedValue: "oblique 20deg 10deg", description: "Bounds out of order" },
            { value: "oblique -100deg 20deg",       isValid: false, description: "Lower bound out of range" },
            { value: "oblique 20deg 100deg",        isValid: false, description: "Upper bound out of range" },
            { value: "oblique 10deg 20deg 30deg",   isValid: false, description: "Extra content after upper bound" },
        ]);
    </script>
</body>
</html>