AtlatestRepositorysigil-css

sigil-css / tree / testtest-css.sgl

1;;; Tests for (sigil css) - S-expression CSS DSL
2
3(import (sigil test))
4(import (sigil css))
5
6(test-group "css basic rules"
7 (test "single property"
8 (assert-equal
9 (css->string (css ".card" (color "red")))
10 ".card {\n color: red;\n}\n\n"))
12 (test "multiple properties"
13 (assert-equal
14 (css->string (css ".card" (color "red") (padding "1rem")))
15 ".card {\n color: red;\n padding: 1rem;\n}\n\n"))
17 (test "empty rule (no properties)"
18 (assert-equal
19 (css->string (css ".empty"))
20 ""))
22 (test "property with multiple values"
23 (assert-equal
24 (css->string (css ".box" (margin "1rem" "2rem")))
25 ".box {\n margin: 1rem 2rem;\n}\n\n")))
27(test-group "css nesting"
28 (test "pseudo-class with &"
29 (let ((result (css->string
30 (css ".button"
31 (color "white")
32 (& ":hover"
33 (background "blue"))))))
34 ;; Should have both .button and .button:hover rules
35 (assert-true (string-contains? result ".button {"))
36 (assert-true (string-contains? result ".button:hover {"))))
38 (test "multiple nested rules"
39 (let ((result (css->string
40 (css ".link"
41 (color "blue")
42 (& ":hover" (color "red"))
43 (& ":active" (color "purple"))))))
44 (assert-true (string-contains? result ".link {"))
45 (assert-true (string-contains? result ".link:hover {"))
46 (assert-true (string-contains? result ".link:active {")))))
48(test-group "css-vars"
49 (test "single variable"
50 (let ((result (css->string (css-vars (--bg "#000")))))
51 (assert-true (string-contains? result ":root {"))
52 (assert-true (string-contains? result "--bg: #000"))))
54 (test "multiple variables"
55 (let ((result (css->string
56 (css-vars
57 (--bg "#0a0a0a")
58 (--fg "#e0e0e0")
59 (--accent "#f0c040")))))
60 (assert-true (string-contains? result "--bg: #0a0a0a"))
61 (assert-true (string-contains? result "--fg: #e0e0e0"))
62 (assert-true (string-contains? result "--accent: #f0c040")))))
64(test-group "css-media"
65 (test "simple media query"
66 (let ((result (css->string
67 (css-media "(max-width: 768px)"
68 (css ".sidebar"
69 (display "none"))))))
70 (assert-true (string-contains? result "@media (max-width: 768px)"))
71 (assert-true (string-contains? result ".sidebar {"))))
73 (test "media query with multiple rules"
74 (let ((result (css->string
75 (css-media "(max-width: 768px)"
76 (css ".sidebar" (visibility "hidden"))
77 (css ".content" (width "100%"))))))
78 (assert-true (string-contains? result ".sidebar {"))
79 (assert-true (string-contains? result ".content {")))))
81(test-group "unit helpers"
82 (test "px"
83 (assert-equal (px 200) "200px"))
85 (test "rem"
86 (assert-equal (rem 1) "1rem"))
88 (test "em"
89 (assert-equal (em 0.5) "0.5em"))
91 (test "%"
92 (assert-equal (% 100) "100%"))
94 (test "units in css rule"
95 (let ((result (css->string
96 (css ".box"
97 (width (px 200))
98 (padding (rem 1))))))
99 (assert-true (string-contains? result "width: 200px"))
100 (assert-true (string-contains? result "padding: 1rem")))))
102(test-group "color helpers"
103 (test "rgb"
104 (assert-equal (rgb 255 128 0) "rgb(255, 128, 0)"))
106 (test "rgba"
107 (assert-equal (rgba 255 128 0 0.5) "rgba(255, 128, 0, 0.5)"))
109 (test "hsl"
110 (assert-equal (hsl 180 50 50) "hsl(180, 50%, 50%)")))
112(test-group "theme support"
113 (test "theme-ref reads from theme alist"
114 (let ((theme '((bg . "#000") (fg . "#fff"))))
115 (assert-equal (theme-ref theme 'bg) "#000")
116 (assert-equal (theme-ref theme 'fg) "#fff")
117 (assert-false (theme-ref theme 'nonexistent))))
119 (test "theme-var generates var() reference"
120 (assert-equal (theme-var 'fg) "var(--fg)")
121 (assert-equal (theme-var 'background-color) "var(--background-color)"))
123 (test "theme->css-vars generates :root"
124 (let* ((theme '((bg . "#000") (fg . "#fff")))
125 (result (css->string (theme->css-vars theme))))
126 (assert-true (string-contains? result ":root {"))
127 (assert-true (string-contains? result "--bg: #000"))
128 (assert-true (string-contains? result "--fg: #fff"))))
130 (test "theme-var in css rule"
131 (let* ((val (theme-var 'fg))
132 (result (css->string (css ".text" (color val)))))
133 (assert-true (string-contains? result "color: var(--fg)")))))
135(test-group "css-combine"
136 (test "combines multiple fragments"
137 (let ((result (css->string
138 (css-combine
139 (css ".a" (color "red"))
140 (css ".b" (color "blue"))))))
141 (assert-true (string-contains? result ".a {"))
142 (assert-true (string-contains? result ".b {")))))
144(test-group "important"
145 (test "adds !important"
146 (assert-equal (important "red") "red !important"))
148 (test "important with number"
149 (assert-equal (important 42) "42 !important")))
151(test-group "integration"
152 (test "complete stylesheet"
153 (let ((result (css->string
154 (css-vars
155 (--primary "#007bff")
156 (--bg "#ffffff"))
157 (css "body"
158 (margin "0")
159 (background "var(--bg)"))
160 (css ".button"
161 (padding (px 10) (px 20))
162 (background "var(--primary)")
163 (& ":hover"
164 (opacity "0.9")))
165 (css-media "(max-width: 600px)"
166 (css ".button"
167 (width "100%"))))))
168 ;; Check all parts are present
169 (assert-true (string-contains? result ":root {"))
170 (assert-true (string-contains? result "--primary: #007bff"))
171 (assert-true (string-contains? result "body {"))
172 (assert-true (string-contains? result ".button {"))
173 (assert-true (string-contains? result ".button:hover {"))
174 (assert-true (string-contains? result "@media (max-width: 600px)")))))
176(test-group "css-sel"
177 (test "joins selectors with comma"
178 (assert-equal (css-sel ".a" ".b") ".a, .b"))
180 (test "single selector passes through"
181 (assert-equal (css-sel ".a") ".a"))
183 (test "three selectors"
184 (assert-equal (css-sel ".a" ".b" ".c") ".a, .b, .c"))
186 (test "compound selector in css rule"
187 (let ((result (css->string
188 (css (css-sel ".btn" "button[type=submit]")
189 (padding "0.5rem")))))
190 (assert-true (string-contains? result ".btn, button[type=submit] {"))))
192 (test "compound selector with & nesting"
193 (let ((result (css->string
194 (css (css-sel ".btn" "button[type=submit]")
195 (color "white")
196 (& ":hover"
197 (background "blue"))))))
198 (assert-true (string-contains? result ".btn, button[type=submit] {"))
199 (assert-true (string-contains? result ".btn:hover, button[type=submit]:hover {"))))
201 (test "pseudo-element with &"
202 (let ((result (css->string
203 (css "dialog"
204 (border "none")
205 (& "::backdrop"
206 (background "rgba(0,0,0,0.5)"))))))
207 (assert-true (string-contains? result "dialog {"))
208 (assert-true (string-contains? result "dialog::backdrop {"))))
210 (test "attribute selector without quotes"
211 (let ((result (css->string
212 (css "input[type=text]"
213 (padding "0.5rem")))))
214 (assert-true (string-contains? result "input[type=text] {")))))
216;;; Helper for string-contains? if not available
217(define (string-contains? str substr)
218 (let ((str-len (string-length str))
219 (sub-len (string-length substr)))
220 (let loop ((i 0))
221 (cond
222 ((> (+ i sub-len) str-len) #f)
223 ((string=? (substring str i (+ i sub-len)) substr) #t)
224 (else (loop (+ i 1)))))))
226(run-tests)