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