codeplain 0.3.11.dev10__tar.gz → 0.3.11.dev11__tar.gz

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.
Files changed (265) hide show
  1. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/PKG-INFO +1 -1
  2. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/codeplain_REST_api.py +5 -0
  3. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/fix_conformance_test.py +11 -0
  4. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/fix_unit_tests.py +25 -0
  5. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/render_types.py +5 -0
  6. codeplain-0.3.11.dev11/tests/test_fix_unit_tests_conformance_context.py +230 -0
  7. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.claude/settings.json +0 -0
  8. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.flake8 +0 -0
  9. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/dependabot.yml +0 -0
  10. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/e2e.yml +0 -0
  11. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/lint-and-test.yml +0 -0
  12. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/lint-powershell.yml +0 -0
  13. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  14. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/publish-dev-to-pypi.yml +0 -0
  15. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/publish-install-script.yml +0 -0
  16. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.github/workflows/publish-to-pypi.yml +0 -0
  17. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.gitignore +0 -0
  18. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.vscode/launch.json +0 -0
  19. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/.vscode/settings.json +0 -0
  20. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/CLAUDE.md +0 -0
  21. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/CONTRIBUTING.md +0 -0
  22. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/LICENSE +0 -0
  23. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/README.md +0 -0
  24. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/change_detection.py +0 -0
  25. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/cli_output/__init__.py +0 -0
  26. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/cli_output/dry_run.py +0 -0
  27. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/cli_output/render_summary.py +0 -0
  28. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/cli_output/status.py +0 -0
  29. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/concept_utils.py +0 -0
  30. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/config/__init__.py +0 -0
  31. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/config/system_config.yaml +0 -0
  32. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/conformance_fix_journal.py +0 -0
  33. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/diff_utils.py +0 -0
  34. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/docs/generate_cli.py +0 -0
  35. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/docs/plain2code_cli.md +0 -0
  36. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/docs/starting_a_plain_project_from_scratch.md +0 -0
  37. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/event_bus.py +0 -0
  38. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_golang/config.yaml +0 -0
  39. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  40. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  41. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_golang/run.sh +0 -0
  42. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_python/config.yaml +0 -0
  43. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  44. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_python/hello_world_python.plain +0 -0
  45. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_python/run.sh +0 -0
  46. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/config.yaml +0 -0
  47. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  48. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  49. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  50. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  51. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  52. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  53. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/example_hello_world_react/run.sh +0 -0
  54. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/examples/run.sh +0 -0
  55. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/file_utils.py +0 -0
  56. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/git_utils.py +0 -0
  57. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/install/bash/examples.sh +0 -0
  58. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/install/bash/install.sh +0 -0
  59. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/install/bash/walkthrough.sh +0 -0
  60. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/install/powershell/examples.ps1 +0 -0
  61. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/install/powershell/install.ps1 +0 -0
  62. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/install/powershell/walkthrough.ps1 +0 -0
  63. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/memory_management.py +0 -0
  64. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/metadata_utils.py +0 -0
  65. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/module_renderer.py +0 -0
  66. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/partial_rendering.py +0 -0
  67. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/path_resolution.py +0 -0
  68. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code.py +0 -0
  69. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_arguments.py +0 -0
  70. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_cli.md +0 -0
  71. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_console.py +0 -0
  72. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_events.py +0 -0
  73. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_exceptions.py +0 -0
  74. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_logger.py +0 -0
  75. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_nodes.py +0 -0
  76. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_read_config.py +0 -0
  77. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_state.py +0 -0
  78. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_telemetry.py +0 -0
  79. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain2code_utils.py +0 -0
  80. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain_file.py +0 -0
  81. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain_modules.py +0 -0
  82. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/plain_spec.py +0 -0
  83. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/pyproject.toml +0 -0
  84. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/pytest.ini +0 -0
  85. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/__init__.py +0 -0
  86. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
  87. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/base_action.py +0 -0
  88. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  89. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  90. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/create_dist.py +0 -0
  91. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/distill_conformance_test_memory.py +0 -0
  92. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/exit_with_error.py +0 -0
  93. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/finish_functional_requirement.py +0 -0
  94. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/prepare_repositories.py +0 -0
  95. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/prepare_testing_environment.py +0 -0
  96. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/refactor_code.py +0 -0
  97. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/render_conformance_tests.py +0 -0
  98. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/render_functional_requirement.py +0 -0
  99. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/run_conformance_tests.py +0 -0
  100. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/run_unit_tests.py +0 -0
  101. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/actions/summarize_conformance_tests.py +0 -0
  102. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/code_renderer.py +0 -0
  103. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/conformance_tests.py +0 -0
  104. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/implementation_code_helpers.py +0 -0
  105. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/render_context.py +0 -0
  106. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/render_utils.py +0 -0
  107. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/state_machine_config.py +0 -0
  108. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/states.py +0 -0
  109. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/render_machine/triggers.py +0 -0
  110. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/requirements.txt +0 -0
  111. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/resources/codeplain_overview.png +0 -0
  112. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/resources/plain_example.png +0 -0
  113. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/standard_template_library/golang-console-app-template.plain +0 -0
  114. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/standard_template_library/python-console-app-template.plain +0 -0
  115. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  116. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/standard_template_library/typescript-react-app-template.plain +0 -0
  117. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/system_config.py +0 -0
  118. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
  119. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  120. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
  121. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_conformance_tests_golang.sh +0 -0
  122. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_conformance_tests_python.ps1 +0 -0
  123. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_conformance_tests_python.sh +0 -0
  124. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_flutter.ps1 +0 -0
  125. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_flutter.sh +0 -0
  126. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_golang.ps1 +0 -0
  127. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_golang.sh +0 -0
  128. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_python.ps1 +0 -0
  129. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_python.sh +0 -0
  130. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_react.ps1 +0 -0
  131. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/test_scripts/run_unittests_react.sh +0 -0
  132. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/__init__.py +0 -0
  133. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/conftest.py +0 -0
  134. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
  135. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
  136. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/circular_imports_1.plain +0 -0
  137. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/circular_imports_2.plain +0 -0
  138. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/circular_imports_main.plain +0 -0
  139. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/diamond_import_1.plain +0 -0
  140. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/diamond_import_2.plain +0 -0
  141. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/diamond_import_common.plain +0 -0
  142. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/diamond_imports_main.plain +0 -0
  143. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/import_with_functionalities.plain +0 -0
  144. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
  145. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/imports/non_existent_import.plain +0 -0
  146. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/partial_rendering/pr_code_var.plain +0 -0
  147. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/partial_rendering/pr_implement.plain +0 -0
  148. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/partial_rendering/pr_leaf.plain +0 -0
  149. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/partial_rendering/pr_middle.plain +0 -0
  150. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/partial_rendering/pr_root.plain +0 -0
  151. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/partial_rendering/pr_solo.plain +0 -0
  152. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
  153. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  154. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
  155. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  156. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  157. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
  158. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  159. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  160. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
  161. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  162. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  163. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  164. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  165. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  166. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  167. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  168. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  169. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  170. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  171. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  172. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  173. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  174. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  175. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  176. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  177. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
  178. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
  179. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  180. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  181. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  182. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  183. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  184. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  185. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  186. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  187. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts.plain +0 -0
  188. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  189. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  190. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  191. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  192. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  193. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  194. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  195. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  196. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/topological_sort.plain +0 -0
  197. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  198. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/circular_requires_main.plain +0 -0
  199. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/circular_requires_sub.plain +0 -0
  200. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/diamond_requires_1.plain +0 -0
  201. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/diamond_requires_2.plain +0 -0
  202. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/diamond_requires_common.plain +0 -0
  203. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/diamond_requires_main.plain +0 -0
  204. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/independent_requires_1.plain +0 -0
  205. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/independent_requires_2.plain +0 -0
  206. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/independent_requires_main.plain +0 -0
  207. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/non_existent_require.plain +0 -0
  208. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/normal_requires_1.plain +0 -0
  209. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/normal_requires_2.plain +0 -0
  210. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/normal_requires_common.plain +0 -0
  211. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/requires/normal_requires_main.plain +0 -0
  212. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/sample_base64_image.txt +0 -0
  213. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/simple.plain +0 -0
  214. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/block_level_include.plain +0 -0
  215. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/code_variables.plain +0 -0
  216. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/header.plain +0 -0
  217. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/implement.plain +0 -0
  218. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/implement_2.plain +0 -0
  219. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/template_include.plain +0 -0
  220. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/data/templates/test_hardest_problem.plain +0 -0
  221. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/e2e/Dockerfile +0 -0
  222. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/e2e/conftest.py +0 -0
  223. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/e2e/test_hello_world_python.py +0 -0
  224. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/e2e/test_hello_world_python_windows.py +0 -0
  225. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_arg_provenance.py +0 -0
  226. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_change_detection.py +0 -0
  227. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_cli_output.py +0 -0
  228. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_conformance_fix_journal.py +0 -0
  229. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_console_log_styles.py +0 -0
  230. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_distill_conformance_test_memory.py +0 -0
  231. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_dry_run_link_validation.py +0 -0
  232. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_file_utils.py +0 -0
  233. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_folder_path_resolution.py +0 -0
  234. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_git_utils.py +0 -0
  235. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_headless_logging.py +0 -0
  236. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_imports.py +0 -0
  237. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_log_file_name_resolution.py +0 -0
  238. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_logging_config_path_resolution.py +0 -0
  239. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_partial_rendering.py +0 -0
  240. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_path_resolution.py +0 -0
  241. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plain2code.py +0 -0
  242. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plain2code_state.py +0 -0
  243. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plain2code_utils.py +0 -0
  244. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plain_modules.py +0 -0
  245. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plainfile.py +0 -0
  246. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plainfileparser.py +0 -0
  247. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_plainspec.py +0 -0
  248. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_prepare_repositories_layout.py +0 -0
  249. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_requires.py +0 -0
  250. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_resolve_config_file.py +0 -0
  251. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_script_path_resolution.py +0 -0
  252. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_system_config.py +0 -0
  253. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_telemetry.py +0 -0
  254. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_tui_usage.py +0 -0
  255. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tests/test_usage_summary.py +0 -0
  256. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/__init__.py +0 -0
  257. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/components.py +0 -0
  258. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/models.py +0 -0
  259. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/plain2code_tui.py +0 -0
  260. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/plain_module_render_choice_tui.py +0 -0
  261. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/spinner.py +0 -0
  262. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/state_handlers.py +0 -0
  263. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/styles.css +0 -0
  264. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/tui/widget_helpers.py +0 -0
  265. {codeplain-0.3.11.dev10 → codeplain-0.3.11.dev11}/usage_summary.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codeplain
