codeplain 0.3.11.dev13__tar.gz → 0.3.11.dev15__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 (279) hide show
  1. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/PKG-INFO +1 -1
  2. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain_file.py +34 -9
  3. codeplain-0.3.11.dev15/tests/data/plainfileparser/cyclic_definitions.plain +9 -0
  4. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_defaults_exported.plain +13 -0
  5. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_imported_exported.plain +12 -0
  6. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_inherited_reexported.plain +15 -0
  7. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_malformed.plain +13 -0
  8. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_missing_definition.plain +14 -0
  9. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_missing_definition_example.plain +13 -0
  10. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_multiple_per_bullet.plain +14 -0
  11. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_multiple_per_bullet_undefined.plain +13 -0
  12. codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_no_definitions.plain +10 -0
  13. codeplain-0.3.11.dev13/tests/data/plainfileparser/exported_concepts_missing_example.plain → codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_not_declared_example.plain +1 -1
  14. codeplain-0.3.11.dev15/tests/data/plainfileparser/requires_without_definitions_example.plain +10 -0
  15. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plainfileparser.py +39 -18
  16. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.claude/settings.json +0 -0
  17. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.flake8 +0 -0
  18. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/dependabot.yml +0 -0
  19. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/e2e.yml +0 -0
  20. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/lint-and-test.yml +0 -0
  21. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/lint-powershell.yml +0 -0
  22. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  23. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/publish-dev-to-pypi.yml +0 -0
  24. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/publish-install-script.yml +0 -0
  25. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.github/workflows/publish-to-pypi.yml +0 -0
  26. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.gitignore +0 -0
  27. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.vscode/launch.json +0 -0
  28. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/.vscode/settings.json +0 -0
  29. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/CLAUDE.md +0 -0
  30. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/CONTRIBUTING.md +0 -0
  31. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/LICENSE +0 -0
  32. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/README.md +0 -0
  33. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/change_detection.py +0 -0
  34. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/cli_output/__init__.py +0 -0
  35. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/cli_output/dry_run.py +0 -0
  36. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/cli_output/render_summary.py +0 -0
  37. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/cli_output/status.py +0 -0
  38. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/codeplain_REST_api.py +0 -0
  39. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/concept_utils.py +0 -0
  40. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/config/__init__.py +0 -0
  41. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/config/system_config.yaml +0 -0
  42. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/conformance_fix_journal.py +0 -0
  43. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/diff_utils.py +0 -0
  44. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/docs/generate_cli.py +0 -0
  45. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/docs/plain2code_cli.md +0 -0
  46. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/docs/starting_a_plain_project_from_scratch.md +0 -0
  47. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/event_bus.py +0 -0
  48. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_golang/config.yaml +0 -0
  49. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  50. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  51. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_golang/run.sh +0 -0
  52. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_python/config.yaml +0 -0
  53. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  54. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_python/hello_world_python.plain +0 -0
  55. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_python/run.sh +0 -0
  56. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/config.yaml +0 -0
  57. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  58. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  59. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  60. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  61. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  62. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  63. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/example_hello_world_react/run.sh +0 -0
  64. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/examples/run.sh +0 -0
  65. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/file_utils.py +0 -0
  66. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/git_preflight.py +0 -0
  67. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/git_utils.py +0 -0
  68. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/install/bash/examples.sh +0 -0
  69. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/install/bash/install.sh +0 -0
  70. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/install/bash/walkthrough.sh +0 -0
  71. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/install/powershell/examples.ps1 +0 -0
  72. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/install/powershell/install.ps1 +0 -0
  73. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/install/powershell/walkthrough.ps1 +0 -0
  74. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/memory_management.py +0 -0
  75. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/metadata_utils.py +0 -0
  76. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/module_renderer.py +0 -0
  77. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/partial_rendering.py +0 -0
  78. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/path_resolution.py +0 -0
  79. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code.py +0 -0
  80. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_arguments.py +0 -0
  81. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_cli.md +0 -0
  82. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_console.py +0 -0
  83. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_events.py +0 -0
  84. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_exceptions.py +0 -0
  85. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_logger.py +0 -0
  86. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_nodes.py +0 -0
  87. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_read_config.py +0 -0
  88. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_state.py +0 -0
  89. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_telemetry.py +0 -0
  90. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain2code_utils.py +0 -0
  91. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain_modules.py +0 -0
  92. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/plain_spec.py +0 -0
  93. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/pyproject.toml +0 -0
  94. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/pytest.ini +0 -0
  95. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/__init__.py +0 -0
  96. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
  97. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/base_action.py +0 -0
  98. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  99. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  100. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/create_dist.py +0 -0
  101. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/distill_conformance_test_memory.py +0 -0
  102. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/exit_with_error.py +0 -0
  103. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/finish_functional_requirement.py +0 -0
  104. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/fix_conformance_test.py +0 -0
  105. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/fix_unit_tests.py +0 -0
  106. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/prepare_repositories.py +0 -0
  107. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/prepare_testing_environment.py +0 -0
  108. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/refactor_code.py +0 -0
  109. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/render_conformance_tests.py +0 -0
  110. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/render_functional_requirement.py +0 -0
  111. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/run_conformance_tests.py +0 -0
  112. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/run_unit_tests.py +0 -0
  113. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/actions/summarize_conformance_tests.py +0 -0
  114. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/code_renderer.py +0 -0
  115. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/conformance_tests.py +0 -0
  116. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/implementation_code_helpers.py +0 -0
  117. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/render_context.py +0 -0
  118. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/render_types.py +0 -0
  119. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/render_utils.py +0 -0
  120. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/state_machine_config.py +0 -0
  121. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/states.py +0 -0
  122. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/render_machine/triggers.py +0 -0
  123. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/requirements.txt +0 -0
  124. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/resources/codeplain_overview.png +0 -0
  125. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/resources/plain_example.png +0 -0
  126. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/standard_template_library/golang-console-app-template.plain +0 -0
  127. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/standard_template_library/python-console-app-template.plain +0 -0
  128. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  129. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/standard_template_library/typescript-react-app-template.plain +0 -0
  130. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/system_config.py +0 -0
  131. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
  132. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  133. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
  134. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_conformance_tests_golang.sh +0 -0
  135. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_conformance_tests_python.ps1 +0 -0
  136. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_conformance_tests_python.sh +0 -0
  137. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_flutter.ps1 +0 -0
  138. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_flutter.sh +0 -0
  139. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_golang.ps1 +0 -0
  140. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_golang.sh +0 -0
  141. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_python.ps1 +0 -0
  142. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_python.sh +0 -0
  143. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_react.ps1 +0 -0
  144. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/test_scripts/run_unittests_react.sh +0 -0
  145. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/__init__.py +0 -0
  146. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/conftest.py +0 -0
  147. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
  148. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
  149. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/circular_imports_1.plain +0 -0
  150. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/circular_imports_2.plain +0 -0
  151. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/circular_imports_main.plain +0 -0
  152. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/diamond_import_1.plain +0 -0
  153. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/diamond_import_2.plain +0 -0
  154. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/diamond_import_common.plain +0 -0
  155. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/diamond_imports_main.plain +0 -0
  156. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/import_with_functionalities.plain +0 -0
  157. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
  158. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/imports/non_existent_import.plain +0 -0
  159. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/partial_rendering/pr_code_var.plain +0 -0
  160. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/partial_rendering/pr_implement.plain +0 -0
  161. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/partial_rendering/pr_leaf.plain +0 -0
  162. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/partial_rendering/pr_middle.plain +0 -0
  163. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/partial_rendering/pr_root.plain +0 -0
  164. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/partial_rendering/pr_solo.plain +0 -0
  165. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
  166. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  167. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
  168. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  169. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  170. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
  171. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  172. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  173. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
  174. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  175. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  176. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  177. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  178. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  179. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  180. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  181. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  182. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  183. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  184. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  185. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  186. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  187. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  188. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  189. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  190. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  191. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  192. /codeplain-0.3.11.dev13/tests/data/plainfileparser/exported_concepts_missing.plain → /codeplain-0.3.11.dev15/tests/data/plainfileparser/exported_concepts_not_declared.plain +0 -0
  193. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  194. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  195. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  196. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  197. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  198. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  199. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts.plain +0 -0
  200. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  201. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  202. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  203. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  204. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  205. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  206. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  207. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  208. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/topological_sort.plain +0 -0
  209. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  210. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/circular_requires_main.plain +0 -0
  211. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/circular_requires_sub.plain +0 -0
  212. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/diamond_requires_1.plain +0 -0
  213. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/diamond_requires_2.plain +0 -0
  214. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/diamond_requires_common.plain +0 -0
  215. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/diamond_requires_main.plain +0 -0
  216. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/independent_requires_1.plain +0 -0
  217. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/independent_requires_2.plain +0 -0
  218. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/independent_requires_main.plain +0 -0
  219. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/non_existent_require.plain +0 -0
  220. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/normal_requires_1.plain +0 -0
  221. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/normal_requires_2.plain +0 -0
  222. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/normal_requires_common.plain +0 -0
  223. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/requires/normal_requires_main.plain +0 -0
  224. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/sample_base64_image.txt +0 -0
  225. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/simple.plain +0 -0
  226. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/block_level_include.plain +0 -0
  227. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/code_variables.plain +0 -0
  228. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/header.plain +0 -0
  229. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/implement.plain +0 -0
  230. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/implement_2.plain +0 -0
  231. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/template_include.plain +0 -0
  232. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/data/templates/test_hardest_problem.plain +0 -0
  233. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/e2e/Dockerfile +0 -0
  234. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/e2e/conftest.py +0 -0
  235. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/e2e/test_hello_world_python.py +0 -0
  236. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/e2e/test_hello_world_python_windows.py +0 -0
  237. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_arg_provenance.py +0 -0
  238. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_change_detection.py +0 -0
  239. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_cli_output.py +0 -0
  240. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_conformance_fix_journal.py +0 -0
  241. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_console_log_styles.py +0 -0
  242. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_distill_conformance_test_memory.py +0 -0
  243. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_dry_run_link_validation.py +0 -0
  244. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_file_utils.py +0 -0
  245. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_fix_unit_tests_conformance_context.py +0 -0
  246. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_folder_path_resolution.py +0 -0
  247. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_git_preflight.py +0 -0
  248. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_git_utils.py +0 -0
  249. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_headless_logging.py +0 -0
  250. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_imports.py +0 -0
  251. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_log_file_name_resolution.py +0 -0
  252. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_logging_config_path_resolution.py +0 -0
  253. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_partial_rendering.py +0 -0
  254. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_path_resolution.py +0 -0
  255. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plain2code.py +0 -0
  256. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plain2code_state.py +0 -0
  257. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plain2code_utils.py +0 -0
  258. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plain_modules.py +0 -0
  259. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plainfile.py +0 -0
  260. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_plainspec.py +0 -0
  261. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_prepare_repositories_layout.py +0 -0
  262. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_requires.py +0 -0
  263. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_resolve_config_file.py +0 -0
  264. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_script_path_resolution.py +0 -0
  265. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_system_config.py +0 -0
  266. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_telemetry.py +0 -0
  267. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_tui_components.py +0 -0
  268. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_tui_usage.py +0 -0
  269. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tests/test_usage_summary.py +0 -0
  270. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/__init__.py +0 -0
  271. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/components.py +0 -0
  272. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/models.py +0 -0
  273. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/plain2code_tui.py +0 -0
  274. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/plain_module_render_choice_tui.py +0 -0
  275. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/spinner.py +0 -0
  276. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/state_handlers.py +0 -0
  277. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/styles.css +0 -0
  278. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/tui/widget_helpers.py +0 -0
  279. {codeplain-0.3.11.dev13 → codeplain-0.3.11.dev15}/usage_summary.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codeplain
