1 Commits

Author SHA1 Message Date
9dae210f7f fix(windows): UTF-8 console + self-sufficient validation wrapper
Make the suite run cleanly on Windows.

Product code:
- __init__.py: force UTF-8 on stdout/stderr. The Windows console code
  page (cp1252) cannot encode the box-drawing/accented characters the
  runner prints, which crashed the parent capture_stdout thread. Only
  the stream encoders are reconfigured; the locale default used to read
  cp1252 config files is left untouched.
- report_export_junit/html: open the report file with encoding="utf-8"
  (XML/HTML are UTF-8) instead of the platform default, matching the
  txt/json exporters.

Validation:
- run.bat: source mode now sets up its own venv and runs testium from
  src\ directly instead of delegating to the project run.bat (which
  launches the GUI and drops its arguments). Installs the fake_exporter
  entry-point plugin (report_plugin) and the [lsp] extra, and runs the
  same lsp_check.py pre-flight as run.sh.
- jsonrpc/test.tum: launch the echo server via "$(python_bin)" instead
  of "python3" (the Microsoft Store stub on Windows).
- post_execution.py: write the JUnit XML with encoding="utf-8".
- restore items/run/sub_pass.tum and sub_fail.tum, deleted by mistake in
  d97d00c "removed test logs".
2026-06-06 21:39:36 +02:00
22 changed files with 198 additions and 321 deletions

View File

@@ -9,9 +9,9 @@ This element is of the following form:
- let:
name: Let Item
values:
- key1: value1
- key2: value2
- key3: <| $(variable)[$(loop_index)] |>
key1: value1
key2: value2
key3: <| $(variable)[$(loop_index)] |>
The ``let`` element is used to set values in the global directory.

View File

@@ -51,8 +51,8 @@ The parameter file can be specified in the `.tum` file root:
:caption: configuration files definition in the main `.tum` test file
config_file:
- config1.yaml
- config2.yaml
config1.yaml
config2.yaml
main:
name: Test example

View File

@@ -11,6 +11,16 @@ sys.path.append(os.path.abspath(ourpath.parent))
import interpreter.utils.constants as cst
def main():
# Force UTF-8 on stdout/stderr so the runner's output survives a legacy
# console code page (Windows cp1252 can't encode box-drawing/accented
# chars). Only the stream encoders change; the locale default used for
# config files is untouched.
for _stream in (sys.stdout, sys.stderr):
try:
_stream.reconfigure(encoding="utf-8")
except (AttributeError, ValueError):
pass # no stdout (frozen GUI) or non-reconfigurable stream
# Subcommand dispatch (must run *before* argparse so neither 'schema' nor
# 'lsp' has to share the GUI/batch flag surface). The subcommands also
# skip the multiprocessing 'spawn' setup which is only meaningful for the

View File

@@ -344,7 +344,7 @@ class TestItemConsoleReadUntil(TestItemConsoleAction):
def execute(self):
cons = self.get_console()
ru = self._prms.expanse(self._read_until)
read_timeout = float(self._prms.getParam("timeout", default=-1, processed=True))
read_timeout = int(self._prms.getParam("timeout", default=-1, processed=True))
mute = self._prms.getParam("mute", default=False, processed=True)
if read_timeout < 0:
read_timeout = None

View File

@@ -14,7 +14,7 @@ class ReportExportHTML(rpe.ReportExport):
self.prepareFile()
self.create_base()
self.process_tests()
with open(self._file_name, 'w') as f:
with open(self._file_name, 'w', encoding="utf-8") as f:
f.write(lxml.html.tostring(self.root, pretty_print=True).decode())
def testsIterate(self, row):

View File

@@ -20,7 +20,7 @@ class ReportExportJUnit(rpe.ReportExport):
ts = TestSuite(repname, test_cases=self.test_cases,
hostname=tm.gd('host_ip'))
with open(self._file_name, 'w') as f:
with open(self._file_name, 'w', encoding="utf-8") as f:
TestSuite.to_file(f, [ts])
def testsIterate(self, row):

View File

@@ -56,17 +56,9 @@ function handle.func_call(params)
if err == nil then
print(string.format("Function executed from '%s'", pfile))
utils.log("func_call function found '%s', '%s'", file, fname)
err_res = {pcall(func, unpack(prms))}
succ, ret = pcall(func, unpack(prms))
utils.log("func_call returned '%s', '%s'", tostring(succ), tostring(ret))
-- manage tuple ouput of a lua function
succ = table.remove(err_res, 1)
if #err_res > 1 then
ret = err_res
else
ret = unpack(err_res)
end
if succ then
res = ret
else

