@@ -152,54 +152,54 @@ def test_validate_bids_error_grouping_notification(
152152 assert notification_substring in r .output
153153
154154
155- class TestValidateMatchOption :
156- """Test the --match option for filtering validation results."""
155+ def _mock_validate (* paths , ** kwargs ):
156+ """Mock validation function that returns controlled ValidationResult objects."""
157+ origin = Origin (
158+ type = OriginType .VALIDATION ,
159+ validator = Validator .dandi ,
160+ validator_version = "test" ,
161+ )
157162
158- @staticmethod
159- def _mock_validate (* paths , ** kwargs ):
160- """Mock validation function that returns controlled ValidationResult objects."""
161- origin = Origin (
162- type = OriginType .VALIDATION ,
163- validator = Validator .dandi ,
164- validator_version = "test" ,
165- )
163+ # Return a set of validation results with different IDs
164+ results = [
165+ ValidationResult (
166+ id = "BIDS.DATATYPE_MISMATCH" ,
167+ origin = origin ,
168+ severity = Severity .ERROR ,
169+ scope = Scope .FILE ,
170+ message = "Datatype mismatch error" ,
171+ path = Path (paths [0 ]) / "file1.nii" ,
172+ ),
173+ ValidationResult (
174+ id = "BIDS.EXTENSION_MISMATCH" ,
175+ origin = origin ,
176+ severity = Severity .ERROR ,
177+ scope = Scope .FILE ,
178+ message = "Extension mismatch error" ,
179+ path = Path (paths [0 ]) / "file2.jpg" ,
180+ ),
181+ ValidationResult (
182+ id = "DANDI.NO_DANDISET_FOUND" ,
183+ origin = origin ,
184+ severity = Severity .ERROR ,
185+ scope = Scope .DANDISET ,
186+ message = "No dandiset found" ,
187+ path = Path (paths [0 ]),
188+ ),
189+ ValidationResult (
190+ id = "NWBI.check_data_orientation" ,
191+ origin = origin ,
192+ severity = Severity .WARNING ,
193+ scope = Scope .FILE ,
194+ message = "Data orientation warning" ,
195+ path = Path (paths [0 ]) / "file3.nwb" ,
196+ ),
197+ ]
198+ return iter (results )
166199
167- # Return a set of validation results with different IDs
168- results = [
169- ValidationResult (
170- id = "BIDS.DATATYPE_MISMATCH" ,
171- origin = origin ,
172- severity = Severity .ERROR ,
173- scope = Scope .FILE ,
174- message = "Datatype mismatch error" ,
175- path = Path (paths [0 ]) / "file1.nii" ,
176- ),
177- ValidationResult (
178- id = "BIDS.EXTENSION_MISMATCH" ,
179- origin = origin ,
180- severity = Severity .ERROR ,
181- scope = Scope .FILE ,
182- message = "Extension mismatch error" ,
183- path = Path (paths [0 ]) / "file2.jpg" ,
184- ),
185- ValidationResult (
186- id = "DANDI.NO_DANDISET_FOUND" ,
187- origin = origin ,
188- severity = Severity .ERROR ,
189- scope = Scope .DANDISET ,
190- message = "No dandiset found" ,
191- path = Path (paths [0 ]),
192- ),
193- ValidationResult (
194- id = "NWBI.check_data_orientation" ,
195- origin = origin ,
196- severity = Severity .WARNING ,
197- scope = Scope .FILE ,
198- message = "Data orientation warning" ,
199- path = Path (paths [0 ]) / "file3.nwb" ,
200- ),
201- ]
202- return iter (results )
200+
201+ class TestValidateMatchOption :
202+ """Test the --match option for filtering validation results."""
203203
204204 @pytest .mark .parametrize (
205205 "match_patterns,parsed_patterns,should_contain,should_not_contain" ,
@@ -265,7 +265,7 @@ def test_match_patterns(
265265 # Use to monitor what compiled patterns are passed by the CLI
266266 process_issues_spy = mocker .spy (cmd_validate , "_process_issues" )
267267
268- monkeypatch .setattr (cmd_validate , "validate_" , self . _mock_validate )
268+ monkeypatch .setattr (cmd_validate , "validate_" , _mock_validate )
269269
270270 r = CliRunner ().invoke (validate , [f"--match={ match_patterns } " , str (tmp_path )])
271271
@@ -304,7 +304,7 @@ def test_match_with_ignore_combination(
304304 """Test --match and --ignore options used together."""
305305 from .. import cmd_validate
306306
307- monkeypatch .setattr (cmd_validate , "validate_" , self . _mock_validate )
307+ monkeypatch .setattr (cmd_validate , "validate_" , _mock_validate )
308308
309309 # Then use both match and ignore
310310 r = CliRunner ().invoke (
@@ -318,3 +318,72 @@ def test_match_with_ignore_combination(
318318
319319 assert "BIDS.DATATYPE_MISMATCH" not in r .output
320320 assert "No errors found" in r .output
321+
322+
323+ class TestValidateIncludePathOption :
324+ """Test the --include-path option for filtering validation results."""
325+
326+ def test_nonexistent_include_path (
327+ self ,
328+ tmp_path : Path ,
329+ ) -> None :
330+ """Test --include-path option with a non-existent path."""
331+
332+ non_existent_path = tmp_path / "nonexistent.nwb"
333+
334+ r = CliRunner ().invoke (
335+ validate ,
336+ [f"--include-path={ non_existent_path } " , str (tmp_path )],
337+ )
338+
339+ # Should exit with an error about `--include-path`
340+ assert r .exit_code != 0
341+ assert "--include-path" in r .output
342+
343+ @pytest .mark .parametrize (
344+ "include_paths" ,
345+ [
346+ ["path1.nwb" ],
347+ ["path1.nwb" , "path2.nwb" ],
348+ ],
349+ )
350+ def test_validated_option_args (
351+ self ,
352+ include_paths : list [str ],
353+ tmp_path : Path ,
354+ monkeypatch : pytest .MonkeyPatch ,
355+ mocker : pytest_mock .MockerFixture ,
356+ ) -> None :
357+ """
358+ Test that the validated arguments for --include-path correct
359+ """
360+ from .. import cmd_validate
361+
362+ # Use to monitor what compiled patterns are passed by the CLI
363+ process_issues_spy = mocker .spy (cmd_validate , "_process_issues" )
364+
365+ # We actually don't care about validation results here.
366+ # We are only mocking to avoid running actual validation logic.
367+ monkeypatch .setattr (cmd_validate , "validate_" , _mock_validate )
368+
369+ paths = [tmp_path / p for p in include_paths ]
370+ for p in paths :
371+ p .touch ()
372+
373+ cli_args = [f"--include-path={ p } " for p in paths ] + [str (tmp_path )]
374+ CliRunner ().invoke (
375+ validate ,
376+ cli_args ,
377+ )
378+
379+ process_issues_spy .assert_called_once ()
380+ call_args = process_issues_spy .call_args
381+
382+ # Ensure the paths are parsed and passed correctly
383+ passed_paths = call_args .kwargs .get (
384+ "include_path" ,
385+ call_args .args [4 ] if len (call_args .args ) > 4 else None ,
386+ )
387+ assert len (passed_paths ) == len (include_paths )
388+ assert all (isinstance (p , Path ) for p in passed_paths )
389+ assert all (p .is_absolute () for p in passed_paths )
0 commit comments