@@ -4,6 +4,7 @@ import { createExportBuilder } from './export-builder.js';
44import { resolve } from './path.js' ;
55import { createResolver } from './resolver.js' ;
66import { fakeCSSModule } from './test/css-module.js' ;
7+ import { fakeConfig } from './test/faker.js' ;
78import {
89 fakeAtImportTokenImporter ,
910 fakeAtValueTokenImporter ,
@@ -15,14 +16,15 @@ import type { CSSModule, Location } from './type.js';
1516const resolver = createResolver ( { } , undefined ) ;
1617
1718function prepareCheckerArgs < const T extends CSSModule [ ] > ( cssModules : T ) {
19+ const config = fakeConfig ( ) ;
1820 const getCSSModule = ( path : string ) => cssModules . find ( ( m ) => resolve ( m . fileName ) === resolve ( path ) ) ;
1921 const matchesPattern = ( path : string ) => path . endsWith ( '.module.css' ) ;
2022 const exportBuilder = createExportBuilder ( {
2123 getCSSModule,
2224 matchesPattern,
2325 resolver,
2426 } ) ;
25- return { cssModules, exportBuilder, matchesPattern, resolver, getCSSModule } ;
27+ return { cssModules, config , exportBuilder, matchesPattern, resolver, getCSSModule } ;
2628}
2729
2830function fakeLoc ( { column } : { column : number } ) : Location {
@@ -61,6 +63,7 @@ describe('checkCSSModule', () => {
6163 ] ) ;
6264 const diagnostics = checkCSSModule (
6365 args . cssModules [ 0 ] ,
66+ args . config ,
6467 args . exportBuilder ,
6568 args . matchesPattern ,
6669 args . resolver ,
@@ -123,6 +126,165 @@ describe('checkCSSModule', () => {
123126 ]
124127 ` ) ;
125128 } ) ;
129+ test ( 'report diagnostics for "__proto__" name' , ( ) => {
130+ const args = prepareCheckerArgs ( [
131+ fakeCSSModule ( {
132+ fileName : '/a.module.css' ,
133+ localTokens : [ fakeToken ( { name : '__proto__' , loc : fakeLoc ( { column : 1 } ) } ) ] ,
134+ tokenImporters : [
135+ fakeAtValueTokenImporter ( {
136+ from : './b.module.css' ,
137+ fromLoc : fakeLoc ( { column : 2 } ) ,
138+ values : [
139+ fakeAtValueTokenImporterValue ( { name : '__proto__' , loc : fakeLoc ( { column : 3 } ) } ) ,
140+ fakeAtValueTokenImporterValue ( {
141+ name : 'valid' ,
142+ loc : fakeLoc ( { column : 4 } ) ,
143+ localName : '__proto__' ,
144+ localLoc : fakeLoc ( { column : 5 } ) ,
145+ } ) ,
146+ ] ,
147+ } ) ,
148+ ] ,
149+ } ) ,
150+ fakeCSSModule ( {
151+ fileName : '/b.module.css' ,
152+ localTokens : [ fakeToken ( { name : '__proto__' } ) , fakeToken ( { name : 'valid' } ) ] ,
153+ } ) ,
154+ ] ) ;
155+
156+ const diagnostics = checkCSSModule (
157+ args . cssModules [ 0 ] ,
158+ args . config ,
159+ args . exportBuilder ,
160+ args . matchesPattern ,
161+ args . resolver ,
162+ args . getCSSModule ,
163+ ) ;
164+ expect ( diagnostics ) . toMatchInlineSnapshot ( `
165+ [
166+ {
167+ "category": "error",
168+ "file": {
169+ "fileName": "/a.module.css",
170+ "text": "",
171+ },
172+ "length": 0,
173+ "start": {
174+ "column": 1,
175+ "line": 1,
176+ },
177+ "text": "\`__proto__\` is not allowed as names.",
178+ },
179+ {
180+ "category": "error",
181+ "file": {
182+ "fileName": "/a.module.css",
183+ "text": "",
184+ },
185+ "length": 0,
186+ "start": {
187+ "column": 3,
188+ "line": 1,
189+ },
190+ "text": "\`__proto__\` is not allowed as names.",
191+ },
192+ {
193+ "category": "error",
194+ "file": {
195+ "fileName": "/a.module.css",
196+ "text": "",
197+ },
198+ "length": 0,
199+ "start": {
200+ "column": 5,
201+ "line": 1,
202+ },
203+ "text": "\`__proto__\` is not allowed as names.",
204+ },
205+ ]
206+ ` ) ;
207+ } ) ;
208+ test ( 'report diagnostics for "default" name when namedExports is true' , ( ) => {
209+ const args = prepareCheckerArgs ( [
210+ fakeCSSModule ( {
211+ fileName : '/a.module.css' ,
212+ localTokens : [ fakeToken ( { name : 'default' , loc : fakeLoc ( { column : 1 } ) } ) ] ,
213+ tokenImporters : [
214+ fakeAtValueTokenImporter ( {
215+ from : './b.module.css' ,
216+ fromLoc : fakeLoc ( { column : 2 } ) ,
217+ values : [
218+ fakeAtValueTokenImporterValue ( { name : 'default' , loc : fakeLoc ( { column : 3 } ) } ) ,
219+ fakeAtValueTokenImporterValue ( {
220+ name : 'valid' ,
221+ loc : fakeLoc ( { column : 4 } ) ,
222+ localName : 'default' ,
223+ localLoc : fakeLoc ( { column : 5 } ) ,
224+ } ) ,
225+ ] ,
226+ } ) ,
227+ ] ,
228+ } ) ,
229+ fakeCSSModule ( {
230+ fileName : '/b.module.css' ,
231+ localTokens : [ fakeToken ( { name : 'default' } ) , fakeToken ( { name : 'valid' } ) ] ,
232+ } ) ,
233+ ] ) ;
234+ args . config . namedExports = true ;
235+
236+ const diagnostics = checkCSSModule (
237+ args . cssModules [ 0 ] ,
238+ args . config ,
239+ args . exportBuilder ,
240+ args . matchesPattern ,
241+ args . resolver ,
242+ args . getCSSModule ,
243+ ) ;
244+ expect ( diagnostics ) . toMatchInlineSnapshot ( `
245+ [
246+ {
247+ "category": "error",
248+ "file": {
249+ "fileName": "/a.module.css",
250+ "text": "",
251+ },
252+ "length": 0,
253+ "start": {
254+ "column": 1,
255+ "line": 1,
256+ },
257+ "text": "\`default\` is not allowed as names when \`cmkOptions.namedExports\` is set to \`true\`.",
258+ },
259+ {
260+ "category": "error",
261+ "file": {
262+ "fileName": "/a.module.css",
263+ "text": "",
264+ },
265+ "length": 0,
266+ "start": {
267+ "column": 3,
268+ "line": 1,
269+ },
270+ "text": "\`default\` is not allowed as names when \`cmkOptions.namedExports\` is set to \`true\`.",
271+ },
272+ {
273+ "category": "error",
274+ "file": {
275+ "fileName": "/a.module.css",
276+ "text": "",
277+ },
278+ "length": 0,
279+ "start": {
280+ "column": 5,
281+ "line": 1,
282+ },
283+ "text": "\`default\` is not allowed as names when \`cmkOptions.namedExports\` is set to \`true\`.",
284+ },
285+ ]
286+ ` ) ;
287+ } ) ;
126288 test ( 'report diagnostics for non-existing module' , ( ) => {
127289 const args = prepareCheckerArgs ( [
128290 fakeCSSModule ( {
@@ -139,6 +301,7 @@ describe('checkCSSModule', () => {
139301 ] ) ;
140302 const diagnostics = checkCSSModule (
141303 args . cssModules [ 0 ] ,
304+ args . config ,
142305 args . exportBuilder ,
143306 args . matchesPattern ,
144307 args . resolver ,
@@ -197,6 +360,7 @@ describe('checkCSSModule', () => {
197360 ] ) ;
198361 const diagnostics = checkCSSModule (
199362 args . cssModules [ 0 ] ,
363+ args . config ,
200364 args . exportBuilder ,
201365 args . matchesPattern ,
202366 args . resolver ,
@@ -229,6 +393,7 @@ describe('checkCSSModule', () => {
229393 ] ) ;
230394 const diagnostics = checkCSSModule (
231395 args . cssModules [ 0 ] ,
396+ args . config ,
232397 args . exportBuilder ,
233398 args . matchesPattern ,
234399 ( ) => undefined , // Simulate unresolvable module
@@ -251,6 +416,7 @@ describe('checkCSSModule', () => {
251416 ] ) ;
252417 const diagnostics = checkCSSModule (
253418 args . cssModules [ 0 ] ,
419+ args . config ,
254420 args . exportBuilder ,
255421 ( path : string ) => path === '/a.module.css' , // Only match the current module
256422 args . resolver ,
0 commit comments