Repository: plone/cookieplone

Issue:
Update pytest fixtures to also find usage of variables in hook files

Discussion:

Solution patch:
diff --git a/cookieplone/templates/fixtures.py b/cookieplone/templates/fixtures.py
index 73ef108..84c40cc 100644
--- a/cookieplone/templates/fixtures.py
+++ b/cookieplone/templates/fixtures.py
@@ -7,25 +7,35 @@
 
 from . import types
 
+IGNORED_KEYS = (
+    "_extensions",
+    "_copy_without_render",
+    "__prompts__",
+    "__cookieplone_subtemplates",
+    "json",  # Probably `cookiecutter.json`
+)
+
+PATTERNS: tuple[re.Pattern, ...] = (
+    re.compile(r" ?(cookiecutter)[.](?P<key>[a-zA-Z0-9-_]*) ?"),
+    re.compile(r"(context\.get\(\")(?P<key>[a-zA-Z0-9-_]*)\""),
+)
+
 
 @pytest.fixture(scope="session")
-def variable_pattern() -> re.Pattern:
-    return re.compile(
-        "({{ ?(cookiecutter)[.]([a-zA-Z0-9-_]*)|{%.+(cookiecutter)[.]([a-zA-Z0-9-_]*).+%})"  # noQA: E501
-    )
+def variable_pattern() -> tuple[re.Pattern, ...]:
+    return PATTERNS
 
 
 @pytest.fixture(scope="session")
-def find_variables(variable_pattern) -> types.VariableFinder:
+def find_variables(variable_pattern, valid_key) -> types.VariableFinder:
     """Find variables in a string."""
 
     def func(data: str) -> set:
         keys = set()
-        matches = variable_pattern.findall(data) or []
-        for match in matches:
-            # Remove empty matches
-            match = [item for item in match if item.strip()]
-            keys.add(match[-1])
+        for pattern in variable_pattern:
+            matches = {match.groupdict()["key"] for match in pattern.finditer(data)}
+            matches = {key for key in matches if valid_key(key)}
+            keys = keys.union(matches)
         return keys
 
     return func
@@ -51,10 +61,10 @@ def template_folder_name() -> str:
 
 @pytest.fixture(scope="session")
 def valid_key() -> types.VariableValidator:
-    """Check if we will check for this key."""
+    """Should we check for this key."""
 
     def func(key: str, ignore: list[str] | None = None) -> bool:
-        ignore = ignore if ignore else ["__prompts__"]
+        ignore = ignore if ignore else IGNORED_KEYS
         return all([
             key not in ignore,
             key.startswith("__") or not key.startswith("_"),
diff --git a/news/100.feature b/news/100.feature
new file mode 100644
index 0000000..15abc33
--- /dev/null
+++ b/news/100.feature
@@ -0,0 +1 @@
+Update variable_pattern fixture to support also usage in hook files. @stevepiercy


Test patch:
diff --git a/tests/templates/test_fixtures.py b/tests/templates/test_fixtures.py
index ed82094..6df823c 100644
--- a/tests/templates/test_fixtures.py
+++ b/tests/templates/test_fixtures.py
@@ -8,7 +8,8 @@ def test_fixture_variable_pattern(testdir):
         import re
 
         def test_fixture(variable_pattern):
-            assert isinstance(variable_pattern, re.Pattern)
+            assert isinstance(variable_pattern, tuple)
+            assert isinstance(variable_pattern[0], re.Pattern)
         """
     )
     result = testdir.runpytest()
@@ -159,7 +160,7 @@ def test_fixture_variables_not_used(testdir, key: str):
         f"""
         def test_fixture(variables_not_used):
             assert isinstance(variables_not_used, list)
-            assert "{key}" in variables_not_used
+            assert "{key}" not in variables_not_used
         """
     )
     result = testdir.runpytest()