3
- Version: 0.3.11.dev13
3
+ Version: 0.3.11.dev15
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -615,15 +615,45 @@ def parse_plain_source( # noqa: C901
615
615
  f"Plain syntax error: Syntax error at line {nested_acceptance_test_heading.line_number}: {plain_spec.ACCEPTANCE_TEST_HEADING} heading should be nested under specific functional spec."
616
616
  )
617
617
 
618
+ defined_concepts = set[str]()
618
619
  if plain_source[plain_spec.DEFINITIONS] is not None:
619
620
  with PlainRenderer() as renderer:
620
621
  for token in plain_source[plain_spec.DEFINITIONS].children:
621
622
  rendered_token = renderer.render(token)
622
623
  new_concepts, _ = concept_utils.extract_concepts_from_definition(rendered_token)
624
+ defined_concepts.update(new_concepts)
623
625
  for concept in new_concepts:
624
626
  if concept in required_concepts:
625
627
  required_concepts.remove(concept)
626
628
 
629
+ if EXPORTED_CONCEPTS_DIRECTIVE in plain_source_obj.metadata:
630
+ module_name = modules_trace[-1] if modules_trace else None
631
+ subject = f"Module '{module_name}'" if module_name else "Module"
632
+
633
+ for entry in plain_source_obj.metadata[EXPORTED_CONCEPTS_DIRECTIVE]:
634
+ exported_concepts, errors = concept_utils.extract_concepts_from_definition(entry)
635
+ if errors:
636
+ raise PlainSyntaxError(
637
+ f"Plain syntax error: {subject} exports an invalid concept (`{entry}`). "
638
+ f"Expected a concept token, e.g. :ConceptName:."
639
+ )
640
+
641
+ for exported_concept in exported_concepts:
642
+ if exported_concept in concept_utils.DEFAULT_CONCEPTS:
643
+ raise PlainSyntaxError(
644
+ f"Plain syntax error: {subject} cannot export default concept {exported_concept}. "
645
+ f"Only user-defined concepts can be exported."
646
+ )
647
+
648
+ if exported_concept not in defined_concepts:
649
+ message = f"Plain syntax error: {subject} exports undefined concept {exported_concept}."
650
+ if REQUIRES_DIRECTIVE in plain_source_obj.metadata:
651
+ message += (
652
+ " An exported concept must be defined in this module's definitions or in an "
653
+ "imported module; a concept inherited through requires cannot be re-exported."
654
+ )
655
+ raise PlainSyntaxError(message)
656
+
627
657
  required_modules = []