View File

@@ -51,18 +51,14 @@ class TestFileManager:
w.disconnect_signals()
# Snapshot user-selected checkboxes and fold state so they survive a
# reload of the same file (same logic as session-restore through prefs).
# checkList works only if show_checkboxes is True
previous_check_list = w.treeTests.getCheckList()
previous_fold_list = w.treeTests.getFoldList()
previous_count = w.treeTests.getItemCount()
self.clear_process()
if self.load(file_name) and \
w.test_service is not None and \
w.treeTests.getItemCount() == previous_count:
if prefs.settings.show_checkboxes :
w.treeTests.restoreCheckList(previous_check_list, w.test_service)
if self.load(file_name) and w.test_service is not None:
if w.treeTests.getItemCount() == previous_count:
w.treeTests.restoreCheckList(previous_check_list, w.test_service)
w.treeTests.restoreFoldList(previous_fold_list)
w.reconnect_signals()
def _make_progress(self, w):

View File

@@ -84,18 +84,7 @@
- read_until: {expected: HelloConsole, timeout: 1, mute: true}
- console:
name: Console read_until float timeout
console_name: term
key: $(test)_PASS
steps:
- writeln: echo "HelloConsole"
{% if os == "Windows" %}
- read_until: {expected: echo "HelloConsole", timeout: 0.2}
{% endif %}
- read_until: {expected: HelloConsole, timeout: 0.2}
- console:
name: Console read_until process result
name: Console read_until muted
console_name: term
key: $(test)_PASS
steps:

View File

@@ -20,7 +20,7 @@
console_name: jrpces
key: $(test)_PASS
steps:
- writeln: python3 {{include_directory}}/jrpc_echo_server.py -c {{include_directory}}/jrpces.ini
- writeln: '"$(python_bin)" {{include_directory}}/jrpc_echo_server.py -c {{include_directory}}/jrpces.ini'
- read_until: {expected: ready, timeout: 5}
- console:

View File

@@ -11,8 +11,8 @@
- let:
name: Let it be
values:
- it: $(loop_param)
- be: <| $(loop_param) == $(it) |>
it: $(loop_param)
be: <| $(loop_param) == $(it) |>
- loop:
name: Cycle iterating on list

View File

@@ -12,12 +12,12 @@ function module.assertparam(param)
end
function module.checkglobal(param)
assert(param=='test parameter')
return 0
local res = tm.gd(param)
return res
end
function module.checkglobal2(index)
return tm.gd("data_to_be_returned")[index+1]
return tm.gd("lua_data_to_be_returned")[index]
end
function module.should_not_be_called(param)
@@ -53,7 +53,7 @@ function module.return_nothing()
-- Returns no value: ret is nil but no error.
end
function module.return_explicit_none()
function module.return_explicit_nil()
return nil
end

View File

@@ -1,6 +1,6 @@
skipped_test_item: ['skipped_checkglobal']
data_to_be_returned:
lua_data_to_be_returned:
- 1
- {a: 1, b: 2}
- ["a", 1, 2.1, True]

View File

