@@ -138,6 +138,141 @@ public async Task ArgsVariable_InExcludePattern_ShouldNotSkip_WhenNotExcludedByA
138138 result . Stdout . Should ( ) . NotContain ( DockerHelper . Skipped ) ;
139139 }
140140
141+ // ── Regression tests: old behavior must still work ──────────────────────────
142+
143+ [ Fact ]
144+ public async Task StagedVariable_WithStaticInclude_ShouldRun_WhenPatternMatchesStagedFiles ( )
145+ {
146+ // arrange: old behavior — ${staged} in args, plain static include glob (no ${args})
147+ const string taskRunner =
148+ """
149+ {
150+ "tasks": [
151+ {
152+ "name": "Echo",
153+ "command": "echo",
154+ "filteringRule": "staged",
155+ "args": [
156+ "${staged}"
157+ ],
158+ "include": [
159+ "**/*.cs"
160+ ]
161+ }
162+ ]
163+ }
164+ """ ;
165+ await using var c = await ArrangeContainer ( taskRunner ) ;
166+
167+ // act: run without --args; staged src/Foo.cs matches **/*.cs
168+ var result = await c . BashAsync ( output , "dotnet husky run" ) ;
169+
170+ // assert
171+ result . ExitCode . Should ( ) . Be ( 0 ) ;
172+ result . Stdout . Should ( ) . Contain ( DockerHelper . SuccessfullyExecuted ) ;
173+ result . Stdout . Should ( ) . NotContain ( DockerHelper . Skipped ) ;
174+ }
175+
176+ [ Fact ]
177+ public async Task StagedVariable_WithStaticInclude_ShouldSkip_WhenPatternDoesNotMatchStagedFiles ( )
178+ {
179+ // arrange: old behavior — ${staged} in args, plain static include glob (no ${args})
180+ const string taskRunner =
181+ """
182+ {
183+ "tasks": [
184+ {
185+ "name": "Echo",
186+ "command": "echo",
187+ "filteringRule": "staged",
188+ "args": [
189+ "${staged}"
190+ ],
191+ "include": [
192+ "**/*.ts"
193+ ]
194+ }
195+ ]
196+ }
197+ """ ;
198+ await using var c = await ArrangeContainer ( taskRunner ) ;
199+
200+ // act: run without --args; no .ts files are staged so no match
201+ var result = await c . BashAsync ( output , "dotnet husky run" ) ;
202+
203+ // assert
204+ result . ExitCode . Should ( ) . Be ( 0 ) ;
205+ result . Stdout . Should ( ) . Contain ( DockerHelper . Skipped ) ;
206+ }
207+
208+ [ Fact ]
209+ public async Task NoVariable_WithStaticArgs_WithMatchingInclude_ShouldRun ( )
210+ {
211+ // arrange: old behavior — no variables anywhere, plain static args and include
212+ const string taskRunner =
213+ """
214+ {
215+ "tasks": [
216+ {
217+ "name": "Echo",
218+ "command": "echo",
219+ "filteringRule": "staged",
220+ "args": [
221+ "Husky.Net is awesome!"
222+ ],
223+ "include": [
224+ "**/*.cs"
225+ ]
226+ }
227+ ]
228+ }
229+ """ ;
230+ await using var c = await ArrangeContainer ( taskRunner ) ;
231+
232+ // act: run without --args; staged src/Foo.cs matches **/*.cs
233+ var result = await c . BashAsync ( output , "dotnet husky run" ) ;
234+
235+ // assert
236+ result . ExitCode . Should ( ) . Be ( 0 ) ;
237+ result . Stdout . Should ( ) . Contain ( DockerHelper . SuccessfullyExecuted ) ;
238+ result . Stdout . Should ( ) . NotContain ( DockerHelper . Skipped ) ;
239+ }
240+
241+ [ Fact ]
242+ public async Task StaticIncludePattern_ShouldNotBeAffectedByArgs_WhenNoArgsVariable ( )
243+ {
244+ // arrange: new behavior baseline — static include pattern (no ${args}),
245+ // verify pattern is NOT substituted even when --args is supplied
246+ const string taskRunner =
247+ """
248+ {
249+ "tasks": [
250+ {
251+ "name": "Echo",
252+ "command": "echo",
253+ "filteringRule": "staged",
254+ "args": [
255+ "${staged}"
256+ ],
257+ "include": [
258+ "**/*.cs"
259+ ]
260+ }
261+ ]
262+ }
263+ """ ;
264+ await using var c = await ArrangeContainer ( taskRunner ) ;
265+
266+ // act: --args is provided but the include pattern has no ${args}, so it
267+ // must remain a plain **/*.cs glob and still match staged src/Foo.cs
268+ var result = await c . BashAsync ( output , "dotnet husky run --args tests" ) ;
269+
270+ // assert
271+ result . ExitCode . Should ( ) . Be ( 0 ) ;
272+ result . Stdout . Should ( ) . Contain ( DockerHelper . SuccessfullyExecuted ) ;
273+ result . Stdout . Should ( ) . NotContain ( DockerHelper . Skipped ) ;
274+ }
275+
141276 private async Task < IContainer > ArrangeContainer ( string taskRunner , [ CallerMemberName ] string name = null ! )
142277 {
143278 var c = await DockerHelper . StartWithInstalledHusky ( name ) ;
0 commit comments