codeplain 0.3.13.dev37__tar.gz → 0.3.13.dev39__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.
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/PKG-INFO +2 -2
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/module_renderer.py +2 -4
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/pyproject.toml +1 -1
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/exit_with_error.py +8 -7
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/render_functional_requirement.py +10 -3
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/code_renderer.py +0 -3
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/render_context.py +1 -2
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/render_types.py +9 -11
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/requirements.txt +1 -1
- codeplain-0.3.13.dev39/tests/test_render_stop_reason.py +210 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.claude/settings.json +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.flake8 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/dependabot.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/e2e.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/lint-powershell.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/publish-dev-to-pypi.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.gitignore +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.vscode/launch.json +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.vscode/settings.json +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/CLAUDE.md +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/CONTRIBUTING.md +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/LICENSE +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/README.md +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/change_detection.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/cli_output/__init__.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/cli_output/status.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/codeplain_REST_api.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/concept_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/config/__init__.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/config/system_config.yaml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/conformance_fix_journal.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/diff_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/docs/generate_cli.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/docs/plain2code_cli.md +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/event_bus.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/run.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/file_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/git_preflight.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/git_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/install/bash/examples.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/install/bash/install.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/install/powershell/examples.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/install/powershell/install.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/install/powershell/walkthrough.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/memory_management.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/metadata_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/partial_rendering.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/path_resolution.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_arguments.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_cli.md +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_console.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_events.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_exceptions.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_logger.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_nodes.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_read_config.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_state.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain2code_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain_file.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain_modules.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/plain_spec.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/pytest.ini +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/__init__.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/agent_tools.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/states.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/triggers.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/resources/plain_example.png +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/system_config.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/__init__.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/conftest.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/plain_source_with_missing_link.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/cyclic_definitions.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_defaults_exported.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_imported_exported.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_inherited_reexported.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_malformed.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_missing_definition.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_missing_definition_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_multiple_per_bullet.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_multiple_per_bullet_undefined.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_no_definitions.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_not_declared.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_not_declared_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/requires_without_definitions_example.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/simple.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_agent_tools.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_cli_output.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_conformance_fix_journal.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_dry_run_link_validation.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_fix_unit_tests_action.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_fix_unit_tests_conformance_context.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_git_preflight.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_headless_logging.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_imports.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plain_modules.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_prepare_repositories_layout.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_render_finished_report.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_requires.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_system_config.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_terminal_attachment.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_tui_components.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/__init__.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/components.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/models.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/plain_module_render_choice_tui.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/spinner.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/state_handlers.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/styles.css +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/usage_summary.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codeplain
|
|
3
|
-
Version: 0.3.13.
|
|
3
|
+
Version: 0.3.13.dev39
|
|
4
4
|
Summary: Transform plain language specifications into working code
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Classifier: Environment :: Console
|
|
@@ -8,7 +8,7 @@ Classifier: Intended Audience :: Developers
|
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
9
|
Classifier: Topic :: Software Development :: Code Generators
|
|
10
10
|
Requires-Python: ==3.11.*
|
|
11
|
-
Requires-Dist: gitpython==3.1
|
|
11
|
+
Requires-Dist: gitpython==3.2.1
|
|
12
12
|
Requires-Dist: mistletoe==1.6.0
|
|
13
13
|
Requires-Dist: networkx==3.6.1
|
|
14
14
|
Requires-Dist: python-frontmatter==1.3.0
|
|
@@ -134,10 +134,8 @@ class ModuleRenderer:
|
|
|
134
134
|
|
|
135
135
|
code_renderer.run()
|
|
136
136
|
if code_renderer.render_context.state == States.RENDER_FAILED.value:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
fallback_message=code_renderer.render_context.last_error_message,
|
|
140
|
-
)
|
|
137
|
+
# ExitWithError resolved and logged the stop reason; the TUI shows the same text.
|
|
138
|
+
error_message = code_renderer.render_context.last_error_message or RenderError.get_display_message(None)
|
|
141
139
|
code_renderer.render_context.event_bus.publish(RenderFailed(error_message=error_message))
|
|
142
140
|
return False, True
|
|
143
141
|
|
|
@@ -10,7 +10,13 @@ class ExitWithError(BaseAction):
|
|
|
10
10
|
SUCCESSFUL_OUTCOME = "error_handled"
|
|
11
11
|
|
|
12
12
|
def execute(self, render_context: RenderContext, previous_action_payload: Any | None):
|
|
13
|
-
|
|
13
|
+
# The stop reason is the error payload of the failed action, or the message stored when the
|
|
14
|
+
# error was dispatched from a state callback. The log and the TUI both show this text.
|
|
15
|
+
error_message = RenderError.get_display_message(
|
|
16
|
+
previous_action_payload, fallback_message=render_context.last_error_message
|
|
17
|
+
)
|
|
18
|
+
render_context.last_error_message = error_message
|
|
19
|
+
console.error(error_message)
|
|
14
20
|
|
|
15
21
|
render_context.codeplain_api.fail_functional_requirement(
|
|
16
22
|
render_context.frid_context.frid,
|
|
@@ -27,9 +33,4 @@ class ExitWithError(BaseAction):
|
|
|
27
33
|
if render_context.run_state.render_id is not None:
|
|
28
34
|
console.info(f"Render ID: {render_context.run_state.render_id}")
|
|
29
35
|
|
|
30
|
-
return (
|
|
31
|
-
self.SUCCESSFUL_OUTCOME,
|
|
32
|
-
RenderError.encode(
|
|
33
|
-
message=render_context.last_error_message or "Unknown error",
|
|
34
|
-
).to_payload(),
|
|
35
|
-
)
|
|
36
|
+
return self.SUCCESSFUL_OUTCOME, RenderError.encode(message=error_message).to_payload()
|
|
@@ -7,7 +7,7 @@ from plain2code_console import RETRY_COLOR, console
|
|
|
7
7
|
from plain2code_exceptions import FunctionalRequirementTooComplex
|
|
8
8
|
from render_machine.actions.base_action import BaseAction
|
|
9
9
|
from render_machine.implementation_code_helpers import ImplementationCodeHelpers
|
|
10
|
-
from render_machine.render_context import RenderContext
|
|
10
|
+
from render_machine.render_context import MAX_UNITTEST_FIX_ATTEMPTS, RenderContext
|
|
11
11
|
from render_machine.render_types import RenderError
|
|
12
12
|
|
|
13
13
|
MAX_CODE_GENERATION_RETRIES = 2
|
|
@@ -20,9 +20,16 @@ class RenderFunctionalRequirement(BaseAction):
|
|
|
20
20
|
|
|
21
21
|
def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
|
|
22
22
|
if render_context.frid_context.functional_requirement_render_attempts >= MAX_CODE_GENERATION_RETRIES:
|
|
23
|
-
|
|
23
|
+
# A render attempt is only restarted once its unit tests used up every fix round.
|
|
24
|
+
error_msg = (
|
|
25
|
+
f"Functionality {render_context.frid_context.frid}: unit tests still fail after "
|
|
26
|
+
f"{MAX_CODE_GENERATION_RETRIES} render attempts, {MAX_UNITTEST_FIX_ATTEMPTS} fix rounds each."
|
|
27
|
+
)
|
|
28
|
+
last_output_path = render_context.script_execution_history.latest_unit_test_output_path
|
|
29
|
+
if last_output_path:
|
|
30
|
+
error_msg += f" Last unit tests output: {last_output_path}"
|
|
24
31
|
render_context.last_error_message = error_msg
|
|
25
|
-
return self.ITERATION_LIMIT_EXCEEDED_OUTCOME,
|
|
32
|
+
return self.ITERATION_LIMIT_EXCEEDED_OUTCOME, RenderError.encode(message=error_msg).to_payload()
|
|
26
33
|
|
|
27
34
|
render_context.frid_context.functional_requirement_render_attempts += 1
|
|
28
35
|
|
|
@@ -67,14 +67,11 @@ class CodeRenderer:
|
|
|
67
67
|
self.render_context.run_state.current_render_state = self.render_context.state
|
|
68
68
|
self.render_context.script_execution_history.should_update_script_outputs = False
|
|
69
69
|
|
|
70
|
-
self.render_context.previous_action_payload = previous_action_payload
|
|
71
|
-
|
|
72
70
|
outcome, previous_action_payload = self.action_map[self.render_context.state].execute(
|
|
73
71
|
self.render_context, previous_action_payload
|
|
74
72
|
)
|
|
75
73
|
|
|
76
74
|
if self.render_context.state == States.RENDER_FAILED.value:
|
|
77
|
-
self.render_context.last_error_message = previous_action_payload
|
|
78
75
|
self.render_context.event_bus.publish(RenderModuleFailed(module_name=self.render_context.module_name))
|
|
79
76
|
break
|
|
80
77
|
|
|
@@ -113,12 +113,11 @@ class RenderContext:
|
|
|
113
113
|
self.machine = machine
|
|
114
114
|
|
|
115
115
|
def dispatch_error(self, error_message: str):
|
|
116
|
-
"""
|
|
116
|
+
"""Store the error and dispatch HANDLE_ERROR trigger. ExitWithError logs it and the TUI displays it.
|
|
117
117
|
|
|
118
118
|
Args:
|
|
119
119
|
error_message: The error message to log and display to the user.
|
|
120
120
|
"""
|
|
121
|
-
console.error(error_message)
|
|
122
121
|
self.last_error_message = error_message
|
|
123
122
|
self.machine.dispatch(triggers.HANDLE_ERROR)
|
|
124
123
|
|
|
@@ -259,17 +259,15 @@ class RenderError:
|
|
|
259
259
|
"""Decode error from action payload.
|
|
260
260
|
|
|
261
261
|
Expects standardized format: {"error": {"message": ..., "type": ..., "details": ...}}
|
|
262
|
+
Any other payload is not an error (e.g. the payload of the action that ran before an error was
|
|
263
|
+
dispatched from a state callback) and decodes to None.
|
|
262
264
|
"""
|
|
263
|
-
if payload
|
|
265
|
+
if not isinstance(payload, dict) or "error" not in payload:
|
|
264
266
|
return None
|
|
265
267
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
)
|
|
273
|
-
|
|
274
|
-
# Unexpected format - log and return generic error
|
|
275
|
-
return cls(message=f"Unexpected error format: {type(payload).__name__}")
|
|
268
|
+
error_data = payload["error"]
|
|
269
|
+
return cls(
|
|
270
|
+
message=error_data.get("message", "Unknown error"),
|
|
271
|
+
error_type=error_data.get("type"),
|
|
272
|
+
details=error_data.get("details"),
|
|
273
|
+
)
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""Tests for the reason a render gives when it stops on an error.
|
|
2
|
+
|
|
3
|
+
When a render stops, the reason is logged and shown in the TUI. These tests drive the
|
|
4
|
+
real render state machine through the last failing unit-test run of a functionality
|
|
5
|
+
and check that the stop reason names the cause, instead of the literal "None".
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import os
|
|
10
|
+
import stat
|
|
11
|
+
import tempfile
|
|
12
|
+
import threading
|
|
13
|
+
from types import SimpleNamespace
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
import plain2code_logger
|
|
18
|
+
from event_bus import EventBus
|
|
19
|
+
from memory_management import MemoryManager
|
|
20
|
+
from plain2code_state import RunState
|
|
21
|
+
from plain_modules import PlainModule
|
|
22
|
+
from render_machine.actions.exit_with_error import ExitWithError
|
|
23
|
+
from render_machine.actions.render_functional_requirement import MAX_CODE_GENERATION_RETRIES
|
|
24
|
+
from render_machine.code_renderer import CodeRenderer
|
|
25
|
+
from render_machine.render_context import (
|
|
26
|
+
MAX_FUNCTIONAL_REQUIREMENT_RENDER_ATTEMPTS_FAILED_UNIT_DURING_CONFORMANCE_TESTS,
|
|
27
|
+
MAX_UNITTEST_FIX_ATTEMPTS,
|
|
28
|
+
RenderContext,
|
|
29
|
+
)
|
|
30
|
+
from render_machine.render_types import RenderError, UnitTestsRunningContext
|
|
31
|
+
from render_machine.states import States
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class FakeCodeplainAPI:
|
|
35
|
+
def __init__(self):
|
|
36
|
+
self.failed_frids = []
|
|
37
|
+
|
|
38
|
+
def fail_functional_requirement(self, frid, module_name, run_state):
|
|
39
|
+
self.failed_frids.append(frid)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.fixture
|
|
43
|
+
def workspace():
|
|
44
|
+
with tempfile.TemporaryDirectory() as folder:
|
|
45
|
+
build_folder = os.path.join(folder, "plain_modules")
|
|
46
|
+
os.makedirs(build_folder)
|
|
47
|
+
|
|
48
|
+
unittests_script = os.path.join(folder, "run_unittests.sh")
|
|
49
|
+
with open(unittests_script, "w", encoding="utf-8") as script:
|
|
50
|
+
script.write("#!/bin/sh\necho '1 failed, 0 passed'\nexit 1\n")
|
|
51
|
+
os.chmod(unittests_script, os.stat(unittests_script).st_mode | stat.S_IEXEC)
|
|
52
|
+
|
|
53
|
+
yield build_folder, unittests_script
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def make_render_context(api, build_folder, unittests_script, fixtures_dir):
|
|
57
|
+
plain_module = PlainModule("pr_solo.plain", build_folder, [fixtures_dir])
|
|
58
|
+
os.makedirs(plain_module.module_build_folder, exist_ok=True)
|
|
59
|
+
return RenderContext(
|
|
60
|
+
api,
|
|
61
|
+
MemoryManager(api, plain_module.module_memory_folder),
|
|
62
|
+
plain_module,
|
|
63
|
+
build_folder=plain_module.module_build_folder,
|
|
64
|
+
build_dest="dist",
|
|
65
|
+
conformance_tests_dest="dist_tests",
|
|
66
|
+
unittests_script=unittests_script,
|
|
67
|
+
conformance_tests_script=None,
|
|
68
|
+
prepare_environment_script=None,
|
|
69
|
+
copy_build=False,
|
|
70
|
+
copy_conformance_tests=False,
|
|
71
|
+
render_range=None,
|
|
72
|
+
render_conformance_tests=False,
|
|
73
|
+
base_folder=fixtures_dir,
|
|
74
|
+
run_state=RunState(spec_filename="pr_solo.plain"),
|
|
75
|
+
event_bus=EventBus(),
|
|
76
|
+
enter_pause_event=threading.Event(),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def nested_state(*states: States) -> str:
|
|
81
|
+
return "_".join(state.value for state in states)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def error_log_messages(caplog) -> list[str]:
|
|
85
|
+
return [
|
|
86
|
+
record.getMessage()
|
|
87
|
+
for record in caplog.records
|
|
88
|
+
if record.name == plain2code_logger.LOGGER_NAME and record.levelno == logging.ERROR
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@pytest.fixture
|
|
93
|
+
def fixtures_dir(get_test_data_path):
|
|
94
|
+
return get_test_data_path("data/partial_rendering")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_unit_tests_failing_after_the_last_attempt_name_the_cause(workspace, fixtures_dir, caplog):
|
|
98
|
+
build_folder, unittests_script = workspace
|
|
99
|
+
api = FakeCodeplainAPI()
|
|
100
|
+
render_context = make_render_context(api, build_folder, unittests_script, fixtures_dir)
|
|
101
|
+
code_renderer = CodeRenderer(render_context)
|
|
102
|
+
|
|
103
|
+
# The last render attempt of functionality 1, after its last unit-test fix round.
|
|
104
|
+
render_context.start_implementing_frid()
|
|
105
|
+
render_context.frid_context.functional_requirement_render_attempts = MAX_CODE_GENERATION_RETRIES
|
|
106
|
+
render_context.unit_tests_running_context = UnitTestsRunningContext(fix_attempts=MAX_UNITTEST_FIX_ATTEMPTS)
|
|
107
|
+
code_renderer.machine.set_state(
|
|
108
|
+
nested_state(States.IMPLEMENTING_FRID, States.PROCESSING_UNIT_TESTS, States.UNIT_TESTS_READY)
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
with caplog.at_level(logging.DEBUG, logger=plain2code_logger.LOGGER_NAME):
|
|
112
|
+
code_renderer.run()
|
|
113
|
+
|
|
114
|
+
assert render_context.state == States.RENDER_FAILED.value
|
|
115
|
+
assert api.failed_frids == ["1"]
|
|
116
|
+
|
|
117
|
+
last_output_path = render_context.script_execution_history.latest_unit_test_output_path
|
|
118
|
+
assert last_output_path is not None and os.path.exists(last_output_path)
|
|
119
|
+
|
|
120
|
+
expected_message = (
|
|
121
|
+
f"Functionality 1: unit tests still fail after {MAX_CODE_GENERATION_RETRIES} render attempts, "
|
|
122
|
+
f"{MAX_UNITTEST_FIX_ATTEMPTS} fix rounds each. Last unit tests output: {last_output_path}"
|
|
123
|
+
)
|
|
124
|
+
assert error_log_messages(caplog) == [expected_message]
|
|
125
|
+
# The TUI shows the same stop reason as the log.
|
|
126
|
+
assert render_context.last_error_message == expected_message
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_unit_tests_failing_again_during_conformance_tests_name_the_cause_once(workspace, fixtures_dir, caplog):
|
|
130
|
+
build_folder, unittests_script = workspace
|
|
131
|
+
api = FakeCodeplainAPI()
|
|
132
|
+
render_context = make_render_context(api, build_folder, unittests_script, fixtures_dir)
|
|
133
|
+
code_renderer = CodeRenderer(render_context)
|
|
134
|
+
|
|
135
|
+
# Unit tests broken by a conformance fix, failing their last fix round for the last allowed time.
|
|
136
|
+
render_context.start_implementing_frid()
|
|
137
|
+
render_context.start_conformance_tests_processing()
|
|
138
|
+
render_context.functional_requirements_render_attempts_failed_unit_during_conformance_tests = (
|
|
139
|
+
MAX_FUNCTIONAL_REQUIREMENT_RENDER_ATTEMPTS_FAILED_UNIT_DURING_CONFORMANCE_TESTS - 1
|
|
140
|
+
)
|
|
141
|
+
render_context.unit_tests_running_context = UnitTestsRunningContext(fix_attempts=MAX_UNITTEST_FIX_ATTEMPTS)
|
|
142
|
+
code_renderer.machine.set_state(
|
|
143
|
+
nested_state(
|
|
144
|
+
States.IMPLEMENTING_FRID,
|
|
145
|
+
States.PROCESSING_CONFORMANCE_TESTS,
|
|
146
|
+
States.PROCESSING_UNIT_TESTS,
|
|
147
|
+
States.UNIT_TESTS_READY,
|
|
148
|
+
)
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
with caplog.at_level(logging.DEBUG, logger=plain2code_logger.LOGGER_NAME):
|
|
152
|
+
code_renderer.run()
|
|
153
|
+
|
|
154
|
+
assert render_context.state == States.RENDER_FAILED.value
|
|
155
|
+
error_messages = error_log_messages(caplog)
|
|
156
|
+
assert len(error_messages) == 1
|
|
157
|
+
assert error_messages[0].startswith("Failed to adjust the unit tests")
|
|
158
|
+
assert "functionality 1" in error_messages[0]
|
|
159
|
+
# The TUI shows the same stop reason as the log, not the unit tests output of the payload.
|
|
160
|
+
assert render_context.last_error_message == error_messages[0]
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class TestExitWithErrorMessage:
|
|
164
|
+
@staticmethod
|
|
165
|
+
def make_context(last_error_message=None):
|
|
166
|
+
render_context = RenderContext.__new__(RenderContext)
|
|
167
|
+
render_context.codeplain_api = FakeCodeplainAPI()
|
|
168
|
+
render_context.frid_context = SimpleNamespace(frid="1")
|
|
169
|
+
render_context.module_name = "mod"
|
|
170
|
+
render_context.run_state = RunState(spec_filename="mod.plain")
|
|
171
|
+
render_context.last_error_message = last_error_message
|
|
172
|
+
return render_context
|
|
173
|
+
|
|
174
|
+
def run_exit(self, render_context, payload, caplog):
|
|
175
|
+
with caplog.at_level(logging.DEBUG, logger=plain2code_logger.LOGGER_NAME):
|
|
176
|
+
ExitWithError().execute(render_context, payload)
|
|
177
|
+
return error_log_messages(caplog)
|
|
178
|
+
|
|
179
|
+
def test_logs_the_message_of_an_error_payload(self, caplog):
|
|
180
|
+
render_context = self.make_context()
|
|
181
|
+
payload = RenderError.encode(
|
|
182
|
+
message="Unit tests script failed due to problems in the environment setup.",
|
|
183
|
+
error_type="ENVIRONMENT_ERROR",
|
|
184
|
+
script="run_unittests.sh",
|
|
185
|
+
).to_payload()
|
|
186
|
+
|
|
187
|
+
messages = self.run_exit(render_context, payload, caplog)
|
|
188
|
+
|
|
189
|
+
expected = (
|
|
190
|
+
"Unit tests script failed due to problems in the environment setup.\n\nDetails:\n Script: run_unittests.sh"
|
|
191
|
+
)
|
|
192
|
+
assert messages == [expected]
|
|
193
|
+
assert render_context.last_error_message == expected
|
|
194
|
+
|
|
195
|
+
def test_logs_the_stored_message_when_the_payload_is_not_an_error(self, caplog):
|
|
196
|
+
render_context = self.make_context(last_error_message="Conformance tests could not be fixed.")
|
|
197
|
+
|
|
198
|
+
messages = self.run_exit(render_context, {"previous_unittests_issue": "1 failed"}, caplog)
|
|
199
|
+
|
|
200
|
+
assert messages == ["Conformance tests could not be fixed."]
|
|
201
|
+
assert render_context.last_error_message == "Conformance tests could not be fixed."
|
|
202
|
+
|
|
203
|
+
def test_never_logs_none(self, caplog):
|
|
204
|
+
render_context = self.make_context()
|
|
205
|
+
|
|
206
|
+
messages = self.run_exit(render_context, None, caplog)
|
|
207
|
+
|
|
208
|
+
assert len(messages) == 1
|
|
209
|
+
assert "None" not in messages[0]
|
|
210
|
+
assert render_context.last_error_message == messages[0]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/nofity-slack-on-main-merge.yml
RENAMED
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/.github/workflows/publish-install-script.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/docs/starting_a_plain_project_from_scratch.md
RENAMED
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_golang/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_golang/run.sh
RENAMED
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_python/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_python/run.sh
RENAMED
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/examples/example_hello_world_react/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/fix_conformance_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/prepare_repositories.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/render_conformance_tests.py
RENAMED
|
File without changes
|
{codeplain-0.3.13.dev37 → codeplain-0.3.13.dev39}/render_machine/actions/run_conformance_tests.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|