@@ -1,15 +1,7 @@
- let:
name: lua_func test constants,
values:
- func_test_parameter: test parameter
- lua_func:
name: pass lua_func
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: assertparam
param:
- true
lua_func test parameter: test parameter lua_func
- lua_func:
name: fail lua_func
@@ -20,7 +12,7 @@
- false
- lua_func:
name: fail lua_func with expected result "FAIL"
name: fail lua_func with expected result FAIL
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: assertparam
@@ -70,7 +62,35 @@
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal
param:
- $(func_test_parameter)
- lua_func test parameter
expected_result: $(lua_func test parameter)
- lua_func:
name: global param lua_func 1
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
param:
- 1
expected_result: ($(lua_data_to_be_returned))[0]
- lua_func:
name: global param lua_func 2
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
param:
- 2
expected_result: ($(lua_data_to_be_returned))[1]
- lua_func:
name: global param lua_func 3
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
param:
- 3
expected_result: ($(lua_data_to_be_returned))[2]
- let:
name: python2func
@@ -78,189 +98,88 @@
values:
- py: $(test_path)$(psep)lua_func.lua
- lua_func:
name: global param int
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
param:
- 0
expected_result: ($(data_to_be_returned))[0]
- lua_func:
name: global param dict
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
param:
- 1
expected_result: ($(data_to_be_returned))[1]
- lua_func:
name: global param list
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: checkglobal2
param:
- 2
expected_result: ($(data_to_be_returned))[2]
- lua_func:
name: global param lua_func
key: $(test)_PASS
file: $(py)
func_name: checkglobal
param:
- $(func_test_parameter)
- lua_func:
name: skipped_checkglobal
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: should_not_be_called
param:
- $(func_test_parameter)
- $(test parameter)
- lua_func:
name: skipped true
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
func_name: checkglobal
skipped: true
param:
- "skipped"
- $(test parameter)
- lua_func:
name: skipped 1
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
func_name: checkglobal
skipped: 1
param:
- "skipped"
- $(test parameter)
- group:
name: Function results check
steps:
- group:
name: Functions result
name: Function result failure
steps:
- lua_func:
name: int
name: int failure
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [-1]
- lua_func:
name: float
name: float failure
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [-20.3]
param: [-1.3]
- lua_func:
name: String
name: String failure
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ "FAIL" ]
- lua_func:
name: Tuple int,str
name: Tuple int,str failure
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: tuple_return
param: [ 0, "OK" ]
param: [ -1, "Got a failure" ]
- group:
name: Functions result expected
name: Functions result success
steps:
- lua_func:
name: int expected
name: int success
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [18]
expected_result: 18
param: [0]
- lua_func:
name: float expected
name: float success
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [0.3]
expected_result: 0.3
- lua_func:
name: String expected
name: String success
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ "Something" ]
expected_result: Something
param: [ "Something that is not only strictly FAIL" ]
- lua_func:
name: Tuple int,str expected
name: Tuple int,str success
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: tuple_return
param: [ 0, "OK" ]
expected_result: [0, "OK"]
- lua_func:
name: small list expected
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ [-23] ]
expected_result: [-23]
- lua_func:
name: big list expected
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ [-23, 17, 67] ]
expected_result: [-23, 17, 67]
- group:
name: Function result not expected
steps:
- lua_func:
name: int not expected
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [18]
expected_result: 17
- lua_func:
name: float not expected
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [0.3]
expected_result: 0.5
- lua_func:
name: String not expected
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ "Something" ]
expected_result: Nothing
- lua_func:
name: Tuple int,str not expected
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: tuple_return
param: [ 0, "OK" ]
expected_result: [0, "OUPS"]
- lua_func:
name: small list not expected
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ [-23] ]
expected_result: [-22]
- lua_func:
name: big list not expected
key: $(test)_FAIL
file: $(test_path)$(psep)lua_func.lua
func_name: echo
param: [ [-23, 17, 67] ]
expected_result: [-23, 16, 67]
- lua_func:
name: delgd test
key: $(test)_PASS
@@ -274,39 +193,40 @@
func_name: return_nothing
- lua_func:
name: function returning explicit None should succeed
name: function returning explicit nil should succeed
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: return_explicit_none
func_name: return_explicit_nil
- group:
name: context_id tests
steps:
- lua_func:
name: set serializable value
name: set context value
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: set_context_value
context_id: lua_ctx_test
param:
- hello context
expected_result: hello context
- hello lua
expected_result: hello lua
- lua_func:
name: get serializable value (same context_id)
name: get context value (same context_id)
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: get_context_value
context_id: ctx_test
expected_result: hello context
context_id: lua_ctx_test
expected_result: hello lua
- lua_func:
name: get serializable value (no context_id, from main gd)
name: get context value (no context_id, from main gd)
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: get_context_value
expected_result: hello context
expected_result: hello lua
- lua_func:
name: get serializable value (different context_id)
name: get context value (different context_id)
key: $(test)_PASS
file: $(test_path)$(psep)lua_func.lua
func_name: get_context_value
context_id: ctx_other
expected_result: hello context
context_id: lua_ctx_other
expected_result: hello lua

View File

@@ -1,6 +1 @@
skipped_test_item: ['skipped_checkglobal']
data_to_be_returned:
- 1
- {a: 1, b: 2}
- ["a", 1, 2.1, True]
skipped_test_item: ['skipped_checkglobal']

View File

@@ -16,8 +16,8 @@ def checkglobal(param):
assert param=='test parameter'
return 0
def checkglobal2(index):
return tm.gd("data_to_be_returned")[index]
def checkglobal2():
return tm.gd("py_func test parameter")
def should_not_be_called(param):
raise

View File

