diff --git a/tests/messages/test_frontend.py b/tests/messages/test_frontend.py index 7a6b08c44..a66310038 100644 --- a/tests/messages/test_frontend.py +++ b/tests/messages/test_frontend.py @@ -45,6 +45,7 @@ project_dir, this_dir, ) +from tests.messages.utils import CUSTOM_EXTRACTOR_COOKIE def _po_file(locale): @@ -1392,7 +1393,11 @@ def test_update_init_missing(self): mapping_cfg = """ [extractors] -custom = mypackage.module:myfunc +custom = tests.messages.utils:custom_extractor + +# Special extractor for a given Python file +[custom: special.py] +treat = delicious # Python source files [python: **.py] @@ -1411,7 +1416,13 @@ def test_update_init_missing(self): mapping_toml = """ [extractors] -custom = "mypackage.module:myfunc" +custom = "tests.messages.utils:custom_extractor" + +# Special extractor for a given Python file +[[mappings]] +method = "custom" +pattern = "special.py" +treat = "delightful" # Python source files [[mappings]] @@ -1663,3 +1674,29 @@ def test_extract_header_comment(monkeypatch, tmp_path): cmdinst.run() pot_content = pot_file.read_text() assert 'Boing' in pot_content + + +@pytest.mark.parametrize("mapping_format", ("toml", "cfg")) +def test_pr_1121(tmp_path, monkeypatch, caplog, mapping_format): + """ + Test that extraction uses the first matching method and options, + instead of the first matching method and last matching options. + + Without the fix in PR #1121, this test would fail, + since the `custom_extractor` isn't passed a delicious treat via + the configuration. + """ + if mapping_format == "cfg": + mapping_file = (tmp_path / "mapping.cfg") + mapping_file.write_text(mapping_cfg) + else: + mapping_file = (tmp_path / "mapping.toml") + mapping_file.write_text(mapping_toml) + (tmp_path / "special.py").write_text("# this file is special") + pot_path = (tmp_path / "output.pot") + monkeypatch.chdir(tmp_path) + cmdinst = configure_cli_command(f"extract . -o {shlex.quote(str(pot_path))} --mapping {shlex.quote(mapping_file.name)}") + assert isinstance(cmdinst, ExtractMessages) + cmdinst.run() + # If the custom extractor didn't run, we wouldn't see the cookie in there. + assert CUSTOM_EXTRACTOR_COOKIE in pot_path.read_text() diff --git a/tests/messages/utils.py b/tests/messages/utils.py new file mode 100644 index 000000000..d0797a337 --- /dev/null +++ b/tests/messages/utils.py @@ -0,0 +1,7 @@ +CUSTOM_EXTRACTOR_COOKIE = "custom extractor was here" + + +def custom_extractor(fileobj, keywords, comment_tags, options): + if "treat" not in options: + raise RuntimeError(f"The custom extractor refuses to run without a delicious treat; got {options!r}") + return [(1, next(iter(keywords)), (CUSTOM_EXTRACTOR_COOKIE,), [])]