0
# CSS Output Testing
1
2
Testing compiled CSS output from mixins and complex Sass expressions, with exact matching, subset matching, and string matching capabilities. These assertions compare the final CSS output after compilation.
3
4
## Capabilities
5
6
### Basic Output Testing
7
8
Tests that CSS output matches exactly between actual and expected results.
9
10
```scss { .api }
11
/**
12
* Wrapper for CSS output assertions containing output and expect blocks
13
* @param $description - Optional description of the assertion
14
* @content Must contain exactly one @include output and one @include expect
15
*/
16
@mixin assert($description: null);
17
18
/**
19
* Defines the actual CSS output to test
20
* @param $selector - Whether to wrap output in .test-output selector (default: true)
21
* @content CSS rules and properties to test
22
*/
23
@mixin output($selector: true);
24
25
/**
26
* Defines the expected CSS output for comparison
27
* @param $selector - Whether to wrap output in .test-output selector (default: true)
28
* @content Expected CSS rules and properties
29
*/
30
@mixin expect($selector: true);
31
```
32
33
**Usage Examples:**
34
35
```scss
36
@use 'pkg:sass-true' as *;
37
38
@include test('Button mixin generates correct CSS') {
39
@include assert('Should generate primary button styles') {
40
@include output {
41
@include button('primary', 'large');
42
}
43
44
@include expect {
45
padding: 1rem 2rem;
46
background-color: #007bff;
47
color: white;
48
border: none;
49
border-radius: 0.25rem;
50
font-size: 1.25rem;
51
}
52
}
53
}
54
55
@include test('Responsive mixin works correctly') {
56
@include assert {
57
@include output {
58
@include responsive('mobile') {
59
font-size: 14px;
60
}
61
}
62
63
@include expect {
64
@media (max-width: 767px) {
65
font-size: 14px;
66
}
67
}
68
}
69
}
70
```
71
72
### Subset Matching
73
74
Tests that expected CSS is contained within the actual output (subset matching).
75
76
```scss { .api }
77
/**
78
* Tests that expected CSS is contained within the actual output
79
* @param $selector - Whether to wrap output in .test-output selector
80
* @content Expected CSS that should be present in the output
81
*/
82
@mixin contains($selector: true);
83
```
84
85
**Usage Examples:**
86
87
```scss
88
@use 'pkg:sass-true' as *;
89
90
@include test('Mixin includes required properties') {
91
@include assert('Should contain essential button properties') {
92
@include output {
93
@include button('primary', 'large');
94
// This might generate additional properties like:
95
// display: inline-block;
96
// cursor: pointer;
97
// transition: all 0.2s;
98
// etc.
99
}
100
101
@include contains {
102
// We only care that these specific properties are present
103
background-color: #007bff;
104
padding: 1rem 2rem;
105
border: none;
106
}
107
}
108
}
109
110
@include test('Complex layout contains grid properties') {
111
@include assert {
112
@include output {
113
@include grid-container;
114
}
115
116
@include contains {
117
display: grid;
118
grid-template-columns: repeat(12, 1fr);
119
// Don't care about other properties that might be generated
120
}
121
}
122
}
123
```
124
125
### String Matching
126
127
Tests that a specific substring is present in the CSS output.
128
129
```scss { .api }
130
/**
131
* Tests that CSS output contains a specific substring
132
* @param $string-to-find - The substring to search for in the output
133
*/
134
@mixin contains-string($string-to-find);
135
```
136
137
**Usage Examples:**
138
139
```scss
140
@use 'pkg:sass-true' as *;
141
142
@include test('Generated CSS contains expected strings') {
143
@include assert('Should contain flexbox properties') {
144
@include output {
145
@include flex-center;
146
}
147
148
@include contains-string('display: flex');
149
@include contains-string('justify-content: center');
150
@include contains-string('align-items: center');
151
}
152
}
153
154
@include test('Custom property names are generated') {
155
@include assert {
156
@include output {
157
@include theme-colors('dark');
158
}
159
160
@include contains-string('--theme-bg:');
161
@include contains-string('--theme-text:');
162
@include contains-string('#1a1a1a');
163
}
164
}
165
```
166
167
## Advanced Usage
168
169
### Testing Without Selectors
170
171
For testing raw CSS properties without wrapper selectors:
172
173
```scss
174
@use 'pkg:sass-true' as *;
175
176
@include test('Raw property output') {
177
@include assert {
178
@include output($selector: false) {
179
// Generates raw CSS without .test-output wrapper
180
color: red;
181
font-size: 16px;
182
}
183
184
@include expect($selector: false) {
185
color: red;
186
font-size: 16px;
187
}
188
}
189
}
190
```
191
192
### Testing Complex Nested Structures
193
194
```scss
195
@use 'pkg:sass-true' as *;
196
197
@include test('Nested selector output') {
198
@include assert('Should generate BEM-style selectors') {
199
@include output {
200
@include bem-block('card') {
201
@include bem-element('title') {
202
font-size: 1.5rem;
203
font-weight: bold;
204
}
205
206
@include bem-modifier('featured') {
207
border: 2px solid gold;
208
}
209
}
210
}
211
212
@include expect {
213
.card__title {
214
font-size: 1.5rem;
215
font-weight: bold;
216
}
217
218
.card--featured {
219
border: 2px solid gold;
220
}
221
}
222
}
223
}
224
```
225
226
### Testing Media Queries
227
228
```scss
229
@use 'pkg:sass-true' as *;
230
231
@include test('Responsive utilities') {
232
@include assert('Should generate mobile-first breakpoints') {
233
@include output {
234
@include breakpoint('tablet') {
235
.container {
236
max-width: 768px;
237
}
238
}
239
}
240
241
@include expect {
242
@media (min-width: 768px) {
243
.container {
244
max-width: 768px;
245
}
246
}
247
}
248
}
249
}
250
```
251
252
### Combining Different Assertion Types
253
254
```scss
255
@use 'pkg:sass-true' as *;
256
257
@include test('Comprehensive output testing') {
258
@include assert('Full button test') {
259
@include output {
260
@include button('primary', 'large', $rounded: true);
261
}
262
263
// Test exact match for critical properties
264
@include expect {
265
padding: 1rem 2rem;
266
background-color: #007bff;
267
color: white;
268
border: none;
269
border-radius: 0.5rem;
270
font-size: 1.25rem;
271
cursor: pointer;
272
}
273
}
274
275
// Also test that it contains hover state
276
@include assert('Should include hover state') {
277
@include output {
278
@include button('primary', 'large', $rounded: true);
279
}
280
281
@include contains-string(':hover');
282
@include contains-string('background-color: #0056b3');
283
}
284
}
285
```
286
287
### Testing Error Output
288
289
When testing mixins that might generate CSS comments for errors:
290
291
```scss
292
@use 'pkg:sass-true' as *;
293
294
@include test('Error handling in mixins') {
295
@include assert('Should output error comment for invalid input') {
296
@include output {
297
@include color-scheme('invalid-scheme');
298
}
299
300
@include contains-string('ERROR');
301
@include contains-string('invalid-scheme');
302
}
303
}
304
```
305
306
## CSS Formatting Notes
307
308
### Whitespace and Formatting
309
310
CSS output testing is sensitive to formatting. The compiled CSS from both `output` and `expect` blocks is compared exactly, including whitespace and property order.
311
312
```scss
313
// These might not match due to different formatting:
314
@include expect {
315
margin:0;
316
padding:0;
317
}
318
319
@include expect {
320
margin: 0;
321
padding: 0;
322
}
323
```
324
325
### Property Order
326
327
Properties should generally be in the same order:
328
329
```scss
330
// Preferred - consistent order
331
@include expect {
332
display: flex;
333
justify-content: center;
334
align-items: center;
335
}
336
337
// May fail if actual output has different order
338
@include expect {
339
align-items: center;
340
display: flex;
341
justify-content: center;
342
}
343
```
344
345
### Using Contains for Flexibility
346
347
When exact formatting or property order is uncertain, use `contains` for more flexible testing:
348
349
```scss
350
@include assert {
351
@include output {
352
@include flex-center; // Might generate properties in any order
353
}
354
355
@include contains {
356
display: flex;
357
}
358
359
@include contains {
360
justify-content: center;
361
}
362
363
@include contains {
364
align-items: center;
365
}
366
}
367
```
368
369
## Integration with JavaScript Runners
370
371
When using JavaScript test runners (Mocha, Jest), CSS output comparison is automated. The JavaScript integration parses the compiled CSS and runs the comparisons, providing detailed diff output for failures.