codeplain 0.2.4__py3-none-any.whl → 0.2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codeplain-0.2.4.dist-info → codeplain-0.2.5.dist-info}/METADATA +3 -3
- {codeplain-0.2.4.dist-info → codeplain-0.2.5.dist-info}/RECORD +41 -41
- codeplain_REST_api.py +57 -37
- config/system_config.yaml +1 -16
- file_utils.py +5 -4
- git_utils.py +42 -7
- memory_management.py +1 -1
- module_renderer.py +114 -0
- plain2code.py +87 -19
- plain2code_console.py +3 -5
- plain2code_exceptions.py +14 -4
- plain2code_logger.py +11 -5
- plain2code_utils.py +7 -5
- plain_file.py +1 -1
- plain_spec.py +22 -2
- render_machine/actions/create_dist.py +1 -1
- render_machine/actions/exit_with_error.py +1 -1
- render_machine/actions/prepare_testing_environment.py +1 -1
- render_machine/actions/render_conformance_tests.py +2 -4
- render_machine/actions/render_functional_requirement.py +6 -6
- render_machine/actions/run_conformance_tests.py +3 -2
- render_machine/actions/run_unit_tests.py +1 -1
- render_machine/render_context.py +3 -3
- render_machine/render_utils.py +14 -6
- standard_template_library/golang-console-app-template.plain +2 -2
- standard_template_library/python-console-app-template.plain +2 -2
- standard_template_library/typescript-react-app-template.plain +2 -2
- system_config.py +3 -11
- tests/test_imports.py +2 -2
- tests/test_plainfile.py +1 -1
- tests/test_plainfileparser.py +10 -10
- tests/test_plainspec.py +2 -2
- tui/components.py +311 -103
- tui/plain2code_tui.py +101 -52
- tui/state_handlers.py +94 -47
- tui/styles.css +240 -52
- tui/widget_helpers.py +43 -47
- {codeplain-0.2.4.dist-info → codeplain-0.2.5.dist-info}/WHEEL +0 -0
- {codeplain-0.2.4.dist-info → codeplain-0.2.5.dist-info}/entry_points.txt +0 -0
- {codeplain-0.2.4.dist-info → codeplain-0.2.5.dist-info}/licenses/LICENSE +0 -0
- /spinner.py → /tui/spinner.py +0 -0
tui/plain2code_tui.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import threading
|
|
3
3
|
import time
|
|
4
|
-
from typing import Callable
|
|
4
|
+
from typing import Callable, Optional
|
|
5
5
|
|
|
6
6
|
from textual.app import App, ComposeResult
|
|
7
7
|
from textual.containers import Vertical, VerticalScroll
|
|
8
|
-
from textual.widgets import ContentSwitcher,
|
|
9
|
-
from textual.worker import Worker, WorkerState
|
|
8
|
+
from textual.widgets import ContentSwitcher, Static
|
|
9
|
+
from textual.worker import Worker, WorkerFailed, WorkerState
|
|
10
10
|
|
|
11
11
|
from event_bus import EventBus
|
|
12
12
|
from plain2code_console import console
|
|
@@ -19,14 +19,19 @@ from plain2code_events import (
|
|
|
19
19
|
RenderModuleStarted,
|
|
20
20
|
RenderStateUpdated,
|
|
21
21
|
)
|
|
22
|
+
from plain2code_exceptions import InternalServerError
|
|
22
23
|
from render_machine.states import States
|
|
24
|
+
from tui.widget_helpers import log_to_widget
|
|
23
25
|
|
|
24
26
|
from .components import (
|
|
27
|
+
CustomFooter,
|
|
25
28
|
FRIDProgress,
|
|
26
29
|
LogFilterChanged,
|
|
27
30
|
LogLevelFilter,
|
|
31
|
+
RenderingInfoBox,
|
|
28
32
|
ScriptOutputType,
|
|
29
33
|
StructuredLogView,
|
|
34
|
+
TestScriptsContainer,
|
|
30
35
|
TUIComponents,
|
|
31
36
|
)
|
|
32
37
|
from .state_handlers import (
|
|
@@ -37,6 +42,7 @@ from .state_handlers import (
|
|
|
37
42
|
RenderErrorHandler,
|
|
38
43
|
RenderSuccessHandler,
|
|
39
44
|
ScriptOutputsHandler,
|
|
45
|
+
StateCompletionHandler,
|
|
40
46
|
StateHandler,
|
|
41
47
|
UnitTestsHandler,
|
|
42
48
|
)
|
|
@@ -60,6 +66,7 @@ class Plain2CodeTUI(App):
|
|
|
60
66
|
unittests_script: str,
|
|
61
67
|
conformance_tests_script: str,
|
|
62
68
|
prepare_environment_script: str,
|
|
69
|
+
state_machine_version: str,
|
|
63
70
|
**kwargs,
|
|
64
71
|
):
|
|
65
72
|
super().__init__(**kwargs)
|
|
@@ -67,21 +74,35 @@ class Plain2CodeTUI(App):
|
|
|
67
74
|
self.event_bus = event_bus
|
|
68
75
|
self.worker_fun = worker_fun
|
|
69
76
|
self.render_id = render_id
|
|
70
|
-
self.unittests_script = unittests_script
|
|
71
|
-
self.conformance_tests_script = conformance_tests_script
|
|
72
|
-
self.prepare_environment_script = prepare_environment_script
|
|
77
|
+
self.unittests_script: Optional[str] = unittests_script
|
|
78
|
+
self.conformance_tests_script: Optional[str] = conformance_tests_script
|
|
79
|
+
self.prepare_environment_script: Optional[str] = prepare_environment_script
|
|
80
|
+
self.state_machine_version = state_machine_version
|
|
73
81
|
|
|
74
82
|
# Initialize state handlers
|
|
75
83
|
self._state_handlers: dict[str, StateHandler] = {
|
|
76
|
-
States.READY_FOR_FRID_IMPLEMENTATION.value: FridReadyHandler(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
States.
|
|
80
|
-
|
|
84
|
+
States.READY_FOR_FRID_IMPLEMENTATION.value: FridReadyHandler(
|
|
85
|
+
self, self.unittests_script, self.conformance_tests_script
|
|
86
|
+
),
|
|
87
|
+
States.PROCESSING_UNIT_TESTS.value: UnitTestsHandler(
|
|
88
|
+
self, self.unittests_script, self.conformance_tests_script
|
|
89
|
+
),
|
|
90
|
+
States.REFACTORING_CODE.value: RefactoringHandler(
|
|
91
|
+
self, self.unittests_script, self.conformance_tests_script
|
|
92
|
+
),
|
|
93
|
+
States.PROCESSING_CONFORMANCE_TESTS.value: ConformanceTestsHandler(
|
|
94
|
+
self, self.unittests_script, self.conformance_tests_script
|
|
95
|
+
),
|
|
96
|
+
States.FRID_FULLY_IMPLEMENTED.value: FridFullyImplementedHandler(
|
|
97
|
+
self, self.unittests_script, self.conformance_tests_script
|
|
98
|
+
),
|
|
81
99
|
}
|
|
82
100
|
self._script_outputs_handler = ScriptOutputsHandler(self)
|
|
83
101
|
self._render_error_handler = RenderErrorHandler(self)
|
|
84
102
|
self._render_success_handler = RenderSuccessHandler(self)
|
|
103
|
+
self._state_completion_handler = StateCompletionHandler(
|
|
104
|
+
self, self.unittests_script, self.conformance_tests_script
|
|
105
|
+
)
|
|
85
106
|
|
|
86
107
|
def get_active_script_types(self) -> list[ScriptOutputType]:
|
|
87
108
|
"""Get the list of active script output types based on which scripts exist.
|
|
@@ -114,52 +135,74 @@ class Plain2CodeTUI(App):
|
|
|
114
135
|
def on_worker_state_changed(self, event: Worker.StateChanged) -> None:
|
|
115
136
|
"""Handle worker state changes."""
|
|
116
137
|
if event.worker.state == WorkerState.ERROR:
|
|
117
|
-
#
|
|
118
|
-
|
|
138
|
+
# Extract the original exception from WorkerFailed wrapper
|
|
139
|
+
error = event.worker.error
|
|
140
|
+
original_error = error.__cause__ if isinstance(error, WorkerFailed) and error.__cause__ else error
|
|
141
|
+
|
|
142
|
+
# Every error in worker thread gets converted to InternalServerError so it's handled by the common call to
|
|
143
|
+
# action in plain2code.py
|
|
144
|
+
internal_error = InternalServerError(str(original_error))
|
|
145
|
+
internal_error.__cause__ = original_error
|
|
146
|
+
|
|
147
|
+
# Exit the TUI and return the wrapped exception
|
|
148
|
+
self.exit(result=internal_error)
|
|
149
|
+
|
|
150
|
+
def _handle_exception(self, error: Exception) -> None:
|
|
151
|
+
"""Override Textual's exception handler to suppress console tracebacks for worker errors.
|
|
152
|
+
|
|
153
|
+
Worker exceptions are logged to file via the logging system (configured in file handler in plain2code.py),
|
|
154
|
+
but the verbose Textual/Rich traceback is suppressed from the terminal. The clean error message
|
|
155
|
+
is displayed via the exception handlers in main().
|
|
156
|
+
"""
|
|
157
|
+
# Because TUI is running in main thread and code renderer is running in a worker thread, textual models this
|
|
158
|
+
# by raising a WorkerFailed exception in this case
|
|
159
|
+
if isinstance(error, WorkerFailed):
|
|
160
|
+
# Here, we still print the error to get some additional information to the file, but it's probably
|
|
161
|
+
# not necessary because we either way print the entire traceback to the console. Here, we could in the future
|
|
162
|
+
# print more information if we would want to.
|
|
163
|
+
original_error = error.__cause__ if error.__cause__ else error
|
|
164
|
+
console.error(
|
|
165
|
+
f"Worker failed with exception: {type(original_error).__name__}: {original_error}",
|
|
166
|
+
exc_info=(type(original_error), original_error, original_error.__traceback__),
|
|
167
|
+
stack_info=False,
|
|
168
|
+
)
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
# For non-worker exceptions, use the default Textual behavior
|
|
172
|
+
super()._handle_exception(error)
|
|
119
173
|
|
|
120
174
|
def compose(self) -> ComposeResult:
|
|
121
175
|
"""Create child widgets for the app."""
|
|
122
|
-
yield Header()
|
|
123
176
|
with ContentSwitcher(id=TUIComponents.CONTENT_SWITCHER.value, initial=TUIComponents.DASHBOARD_VIEW.value):
|
|
124
177
|
with Vertical(id=TUIComponents.DASHBOARD_VIEW.value):
|
|
125
178
|
with VerticalScroll():
|
|
126
179
|
yield Static(
|
|
127
|
-
f"
|
|
128
|
-
id=
|
|
180
|
+
f"[#FFFFFF]*codeplain[/#FFFFFF] [#888888](v{self.state_machine_version})[/#888888]\n",
|
|
181
|
+
id="codeplain-header",
|
|
182
|
+
classes="codeplain-header",
|
|
129
183
|
)
|
|
130
184
|
yield Static(
|
|
131
|
-
"Rendering in progress...",
|
|
185
|
+
"[#FFFFFF]Rendering in progress...[/#FFFFFF]",
|
|
132
186
|
id=TUIComponents.RENDER_STATUS_WIDGET.value,
|
|
133
187
|
)
|
|
134
|
-
yield FRIDProgress(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if self.conformance_tests_script is not None:
|
|
148
|
-
yield Static(
|
|
149
|
-
ScriptOutputType.CONFORMANCE_TEST_OUTPUT_TEXT.get_padded_label(active_script_types),
|
|
150
|
-
id=TUIComponents.CONFORMANCE_TESTS_SCRIPT_OUTPUT_WIDGET.value,
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
# Conditionally display testing environment preparation output widget
|
|
154
|
-
if self.prepare_environment_script is not None:
|
|
155
|
-
yield Static(
|
|
156
|
-
ScriptOutputType.TESTING_ENVIRONMENT_OUTPUT_TEXT.get_padded_label(active_script_types),
|
|
157
|
-
id=TUIComponents.TESTING_ENVIRONMENT_SCRIPT_OUTPUT_WIDGET.value,
|
|
158
|
-
)
|
|
188
|
+
yield FRIDProgress(
|
|
189
|
+
id=TUIComponents.FRID_PROGRESS.value,
|
|
190
|
+
unittests_script=self.unittests_script,
|
|
191
|
+
conformance_tests_script=self.conformance_tests_script,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Test scripts container with border
|
|
195
|
+
yield TestScriptsContainer(
|
|
196
|
+
id=TUIComponents.TEST_SCRIPTS_CONTAINER.value,
|
|
197
|
+
show_unit_test=self.unittests_script is not None,
|
|
198
|
+
show_conformance_test=self.conformance_tests_script is not None,
|
|
199
|
+
show_testing_env=self.prepare_environment_script is not None,
|
|
200
|
+
)
|
|
159
201
|
with Vertical(id=TUIComponents.LOG_VIEW.value):
|
|
160
202
|
yield LogLevelFilter(id=TUIComponents.LOG_FILTER.value)
|
|
203
|
+
yield Static("", classes="filter-spacer")
|
|
161
204
|
yield StructuredLogView(id=TUIComponents.LOG_WIDGET.value)
|
|
162
|
-
yield
|
|
205
|
+
yield CustomFooter(render_id=self.render_id)
|
|
163
206
|
|
|
164
207
|
def action_toggle_logs(self) -> None:
|
|
165
208
|
"""Toggle between dashboard and log view."""
|
|
@@ -172,18 +215,20 @@ class Plain2CodeTUI(App):
|
|
|
172
215
|
def on_render_module_started(self, event: RenderModuleStarted):
|
|
173
216
|
"""Update TUI based on the current state machine state."""
|
|
174
217
|
try:
|
|
175
|
-
|
|
176
|
-
|
|
218
|
+
frid_progress = self.query_one(f"#{TUIComponents.FRID_PROGRESS.value}", FRIDProgress)
|
|
219
|
+
info_box = frid_progress.query_one(RenderingInfoBox)
|
|
220
|
+
info_box.update_module(f"{FRIDProgress.RENDERING_MODULE_TEXT}{event.module_name}")
|
|
177
221
|
except Exception as e:
|
|
178
|
-
|
|
222
|
+
log_to_widget(self, "WARNING", f"Error updating render module name: {type(e).__name__}: {e}")
|
|
179
223
|
|
|
180
224
|
def on_render_module_completed(self, _event: RenderModuleCompleted):
|
|
181
225
|
"""Update TUI based on the current state machine state."""
|
|
182
226
|
try:
|
|
183
|
-
|
|
184
|
-
|
|
227
|
+
frid_progress = self.query_one(f"#{TUIComponents.FRID_PROGRESS.value}", FRIDProgress)
|
|
228
|
+
info_box = frid_progress.query_one(RenderingInfoBox)
|
|
229
|
+
info_box.update_module(FRIDProgress.RENDERING_MODULE_TEXT)
|
|
185
230
|
except Exception as e:
|
|
186
|
-
|
|
231
|
+
log_to_widget(self, "WARNING", f"Error resetting render module name: {type(e).__name__}: {e}")
|
|
187
232
|
|
|
188
233
|
def on_log_message_emitted(self, event: LogMessageEmitted):
|
|
189
234
|
try:
|
|
@@ -196,7 +241,9 @@ class Plain2CodeTUI(App):
|
|
|
196
241
|
event.timestamp,
|
|
197
242
|
)
|
|
198
243
|
except Exception as e:
|
|
199
|
-
|
|
244
|
+
log_to_widget(
|
|
245
|
+
self, "WARNING", f"Error adding log message from {event.logger_name}: {type(e).__name__}: {e}"
|
|
246
|
+
)
|
|
200
247
|
|
|
201
248
|
def on_log_filter_changed(self, event: LogFilterChanged):
|
|
202
249
|
"""Handle log filter changes from LogLevelFilter widget."""
|
|
@@ -204,7 +251,7 @@ class Plain2CodeTUI(App):
|
|
|
204
251
|
log_widget = self.query_one(f"#{TUIComponents.LOG_WIDGET.value}", StructuredLogView)
|
|
205
252
|
log_widget.filter_logs(event.min_level)
|
|
206
253
|
except Exception as e:
|
|
207
|
-
|
|
254
|
+
log_to_widget(self, "WARNING", f"Error filtering logs to level {event.min_level}: {type(e).__name__}: {e}")
|
|
208
255
|
|
|
209
256
|
def on_render_state_updated(self, event: RenderStateUpdated):
|
|
210
257
|
"""Update TUI based on the current state machine state."""
|
|
@@ -231,6 +278,8 @@ class Plain2CodeTUI(App):
|
|
|
231
278
|
if snapshot.script_execution_history.should_update_script_outputs:
|
|
232
279
|
self._script_outputs_handler.handle(segments, snapshot, previous_state_segments)
|
|
233
280
|
|
|
281
|
+
self._state_completion_handler.handle(segments, snapshot, previous_state_segments)
|
|
282
|
+
|
|
234
283
|
def on_render_completed(self, _event: RenderCompleted):
|
|
235
284
|
"""Handle successful render completion."""
|
|
236
285
|
self._render_success_handler.handle()
|
|
@@ -250,7 +299,7 @@ class Plain2CodeTUI(App):
|
|
|
250
299
|
# It ensures terminal reset sequences are flushed before exiting.
|
|
251
300
|
self._driver.suspend_application_mode()
|
|
252
301
|
except Exception as e:
|
|
253
|
-
|
|
302
|
+
log_to_widget(self, "WARNING", f"Error suspending application mode: {type(e).__name__}: {e}")
|
|
254
303
|
finally:
|
|
255
304
|
os._exit(0) # Kill process immediately, no cleanup - terminates all threads
|
|
256
305
|
|
tui/state_handlers.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""State handlers for Plain2Code TUI state machine transitions."""
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Optional
|
|
4
5
|
|
|
5
6
|
from plain2code_events import RenderContextSnapshot
|
|
6
7
|
from render_machine.states import States
|
|
7
8
|
|
|
8
9
|
from . import components as tui_components
|
|
9
|
-
from .components import ProgressItem, ScriptOutputType, TUIComponents
|
|
10
|
+
from .components import ProgressItem, ScriptOutputType, TestScriptsContainer, TUIComponents
|
|
10
11
|
from .models import Substate
|
|
11
12
|
from .widget_helpers import (
|
|
12
13
|
display_error_message,
|
|
@@ -15,7 +16,6 @@ from .widget_helpers import (
|
|
|
15
16
|
set_frid_progress_to_stopped,
|
|
16
17
|
update_progress_item_status,
|
|
17
18
|
update_progress_item_substates,
|
|
18
|
-
update_widget_text,
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
@@ -53,13 +53,15 @@ class StateHandler(ABC):
|
|
|
53
53
|
class FridReadyHandler(StateHandler):
|
|
54
54
|
"""Handler for READY_FOR_FRID_IMPLEMENTATION state."""
|
|
55
55
|
|
|
56
|
-
def __init__(self, tui):
|
|
56
|
+
def __init__(self, tui, unittests_script: Optional[str], conformance_tests_script: Optional[str]):
|
|
57
57
|
"""Initialize handler with TUI instance.
|
|
58
58
|
|
|
59
59
|
Args:
|
|
60
60
|
tui: The Plain2CodeTUI instance
|
|
61
61
|
"""
|
|
62
62
|
self.tui = tui
|
|
63
|
+
self.unittests_script = unittests_script
|
|
64
|
+
self.conformance_tests_script = conformance_tests_script
|
|
63
65
|
|
|
64
66
|
def handle(self, _: list[str], snapshot: RenderContextSnapshot, _previous_state_segments: list[str]) -> None:
|
|
65
67
|
"""Handle READY_FOR_FRID_IMPLEMENTATION state."""
|
|
@@ -69,9 +71,13 @@ class FridReadyHandler(StateHandler):
|
|
|
69
71
|
|
|
70
72
|
# Set progress states
|
|
71
73
|
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_RENDER_FR.value, ProgressItem.PROCESSING)
|
|
72
|
-
|
|
74
|
+
if self.conformance_tests_script is not None:
|
|
75
|
+
update_progress_item_status(
|
|
76
|
+
self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, ProgressItem.PENDING
|
|
77
|
+
)
|
|
73
78
|
# Reset others to PENDING if this is a restart/loop
|
|
74
|
-
|
|
79
|
+
if self.unittests_script is not None:
|
|
80
|
+
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_UNIT_TEST.value, ProgressItem.PENDING)
|
|
75
81
|
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_REFACTORING.value, ProgressItem.PENDING)
|
|
76
82
|
|
|
77
83
|
# Set substate for initial implementation
|
|
@@ -85,51 +91,59 @@ class FridReadyHandler(StateHandler):
|
|
|
85
91
|
class UnitTestsHandler(StateHandler):
|
|
86
92
|
"""Handler for PROCESSING_UNIT_TESTS state."""
|
|
87
93
|
|
|
88
|
-
def __init__(self, tui):
|
|
94
|
+
def __init__(self, tui, unittests_script: Optional[str], conformance_tests_script: Optional[str]):
|
|
89
95
|
"""Initialize handler with TUI instance.
|
|
90
96
|
|
|
91
97
|
Args:
|
|
92
98
|
tui: The Plain2CodeTUI instance
|
|
93
99
|
"""
|
|
94
100
|
self.tui = tui
|
|
101
|
+
self.unittests_script = unittests_script
|
|
102
|
+
self.conformance_tests_script = conformance_tests_script
|
|
95
103
|
|
|
96
104
|
def handle(
|
|
97
105
|
self, segments: list[str], _snapshot: RenderContextSnapshot, _previous_state_segments: list[str]
|
|
98
106
|
) -> None:
|
|
99
107
|
"""Handle PROCESSING_UNIT_TESTS state."""
|
|
100
108
|
if segments[2] == States.UNIT_TESTS_READY.value:
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
if self.unittests_script is not None:
|
|
110
|
+
update_progress_item_status(
|
|
111
|
+
self.tui, TUIComponents.FRID_PROGRESS_UNIT_TEST.value, ProgressItem.PROCESSING
|
|
112
|
+
)
|
|
103
113
|
|
|
104
114
|
# Clear substates from completed implementation phase
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
if self.unittests_script is not None:
|
|
116
|
+
update_progress_item_substates(
|
|
117
|
+
self.tui,
|
|
118
|
+
TUIComponents.FRID_PROGRESS_UNIT_TEST.value,
|
|
119
|
+
[Substate("Running unit tests")],
|
|
120
|
+
)
|
|
121
|
+
|
|
110
122
|
if segments[2] == States.UNIT_TESTS_FAILED.value:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
if self.unittests_script is not None:
|
|
124
|
+
update_progress_item_substates(
|
|
125
|
+
self.tui,
|
|
126
|
+
TUIComponents.FRID_PROGRESS_UNIT_TEST.value,
|
|
127
|
+
[Substate("Fixing unit tests")],
|
|
128
|
+
)
|
|
116
129
|
|
|
117
130
|
|
|
118
131
|
class RefactoringHandler(StateHandler):
|
|
119
132
|
"""Handler for REFACTORING_CODE state."""
|
|
120
133
|
|
|
121
|
-
def __init__(self, tui):
|
|
134
|
+
def __init__(self, tui, unittests_script: Optional[str], conformance_tests_script: Optional[str]):
|
|
122
135
|
"""Initialize handler with TUI instance.
|
|
123
136
|
|
|
124
137
|
Args:
|
|
125
138
|
tui: The Plain2CodeTUI instance
|
|
126
139
|
"""
|
|
127
140
|
self.tui = tui
|
|
141
|
+
self.unittests_script = unittests_script
|
|
142
|
+
self.conformance_tests_script = conformance_tests_script
|
|
128
143
|
|
|
129
144
|
def handle(self, segments: list[str], _snapshot: RenderContextSnapshot, previous_state_segments: list[str]) -> None:
|
|
130
145
|
"""Handle REFACTORING_CODE state."""
|
|
131
146
|
if len(previous_state_segments) == 2 and previous_state_segments[1] == States.STEP_COMPLETED.value:
|
|
132
|
-
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_UNIT_TEST.value, ProgressItem.COMPLETED)
|
|
133
147
|
update_progress_item_status(
|
|
134
148
|
self.tui, TUIComponents.FRID_PROGRESS_REFACTORING.value, ProgressItem.PROCESSING
|
|
135
149
|
)
|
|
@@ -151,7 +165,7 @@ class RefactoringHandler(StateHandler):
|
|
|
151
165
|
elif segments[3] == States.UNIT_TESTS_FAILED.value:
|
|
152
166
|
update_progress_item_substates(
|
|
153
167
|
self.tui,
|
|
154
|
-
TUIComponents.
|
|
168
|
+
TUIComponents.FRID_PROGRESS_REFACTORING.value,
|
|
155
169
|
[Substate("Refactoring code", children=[Substate("Fixing unit tests")])],
|
|
156
170
|
)
|
|
157
171
|
|
|
@@ -159,21 +173,23 @@ class RefactoringHandler(StateHandler):
|
|
|
159
173
|
class ConformanceTestsHandler(StateHandler):
|
|
160
174
|
"""Handler for PROCESSING_CONFORMANCE_TESTS state."""
|
|
161
175
|
|
|
162
|
-
def __init__(self, tui):
|
|
176
|
+
def __init__(self, tui, unittests_script: Optional[str], conformance_tests_script: Optional[str]):
|
|
163
177
|
"""Initialize handler with TUI instance.
|
|
164
178
|
|
|
165
179
|
Args:
|
|
166
180
|
tui: The Plain2CodeTUI instance
|
|
167
181
|
"""
|
|
168
182
|
self.tui = tui
|
|
183
|
+
self.unittests_script = unittests_script
|
|
184
|
+
self.conformance_tests_script = conformance_tests_script
|
|
169
185
|
|
|
170
186
|
def handle(self, segments: list[str], snapshot: RenderContextSnapshot, previous_state_segments: list[str]) -> None:
|
|
171
187
|
"""Handle PROCESSING_CONFORMANCE_TESTS state."""
|
|
172
188
|
if previous_state_segments[1] == States.REFACTORING_CODE.value:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
189
|
+
if self.conformance_tests_script is not None:
|
|
190
|
+
update_progress_item_status(
|
|
191
|
+
self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, ProgressItem.PROCESSING
|
|
192
|
+
)
|
|
177
193
|
|
|
178
194
|
if segments[2] != States.POSTPROCESSING_CONFORMANCE_TESTS.value:
|
|
179
195
|
if segments[2] == States.CONFORMANCE_TESTING_INITIALISED.value:
|
|
@@ -229,50 +245,47 @@ class ScriptOutputsHandler(StateHandler):
|
|
|
229
245
|
self.tui = tui
|
|
230
246
|
|
|
231
247
|
def handle(self, _segments: list[str], snapshot: RenderContextSnapshot, previous_state_segments: list[str]) -> None:
|
|
232
|
-
#
|
|
233
|
-
|
|
248
|
+
# Update test scripts container
|
|
249
|
+
container = self.tui.query_one(f"#{TUIComponents.TEST_SCRIPTS_CONTAINER.value}", TestScriptsContainer)
|
|
234
250
|
|
|
235
251
|
if any(segment == States.UNIT_TESTS_READY.value for segment in previous_state_segments):
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
)
|
|
252
|
+
if snapshot.script_execution_history.latest_unit_test_output_path:
|
|
253
|
+
container.update_unit_test(
|
|
254
|
+
f"{ScriptOutputType.UNIT_TEST_OUTPUT_TEXT.value}{snapshot.script_execution_history.latest_unit_test_output_path}"
|
|
255
|
+
)
|
|
241
256
|
|
|
242
257
|
if len(previous_state_segments) > 2 and previous_state_segments[2] == States.CONFORMANCE_TEST_GENERATED.value:
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
)
|
|
258
|
+
if snapshot.script_execution_history.latest_testing_environment_output_path:
|
|
259
|
+
container.update_testing_env(
|
|
260
|
+
f"{ScriptOutputType.TESTING_ENVIRONMENT_OUTPUT_TEXT.value}{snapshot.script_execution_history.latest_testing_environment_output_path}"
|
|
261
|
+
)
|
|
248
262
|
|
|
249
263
|
if (
|
|
250
264
|
len(previous_state_segments) > 2
|
|
251
265
|
and previous_state_segments[2] == States.CONFORMANCE_TEST_ENV_PREPARED.value
|
|
252
266
|
):
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
)
|
|
267
|
+
if snapshot.script_execution_history.latest_conformance_test_output_path:
|
|
268
|
+
container.update_conformance_test(
|
|
269
|
+
f"{ScriptOutputType.CONFORMANCE_TEST_OUTPUT_TEXT.value}{snapshot.script_execution_history.latest_conformance_test_output_path}"
|
|
270
|
+
)
|
|
258
271
|
|
|
259
272
|
|
|
260
273
|
class FridFullyImplementedHandler(StateHandler):
|
|
261
274
|
"""Handler for FRID_FULLY_IMPLEMENTED state."""
|
|
262
275
|
|
|
263
|
-
def __init__(self, tui):
|
|
276
|
+
def __init__(self, tui, unittests_script: Optional[str], conformance_tests_script: Optional[str]):
|
|
264
277
|
"""Initialize handler with TUI instance.
|
|
265
278
|
|
|
266
279
|
Args:
|
|
267
280
|
tui: The Plain2CodeTUI instance
|
|
268
281
|
"""
|
|
269
282
|
self.tui = tui
|
|
283
|
+
self.unittests_script = unittests_script
|
|
284
|
+
self.conformance_tests_script = conformance_tests_script
|
|
270
285
|
|
|
271
286
|
def handle(self, _: list[str], _snapshot: RenderContextSnapshot, _previous_state_segments: list[str]) -> None:
|
|
272
287
|
"""Handle FRID_FULLY_IMPLEMENTED state."""
|
|
273
|
-
|
|
274
|
-
self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, ProgressItem.COMPLETED
|
|
275
|
-
)
|
|
288
|
+
pass
|
|
276
289
|
|
|
277
290
|
|
|
278
291
|
class RenderSuccessHandler:
|
|
@@ -305,3 +318,37 @@ class RenderErrorHandler:
|
|
|
305
318
|
def handle(self, error_message: str) -> None:
|
|
306
319
|
set_frid_progress_to_stopped(self.tui)
|
|
307
320
|
display_error_message(self.tui, error_message)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
class StateCompletionHandler(StateHandler):
|
|
324
|
+
"""Handler for state completion."""
|
|
325
|
+
|
|
326
|
+
def __init__(self, tui, unittests_script: Optional[str], conformance_tests_script: Optional[str]):
|
|
327
|
+
"""Initialize handler with TUI instance.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
tui: The Plain2CodeTUI instance
|
|
331
|
+
"""
|
|
332
|
+
self.tui = tui
|
|
333
|
+
self.unittests_script = unittests_script
|
|
334
|
+
self.conformance_tests_script = conformance_tests_script
|
|
335
|
+
|
|
336
|
+
def handle(self, segments: list[str], _snapshot: RenderContextSnapshot, previous_state_segments: list[str]) -> None:
|
|
337
|
+
if len(previous_state_segments) < 2 or len(segments) < 2:
|
|
338
|
+
return
|
|
339
|
+
current_segment = segments[1]
|
|
340
|
+
previous_segment = previous_state_segments[1]
|
|
341
|
+
should_update_state = current_segment != previous_segment
|
|
342
|
+
if not should_update_state:
|
|
343
|
+
return
|
|
344
|
+
|
|
345
|
+
if previous_segment == States.READY_FOR_FRID_IMPLEMENTATION.value:
|
|
346
|
+
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_RENDER_FR.value, ProgressItem.COMPLETED)
|
|
347
|
+
if previous_segment == States.PROCESSING_UNIT_TESTS.value:
|
|
348
|
+
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_UNIT_TEST.value, ProgressItem.COMPLETED)
|
|
349
|
+
if previous_segment == States.REFACTORING_CODE.value:
|
|
350
|
+
update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_REFACTORING.value, ProgressItem.COMPLETED)
|
|
351
|
+
if previous_segment == States.PROCESSING_CONFORMANCE_TESTS.value:
|
|
352
|
+
update_progress_item_status(
|
|
353
|
+
self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, ProgressItem.COMPLETED
|
|
354
|
+
)
|