88import pytest
99import yaml
1010
11- from commitizen import config , defaults , git
11+ from commitizen import cmd , config , defaults , git
1212from commitizen .config .json_config import JsonConfig
1313from commitizen .config .toml_config import TomlConfig
1414from commitizen .config .yaml_config import YAMLConfig
@@ -239,71 +239,92 @@ def test_load_empty_pyproject_toml_from_config_argument(_, tmpdir):
239239 with pytest .raises (ConfigFileIsEmpty ):
240240 config .read_cfg (filepath = "./not_in_root/pyproject.toml" )
241241
242- def test_warn_multiple_config_files (_ , tmpdir , capsys ):
243- """Test that a warning is issued when multiple config files exist."""
244- with tmpdir .as_cwd ():
245- # Create multiple config files
246- tmpdir .join (".cz.toml" ).write (PYPROJECT )
247- tmpdir .join (".cz.json" ).write (JSON_STR )
248-
249- # Read config
250- cfg = config .read_cfg ()
251-
252- # Check that the warning was issued
253- captured = capsys .readouterr ()
254- assert "Multiple config files detected" in captured .err
255- assert ".cz.toml" in captured .err
256- assert ".cz.json" in captured .err
257- assert "Using" in captured .err
258-
259- # Verify the correct config is loaded (first in priority order)
260- assert cfg .settings == _settings
261242
262- def test_warn_multiple_config_files_with_pyproject (_ , tmpdir , capsys ):
263- """Test warning excludes pyproject.toml from the warning message."""
243+ class TestWarnMultipleConfigFiles :
244+ @pytest .mark .parametrize (
245+ "files,expected_path,should_warn" ,
246+ [
247+ # Same directory, different file types
248+ ([(".cz.toml" , PYPROJECT ), (".cz.json" , JSON_STR )], ".cz.toml" , True ),
249+ ([(".cz.json" , JSON_STR ), (".cz.yaml" , YAML_STR )], ".cz.json" , True ),
250+ ([(".cz.toml" , PYPROJECT ), (".cz.yaml" , YAML_STR )], ".cz.toml" , True ),
251+ # With pyproject.toml (excluded from warning)
252+ (
253+ [("pyproject.toml" , PYPROJECT ), (".cz.json" , JSON_STR )],
254+ "pyproject.toml" ,
255+ False ,
256+ ),
257+ (
258+ [("pyproject.toml" , PYPROJECT ), (".cz.toml" , PYPROJECT )],
259+ "pyproject.toml" ,
260+ False ,
261+ ),
262+ ],
263+ )
264+ def test_warn_multiple_config_files_same_dir (
265+ _ , tmpdir , capsys , files , expected_path , should_warn
266+ ):
267+ """Test warning when multiple config files exist in same directory."""
264268 with tmpdir .as_cwd ():
265- # Create multiple config files including pyproject.toml
266- tmpdir .join ("pyproject.toml" ).write (PYPROJECT )
267- tmpdir .join (".cz.json" ).write (JSON_STR )
269+ for filename , content in files :
270+ tmpdir .join (filename ).write (content )
268271
269- # Read config - should use pyproject.toml (first in priority)
270272 cfg = config .read_cfg ()
271-
272- # No warning should be issued as only one non-pyproject config exists
273273 captured = capsys .readouterr ()
274- assert "Multiple config files detected" not in captured .err
275274
276- # Verify the correct config is loaded
277- assert cfg .settings == _settings
275+ if should_warn :
276+ assert "Multiple config files detected" in captured .err
277+ assert "Using" in captured .err
278+ for filename , _ in files :
279+ if filename != "pyproject.toml" :
280+ assert filename in captured .err
281+ else :
282+ assert "Multiple config files detected" not in captured .err
283+
284+ assert cfg .path == Path (expected_path )
285+ # Verify config loaded correctly (name and version match expected)
286+ assert cfg .settings ["name" ] == "cz_jira"
287+ assert cfg .settings ["version" ] == "1.0.0"
278288
279- def test_warn_multiple_config_files_uses_correct_one (_ , tmpdir , capsys ):
280- """Test that the correct config file is used when multiple exist."""
289+ @pytest .mark .parametrize (
290+ "config_file" ,
291+ [".cz.json" , ".cz.toml" , ".cz.yaml" ],
292+ )
293+ def test_warn_same_filename_different_directories (_ , tmpdir , capsys , config_file ):
294+ """Test warning when same config filename exists in different directories."""
281295 with tmpdir .as_cwd ():
282- # Create .cz.json with different settings
283- json_different = """
284- {
285- "commitizen": {
286- "name": "cz_conventional_commits",
287- "version": "2.0.0"
288- }
289- }
290- """
291- tmpdir .join (".cz.json" ).write (json_different )
292- tmpdir .join (".cz.toml" ).write (PYPROJECT )
293-
294- # Read config - should use pyproject.toml (first in defaults.CONFIG_FILES)
295- # But since pyproject.toml doesn't exist, .cz.toml is second in priority
296- cfg = config .read_cfg ()
297-
298- # Check that warning mentions both files
299- captured = capsys .readouterr ()
300- assert "Multiple config files detected" in captured .err
301- assert ".cz.toml" in captured .err
302- assert ".cz.json" in captured .err
303-
304- # Verify .cz.toml was used (second in priority after pyproject.toml)
305- assert cfg .settings ["name" ] == "cz_jira" # from PYPROJECT
306- assert cfg .settings ["version" ] == "1.0.0"
296+ cmd .run ("git init" )
297+
298+ # Create config in git root
299+ if config_file .endswith (".json" ):
300+ root_content = '{"commitizen": {"name": "cz_jira", "version": "1.0.0"}}'
301+ elif config_file .endswith (".yaml" ):
302+ root_content = "commitizen:\n name: cz_jira\n version: 1.0.0"
303+ else :
304+ root_content = PYPROJECT
305+ tmpdir .join (config_file ).write (root_content )
306+
307+ # Create same filename in subdirectory
308+ subdir = tmpdir .mkdir ("subdir" )
309+ if config_file .endswith (".json" ):
310+ subdir_content = '{"commitizen": {"name": "cz_conventional_commits", "version": "2.0.0"}}'
311+ elif config_file .endswith (".yaml" ):
312+ subdir_content = (
313+ "commitizen:\n name: cz_conventional_commits\n version: 2.0.0"
314+ )
315+ else :
316+ subdir_content = PYPROJECT .replace (
317+ 'name = "cz_jira"' , 'name = "cz_conventional_commits"'
318+ ).replace ('version = "1.0.0"' , 'version = "2.0.0"' )
319+ subdir .join (config_file ).write (subdir_content )
320+
321+ with subdir .as_cwd ():
322+ cfg = config .read_cfg ()
323+ captured = capsys .readouterr ()
324+
325+ assert "Multiple config files detected" in captured .err
326+ assert f"Using config file: '{ config_file } '" in captured .err
327+ assert cfg .path == Path (config_file )
307328
308329 def test_no_warn_with_explicit_config_path (_ , tmpdir , capsys ):
309330 """Test that no warning is issued when user explicitly specifies config."""
@@ -323,6 +344,33 @@ def test_no_warn_with_explicit_config_path(_, tmpdir, capsys):
323344 json_cfg_expected = JsonConfig (data = JSON_STR , path = Path (".cz.json" ))
324345 assert cfg .settings == json_cfg_expected .settings
325346
347+ @pytest .mark .parametrize (
348+ "config_file, content" ,
349+ [
350+ (".cz.toml" , PYPROJECT ),
351+ (".cz.json" , JSON_STR ),
352+ (".cz.yaml" , YAML_STR ),
353+ ("pyproject.toml" , PYPROJECT ),
354+ ("cz.toml" , PYPROJECT ),
355+ ("cz.json" , JSON_STR ),
356+ ("cz.yaml" , YAML_STR ),
357+ ],
358+ )
359+ def test_no_warn_with_single_config_file (_ , tmpdir , capsys , config_file , content ):
360+ """Test that no warning is issued when user explicitly specifies config."""
361+ with tmpdir .as_cwd ():
362+ # Create multiple config files
363+ tmpdir .join (config_file ).write (content )
364+
365+ # Read config with explicit path
366+ cfg = config .read_cfg (filepath = config_file )
367+ captured = capsys .readouterr ()
368+
369+ # No warning should be issued
370+ assert "Multiple config files detected" not in captured .err
371+
372+ assert cfg .path == Path (config_file )
373+
326374
327375@pytest .mark .parametrize (
328376 "config_file, exception_string" ,
0 commit comments