@@ -1,7 +1,7 @@
- let:
name: py_func test constants,
values:
- func_test_parameter: test parameter
py_func test parameter: test parameter
- py_func:
name: pass py_func
@@ -70,7 +70,7 @@
file: $(test_path)$(psep)py_func.py
func_name: checkglobal
param:
- $(func_test_parameter)
- $(py_func test parameter)
- let:
name: python2func
@@ -79,32 +79,11 @@
- py: $(test_path)$(psep)py_func.py
- py_func:
name: global param int
name: global param py_func 2
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
file: $(py)
func_name: checkglobal2
param:
- 0
expected_result: ($(data_to_be_returned))[0]
- py_func:
name: global param dict
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: checkglobal2
param:
- 1
expected_result: ($(data_to_be_returned))[1]
- py_func:
name: global param list
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: checkglobal2
param:
- 2
expected_result: ($(data_to_be_returned))[2]
expected_result: $(py_func test parameter)
- py_func:
@@ -113,162 +92,104 @@
file: $(py)
func_name: checkglobal
param:
- $(func_test_parameter)
- $(py_func test parameter)
- py_func:
name: skipped_checkglobal
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: should_not_be_called
param:
- $(func_test_parameter)
- $(py_func test parameter)
- py_func:
name: skipped true
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
func_name: checkglobal
skipped: true
param:
- "skipped"
- $(py_func test parameter)
- py_func:
name: skipped 1
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
func_name: checkglobal
skipped: 1
param:
- "skipped"
- $(py_func test parameter)
- py_func:
name: FunctionItem test
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: ValidationTest
param:
- $(func_test_parameter)
- $(py_func test parameter)
- group:
name: Function results check
steps:
- group:
name: Functions result
name: Function result 1
steps:
- py_func:
name: int
name: int failure
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [-1]
expected_result: -1
- py_func:
name: float
name: float failure
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [-20.3]
param: [-1.3]
expected_result: -1.3
- py_func:
name: String
name: String failure
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ "FAIL" ]
expected_result: FAIL
- py_func:
name: Tuple int,str
name: Tuple int,str failure
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: tuple_return
param: [ 0, "OK" ]
param: [ -1, "Got a failure" ]
expected_result: [-1, "Got a failure"]
- group:
name: Functions result expected
name: Functions result 2
steps:
- py_func:
name: int expected
name: int success
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [18]
expected_result: 18
param: [0]
expected_result: 0
- py_func:
name: float expected
name: float success
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [0.3]
expected_result: 0.3
- py_func:
name: String expected
name: String success
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ "Something" ]
expected_result: Something
param: [ "Something that is not only strictly FAIL" ]
expected_result: Something that is not only strictly FAIL
- py_func:
name: Tuple int,str expected
name: Tuple int,str success
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: tuple_return
param: [ 0, "OK" ]
expected_result: [0, "OK"]
- py_func:
name: small list expected
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ [-23] ]
expected_result: [-23]
- py_func:
name: big list expected
key: $(test)_PASS
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ [-23, 17, 67] ]
expected_result: [-23, 17, 67]
- group:
name: Function result not expected
steps:
- py_func:
name: int not expected
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [18]
expected_result: 17
- py_func:
name: float not expected
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [0.3]
expected_result: 0.5
- py_func:
name: String not expected
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ "Something" ]
expected_result: Nothing
- py_func:
name: Tuple int,str not expected
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: tuple_return
param: [ 0, "OK" ]
expected_result: [0, "OUPS"]
- py_func:
name: small list not expected
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ [-23] ]
expected_result: [-22]
- py_func:
name: big list not expected
key: $(test)_FAIL
file: $(test_path)$(psep)py_func.py
func_name: echo
param: [ [-23, 17, 67] ]
expected_result: [-23, 16, 67]
- py_func:
name: delgd test
key: $(test)_PASS

View File

@@ -0,0 +1,7 @@
main:
name: run sub-test (always fail)
steps:
- check:
name: fail
values:
- false

View File

@@ -0,0 +1,7 @@
main:
name: run sub-test (always pass)
steps:
- check:
name: pass
values:
- true

View File

@@ -31,11 +31,7 @@ main:
{% for item in items %}
# item test
- let:
name: {{ item }} test constants
values:
- test: {{ item }}
- test_path: items/$(test)
- let: {name: {{ item }} test constants, values: {test: {{ item }}, test_path: items/$(test)}}
- group:
name: {{ item }} test
steps:

View File

@@ -89,7 +89,7 @@ def exec():
junit_report = report.replace(".sqlite", f"-{test}.xml")
print(junit_report)
_prepare_file_to_save(junit_report)
with open(junit_report, "w") as f:
with open(junit_report, "w", encoding="utf-8") as f:
f.write(TestSuite.to_xml_string([ts]))
# cleanup

View File

