@@ -39,13 +39,17 @@ protected function tearDown(): void
3939 */
4040public function testAccept (array $ gitIgnoreFiles ,array $ otherFileNames ,array $ expectedResult )
4141 {
42- foreach ($ gitIgnoreFilesas $ path =>$ content ) {
43- $ this ->createFile ("{$ this ->tmpDir }/ {$ path }" ,$ content );
44- }
45-
4642$ otherFileNames =$ this ->toAbsolute ($ otherFileNames );
4743foreach ($ otherFileNamesas $ path ) {
48- $ this ->createFile ($ path );
44+ if (str_ends_with ($ path ,'/ ' )) {
45+ mkdir ($ path );
46+ }else {
47+ touch ($ path );
48+ }
49+ }
50+
51+ foreach ($ gitIgnoreFilesas $ path =>$ content ) {
52+ file_put_contents ("{$ this ->tmpDir }/ {$ path }" ,$ content );
4953 }
5054
5155$ inner =new InnerNameIterator ($ otherFileNames );
@@ -64,10 +68,12 @@ public function getAcceptData(): iterable
6468 [
6569'a.txt ' ,
6670'b.txt ' ,
71+ 'dir/ ' ,
6772'dir/a.txt ' ,
6873 ],
6974 [
7075'b.txt ' ,
76+ 'dir ' ,
7177 ],
7278 ];
7379
@@ -78,20 +84,23 @@ public function getAcceptData(): iterable
7884 [
7985'a.txt ' ,
8086'b.txt ' ,
87+ 'dir/ ' ,
8188'dir/a.txt ' ,
8289 ],
8390 [
8491'b.txt ' ,
92+ 'dir ' ,
8593'dir/a.txt ' ,
8694 ],
8795 ];
8896
89- yield 'directy ' => [
97+ yield 'directory ' => [
9098 [
9199'.gitignore ' =>'dir/ ' ,
92100 ],
93101 [
94102'a.txt ' ,
103+ 'dir/ ' ,
95104'dir/a.txt ' ,
96105'dir/b.txt ' ,
97106 ],
@@ -100,7 +109,7 @@ public function getAcceptData(): iterable
100109 ],
101110 ];
102111
103- yield 'directy matching a file ' => [
112+ yield 'directory matching a file ' => [
104113 [
105114'.gitignore ' =>'dir.txt/ ' ,
106115 ],
@@ -112,15 +121,20 @@ public function getAcceptData(): iterable
112121 ],
113122 ];
114123
115- yield 'directy at root ' => [
124+ yield 'directory at root ' => [
116125 [
117126'.gitignore ' =>'/dir/ ' ,
118127 ],
119128 [
129+ 'dir/ ' ,
120130'dir/a.txt ' ,
131+ 'other/ ' ,
132+ 'other/dir/ ' ,
121133'other/dir/b.txt ' ,
122134 ],
123135 [
136+ 'other ' ,
137+ 'other/dir ' ,
124138'other/dir/b.txt ' ,
125139 ],
126140 ];
@@ -131,11 +145,15 @@ public function getAcceptData(): iterable
131145 ],
132146 [
133147'a.txt ' ,
148+ 'nested/ ' ,
134149'nested/a.txt ' ,
150+ 'nested/nested/ ' ,
135151'nested/nested/a.txt ' ,
136152 ],
137153 [
138154'a.txt ' ,
155+ 'nested ' ,
156+ 'nested/nested ' ,
139157 ],
140158 ];
141159
@@ -145,58 +163,81 @@ public function getAcceptData(): iterable
145163 ],
146164 [
147165'a.txt ' ,
166+ 'nested/ ' ,
148167'nested/a.txt ' ,
168+ 'nested/nested/ ' ,
149169'nested/nested/a.txt ' ,
150170 ],
151171 [
152172'a.txt ' ,
173+ 'nested ' ,
174+ 'nested/nested ' ,
153175'nested/nested/a.txt ' ,
154176 ],
155177 ];
156178
157- yield 'directy in nested .gitignore ' => [
179+ yield 'directory in nested .gitignore ' => [
158180 [
159181'nested/.gitignore ' =>'dir/ ' ,
160182 ],
161183 [
162184'a.txt ' ,
185+ 'dir/ ' ,
163186'dir/a.txt ' ,
187+ 'nested/ ' ,
188+ 'nested/dir/ ' ,
164189'nested/dir/a.txt ' ,
190+ 'nested/nested/ ' ,
191+ 'nested/nested/dir/ ' ,
165192'nested/nested/dir/a.txt ' ,
166193 ],
167194 [
168195'a.txt ' ,
196+ 'dir ' ,
169197'dir/a.txt ' ,
198+ 'nested ' ,
199+ 'nested/nested ' ,
170200 ],
171201 ];
172202
173- yield 'directy matching a file in nested .gitignore ' => [
203+ yield 'directory matching a file in nested .gitignore ' => [
174204 [
175205'nested/.gitignore ' =>'dir.txt/ ' ,
176206 ],
177207 [
178208'dir.txt ' ,
209+ 'nested/ ' ,
179210'nested/dir.txt ' ,
180211 ],
181212 [
182213'dir.txt ' ,
214+ 'nested ' ,
183215'nested/dir.txt ' ,
184216 ],
185217 ];
186218
187- yield 'directy at root of nested .gitignore ' => [
219+ yield 'directory at root of nested .gitignore ' => [
188220 [
189221'nested/.gitignore ' =>'/dir/ ' ,
190222 ],
191223 [
192224'a.txt ' ,
225+ 'dir/ ' ,
193226'dir/a.txt ' ,
227+ 'nested/ ' ,
228+ 'nested/dir/ ' ,
194229'nested/dir/a.txt ' ,
230+ 'nested/nested/ ' ,
231+ 'nested/nested/dir/ ' ,
195232'nested/nested/dir/a.txt ' ,
196233 ],
197234 [
198235'a.txt ' ,
236+ 'dir ' ,
199237'dir/a.txt ' ,
238+ 'nested ' ,
239+ 'nested/nested ' ,
240+ 'nested/nested/dir ' ,
200241'nested/nested/dir/a.txt ' ,
201242 ],
202243 ];
@@ -209,12 +250,15 @@ public function getAcceptData(): iterable
209250 [
210251'a.txt ' ,
211252'b.txt ' ,
253+ 'nested/ ' ,
212254'nested/a.txt ' ,
213255'nested/b.txt ' ,
256+ 'nested/dir/ ' ,
214257'nested/dir/a.txt ' ,
215258'nested/dir/b.txt ' ,
216259 ],
217260 [
261+ 'nested ' ,
218262'nested/a.txt ' ,
219263 ],
220264 ];
@@ -227,8 +271,10 @@ public function getAcceptData(): iterable
227271 [
228272'a.txt ' ,
229273'b.txt ' ,
274+ 'nested/ ' ,
230275'nested/a.txt ' ,
231276'nested/b.txt ' ,
277+ 'nested/dir/ ' ,
232278'nested/dir/a.txt ' ,
233279'nested/dir/b.txt ' ,
234280 ],
@@ -241,12 +287,33 @@ public function getAcceptData(): iterable
241287'a/.gitignore ' =>'!c/ ' ,
242288 ],
243289 [
290+ 'a/ ' ,
291+ 'a/b/ ' ,
292+ 'a/b/c/ ' ,
244293'a/b/c/d.txt ' ,
245294 ],
246295 [
296+ 'a ' ,
297+ 'a/b ' ,
298+ 'a/b/c ' ,
247299'a/b/c/d.txt ' ,
248300 ],
249301 ];
302+
303+ yield 'file included from subdirectory with everything excluded ' => [
304+ [
305+ '.gitignore ' =>"/a/** \n!/a/b.txt " ,
306+ ],
307+ [
308+ 'a/ ' ,
309+ 'a/a.txt ' ,
310+ 'a/b.txt ' ,
311+ 'a/c.txt ' ,
312+ ],
313+ [
314+ 'a/b.txt ' ,
315+ ],
316+ ];
250317 }
251318
252319public function testAcceptAtRootDirectory ()
@@ -267,20 +334,6 @@ private function toAbsolute(array $files): array
267334return $ files ;
268335 }
269336
270- private function createFile (string $ path ,string $ content =null ):void
271- {
272- $ dir =\dirname ($ path );
273- if (!file_exists ($ dir )) {
274- mkdir ($ dir ,0777 ,true );
275- }
276-
277- if (null !==$ content ) {
278- file_put_contents ($ path ,$ content );
279- }else {
280- touch ($ path );
281- }
282- }
283-
284337private function removeDirectory (string $ dir ):void
285338 {
286339foreach ((new Finder ())->in ($ dir )->ignoreDotFiles (false )->depth ('< 1 ' )as $ file ) {