628
658
  if REQUIRES_DIRECTIVE in plain_source_obj.metadata:
629
659
  required_modules = plain_source_obj.metadata[REQUIRES_DIRECTIVE]
@@ -710,15 +740,7 @@ def process_required_modules(
710
740
  if EXPORTED_CONCEPTS_DIRECTIVE in plain_file_parse_result.plain_source_obj.metadata:
711
741
  exported_concepts = list[str]()
712
742
  for concept in plain_file_parse_result.plain_source_obj.metadata[EXPORTED_CONCEPTS_DIRECTIVE]:
713
- if concept in concept_utils.DEFAULT_CONCEPTS:
714
- raise PlainSyntaxError(
715
- f"Plain syntax error: Default concept cannot be exported: {concept}. Only user-defined concepts can be exported."
716
- )
717
-
718
- if isinstance(concept, str):
719
- exported_concepts.extend(concept_utils.extract_concepts_from_definition(concept)[0])
720
- else:
721
- raise PlainSyntaxError(f"Plain syntax error: Invalid exported concept: {concept}.")
743
+ exported_concepts.extend(concept_utils.extract_concepts_from_definition(concept)[0])
722
744
 
723
745
  with PlainRenderer() as renderer:
724
746
  for exported_concept in exported_concepts:
@@ -737,6 +759,9 @@ def process_exported_definitions(plain_source: dict, exported_definitions: list[
737
759
  if len(exported_definitions) == 0:
738
760
  return
739
761
 
762
+ if plain_source[plain_spec.DEFINITIONS] is None:
763
+ plain_source[plain_spec.DEFINITIONS] = mistletoe.Document("")
764
+
740
765
  with PlainRenderer() as renderer:
741
766
  for exported_definition in exported_definitions:
742
767
  add_defintion = True
@@ -0,0 +1,9 @@
1
+ ***definitions***
2
+ - :A: relates to :B:.
3
+ - :B: relates to :A:.
4
+
5
+ ***implementation reqs***
6
+ - The :A: concept must be implemented.
7
+
8
+ ***functional specs***
9
+ - Implement a wrapper for the :A: concept.
@@ -0,0 +1,13 @@
1
+ ---
2
+ exported_concepts:
3
+ - :UnitTests:
4
+ ---
5
+
6
+ ***definitions***
7
+ - :NewConcept: is a new concept.
8
+
9
+ ***implementation reqs***
10
+ - The :NewConcept: must be implemented.
11
+
12
+ ***functional specs***
13
+ - Implement a wrapper for the :NewConcept: concept.
@@ -0,0 +1,12 @@
1
+ ---
2
+ import:
3
+ - exported_concepts_base
4
+ exported_concepts:
5
+ - :Concept:
6
+ ---
7
+
8
+ ***implementation reqs***
9
+ - The :Concept: concept must be implemented.
10
+
11
+ ***functional specs***
12
+ - Implement a wrapper for the :Concept: concept.
@@ -0,0 +1,15 @@
1
+ ---
2
+ requires:
3
+ - exported_concepts
4
+ exported_concepts:
5
+ - :Concept:
6
+ ---
7
+
8
+ ***definitions***
9
+ - :DependantConcept: depends on the :Concept: concept.
10
+
11
+ ***implementation reqs***
12
+ - The :DependantConcept: concept must be implemented.
13
+
14
+ ***functional specs***
15
+ - Implement a wrapper for the :DependantConcept: concept.
@@ -0,0 +1,13 @@
1
+ ---
2
+ exported_concepts:
3
+ - not a concept at all
4
+ ---
5
+
6
+ ***definitions***
7
+ - :A: is a concept.
8
+
9
+ ***implementation reqs***
10
+ - The :A: concept must be implemented.
11
+
12
+ ***functional specs***
13
+ - Implement a wrapper for the :A: concept.
@@ -0,0 +1,14 @@
1
+ ---
2
+ exported_concepts:
3
+ - :NewConcept:
4
+ - :Concept:
5
+ ---
6
+
7
+ ***definitions***
8
+ - :NewConcept: is a new concept.
9
+
10
+ ***implementation reqs***
11
+ - The :NewConcept: must be implemented.
12
+
13
+ ***functional specs***
14
+ - Implement a wrapper for the :NewConcept: concept.
@@ -0,0 +1,13 @@
1
+ ---
2
+ requires:
3
+ - exported_concepts_missing_definition
4
+ ---
5
+
6
+ ***definitions***
7
+ - :AnotherConcept: is a new concept.
8
+
9
+ ***implementation reqs***
10
+ - :AnotherConcept: must be implemented.
11
+
12
+ ***functional specs***
13
+ - Implement a wrapper for the :AnotherConcept: concept.
@@ -0,0 +1,14 @@
1
+ ---
2
+ exported_concepts:
3
+ - :NewConcept:, :OtherConcept:
4
+ ---
5
+
6
+ ***definitions***
7
+ - :NewConcept: is a new concept.
8
+ - :OtherConcept: is another concept.
9
+
10
+ ***implementation reqs***
11
+ - The :NewConcept: and :OtherConcept: concepts must be implemented.
12
+
13
+ ***functional specs***
14
+ - Implement a wrapper for the :NewConcept: and :OtherConcept: concepts.
@@ -0,0 +1,13 @@
1
+ ---
2
+ exported_concepts:
3
+ - :NewConcept:, :OtherConcept:
4
+ ---
5
+
6
+ ***definitions***
7
+ - :NewConcept: is a new concept.
8
+
9
+ ***implementation reqs***
10
+ - The :NewConcept: concept must be implemented.
11
+
12
+ ***functional specs***
13
+ - Implement a wrapper for the :NewConcept: concept.
@@ -0,0 +1,10 @@
1
+ ---
2
+ exported_concepts:
3
+ - :Concept:
4
+ ---
5
+
6
+ ***implementation reqs***
7
+ - :Implementation: is a simple wrapper.
8
+
9
+ ***functional specs***
10
+ - :Implementation: has an entry point.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  requires:
3
- - exported_concepts_missing
3
+ - exported_concepts_not_declared
4
4
  ---
5
5
 
6
6
  ***definitions***
@@ -0,0 +1,10 @@
1
+ ---
2
+ requires:
3
+ - exported_concepts
4
+ ---
5
+
6
+ ***implementation reqs***
7
+ - The :Concept: concept must be reused.
8
+
9
+ ***functional specs***
10
+ - Implement a second wrapper for the :Concept: concept.
@@ -632,6 +632,11 @@ def test_concept_validation_acceptance_tests(get_test_data_path):
632
632
  )
633
633
 
634
634
 
635
+ def test_concept_validation_cyclic_definitions(get_test_data_path):
636
+ with pytest.raises(PlainSyntaxError, match="cycles in the concept graph"):
637
+ plain_file.plain_file_parser("cyclic_definitions.plain", [get_test_data_path("data/plainfileparser")])
638
+
639
+
635
640
  def test_required_concepts(get_test_data_path):
636
641
  plain_file.plain_file_parser(
637
642
  "required_concepts_example.plain",
@@ -661,28 +666,44 @@ def test_required_concepts(get_test_data_path):
661
666
  )
662
667
 
663
668
 
664
- def test_exported_concepts(get_test_data_path):
665
- plain_file.plain_file_parser(
669
+ @pytest.mark.parametrize(
670
+ "fixture",
671
+ [
666
672
  "exported_concepts_example.plain",
667
- [get_test_data_path("data/plainfileparser")],
668
- )
669
-
670
- plain_file.plain_file_parser(
673
+ "exported_concepts_imported_exported.plain",
674
+ "exported_concepts_multiple_per_bullet.plain",
671
675
  "exported_concepts_nested_example.plain",
676
+ ],
677
+ )
678
+ def test_exported_concepts_valid(get_test_data_path, fixture):
679
+ plain_file.plain_file_parser(fixture, [get_test_data_path("data/plainfileparser")])
680
+
681
+
682
+ @pytest.mark.parametrize(
683
+ ("fixture", "expected_word"),
684
+ [
685
+ ("exported_concepts_defaults_exported.plain", "cannot export default concept"),
686
+ ("exported_concepts_inherited_reexported.plain", "cannot be re-exported"),
687
+ ("exported_concepts_malformed.plain", "exports an invalid concept"),
688
+ ("exported_concepts_missing_definition_example.plain", "'exported_concepts_missing_definition' exports"),
689
+ ("exported_concepts_missing_definition.plain", "exports undefined concept"),
690
+ ("exported_concepts_multiple_per_bullet_undefined.plain", "exports undefined concept"),
691
+ ("exported_concepts_no_definitions.plain", "exports undefined concept"),
692
+ ("exported_concepts_not_declared_example.plain", "not defined"),
693
+ ("exported_concepts_transitive_example.plain", "not defined"),
694
+ ],
695
+ )
696
+ def test_exported_concepts_invalid(get_test_data_path, fixture, expected_word):
697
+ with pytest.raises(PlainSyntaxError, match=expected_word):
698
+ plain_file.plain_file_parser(fixture, [get_test_data_path("data/plainfileparser")])
699
+
700
+
701
+ def test_requires_without_definitions(get_test_data_path):
702
+ _, plain_source, _ = plain_file.plain_file_parser(
703
+ "requires_without_definitions_example.plain",
672
704
  [get_test_data_path("data/plainfileparser")],
673
705
  )
674
-
675
- with pytest.raises(PlainSyntaxError):
676
- plain_file.plain_file_parser(
677
- "exported_concepts_missing_example.plain",
678
- [get_test_data_path("data/plainfileparser")],
679
- )
680
-
681
- with pytest.raises(PlainSyntaxError):
682
- plain_file.plain_file_parser(
683
- "exported_concepts_transitive_example.plain",
684
- [get_test_data_path("data/plainfileparser")],
685
- )
706
+ assert plain_source[plain_spec.DEFINITIONS] == [{"markdown": "- :Concept: is a concept."}]
686
707
 
687
708
 
688
709
  def test_topological_sort(get_test_data_path):