1
+ let { equal, throws } = require ( 'uvu/assert' )
2
+ let { test } = require ( 'uvu' )
1
3
let postcss = require ( 'postcss' )
2
4
3
5
let plugin = require ( './' )
4
6
5
- function run ( input , output , opts ) {
7
+ function run ( input , output , opts ) {
6
8
let result = postcss ( [ plugin ( opts ) ] ) . process ( input , { from : '/test.css' } )
7
- expect ( result . css ) . toEqual ( output )
8
- expect ( result . warnings ( ) ) . toHaveLength ( 0 )
9
+ equal ( result . css , output )
10
+ equal ( result . warnings ( ) . length , 0 )
9
11
}
10
12
11
- it ( 'unwraps rule inside rule' , ( ) => {
13
+ test ( 'unwraps rule inside rule' , ( ) => {
12
14
run (
13
15
'a { a: 1 } a { a: 1; b { b: 2; c { c: 3 } } }' ,
14
16
'a { a: 1 } a { a: 1; } a b { b: 2; } a b c { c: 3 }'
15
17
)
16
18
} )
17
19
18
- it ( 'cleans rules after unwrap' , ( ) => {
20
+ test ( 'cleans rules after unwrap' , ( ) => {
19
21
run ( 'a { b .one {} b .two {} }' , 'a b .one {} a b .two {}' )
20
22
} )
21
23
22
- it ( 'preserve empty rules if preserveEmpty is set to true' , ( ) => {
24
+ test ( 'preserve empty rules if preserveEmpty is set to true' , ( ) => {
23
25
run ( 'a { b .one {} b .two {} }' , 'a { } a b .one {} a b .two {}' , {
24
26
preserveEmpty : true
25
27
} )
26
28
} )
27
29
28
- it ( 'hoists at-root' , ( ) => {
30
+ test ( 'hoists at-root' , ( ) => {
29
31
run ( 'a { & {} @at-root { b {} } }' , 'a {} b {}' )
30
32
} )
31
33
32
- it ( 'at-root short hand' , ( ) => {
34
+ test ( 'at-root short hand' , ( ) => {
33
35
run ( 'a { & {} @at-root b { } }' , 'a {} b {}' )
34
36
} )
35
37
36
- it ( 'replaces ampersand' , ( ) => {
38
+ test ( 'replaces ampersand' , ( ) => {
37
39
run ( 'a { body &:hover b {} }' , 'body a:hover b {}' )
38
40
} )
39
41
40
- it ( 'replaces ampersands' , ( ) => {
42
+ test ( 'replaces ampersands' , ( ) => {
41
43
run ( 'a { &:hover, &:active {} }' , 'a:hover, a:active {}' )
42
44
} )
43
45
44
- it ( 'replaces ampersand in string' , ( ) => {
46
+ test ( 'replaces ampersand in string' , ( ) => {
45
47
run ( '.block { &_elem {} }' , '.block_elem {}' )
46
48
} )
47
49
48
- it ( 'unwrap rules inside at-rules' , ( ) => {
50
+ test ( 'unwrap rules inside at-rules' , ( ) => {
49
51
run (
50
52
'@media (max-width: 500px) { a { b {} } }' ,
51
53
'@media (max-width: 500px) { a b {} }'
52
54
)
53
55
} )
54
56
55
- it ( 'unwraps at-rule' , ( ) => {
57
+ test ( 'unwraps at-rule' , ( ) => {
56
58
run (
57
59
'a { b { @media screen { width: auto } } }' ,
58
60
'@media screen {a b { width: auto } }'
59
61
)
60
62
} )
61
63
62
- it ( 'unwraps at-rule with rules' , ( ) => {
64
+ test ( 'unwraps at-rule with rules' , ( ) => {
63
65
run (
64
66
'a { @media screen { b { color: black } } }' ,
65
67
'@media screen { a b { color: black } }'
66
68
)
67
69
} )
68
70
69
- it ( 'unwraps font-face to top level css' , ( ) => {
71
+ test ( 'unwraps font-face to top level css' , ( ) => {
70
72
run (
71
73
'.a { @font-face { font-family:font; src:url() format("woff"); } }' ,
72
74
'@font-face { font-family:font; src:url() format("woff"); }'
73
75
)
74
76
} )
75
77
76
- it ( 'unwraps multiple fonts to top level css' , ( ) => {
78
+ test ( 'unwraps multiple fonts to top level css' , ( ) => {
77
79
run (
78
80
'.a { @font-face { font-family:f1; } @font-face { font-family:f2; }}' ,
79
81
'@font-face { font-family:f1; } @font-face { font-family:f2; }'
80
82
)
81
83
} )
82
84
83
- it ( 'unwraps at-rules' , ( ) => {
85
+ test ( 'unwraps at-rules' , ( ) => {
84
86
run (
85
87
'a { a: 1 } a { @media screen { @supports (a: 1) { a: 1 } } }' ,
86
88
'a { a: 1 } @media screen { @supports (a: 1) { a { a: 1 } } }'
87
89
)
88
90
} )
89
91
90
- it ( 'unwraps at-rules with interleaved properties' , ( ) => {
92
+ test ( 'unwraps at-rules with interleaved properties' , ( ) => {
91
93
run (
92
94
'a { a: 1 } a { color: red; @media screen { @supports (a: 1) { a: 1 } } background: green }' ,
93
95
'a { a: 1 } a { color: red; } @media screen { @supports (a: 1) { a { a: 1 } } } a { background: green }'
94
96
)
95
97
} )
96
98
97
- it ( 'does not move custom at-rules' , ( ) => {
99
+ test ( 'does not move custom at-rules' , ( ) => {
98
100
run (
99
101
'.one { @mixin test; } .two { @media screen { @mixin test; } } .three { @media screen { @mixin test { color: black } } } .four { @phone { color: black } }' ,
100
102
'.one { @mixin test; } @media screen { .two { @mixin test } } @media screen { .three { @mixin test { color: black } } } @phone { .four { color: black } }' ,
101
103
{ bubble : [ 'phone' ] }
102
104
)
103
105
} )
104
106
105
- it ( 'does not move custom at-rules placed under nested bubbling ones' , ( ) => {
107
+ test ( 'does not move custom at-rules placed under nested bubbling ones' , ( ) => {
106
108
run (
107
109
'.one { @supports (color: black) { @media screen { @mixin test; } } } .two { @supports (color: black) { @media screen { @mixin test { color: black } } } }' ,
108
110
'@supports (color: black) { @media screen {.one { @mixin test } } } @supports (color: black) { @media screen { .two { @mixin test { color: black } } } }'
109
111
)
110
112
} )
111
113
112
- it ( 'supports bubble option with at-name' , ( ) => {
114
+ test ( 'supports bubble option with at-name' , ( ) => {
113
115
run ( 'a { @phone { color: black } }' , '@phone {a { color: black } }' , {
114
116
bubble : [ '@phone' ]
115
117
} )
116
118
} )
117
119
118
- it ( 'unwraps keyframes' , ( ) => {
120
+ test ( 'unwraps keyframes' , ( ) => {
119
121
run (
120
122
'a { color: white; @keyframes name { to { color: black } } }' ,
121
123
'a { color: white; } @keyframes name { to { color: black } }'
122
124
)
123
125
} )
124
126
125
- it ( 'supports unwrap option with at-name' , ( ) => {
127
+ test ( 'supports unwrap option with at-name' , ( ) => {
126
128
run ( 'a { @phone { color: black } }' , '@phone { color: black }' , {
127
129
unwrap : [ '@phone' ]
128
130
} )
129
131
} )
130
132
131
- it ( 'processes comma' , ( ) => {
133
+ test ( 'processes comma' , ( ) => {
132
134
run ( '.one, .two { a {} }' , '.one a, .two a {}' )
133
135
} )
134
136
135
- it ( 'processes comma with ampersand' , ( ) => {
137
+ test ( 'processes comma with ampersand' , ( ) => {
136
138
run ( '.one, .two { &:hover {} }' , '.one:hover, .two:hover {}' )
137
139
} )
138
140
139
- it ( 'processes comma inside' , ( ) => {
141
+ test ( 'processes comma inside' , ( ) => {
140
142
run ( 'a, b { .one, .two {} }' , 'a .one, a .two, b .one, b .two {}' )
141
143
} )
142
144
143
- it ( 'clears empty selector after comma' , ( ) => {
145
+ test ( 'clears empty selector after comma' , ( ) => {
144
146
run ( 'a, b { .one, .two, {} }' , 'a .one, a .two, b .one, b .two {}' )
145
147
} )
146
148
147
- it ( 'moves comment with rule' , ( ) => {
149
+ test ( 'moves comment with rule' , ( ) => {
148
150
run ( 'a { /*B*/ b {} }' , '/*B*/ a b {}' )
149
151
} )
150
152
151
- it ( 'moves comment with at-rule' , ( ) => {
153
+ test ( 'moves comment with at-rule' , ( ) => {
152
154
run ( 'a { /*B*/ @media { one: 1 } }' , '/*B*/ @media {a { one: 1 } }' )
153
155
} )
154
156
155
- it ( 'moves comment with declaration' , ( ) => {
157
+ test ( 'moves comment with declaration' , ( ) => {
156
158
run ( 'a { @media { /*B*/ one: 1 } }' , '@media {a { /*B*/ one: 1 } }' )
157
159
} )
158
160
159
- it ( 'saves order of rules' , ( ) => {
161
+ test ( 'saves order of rules' , ( ) => {
160
162
run ( '.one { & .two {} & .tree {} }' , '.one .two {} .one .tree {}' )
161
163
} )
162
164
163
- it ( 'copies rule for declarations after nested rule' , ( ) => {
165
+ test ( 'copies rule for declarations after nested rule' , ( ) => {
164
166
run (
165
167
'a { a: 1; &b { b: 2 } c: 1; &c { d: 5 } e: 6 } c { f: 1 }' ,
166
168
'a { a: 1; } ab { b: 2 } a { c: 1; } ac { d: 5 } a { e: 6; } c { f: 1 }'
167
169
)
168
170
} )
169
171
170
- it ( 'copies rule for declarations after nested rule and before at-rule' , ( ) => {
172
+ test ( 'copies rule for declarations after nested rule and before at-rule' , ( ) => {
171
173
run (
172
174
'a { &b { a: 1 } b: 2; @media { c: 3 } }' ,
173
175
'ab { a: 1 } a { b: 2 } @media {a { c: 3 } }'
174
176
)
175
177
} )
176
178
177
- it ( 'does not replace ampersand inside string' , ( ) => {
179
+ test ( 'does not replace ampersand inside string' , ( ) => {
178
180
run (
179
181
'div { &[data-category="sound & vision"] {} }' ,
180
182
'div[data-category="sound & vision"] {}'
181
183
)
182
184
} )
183
185
184
- it ( 'replaces ampersand in adjacent sibling selector' , ( ) => {
186
+ test ( 'replaces ampersand in adjacent sibling selector' , ( ) => {
185
187
run ( 'div { & + & {} }' , 'div + div {}' )
186
188
} )
187
189
188
- it ( 'replaces ampersands in not selector' , ( ) => {
190
+ test ( 'replaces ampersands in not selector' , ( ) => {
189
191
run ( '.a { &:not(&.no) {} }' , '.a:not(.a.no) {}' )
190
192
} )
191
193
192
- it ( 'correctly replaces tail ampersands' , ( ) => {
194
+ test ( 'correctly replaces tail ampersands' , ( ) => {
193
195
run ( '.a { .b & {} }' , '.b .a {}' )
194
196
} )
195
197
196
- it ( 'correctly replaces tail ampersands that are nested further down' , ( ) => {
198
+ test ( 'correctly replaces tail ampersands that are nested further down' , ( ) => {
197
199
run ( '.a { .b { .c & {} } }' , '.c .a .b {}' )
198
200
} )
199
201
200
- it ( 'correctly replaces tail ampersands that are nested inside ampersand rules' , ( ) => {
202
+ test ( 'correctly replaces tail ampersands that are nested inside ampersand rules' , ( ) => {
201
203
run ( '.a { &:hover { .b { .c & {} } } }' , '.c .a:hover .b {}' )
202
204
} )
203
205
204
- it ( 'preserves child order when replacing tail ampersands' , ( ) => {
206
+ test ( 'preserves child order when replacing tail ampersands' , ( ) => {
205
207
run (
206
208
'.a { color: red; .first {} @mixinFirst; .b & {} @mixinLast; .last {} }' ,
207
209
'.a { color: red; } .a .first {} .a { @mixinFirst; } .b .a {} .a { @mixinLast; } .a .last {}'
208
210
)
209
211
} )
210
212
211
- it ( 'handles :host selector case' , ( ) => {
213
+ test ( 'handles :host selector case' , ( ) => {
212
214
run ( ':host { &(:focus) {} }' , ':host(:focus) {}' )
213
215
} )
214
216
215
- it ( 'works with other visitors' , ( ) => {
217
+ test ( 'works with other visitors' , ( ) => {
216
218
let css = 'a{b{color:red}@mixin;}'
217
219
let mixinPlugin = ( ) => {
218
220
return {
219
221
postcssPlugin : 'mixin' ,
220
222
AtRule : {
221
- mixin ( node ) {
223
+ mixin ( node ) {
222
224
node . replaceWith ( '.in{.deep{color:blue}}' )
223
225
}
224
226
}
@@ -228,16 +230,16 @@ it('works with other visitors', () => {
228
230
let out = postcss ( [ plugin , mixinPlugin ] ) . process ( css , {
229
231
from : undefined
230
232
} ) . css
231
- expect ( out ) . toEqual ( 'a b{color:red}a .in .deep{color:blue}' )
233
+ equal ( out , 'a b{color:red}a .in .deep{color:blue}' )
232
234
} )
233
235
234
- it ( 'works with other visitors #2' , ( ) => {
236
+ test ( 'works with other visitors #2' , ( ) => {
235
237
let css = 'a { @mixin; b {color:red} }'
236
238
let mixinPlugin = ( ) => {
237
239
return {
238
240
postcssPlugin : 'mixin' ,
239
241
AtRule : {
240
- mixin ( node ) {
242
+ mixin ( node ) {
241
243
node . replaceWith ( '.in { .deep {color:blue} }' )
242
244
}
243
245
}
@@ -247,30 +249,32 @@ it('works with other visitors #2', () => {
247
249
let out = postcss ( [ plugin , mixinPlugin ] ) . process ( css , {
248
250
from : undefined
249
251
} ) . css
250
- expect ( out ) . toEqual ( 'a .in .deep {color:blue} a b {color:red}' )
252
+ equal ( out , 'a .in .deep {color:blue} a b {color:red}' )
251
253
} )
252
254
253
- it ( 'shows clear errors on missed semicolon' , ( ) => {
255
+ test ( 'shows clear errors on missed semicolon' , ( ) => {
254
256
let css = 'a{\n color: black\n @mixin b { }\n}\n'
255
- expect ( ( ) => {
257
+ throws ( ( ) => {
256
258
css = postcss ( [ plugin ] ) . process ( css , { from : undefined } ) . css
257
- } ) . toThrow ( '2:3: Missed semicolon' )
259
+ } , '2:3: Missed semicolon' )
258
260
} )
259
261
260
- it ( 'shows clear errors on other errors' , ( ) => {
262
+ test ( 'shows clear errors on other errors' , ( ) => {
261
263
let css = 'a{\n -Option/root { }\n}\n'
262
- expect ( ( ) => {
264
+ throws ( ( ) => {
263
265
css = postcss ( [ plugin ] ) . process ( css , { from : undefined } ) . css
264
- } ) . toThrow ( ':2:3: Unexpected' )
266
+ } , ':2:3: Unexpected' )
265
267
} )
266
268
267
- it ( 'third level dependencies' , ( ) => {
269
+ test ( 'third level dependencies' , ( ) => {
268
270
run (
269
271
'.text {&:hover{border-color: red;&:before{color: red;}}}' ,
270
272
'.text:hover{border-color: red;}.text:hover:before{color: red;}'
271
273
)
272
274
} )
273
275
274
- it ( 'third level dependencies #2' , ( ) => {
276
+ test ( 'third level dependencies #2' , ( ) => {
275
277
run ( '.selector{:global{h2{color:pink}}}' , '.selector :global h2{color:pink}' )
276
278
} )
279
+
280
+ test . run ( )
0 commit comments