3
- Version: 0.3.11.dev10
3
+ Version: 0.3.11.dev11
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -237,6 +237,7 @@ class CodeplainAPI:
237
237
  required_modules,
238
238
  unittests_issue,
239
239
  run_state: RunState,
240
+ conformance_tests_fixes: list[dict] | None = None,
240
241
  ):
241
242
  endpoint_url = f"{self.api_url}/fix_unittests_issue"
242
243
  headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
@@ -251,6 +252,10 @@ class CodeplainAPI:
251
252
  "unittests_issue": unittests_issue,
252
253
  "unittest_batch_id": run_state.unittest_batch_id,
253
254
  }
255
+ # Implementation code changes made by the conformance tests fixer right before this unit tests run;
256
+ # only sent when unit tests are processed inside the conformance tests phase.
257
+ if conformance_tests_fixes is not None:
258
+ payload["conformance_tests_fixes"] = conformance_tests_fixes
254
259
 
255
260
  return self.post_request(endpoint_url, headers, payload, run_state)
256
261
 
@@ -189,6 +189,17 @@ class FixConformanceTest(BaseAction):
189
189
  ctx.test_that_triggered_code_change = (ctx.current_testing_module_name, ctx.current_testing_frid)
190
190
  ctx.execution_phase = TestExecutionPhase.RETRYING_AFTER_CODE_CHANGE
