@@ -64,9 +64,10 @@ def test_named_config_file(self, file_class: FilePathType) -> None:
64
64
assert not cov .config .branch
65
65
assert cov .config .data_file == "delete.me"
66
66
67
- def test_toml_config_file (self ) -> None :
68
- # A pyproject.toml file will be read into the configuration.
69
- self .make_file ("pyproject.toml" , """\
67
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
68
+ def test_toml_config_file (self , filename ) -> None :
69
+ # A pyproject.toml and coveragerc.toml will be read into the configuration.
70
+ self .make_file (filename , """\
70
71
# This is just a bogus toml file for testing.
71
72
[tool.somethingelse]
72
73
authors = ["Joe D'Ávila <[email protected] >"]
@@ -94,9 +95,10 @@ def test_toml_config_file(self) -> None:
94
95
assert cov .config .fail_under == 90.5
95
96
assert cov .config .get_plugin_options ("plugins.a_plugin" ) == {"hello" : "world" }
96
97
97
- def test_toml_ints_can_be_floats (self ) -> None :
98
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
99
+ def test_toml_ints_can_be_floats (self , filename ) -> None :
98
100
# Test that our class doesn't reject integers when loading floats
99
- self .make_file ("pyproject.toml" , """\
101
+ self .make_file (filename , """\
100
102
# This is just a bogus toml file for testing.
101
103
[tool.coverage.report]
102
104
fail_under = 90
@@ -205,7 +207,8 @@ def test_parse_errors(self, bad_config: str, msg: str) -> None:
205
207
self .make_file (".coveragerc" , bad_config )
206
208
with pytest .raises (ConfigError , match = msg ):
207
209
coverage .Coverage ()
208
-
210
+
211
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
209
212
@pytest .mark .parametrize ("bad_config, msg" , [
210
213
("[tool.coverage.run]\n timid = \" maybe?\" \n " , r"maybe[?]" ),
211
214
("[tool.coverage.run\n " , None ),
@@ -223,9 +226,9 @@ def test_parse_errors(self, bad_config: str, msg: str) -> None:
223
226
("[tool.coverage.report]\n precision=1.23" , "not an integer" ),
224
227
('[tool.coverage.report]\n fail_under="s"' , "couldn't convert to a float" ),
225
228
])
226
- def test_toml_parse_errors (self , bad_config : str , msg : str ) -> None :
229
+ def test_toml_parse_errors (self , filename , bad_config : str , msg : str ) -> None :
227
230
# Im-parsable values raise ConfigError, with details.
228
- self .make_file ("pyproject.toml" , bad_config )
231
+ self .make_file (filename , bad_config )
229
232
with pytest .raises (ConfigError , match = msg ):
230
233
coverage .Coverage ()
231
234
@@ -251,9 +254,10 @@ def test_environment_vars_in_config(self) -> None:
251
254
assert cov .config .branch is True
252
255
assert cov .config .exclude_list == ["the_$one" , "anotherZZZ" , "xZZZy" , "xy" , "huh${X}what" ]
253
256
254
- def test_environment_vars_in_toml_config (self ) -> None :
257
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
258
+ def test_environment_vars_in_toml_config (self , filename ) -> None :
255
259
# Config files can have $envvars in them.
256
- self .make_file ("pyproject.toml" , """\
260
+ self .make_file (filename , """\
257
261
[tool.coverage.run]
258
262
data_file = "$DATA_FILE.fooey"
259
263
branch = "$BRANCH"
@@ -325,9 +329,10 @@ def expanduser(s: str) -> str:
325
329
assert cov .config .exclude_list == ["~/data.file" , "~joe/html_dir" ]
326
330
assert cov .config .paths == {'mapping' : ['/Users/me/src' , '/Users/joe/source' ]}
327
331
328
- def test_tilde_in_toml_config (self ) -> None :
332
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
333
+ def test_tilde_in_toml_config (self , filename ) -> None :
329
334
# Config entries that are file paths can be tilde-expanded.
330
- self .make_file ("pyproject.toml" , """\
335
+ self .make_file (filename , """\
331
336
[tool.coverage.run]
332
337
data_file = "~/data.file"
333
338
@@ -441,22 +446,14 @@ def test_unknown_option(self) -> None:
441
446
msg = r"Unrecognized option '\[run\] xyzzy=' in config file .coveragerc"
442
447
with pytest .warns (CoverageWarning , match = msg ):
443
448
_ = coverage .Coverage ()
444
-
445
- def test_unknown_option_toml (self ) -> None :
446
- self .make_file ("pyproject.toml" , """\
449
+
450
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
451
+ def test_unknown_option_toml (self , filename ) -> None :
452
+ self .make_file (filename , """\
447
453
[tool.coverage.run]
448
454
xyzzy = 17
449
455
""" )
450
- msg = r"Unrecognized option '\[tool.coverage.run\] xyzzy=' in config file pyproject.toml"
451
- with pytest .warns (CoverageWarning , match = msg ):
452
- _ = coverage .Coverage ()
453
-
454
- def test_misplaced_option (self ) -> None :
455
- self .make_file (".coveragerc" , """\
456
- [report]
457
- branch = True
458
- """ )
459
- msg = r"Unrecognized option '\[report\] branch=' in config file .coveragerc"
456
+ msg = f"Unrecognized option '\\ [tool.coverage.run\\ ] xyzzy=' in config file { filename } "
460
457
with pytest .warns (CoverageWarning , match = msg ):
461
458
_ = coverage .Coverage ()
462
459
@@ -468,7 +465,7 @@ def test_unknown_option_in_other_ini_file(self) -> None:
468
465
msg = r"Unrecognized option '\[coverage:run\] huh=' in config file setup.cfg"
469
466
with pytest .warns (CoverageWarning , match = msg ):
470
467
_ = coverage .Coverage ()
471
-
468
+
472
469
def test_exceptions_from_missing_things (self ) -> None :
473
470
self .make_file ("config.ini" , """\
474
471
[run]
@@ -481,8 +478,10 @@ def test_exceptions_from_missing_things(self) -> None:
481
478
with pytest .raises (ConfigError , match = "No option 'foo' in section: 'xyzzy'" ):
482
479
config .get ("xyzzy" , "foo" )
483
480
484
- def test_exclude_also (self ) -> None :
485
- self .make_file ("pyproject.toml" , """\
481
+
482
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
483
+ def test_exclude_also (self , filename ) -> None :
484
+ self .make_file (filename , """\
486
485
[tool.coverage.report]
487
486
exclude_also = ["foobar", "raise .*Error"]
488
487
""" )
@@ -775,35 +774,39 @@ def test_no_toml_installed_explicit_toml(self) -> None:
775
774
coverage .Coverage (config_file = "cov.toml" )
776
775
777
776
@pytest .mark .skipif (env .PYVERSION >= (3 , 11 ), reason = "Python 3.11 has toml in stdlib" )
778
- def test_no_toml_installed_pyproject_toml (self ) -> None :
779
- # Can't have coverage config in pyproject.toml without toml installed.
780
- self .make_file ("pyproject.toml" , """\
777
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
778
+ def test_no_toml_installed_pyproject_toml (self , filename ) -> None :
779
+ # Can't have coverage config in pyproject.toml and .coveragerc.toml without toml installed.
780
+ self .make_file (filename , """\
781
781
# A toml file!
782
782
[tool.coverage.run]
783
783
xyzzy = 17
784
784
""" )
785
785
with mock .patch .object (coverage .tomlconfig , "has_tomllib" , False ):
786
- msg = "Can't read 'pyproject.toml ' without TOML support"
786
+ msg = "Can't read '{filename} ' without TOML support"
787
787
with pytest .raises (ConfigError , match = msg ):
788
788
coverage .Coverage ()
789
789
790
790
@pytest .mark .skipif (env .PYVERSION >= (3 , 11 ), reason = "Python 3.11 has toml in stdlib" )
791
- def test_no_toml_installed_pyproject_toml_shorter_syntax (self ) -> None :
791
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
792
+ def test_no_toml_installed_pyproject_toml_shorter_syntax (self , filename ) -> None :
792
793
# Can't have coverage config in pyproject.toml without toml installed.
793
- self .make_file ("pyproject.toml" , """\
794
+ self .make_file (filename , """\
794
795
# A toml file!
795
796
[tool.coverage]
796
797
run.parallel = true
797
798
""" )
798
799
with mock .patch .object (coverage .tomlconfig , "has_tomllib" , False ):
799
- msg = "Can't read 'pyproject.toml ' without TOML support"
800
+ msg = "Can't read '{filename} ' without TOML support"
800
801
with pytest .raises (ConfigError , match = msg ):
801
802
coverage .Coverage ()
802
803
804
+
803
805
@pytest .mark .skipif (env .PYVERSION >= (3 , 11 ), reason = "Python 3.11 has toml in stdlib" )
804
- def test_no_toml_installed_pyproject_no_coverage (self ) -> None :
806
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
807
+ def test_no_toml_installed_pyproject_no_coverage (self , filename ) -> None :
805
808
# It's ok to have non-coverage pyproject.toml without toml installed.
806
- self .make_file ("pyproject.toml" , """\
809
+ self .make_file (filename , """\
807
810
# A toml file!
808
811
[tool.something]
809
812
xyzzy = 17
@@ -814,17 +817,39 @@ def test_no_toml_installed_pyproject_no_coverage(self) -> None:
814
817
assert not cov .config .timid
815
818
assert not cov .config .branch
816
819
assert cov .config .data_file == ".coverage"
817
-
818
- def test_exceptions_from_missing_toml_things (self ) -> None :
819
- self .make_file ("pyproject.toml" , """\
820
+
821
+ @pytest .mark .parametrize ("filename" , ["pyproject.toml" , ".coveragerc.toml" ])
822
+ def test_exceptions_from_missing_toml_things (self , filename ) -> None :
823
+ self .make_file (filename , """\
820
824
[tool.coverage.run]
821
825
branch = true
822
826
""" )
823
827
config = TomlConfigParser (False )
824
- config .read ("pyproject.toml" )
828
+ config .read (filename )
825
829
with pytest .raises (ConfigError , match = "No section: 'xyzzy'" ):
826
830
config .options ("xyzzy" )
827
831
with pytest .raises (ConfigError , match = "No section: 'xyzzy'" ):
828
832
config .get ("xyzzy" , "foo" )
829
833
with pytest .raises (ConfigError , match = "No option 'foo' in section: 'tool.coverage.run'" ):
830
834
config .get ("run" , "foo" )
835
+
836
+ def test_coveragerc_toml_priority (self ) -> None :
837
+ """Test that .coveragerc.toml has priority over pyproject.toml."""
838
+ self .make_file (".coveragerc.toml" , """\
839
+ [tool.coverage.run]
840
+ timid = true
841
+ data_file = ".toml-data.dat"
842
+ branch = true
843
+ """ )
844
+
845
+ self .make_file ("pyproject.toml" , """\
846
+ [tool.coverage.run]
847
+ timid = false
848
+ data_file = "pyproject-data.dat"
849
+ branch = false
850
+ """ )
851
+ cov = coverage .Coverage ()
852
+
853
+ assert cov .config .timid is True
854
+ assert cov .config .data_file == ".toml-data.dat"
855
+ assert cov .config .branch is True
0 commit comments