orionis 0.590.0__py3-none-any.whl → 0.592.0__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.
- orionis/metadata/framework.py +1 -1
- orionis/test/contracts/unit_test.py +0 -81
- orionis/test/core/unit_test.py +732 -602
- orionis/test/kernel.py +2 -1
- orionis/test/output/printer.py +173 -118
- orionis/test/records/logs.py +223 -83
- orionis/test/view/render.py +45 -17
- {orionis-0.590.0.dist-info → orionis-0.592.0.dist-info}/METADATA +1 -1
- {orionis-0.590.0.dist-info → orionis-0.592.0.dist-info}/RECORD +12 -12
- {orionis-0.590.0.dist-info → orionis-0.592.0.dist-info}/WHEEL +0 -0
- {orionis-0.590.0.dist-info → orionis-0.592.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.590.0.dist-info → orionis-0.592.0.dist-info}/top_level.txt +0 -0
orionis/test/kernel.py
CHANGED
@@ -72,7 +72,8 @@ class TestKernel(ITestKernel):
|
|
72
72
|
output = self.__app.call(self.__unit_test, 'run')
|
73
73
|
|
74
74
|
# Only log detailed report if output is available
|
75
|
-
if output is not None:
|
75
|
+
if output is not None and isinstance(output, dict):
|
76
|
+
|
76
77
|
# Extract report details from output dictionary
|
77
78
|
total_tests = output.get("total_tests", 0)
|
78
79
|
passed = output.get("passed", 0)
|
orionis/test/output/printer.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
import io
|
1
2
|
import re
|
2
3
|
from datetime import datetime
|
3
|
-
from typing import Any, Dict, List
|
4
|
+
from typing import Any, Dict, List, Tuple
|
5
|
+
import unittest
|
4
6
|
from rich.console import Console
|
5
7
|
from rich.live import Live
|
6
8
|
from rich.panel import Panel
|
7
9
|
from rich.syntax import Syntax
|
8
10
|
from rich.table import Table
|
11
|
+
from rich.progress import Progress, BarColumn, TextColumn, TaskProgressColumn
|
9
12
|
from rich.text import Text
|
10
|
-
from orionis.services.introspection.instances.reflection import ReflectionInstance
|
11
13
|
from orionis.test.contracts.printer import ITestPrinter
|
12
14
|
from orionis.test.entities.result import TestResult
|
13
15
|
from orionis.test.enums import TestStatus
|
@@ -45,9 +47,6 @@ class TestPrinter(ITestPrinter):
|
|
45
47
|
# Calculate the panel width as a percentage of the console width
|
46
48
|
self.__panel_width: int = int(self.__rich_console.width * (width / 100))
|
47
49
|
|
48
|
-
# Define keywords to detect debugging or dump calls in test code
|
49
|
-
self.__debbug_keywords: list = ['self.dd', 'self.dump']
|
50
|
-
|
51
50
|
# Store the flag indicating whether to print results
|
52
51
|
self.__print_result: bool = print_result
|
53
52
|
|
@@ -56,59 +55,106 @@ class TestPrinter(ITestPrinter):
|
|
56
55
|
value: Any
|
57
56
|
) -> None:
|
58
57
|
"""
|
59
|
-
Print a value to the console using the Rich library.
|
58
|
+
Print a value to the console using the Rich library, supporting strings, lists, and other objects.
|
60
59
|
|
61
60
|
Parameters
|
62
61
|
----------
|
63
62
|
value : Any
|
64
|
-
The value to be printed. Can be a string,
|
63
|
+
The value to be printed. Can be a string, a list of items, or any other object.
|
65
64
|
|
66
65
|
Returns
|
67
66
|
-------
|
68
67
|
None
|
68
|
+
This method does not return any value. Output is sent directly to the console.
|
69
|
+
|
70
|
+
Notes
|
71
|
+
-----
|
72
|
+
- If result printing is disabled (`self.__print_result` is False), no output will be produced.
|
73
|
+
- Strings are printed as-is.
|
74
|
+
- Lists are iterated and each item is printed on a separate line.
|
75
|
+
- Other objects are converted to string before printing.
|
69
76
|
"""
|
70
|
-
|
77
|
+
|
78
|
+
# If printing results is disabled, do not output anything
|
71
79
|
if self.__print_result is False:
|
72
80
|
return
|
73
81
|
|
74
|
-
#
|
82
|
+
# Print string values directly
|
75
83
|
if isinstance(value, str):
|
76
84
|
self.__rich_console.print(value)
|
77
85
|
|
78
|
-
#
|
86
|
+
# Print each item of a list on a new line
|
79
87
|
elif isinstance(value, list):
|
80
88
|
for item in value:
|
81
89
|
self.__rich_console.print(item)
|
82
90
|
|
83
|
-
# For
|
91
|
+
# For other object types, print their string representation
|
84
92
|
else:
|
85
93
|
self.__rich_console.print(str(value))
|
86
94
|
|
95
|
+
def line(
|
96
|
+
self,
|
97
|
+
count: int = 1
|
98
|
+
) -> None:
|
99
|
+
"""
|
100
|
+
Print a specified number of blank lines to the console for spacing.
|
101
|
+
|
102
|
+
Parameters
|
103
|
+
----------
|
104
|
+
count : int, optional
|
105
|
+
The number of blank lines to print (default is 1).
|
106
|
+
Returns
|
107
|
+
-------
|
108
|
+
None
|
109
|
+
This method does not return any value. Blank lines are printed directly to the console.
|
110
|
+
Notes
|
111
|
+
-----
|
112
|
+
- If result printing is disabled (`self.__print_result` is False), no output will be produced.
|
113
|
+
- The method uses the Rich console's built-in line printing functionality.
|
114
|
+
"""
|
115
|
+
|
116
|
+
# If printing results is disabled, do not output anything
|
117
|
+
if self.__print_result is False:
|
118
|
+
return
|
119
|
+
|
120
|
+
# Print the specified number of blank lines
|
121
|
+
self.__rich_console.line(count)
|
122
|
+
|
87
123
|
def zeroTestsMessage(self) -> None:
|
88
124
|
"""
|
89
|
-
Display a message indicating that no tests were found to execute.
|
125
|
+
Display a styled message indicating that no tests were found to execute.
|
126
|
+
|
127
|
+
Parameters
|
128
|
+
----------
|
129
|
+
None
|
90
130
|
|
91
131
|
Returns
|
92
132
|
-------
|
93
133
|
None
|
134
|
+
This method does not return any value. The message is printed directly to the console.
|
135
|
+
|
136
|
+
Notes
|
137
|
+
-----
|
138
|
+
- If result printing is disabled (`self.__print_result` is False), no output will be produced.
|
139
|
+
- The message is displayed in a Rich panel with a yellow border and centered title.
|
94
140
|
"""
|
95
|
-
# If
|
141
|
+
# If printing results is disabled, do not output anything
|
96
142
|
if self.__print_result is False:
|
97
143
|
return
|
98
144
|
|
99
|
-
# Print
|
145
|
+
# Print a styled panel to indicate that no tests were found
|
100
146
|
self.__rich_console.print(
|
101
147
|
Panel(
|
102
148
|
"No tests found to execute.",
|
103
|
-
border_style="yellow",
|
104
|
-
title="No Tests",
|
105
|
-
title_align="center",
|
106
|
-
width=self.__panel_width,
|
107
|
-
padding=(0, 1)
|
149
|
+
border_style="yellow", # Use yellow to indicate a warning or neutral state
|
150
|
+
title="No Tests", # Panel title
|
151
|
+
title_align="center", # Center the title
|
152
|
+
width=self.__panel_width, # Set panel width based on console configuration
|
153
|
+
padding=(0, 1) # Add horizontal padding for better appearance
|
108
154
|
)
|
109
155
|
)
|
110
156
|
|
111
|
-
# Add a blank line after the panel for spacing
|
157
|
+
# Add a blank line after the panel for visual spacing
|
112
158
|
self.__rich_console.line(1)
|
113
159
|
|
114
160
|
def startMessage(
|
@@ -119,53 +165,96 @@ class TestPrinter(ITestPrinter):
|
|
119
165
|
max_workers: int
|
120
166
|
):
|
121
167
|
"""
|
122
|
-
Display a formatted start message for the test execution session.
|
168
|
+
Display a formatted start message for the beginning of a test execution session.
|
123
169
|
|
124
170
|
Parameters
|
125
171
|
----------
|
126
172
|
length_tests : int
|
127
|
-
|
173
|
+
Total number of tests scheduled for execution in the session.
|
128
174
|
execution_mode : str
|
129
|
-
The mode of execution
|
175
|
+
The mode of test execution. Should be either "parallel" or "sequential".
|
130
176
|
max_workers : int
|
131
|
-
|
177
|
+
Number of worker threads or processes to use if running in parallel mode.
|
132
178
|
|
133
179
|
Returns
|
134
180
|
-------
|
135
181
|
None
|
182
|
+
This method does not return any value. It prints a styled panel to the console with session details.
|
183
|
+
|
184
|
+
Notes
|
185
|
+
-----
|
186
|
+
- If result printing is disabled (`self.__print_result` is False), no output will be produced.
|
187
|
+
- The panel displays the total number of tests, execution mode, and the timestamp when the session started.
|
188
|
+
- The execution mode text will indicate parallel execution with the number of workers if applicable.
|
136
189
|
"""
|
137
|
-
|
190
|
+
|
191
|
+
# If printing results is disabled, do not output anything
|
138
192
|
if self.__print_result is False:
|
139
193
|
return
|
140
194
|
|
141
|
-
#
|
195
|
+
# Format the execution mode text for display
|
142
196
|
mode_text = f"[stat]Parallel with {max_workers} workers[/stat]" if execution_mode == "parallel" else "Sequential"
|
143
197
|
|
144
198
|
# Prepare the lines of information to display in the panel
|
145
199
|
textlines = [
|
146
|
-
f"[bold]Total Tests:[/bold] [dim]{length_tests}[/dim]",
|
147
|
-
f"[bold]Mode:[/bold] [dim]{mode_text}[/dim]",
|
148
|
-
f"[bold]Started at:[/bold] [dim]{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}[/dim]"
|
200
|
+
f"[bold]Total Tests:[/bold] [dim]{length_tests}[/dim]", # Show total number of tests
|
201
|
+
f"[bold]Mode:[/bold] [dim]{mode_text}[/dim]", # Show execution mode
|
202
|
+
f"[bold]Started at:[/bold] [dim]{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}[/dim]" # Show start timestamp
|
149
203
|
]
|
150
204
|
|
151
|
-
# Add a blank line before the panel
|
152
|
-
self.__rich_console.line(1)
|
153
|
-
|
154
205
|
# Print the panel with the formatted text lines
|
155
206
|
self.__rich_console.print(
|
156
207
|
Panel(
|
157
|
-
str('\n').join(textlines),
|
158
|
-
border_style="blue",
|
159
|
-
title=self.__panel_title,
|
160
|
-
title_align="center",
|
161
|
-
width=self.__panel_width,
|
162
|
-
padding=(0, 1)
|
208
|
+
str('\n').join(textlines), # Join all lines for panel content
|
209
|
+
border_style="blue", # Use blue border for the panel
|
210
|
+
title=self.__panel_title, # Set the panel title
|
211
|
+
title_align="center", # Center the panel title
|
212
|
+
width=self.__panel_width, # Set panel width based on console configuration
|
213
|
+
padding=(0, 1) # Add horizontal padding for better appearance
|
163
214
|
)
|
164
215
|
)
|
165
216
|
|
166
|
-
# Add a blank line after the panel
|
217
|
+
# Add a blank line after the panel for spacing
|
167
218
|
self.__rich_console.line(1)
|
168
219
|
|
220
|
+
def progressBar(
|
221
|
+
self
|
222
|
+
) -> Progress:
|
223
|
+
"""
|
224
|
+
Create and return a Rich Progress bar instance for tracking task progress in the console.
|
225
|
+
|
226
|
+
Parameters
|
227
|
+
----------
|
228
|
+
self : TestPrinter
|
229
|
+
The instance of the TestPrinter class.
|
230
|
+
|
231
|
+
Returns
|
232
|
+
-------
|
233
|
+
Progress
|
234
|
+
A Rich Progress object configured with:
|
235
|
+
- A cyan-colored task description column.
|
236
|
+
- A visual progress bar.
|
237
|
+
- A percentage completion indicator.
|
238
|
+
- Output directed to the configured Rich console.
|
239
|
+
- Transient display (disappears after completion).
|
240
|
+
- Disabled if result printing is turned off.
|
241
|
+
|
242
|
+
Notes
|
243
|
+
-----
|
244
|
+
- If printing is disabled (`self.__print_result` is False), the progress bar will not be shown.
|
245
|
+
- The progress bar is suitable for tracking the progress of tasks such as test execution.
|
246
|
+
"""
|
247
|
+
|
248
|
+
# Create and return a Rich Progress bar instance with custom columns and settings
|
249
|
+
return Progress(
|
250
|
+
TextColumn("[cyan]{task.description}"), # Task description in cyan
|
251
|
+
BarColumn(), # Visual progress bar
|
252
|
+
TaskProgressColumn(), # Percentage completion indicator
|
253
|
+
console=self.__rich_console, # Output to the configured Rich console
|
254
|
+
transient=True, # Remove the bar after completion
|
255
|
+
disable=not self.__print_result # Disable if printing is turned off
|
256
|
+
)
|
257
|
+
|
169
258
|
def finishMessage(
|
170
259
|
self,
|
171
260
|
*,
|
@@ -214,57 +303,71 @@ class TestPrinter(ITestPrinter):
|
|
214
303
|
def executePanel(
|
215
304
|
self,
|
216
305
|
*,
|
217
|
-
|
218
|
-
|
219
|
-
):
|
306
|
+
func: callable,
|
307
|
+
live_console: bool = True
|
308
|
+
) -> unittest.TestResult:
|
220
309
|
"""
|
221
|
-
|
310
|
+
Executes a callable within a styled Rich panel, optionally using a live console for dynamic updates.
|
222
311
|
|
223
312
|
Parameters
|
224
313
|
----------
|
225
|
-
|
226
|
-
The
|
227
|
-
|
228
|
-
|
314
|
+
func : callable
|
315
|
+
The function or method to execute. It should take no arguments and return a result.
|
316
|
+
live_console : bool, optional
|
317
|
+
If True, displays a live updating panel during execution (default is True).
|
318
|
+
If False, displays a static panel before execution.
|
229
319
|
|
230
320
|
Returns
|
231
321
|
-------
|
232
|
-
|
233
|
-
|
322
|
+
unittest.TestResult
|
323
|
+
The result returned by the executed callable, typically a `unittest.TestResult` object.
|
324
|
+
|
325
|
+
Notes
|
326
|
+
-----
|
327
|
+
- If result printing is disabled, the callable is executed without any panel or output.
|
328
|
+
- If `live_console` is True, a transient live panel is shown while the callable executes.
|
329
|
+
- If `live_console` is False, a static panel is printed before execution.
|
330
|
+
- The method always returns the result of the provided callable, regardless of output mode.
|
234
331
|
"""
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
332
|
+
|
333
|
+
# Ensure the provided func is actually callable
|
334
|
+
if not callable(func):
|
335
|
+
raise ValueError("The 'func' parameter must be a callable (function or method).")
|
239
336
|
|
240
337
|
# Only display output if printing results is enabled
|
241
338
|
if self.__print_result:
|
242
339
|
|
243
|
-
#
|
244
|
-
|
245
|
-
"[yellow]⏳ Running...[/yellow]",
|
246
|
-
border_style="yellow",
|
247
|
-
width=self.__panel_width,
|
248
|
-
padding=(0, 1)
|
249
|
-
)
|
340
|
+
# If live_console is True, use a live panel for dynamic updates
|
341
|
+
if live_console:
|
250
342
|
|
251
|
-
|
252
|
-
|
343
|
+
# Prepare a minimal running message as a single line, using the configured panel width
|
344
|
+
running_panel = Panel(
|
345
|
+
"[yellow]⏳ Running...[/yellow]",
|
346
|
+
border_style="yellow",
|
347
|
+
width=self.__panel_width,
|
348
|
+
padding=(0, 1)
|
349
|
+
)
|
253
350
|
|
254
|
-
# Execute the
|
351
|
+
# Execute the callable within a live Rich panel context
|
255
352
|
with Live(running_panel, console=self.__rich_console, refresh_per_second=4, transient=True):
|
256
|
-
return
|
257
|
-
|
353
|
+
return func()
|
258
354
|
else:
|
259
355
|
|
260
|
-
#
|
356
|
+
# Prepare a panel with a message indicating that test results will follow
|
357
|
+
running_panel = Panel(
|
358
|
+
"[yellow]🧪 Running tests...[/yellow]",
|
359
|
+
border_style="green",
|
360
|
+
width=self.__panel_width,
|
361
|
+
padding=(0, 1)
|
362
|
+
)
|
363
|
+
|
364
|
+
# If live_console is False, print a static panel before running
|
261
365
|
self.__rich_console.print(running_panel)
|
262
|
-
return
|
366
|
+
return func()
|
263
367
|
|
264
368
|
else:
|
265
|
-
|
266
|
-
|
267
|
-
return callable()
|
369
|
+
# If result printing is disabled, execute the callable without any panel
|
370
|
+
return func()
|
268
371
|
|
269
372
|
def linkWebReport(
|
270
373
|
self,
|
@@ -529,54 +632,6 @@ class TestPrinter(ITestPrinter):
|
|
529
632
|
display_msg = msg if len(msg) <= max_width else msg[:max_width - 3] + "..."
|
530
633
|
self.__rich_console.print(display_msg, highlight=False)
|
531
634
|
|
532
|
-
def __withDebugger(
|
533
|
-
self,
|
534
|
-
flatten_test_suite: list
|
535
|
-
) -> bool:
|
536
|
-
"""
|
537
|
-
Determine if any test case in the provided flattened test suite contains active debugging or dumping calls.
|
538
|
-
|
539
|
-
Parameters
|
540
|
-
----------
|
541
|
-
flatten_test_suite : list
|
542
|
-
A list of test case instances whose source code will be inspected for debugging or dumping calls.
|
543
|
-
|
544
|
-
Returns
|
545
|
-
-------
|
546
|
-
bool
|
547
|
-
True if any test case contains an active (non-commented) call to a debugging or dumping method.
|
548
|
-
False if no such calls are found or if an exception occurs during inspection.
|
549
|
-
"""
|
550
|
-
try:
|
551
|
-
|
552
|
-
# Iterate through each test case in the flattened test suite
|
553
|
-
for test_case in flatten_test_suite:
|
554
|
-
|
555
|
-
# Retrieve the source code of the test case using reflection
|
556
|
-
source = ReflectionInstance(test_case).getSourceCode()
|
557
|
-
|
558
|
-
# Check each line of the source code
|
559
|
-
for line in source.splitlines():
|
560
|
-
|
561
|
-
# Strip leading and trailing whitespace from the line
|
562
|
-
stripped = line.strip()
|
563
|
-
|
564
|
-
# Skip lines that are commented out
|
565
|
-
if stripped.startswith('#') or re.match(r'^\s*#', line):
|
566
|
-
continue
|
567
|
-
|
568
|
-
# If any debug keyword is present in the line, return True
|
569
|
-
if any(keyword in line for keyword in self.__debbug_keywords):
|
570
|
-
return True
|
571
|
-
|
572
|
-
# No debug or dump calls found in any test case
|
573
|
-
return False
|
574
|
-
|
575
|
-
except Exception:
|
576
|
-
|
577
|
-
# If any error occurs during inspection, return False
|
578
|
-
return False
|
579
|
-
|
580
635
|
def __sanitizeTraceback(
|
581
636
|
self,
|
582
637
|
test_path: str,
|