@@ -89,6 +89,13 @@ REM Reports are stamped with the mode so successive runs don't clobber each othe
SET "TAIL=-b -d "python_bin=%VENV_PYTHON%" -d "validation_report_file=validation-%MODE%" -- "%SCRIPT_DIR%\main.tum"%EXTRA%"
REM The report-exporter plugin (items\report_plugin) is a pip entry-point
REM package. It must live in the *testium* environment, so it is installed into
REM the source/wheel venvs below. A frozen PyInstaller binary cannot see
REM externally-installed plugins, so report_plugin is expected to be skipped
REM there (same as Linux pyinstaller mode).
SET "FAKE_EXPORTER=%SCRIPT_DIR%\fake_exporter"
REM ---------- per-mode launcher ----------------------------------------------
echo -- validation mode: %MODE%
@@ -100,8 +107,25 @@ echo ERROR: unknown --mode '%MODE%'. Expected: source ^| wheel ^| pyinstaller.
exit /b 1
:MODE_SOURCE
call "%PROJECT_DIR%\run.bat" %TAIL%
exit /b %ERRORLEVEL%
REM Run testium from src\ in a dedicated venv set up here. We do NOT delegate to
REM the project's run.bat: that one launches the GUI and does not forward its
REM arguments, so the suite would never run head-less.
SET "TESTIUM_VENV=%PROJECT_DIR%\test\tmp\testium_venv"
IF NOT EXIST "%TESTIUM_VENV%" (
echo Creating testium venv at %TESTIUM_VENV%
%PYTHON_EXE% -m venv "%TESTIUM_VENV%"
IF !ERRORLEVEL! NEQ 0 (
echo ERROR while creating the testium venv.
exit /b 1
)
call "%TESTIUM_VENV%\Scripts\pip" install --quiet --upgrade pip
call "%TESTIUM_VENV%\Scripts\pip" install --quiet -r "%PROJECT_DIR%\src\requirements.txt"
REM language-server extra so `testium lsp` works from source (lsp_check.py)
call "%TESTIUM_VENV%\Scripts\pip" install --quiet "pygls>=1.3"
)
call "%TESTIUM_VENV%\Scripts\pip" install --quiet -e "%FAKE_EXPORTER%"
SET CMD="%TESTIUM_VENV%\Scripts\python.exe" "%PROJECT_DIR%\src\testium"
GOTO LAUNCH
:MODE_WHEEL
SET "WHEEL=%PROJECT_DIR%\dist\testium-%VERSION%-py3-none-any.whl"
@@ -115,10 +139,13 @@ IF NOT EXIST "%WHEEL_VENV%" (
echo Creating wheel venv at %WHEEL_VENV%
%PYTHON_EXE% -m venv --system-site-packages "%WHEEL_VENV%"
call "%WHEEL_VENV%\Scripts\pip" install --quiet --upgrade pip
call "%WHEEL_VENV%\Scripts\pip" install --quiet "%WHEEL%"
REM install with the [lsp] extra so the wheel channel is validated in its
REM language-server-capable form (pulls pygls), matching `pip install testium[lsp]`.
call "%WHEEL_VENV%\Scripts\pip" install --quiet "%WHEEL%[lsp]"
)
"%WHEEL_VENV%\Scripts\python.exe" -m testium %TAIL%
exit /b %ERRORLEVEL%
call "%WHEEL_VENV%\Scripts\pip" install --quiet -e "%FAKE_EXPORTER%"
SET CMD="%WHEEL_VENV%\Scripts\python.exe" -m testium
GOTO LAUNCH
:MODE_PYI
SET "PYI_BIN=%PROJECT_DIR%\dist\testium-%VERSION%.exe"
@@ -127,5 +154,22 @@ IF NOT EXIST "%PYI_BIN%" (
echo ERROR: PyInstaller binary not found in %PROJECT_DIR%\dist -- run build_all.sh first.
exit /b 1
)
"%PYI_BIN%" %TAIL%
SET CMD="%PYI_BIN%"
GOTO LAUNCH
REM ---------- launch ----------------------------------------------------------
:LAUNCH
echo -- launch: %CMD%
REM LSP check (this exact channel): `schema` must keep its nested actions and
REM `lsp` must answer initialize. Mirrors run.sh; aborts the run on failure.
echo -- LSP check (%MODE%)
"%VENV_PYTHON%" "%SCRIPT_DIR%\lsp_check.py" %CMD%
IF !ERRORLEVEL! NEQ 0 (
echo ERROR: LSP check failed for mode %MODE%.
exit /b 1
)
%CMD% %TAIL%
exit /b %ERRORLEVEL%