codeplain 0.3.10.dev3__py3-none-any.whl → 0.3.10.dev5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,60 @@
1
+ """Regression tests for linked-resource validation during --dry-run.
2
+
3
+ A linked resource must be a single text-based file. Rendering rejects binary
4
+ targets in ``file_utils.load_linked_resources`` (a failed UTF-8 decode raises
5
+ ``UnsupportedResourceType``); dry-run must surface the same errors through
6
+ ``plain2code.validate_linked_resources``, which reuses that exact mechanism.
7
+ """
8
+
9
+ import pytest
10
+
11
+ from plain2code import validate_linked_resources
12
+ from plain2code_exceptions import UnsupportedResourceType
13
+ from plain_modules import PlainModule
14
+
15
+ PLAIN_TEMPLATE = """***definitions***
16
+
17
+ - :Widget: is an item managed by the application.
18
+ - Its icon is [the widget resource](resources/{resource_name}).
19
+
20
+ ***implementation reqs***
21
+
22
+ - Implementation should be in Python.
23
+
24
+ ***functional specs***
25
+
26
+ - A :Widget: can be created.
27
+ """
28
+
29
+
30
+ def _make_module(tmp_path, monkeypatch, resource_name, resource_bytes):
31
+ resources_dir = tmp_path / "resources"
32
+ resources_dir.mkdir()
33
+ (resources_dir / resource_name).write_bytes(resource_bytes)
34
+ (tmp_path / "binlink.plain").write_text(PLAIN_TEMPLATE.format(resource_name=resource_name))
35
+
36
+ # Link targets are resolved relative to the current working directory at parse time.
37
+ monkeypatch.chdir(tmp_path)
38
+ return PlainModule("binlink.plain", str(tmp_path / "build"), [str(tmp_path)])
39
+
40
+
41
+ def test_dry_run_validation_rejects_binary_linked_resource(tmp_path, monkeypatch):
42
+ module = _make_module(tmp_path, monkeypatch, "image.png", b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\xff\xfe\xfd")
43
+
44
+ with pytest.raises(UnsupportedResourceType) as exc_info:
45
+ validate_linked_resources(module)
46
+
47
+ assert "resources/image.png" in str(exc_info.value)
48
+ assert "binary file" in str(exc_info.value)
49
+
50
+
51
+ def test_dry_run_validation_accepts_text_file_with_unusual_extension(tmp_path, monkeypatch):
52
+ module = _make_module(tmp_path, monkeypatch, "notes.xyz123", b"plain text content\n")
53
+
54
+ validate_linked_resources(module)
55
+
56
+
57
+ def test_dry_run_validation_accepts_empty_file(tmp_path, monkeypatch):
58
+ module = _make_module(tmp_path, monkeypatch, "empty.txt", b"")
59
+
60
+ validate_linked_resources(module)
@@ -18,7 +18,9 @@ from types import SimpleNamespace
18
18
 
19
19
  import pytest
20
20
 
21
+ from conformance_fix_journal import CONFORMANCE_TEST_JOURNAL_SUBFOLDER
21
22
  from git_utils import FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE, add_all_files_and_commit, init_git_repo
23
+ from memory_management import CONFORMANCE_TEST_MEMORY_SUBFOLDER
22
24
  from partial_rendering import archive_missing_conformance_tests, get_plain_module_render_state, get_render_choices
23
25
  from plain_modules import PlainModule
24
26
  from render_machine.actions.prepare_repositories import PrepareRepositories
@@ -115,6 +117,42 @@ def test_fresh_render_without_conformance_tests_does_not_create_tests_folder(sol
115
117
  assert not os.path.exists(solo_module.module_conformance_tests_folder)
116
118
 
117
119
 
120
+ def test_fresh_render_inherits_memories_from_the_previous_module(root_module):
121
+ """The previous module's distilled memories are copied into the new module's memory store
122
+ (replacing any stale store), while its fix attempt journals stay behind."""
123
+ previous = root_module.required_modules[-1]
124
+ _init_repo_with_finished_frid(previous.module_build_folder, previous.module_name)
125
+ memory_path = Path(previous.module_memory_folder) / CONFORMANCE_TEST_MEMORY_SUBFOLDER
126
+ memory_path.mkdir(parents=True)
127
+ (memory_path / "learning.json").write_text('{"memory_id": "learning"}')
128
+ journal_path = Path(previous.module_memory_folder) / CONFORMANCE_TEST_JOURNAL_SUBFOLDER
129
+ journal_path.mkdir(parents=True)
130
+ (journal_path / "pr_middle__1.jsonl").write_text('{"attempt": 1}\n')
131
+
132
+ stale_memory = Path(root_module.module_memory_folder) / CONFORMANCE_TEST_MEMORY_SUBFOLDER / "stale.json"
133
+ stale_memory.parent.mkdir(parents=True)
134
+ stale_memory.write_text('{"memory_id": "stale"}')
135
+
136
+ render_context = _make_render_context(root_module, render_conformance_tests=False)
137
+ PrepareRepositories().execute(render_context, None)
138
+
139
+ inherited_memory_folder = Path(root_module.module_memory_folder) / CONFORMANCE_TEST_MEMORY_SUBFOLDER
140
+ assert sorted(os.listdir(inherited_memory_folder)) == ["learning.json"]
141
+ assert not stale_memory.exists()
142
+ assert not (Path(root_module.module_memory_folder) / CONFORMANCE_TEST_JOURNAL_SUBFOLDER).exists()
143
+
144
+
145
+ def test_fresh_render_with_a_memoryless_previous_module_starts_with_an_empty_store(root_module):
146
+ previous = root_module.required_modules[-1]
147
+ _init_repo_with_finished_frid(previous.module_build_folder, previous.module_name)
148
+
149
+ render_context = _make_render_context(root_module, render_conformance_tests=False)
150
+ PrepareRepositories().execute(render_context, None)
151
+
152
+ assert os.path.isdir(os.path.join(root_module.module_build_folder, ".git"))
153
+ assert not os.path.exists(root_module.module_memory_folder)
154
+
155
+
118
156
  # --------------------------------------------------------------------------
119
157
  # ConformanceTests — tests-folder paths
120
158
  # --------------------------------------------------------------------------
tui/state_handlers.py CHANGED
@@ -241,7 +241,13 @@ class ConformanceTestsHandler(StateHandler):
241
241
  self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, [Substate(fixing_text)]
242
242
  )
243
243
  else:
244
- if segments[3] == States.CONFORMANCE_TESTS_READY_FOR_SUMMARY.value:
244
+ if segments[3] == States.CONFORMANCE_TESTS_READY_FOR_MEMORY_DISTILLATION.value:
245
+ update_progress_item_substates(
246
+ self.tui,
247
+ TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value,
248
+ [Substate("Distilling conformance test fix learnings")],
249
+ )
250
+ elif segments[3] == States.CONFORMANCE_TESTS_READY_FOR_SUMMARY.value:
245
251
  update_progress_item_substates(
246
252
  self.tui,
247
253
  TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value,