@@ -86,8 +86,111 @@ test('postcss', async () => {
8686 expect ( style ) . toContain ( `h1[${ id } ] {\n color: red;\n font-size: 14px\n}` )
8787} )
8888
89- test . todo ( 'CSS Modules' )
89+ test ( 'CSS Modules' , async ( ) => {
90+ const testWithIdent = async (
91+ localIdentName : string | undefined ,
92+ regexToMatch : RegExp
93+ ) => {
94+ const baseLoaders = [
95+ 'style-loader' ,
96+ {
97+ loader : 'css-loader' ,
98+ options : {
99+ modules : {
100+ localIdentName,
101+ } ,
102+ } ,
103+ } ,
104+ ]
105+
106+ const { window, instance } = await mockBundleAndRun ( {
107+ entry : 'css-modules.vue' ,
108+ modify : ( config : any ) => {
109+ config ! . module ! . rules = [
110+ {
111+ test : / \. v u e $ / ,
112+ loader : 'vue-loader' ,
113+ } ,
114+ {
115+ test : / \. c s s $ / ,
116+ use : baseLoaders ,
117+ } ,
118+ {
119+ test : / \. s t y l u s $ / ,
120+ use : [ ...baseLoaders , 'stylus-loader' ] ,
121+ } ,
122+ ]
123+ } ,
124+ } )
125+
126+ // get local class name
127+ const className = instance . $style . red
128+ expect ( className ) . toMatch ( regexToMatch )
129+
130+ // class name in style
131+ let style = [ ] . slice
132+ . call ( window . document . querySelectorAll ( 'style' ) )
133+ . map ( ( style : any ) => {
134+ return style ! . textContent
135+ } )
136+ . join ( '\n' )
137+ style = normalizeNewline ( style )
138+ expect ( style ) . toContain ( '.' + className + ' {\n color: red;\n}' )
139+
140+ // animation name
141+ const match = style . match ( / @ k e y f r a m e s \s + ( \S + ) \s + { / )
142+ expect ( match ) . toHaveLength ( 2 )
143+ const animationName = match [ 1 ]
144+ expect ( animationName ) . not . toBe ( 'fade' )
145+ expect ( style ) . toContain ( 'animation: ' + animationName + ' 1s;' )
146+
147+ // default module + pre-processor + scoped
148+ const anotherClassName = instance . $style . red
149+ expect ( anotherClassName ) . toMatch ( regexToMatch )
150+ const id = 'data-v-' + genId ( 'css-modules.vue' )
151+ expect ( style ) . toContain ( '.' + anotherClassName + '[' + id + ']' )
152+ }
153+
154+ // default ident
155+ await testWithIdent ( undefined , / ^ \w { 21 , } / )
156+
157+ // custom ident
158+ await testWithIdent (
159+ '[path][name]---[local]---[hash:base64:5]' ,
160+ / c s s - m o d u l e s - - - r e d - - - \w { 5 } /
161+ )
162+ } )
90163
91- test . todo ( 'CSS Modules Extend' )
164+ test ( 'CSS Modules Extend' , async ( ) => {
165+ const baseLoaders = [
166+ 'style-loader' ,
167+ {
168+ loader : 'css-loader' ,
169+ options : {
170+ modules : true ,
171+ } ,
172+ } ,
173+ ]
174+
175+ const { window, instance } = await mockBundleAndRun ( {
176+ entry : 'css-modules-extend.vue' ,
177+ modify : ( config : any ) => {
178+ config ! . module ! . rules = [
179+ {
180+ test : / \. v u e $ / ,
181+ loader : 'vue-loader' ,
182+ } ,
183+ {
184+ test : / \. c s s $ / ,
185+ use : baseLoaders ,
186+ } ,
187+ ]
188+ } ,
189+ } )
190+
191+ expect ( instance . $el . className ) . toBe ( instance . $style . red )
192+ const style = window . document . querySelectorAll ( 'style' ) ! [ 1 ] ! . textContent
193+ expect ( style ) . toContain ( `.${ instance . $style . red } {\n color: #FF0000;\n}` )
194+ } )
92195
93196test . todo ( 'experimental <style vars>' )
0 commit comments