191
191
 
192
+ # Remember the change so that the unit tests fixer (which runs next) preserves it instead of
193
+ # reverting it - see FixUnitTests.
194
+ summary = fix_attempt_summary if isinstance(fix_attempt_summary, dict) else {}
195
+ ctx.implementation_code_fixes.append(
196
+ {
197
+ "hypothesis": summary.get("hypothesis"),
198
+ "approach": summary.get("approach"),
199
+ "code_diff": code_diff_files_content,
200
+ }
201
+ )
202
+
192
203
  journal.record_fix(
193
204
  ctx.current_testing_module_name,
194
205
  ctx.current_testing_frid,
@@ -32,6 +32,13 @@ class FixUnitTests(BaseAction):
32
32
 
33
33
  render_utils.print_inputs(render_context, existing_files_content, "Files sent as input to unit tests fixing:")
34
34
 
35
+ conformance_tests_fixes = self._get_conformance_tests_fixes(render_context)
36
+ if conformance_tests_fixes:
37
+ console.info(
38
+ f"Unit tests are fixed while preserving {len(conformance_tests_fixes)} implementation code change(s) "
39
+ "made to fix the conformance tests."
40
+ )
41
+
35
42
  response_files = render_context.codeplain_api.fix_unittests_issue(
36
43
  render_context.frid_context.frid,
37
44
  render_context.plain_source_tree,
@@ -41,6 +48,7 @@ class FixUnitTests(BaseAction):
41
48
  render_context.get_required_modules_functionalities(),
42
49
  previous_unittests_issue,
43
50
  run_state=render_context.run_state,
51
+ conformance_tests_fixes=conformance_tests_fixes,
44
52
  )
45
53
 
46
54
  _, changed_files = file_utils.update_build_folder_with_rendered_files(
@@ -52,3 +60,20 @@ class FixUnitTests(BaseAction):
52
60
  console.print_files("Files fixed:", render_context.build_folder, response_files, style=console.OUTPUT_STYLE)
53
61
 
54
62
  return self.SUCCESSFUL_OUTCOME, None
63
+
64
+ @staticmethod
65
+ def _get_conformance_tests_fixes(render_context: RenderContext) -> list[dict] | None:
66
+ """Implementation code changes the conformance tests fixer made before these unit tests were run.
67
+
68
+ Only present when unit tests are processed inside the conformance tests phase - the implementation
69
+ and refactoring unit test passes have no conformance tests running context.
70
+ """
71
+ conformance_tests_running_context = getattr(render_context, "conformance_tests_running_context", None)
72
+ if conformance_tests_running_context is None:
73
+ return None
74
+
75
+ implementation_code_fixes = getattr(conformance_tests_running_context, "implementation_code_fixes", None)
76
+ if not implementation_code_fixes:
77
+ return None
78
+
79
+ return list(implementation_code_fixes)
@@ -91,6 +91,11 @@ class ConformanceTestsRunningContext:
91
91
 
92
92
  self.current_testing_frid_high_level_implementation_plan: Optional[str] = None
93
93
 
94
+ # Implementation code changes made by the conformance tests fixer during this conformance phase, in
95
+ # order. Each entry is {"hypothesis": str | None, "approach": str | None, "code_diff": {file: diff}}.
96
+ # Handed to the unit tests fixer so it adjusts the unit tests instead of reverting these changes.
97
+ self.implementation_code_fixes: list[dict] = []
98
+
94
99
  def get_conformance_tests_json(self, module_name: str) -> dict:
95
100
  return self._conformance_tests_json[module_name]
96
101
 
@@ -0,0 +1,230 @@
1
+ """Tests for handing the conformance tests fixer's implementation changes to the unit tests fixer.
2
+
3
+ When the conformance tests fixer changes implementation code, the unit tests are re-run and fixed next.
4
+ The unit tests fixer must know about that change so it adjusts the unit tests instead of reverting it.
5
+ """
6
+
7
+ import os
8
+ import tempfile
9
+ from types import SimpleNamespace
10
+
11
+ import pytest
12
+
13
+ import plain_spec
14
+ from memory_management import MemoryManager
15
+ from render_machine.actions import fix_unit_tests as fix_unit_tests_module
16
+ from render_machine.actions.fix_conformance_test import FixConformanceTest
17
+ from render_machine.actions.fix_unit_tests import FixUnitTests
18
+ from render_machine.implementation_code_helpers import ImplementationCodeHelpers
19
+ from render_machine.render_types import ConformanceTestsRunningContext, UnitTestsRunningContext
20
+
21
+
22
+ class FakeCodeplainAPI:
23
+ def __init__(self, conformance_fix_response=None, unittests_fix_response=None):
24
+ self.conformance_fix_response = conformance_fix_response
25
+ self.unittests_fix_response = unittests_fix_response or {}
26
+ self.unittests_fix_calls = []
27
+
28
+ def fix_conformance_tests_issue(self, *args, **kwargs):
29
+ return self.conformance_fix_response
30
+
31
+ def fix_unittests_issue(self, *args, **kwargs):
32
+ self.unittests_fix_calls.append(kwargs)
33
+ return self.unittests_fix_response
34
+
35
+
36
+ class FakeConformanceTests:
37
+ def fetch_existing_conformance_test_files(self, *args):
38
+ return {}, {}
39
+
40
+ def store_conformance_tests_files(self, *args):
41
+ pass
42
+
43
+
44
+ @pytest.fixture
45
+ def build_folder():
46
+ with tempfile.TemporaryDirectory() as folder:
47
+ with open(os.path.join(folder, "app.py"), "w", encoding="utf-8") as source_file:
48
+ source_file.write("def add(a, b):\n return a + b\n")
49
+ yield folder
50
+
51
+
52
+ @pytest.fixture
53
+ def memory_folder():
54
+ with tempfile.TemporaryDirectory() as folder:
55
+ yield folder
56
+
57
+
58
+ @pytest.fixture(autouse=True)
59
+ def isolate_from_git_and_console(monkeypatch):
60
+ monkeypatch.setattr(ImplementationCodeHelpers, "get_code_diff", staticmethod(lambda *args: {}))
61
+ monkeypatch.setattr(plain_spec, "collect_linked_resources", lambda *args: None)
62
+ monkeypatch.setattr(fix_unit_tests_module.render_utils, "print_inputs", lambda *args: None)
63
+
64
+
65
+ def make_conformance_context():
66
+ return ConformanceTestsRunningContext(
67
+ current_testing_module_name="mod",
68
+ current_testing_frid="1",
69
+ fix_attempts=0,
70
+ conformance_tests_json={"1": {"folder_name": "conformance_1"}},
71
+ conformance_tests_render_attempts=0,
72
+ current_testing_frid_specifications={},
73
+ should_prepare_testing_environment=False,
74
+ frid_being_implemented="1",
75
+ )
76
+
77
+
78
+ def make_render_context(api, build_folder, memory_folder, conformance_tests_running_context):
79
+ return SimpleNamespace(
80
+ codeplain_api=api,
81
+ build_folder=build_folder,
82
+ memory_manager=MemoryManager(api, memory_folder),
83
+ conformance_tests=FakeConformanceTests(),
84
+ conformance_tests_running_context=conformance_tests_running_context,
85
+ unit_tests_running_context=UnitTestsRunningContext(fix_attempts=1),
86
+ plain_source_tree={},
87
+ module_name="mod",
88
+ required_modules=None,
89
+ frid_context=SimpleNamespace(frid="1", linked_resources={}),
90
+ get_required_modules_functionalities=lambda: {},
91
+ run_state=SimpleNamespace(render_id="test-render-id", unittest_batch_id=1),
92
+ )
93
+
94
+
95
+ def run_conformance_fix(render_context):
96
+ return FixConformanceTest().execute(render_context, {"previous_conformance_tests_issue": "tests failed"})
97
+
98
+
99
+ def test_conformance_fix_of_implementation_code_is_remembered(build_folder, memory_folder):
100
+ api = FakeCodeplainAPI(
101
+ conformance_fix_response=[
102
+ FixConformanceTest.ISSUE_REASON_CODE_IMPLEMENTATION_CODE,
103
+ {"app.py": "def add(a, b):\n return a + b + 1\n"},
104
+ {"hypothesis": "off by one", "approach": "add one"},
105
+ "prepared issue",
106
+ ]
107
+ )
108
+ ctx = make_conformance_context()
109
+ render_context = make_render_context(api, build_folder, memory_folder, ctx)
110
+
111
+ outcome, _ = run_conformance_fix(render_context)
112
+
113
+ assert outcome == FixConformanceTest.IMPLEMENTATION_CODE_UPDATED
114
+ assert len(ctx.implementation_code_fixes) == 1
115
+ recorded_fix = ctx.implementation_code_fixes[0]
116
+ assert recorded_fix["hypothesis"] == "off by one"
117
+ assert recorded_fix["approach"] == "add one"
118
+ assert list(recorded_fix["code_diff"]) == ["app.py"]
119
+ assert "+ return a + b + 1" in recorded_fix["code_diff"]["app.py"]
120
+
121
+
122
+ def test_consecutive_implementation_fixes_accumulate(build_folder, memory_folder):
123
+ ctx = make_conformance_context()
124
+ for attempt in range(2):
125
+ api = FakeCodeplainAPI(
126
+ conformance_fix_response=[
127
+ FixConformanceTest.ISSUE_REASON_CODE_IMPLEMENTATION_CODE,
128
+ {"app.py": f"def add(a, b):\n return a + b + {attempt + 1}\n"},
129
+ {"hypothesis": f"hypothesis {attempt}", "approach": f"approach {attempt}"},
130
+ "prepared issue",
131
+ ]
132
+ )
133
+ render_context = make_render_context(api, build_folder, memory_folder, ctx)
134
+ run_conformance_fix(render_context)
135
+
136
+ assert [fix["hypothesis"] for fix in ctx.implementation_code_fixes] == ["hypothesis 0", "hypothesis 1"]
137
+
138
+
139
+ def test_conformance_fix_without_summary_is_still_remembered(build_folder, memory_folder):
140
+ api = FakeCodeplainAPI(
141
+ conformance_fix_response=[
142
+ FixConformanceTest.ISSUE_REASON_CODE_IMPLEMENTATION_CODE,
143
+ {"app.py": "def add(a, b):\n return a + b + 1\n"},
144
+ None,
145
+ "prepared issue",
146
+ ]
147
+ )
148
+ ctx = make_conformance_context()
149
+ render_context = make_render_context(api, build_folder, memory_folder, ctx)
150
+
151
+ run_conformance_fix(render_context)
152
+
153
+ assert ctx.implementation_code_fixes[0]["hypothesis"] is None
154
+ assert ctx.implementation_code_fixes[0]["approach"] is None
155
+ assert "app.py" in ctx.implementation_code_fixes[0]["code_diff"]
156
+
157
+
158
+ def test_conformance_fix_of_conformance_tests_is_not_remembered(build_folder, memory_folder):
159
+ api = FakeCodeplainAPI(
160
+ conformance_fix_response=[
161
+ FixConformanceTest.ISSUE_REASON_CODE_CONFORMANCE_TESTS,
162
+ {"test_app.py": "def test_add(): pass\n"},
163
+ {"hypothesis": "wrong assertion", "approach": "fix test"},
164
+ "prepared issue",
165
+ ]
166
+ )
167
+ ctx = make_conformance_context()
168
+ render_context = make_render_context(api, build_folder, memory_folder, ctx)
169
+
170
+ outcome, _ = run_conformance_fix(render_context)
171
+
172
+ assert outcome == FixConformanceTest.IMPLEMENTATION_CODE_NOT_UPDATED
173
+ assert ctx.implementation_code_fixes == []
174
+
175
+
176
+ def test_implementation_fix_with_no_files_is_not_remembered(build_folder, memory_folder):
177
+ api = FakeCodeplainAPI(
178
+ conformance_fix_response=[
179
+ FixConformanceTest.ISSUE_REASON_CODE_IMPLEMENTATION_CODE,
180
+ {},
181
+ {"hypothesis": "nothing", "approach": "nothing"},
182
+ "prepared issue",
183
+ ]
184
+ )
185
+ ctx = make_conformance_context()
186
+ render_context = make_render_context(api, build_folder, memory_folder, ctx)
187
+
188
+ outcome, _ = run_conformance_fix(render_context)
189
+
190
+ assert outcome == FixConformanceTest.IMPLEMENTATION_CODE_NOT_UPDATED
191
+ assert ctx.implementation_code_fixes == []
192
+
193
+
194
+ def run_unit_tests_fix(render_context):
195
+ return FixUnitTests().execute(render_context, {"previous_unittests_issue": "1 failed"})
196
+
197
+
198
+ def test_unit_tests_fix_forwards_conformance_fixes(build_folder, memory_folder):
199
+ api = FakeCodeplainAPI(unittests_fix_response={"test_app.py": "def test_add(): pass\n"})
200
+ ctx = make_conformance_context()
201
+ ctx.implementation_code_fixes.append(
202
+ {"hypothesis": "off by one", "approach": "add one", "code_diff": {"app.py": "+ return a + b + 1"}}
203
+ )
204
+ render_context = make_render_context(api, build_folder, memory_folder, ctx)
205
+
206
+ outcome, _ = run_unit_tests_fix(render_context)
207
+
208
+ assert outcome == FixUnitTests.SUCCESSFUL_OUTCOME
209
+ assert len(api.unittests_fix_calls) == 1
210
+ assert api.unittests_fix_calls[0]["conformance_tests_fixes"] == ctx.implementation_code_fixes
211
+ # The forwarded list is a copy, so later conformance fixes do not mutate what was sent.
212
+ assert api.unittests_fix_calls[0]["conformance_tests_fixes"] is not ctx.implementation_code_fixes
213
+
214
+
215
+ def test_unit_tests_fix_outside_conformance_phase_sends_no_fixes(build_folder, memory_folder):
216
+ api = FakeCodeplainAPI()
217
+ render_context = make_render_context(api, build_folder, memory_folder, None)
218
+
219
+ run_unit_tests_fix(render_context)
220
+
221
+ assert api.unittests_fix_calls[0]["conformance_tests_fixes"] is None
222
+
223
+
224
+ def test_unit_tests_fix_in_conformance_phase_without_implementation_changes_sends_no_fixes(build_folder, memory_folder):
225
+ api = FakeCodeplainAPI()
226
+ render_context = make_render_context(api, build_folder, memory_folder, make_conformance_context())
227
+
228
+ run_unit_tests_fix(render_context)
229
+
230
+ assert api.unittests_fix_calls[0]["conformance_tests_fixes"] is None