@@ -86,6 +86,81 @@ describe('extglobs', () => {
8686 assert ( isMatch ( '/file.dhello.ts' , '/!(*.d).@(ts)' ) ) ;
8787 } ) ;
8888
89+ it ( 'should apply dotfile rules to brace alternatives at segment starts' , ( ) => {
90+ const pattern = '**/{!(*.d).mts,!(*.d).cts,*.{mjs,cjs,js}}' ;
91+ const opts = { dot : false } ;
92+ const dotOpts = { dot : true } ;
93+
94+ assert ( ! isMatch ( '.cjs' , pattern , opts ) ) ;
95+ assert ( ! isMatch ( '.cts' , pattern , opts ) ) ;
96+ assert ( ! isMatch ( '.js' , pattern , opts ) ) ;
97+ assert ( ! isMatch ( '.mjs' , pattern , opts ) ) ;
98+ assert ( ! isMatch ( '.mts' , pattern , opts ) ) ;
99+ assert ( isMatch ( 'a.mjs' , pattern , opts ) ) ;
100+ assert ( isMatch ( 'ad.cts' , pattern , opts ) ) ;
101+ assert ( isMatch ( 'ad.mts' , pattern , opts ) ) ;
102+ assert ( ! isMatch ( 'a/.cjs' , pattern , opts ) ) ;
103+ assert ( ! isMatch ( 'a/.cts' , pattern , opts ) ) ;
104+ assert ( ! isMatch ( 'a/.js' , pattern , opts ) ) ;
105+ assert ( ! isMatch ( 'a/.mjs' , pattern , opts ) ) ;
106+ assert ( ! isMatch ( 'a/.mts' , pattern , opts ) ) ;
107+ assert ( isMatch ( 'a/a.mjs' , pattern , opts ) ) ;
108+ assert ( isMatch ( 'a/ad.cts' , pattern , opts ) ) ;
109+ assert ( isMatch ( 'a/ad.mts' , pattern , opts ) ) ;
110+
111+ assert ( isMatch ( '.cjs' , pattern , dotOpts ) ) ;
112+ assert ( isMatch ( '.cts' , pattern , dotOpts ) ) ;
113+ assert ( isMatch ( '.js' , pattern , dotOpts ) ) ;
114+ assert ( isMatch ( '.mjs' , pattern , dotOpts ) ) ;
115+ assert ( isMatch ( '.mts' , pattern , dotOpts ) ) ;
116+ assert ( isMatch ( 'a.mjs' , pattern , dotOpts ) ) ;
117+ assert ( isMatch ( 'ad.cts' , pattern , dotOpts ) ) ;
118+ assert ( isMatch ( 'ad.mts' , pattern , dotOpts ) ) ;
119+ assert ( isMatch ( 'a/.cjs' , pattern , dotOpts ) ) ;
120+ assert ( isMatch ( 'a/.cts' , pattern , dotOpts ) ) ;
121+ assert ( isMatch ( 'a/.js' , pattern , dotOpts ) ) ;
122+ assert ( isMatch ( 'a/.mjs' , pattern , dotOpts ) ) ;
123+ assert ( isMatch ( 'a/.mts' , pattern , dotOpts ) ) ;
124+ assert ( isMatch ( 'a/a.mjs' , pattern , dotOpts ) ) ;
125+ assert ( isMatch ( 'a/ad.cts' , pattern , dotOpts ) ) ;
126+ assert ( isMatch ( 'a/ad.mts' , pattern , dotOpts ) ) ;
127+ } ) ;
128+
129+ it ( 'should apply dotfile rules only at segment starts' , ( ) => {
130+ assert ( isMatch ( '.foo' , '**/{.foo,*}' ) ) ;
131+ assert ( ! isMatch ( '.bar' , '**/{.foo,*}' ) ) ;
132+ assert ( isMatch ( 'a.foo' , 'a{*,b}' ) ) ;
133+ } ) ;
134+
135+ it ( 'should apply dotfile rules to first and subsequent brace alternatives' , ( ) => {
136+ assert ( ! isMatch ( '.js' , '**/{*.js,x}' , { dot : false } ) ) ;
137+ assert ( ! isMatch ( 'a/.js' , '**/{*.js,x}' , { dot : false } ) ) ;
138+ assert ( isMatch ( '.js' , '**/{*.js,x}' , { dot : true } ) ) ;
139+ assert ( isMatch ( 'a/.js' , '**/{*.js,x}' , { dot : true } ) ) ;
140+
141+ assert ( ! isMatch ( '.js' , '**/{x,*.js}' , { dot : false } ) ) ;
142+ assert ( ! isMatch ( 'a/.js' , '**/{x,*.js}' , { dot : false } ) ) ;
143+ assert ( isMatch ( '.js' , '**/{x,*.js}' , { dot : true } ) ) ;
144+ assert ( isMatch ( 'a/.js' , '**/{x,*.js}' , { dot : true } ) ) ;
145+
146+ assert ( ! isMatch ( '.mts' , '**/{!(*.d).mts,x}' , { dot : false } ) ) ;
147+ assert ( ! isMatch ( 'a/.mts' , '**/{!(*.d).mts,x}' , { dot : false } ) ) ;
148+ assert ( isMatch ( '.mts' , '**/{!(*.d).mts,x}' , { dot : true } ) ) ;
149+ assert ( isMatch ( 'a/.mts' , '**/{!(*.d).mts,x}' , { dot : true } ) ) ;
150+
151+ assert ( ! isMatch ( '.mts' , '**/{x,!(*.d).mts}' , { dot : false } ) ) ;
152+ assert ( ! isMatch ( 'a/.mts' , '**/{x,!(*.d).mts}' , { dot : false } ) ) ;
153+ assert ( isMatch ( '.mts' , '**/{x,!(*.d).mts}' , { dot : true } ) ) ;
154+ assert ( isMatch ( 'a/.mts' , '**/{x,!(*.d).mts}' , { dot : true } ) ) ;
155+
156+ assert ( ! isMatch ( '.js' , '{*.js,x}' , { bash : true } ) ) ;
157+ assert ( isMatch ( 'a.js' , '{*.js,x}' , { bash : true } ) ) ;
158+ assert ( ! isMatch ( '.js' , '{x,*.js}' , { bash : true } ) ) ;
159+ assert ( isMatch ( 'a.js' , '{x,*.js}' , { bash : true } ) ) ;
160+ assert ( isMatch ( 'a,.js' , '{x,@(a,*.js)}' ) ) ;
161+ assert ( isMatch ( 'a,.mts' , '{x,@(a,!(*.d).mts)}' ) ) ;
162+ } ) ;
163+
89164 it ( 'should support negation extglobs in patterns with slashes' , ( ) => {
90165 assert ( ! isMatch ( 'foo/abc' , 'foo/!(abc)' ) ) ;
91166 assert ( isMatch ( 'foo/bar' , 'foo/!(abc)' ) ) ;
@@ -292,6 +367,13 @@ describe('extglobs', () => {
292367 assert ( isMatch ( 'bb.md' , '*(a|b).md' ) ) ;
293368 } ) ;
294369
370+ it ( 'should preserve zero-length *(...) matches in brace alternatives' , ( ) => {
371+ assert ( isMatch ( '.md' , '{*(a|b).md,x}' ) ) ;
372+ assert ( isMatch ( 'a/.md' , 'a/{x,*(a|b).md}' ) ) ;
373+ assert ( ! isMatch ( '.a.md' , '{*(a|b).md,x}' , { noextglob : true } ) ) ;
374+ assert ( isMatch ( 'a.md' , '{*(a|b).md,x}' , { noextglob : true } ) ) ;
375+ } ) ;
376+
295377 it ( 'should support matching file extensions with ?(...)' , ( ) => {
296378 assert ( ! isMatch ( 'a.js' , '?(a|b).md' ) ) ;
297379 assert ( ! isMatch ( 'bb.md' , '?(a|b).md' ) ) ;
@@ -770,4 +852,3 @@ describe('extglobs', () => {
770852 assert . deepStrictEqual ( match ( [ 'foo' , ' foo ' ] , '(f|o)+\\b' ) , [ 'foo' ] , 'Should match word boundaries' ) ;
771853 } ) ;
772854} ) ;
773-
0 commit comments