Skip to content

Commit 99b4750

Browse files
committed
added xml docgen to script.
1 parent ca3d0a8 commit 99b4750

File tree

1 file changed

+101
-30
lines changed

1 file changed

+101
-30
lines changed

test/run-tests.py

Lines changed: 101 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,11 @@ def filter_output(lines: list[str]) -> list[str]:
6565
result.append(cleaned)
6666
return result
6767

68-
def is_successful(output: str) -> bool:
69-
return END_MARKER in output and PASSED_MARKER in output and FAILED_MARKER not in output
70-
7168
# ──────────────────────────────────────────────
7269
# Portable Godot
7370
# ──────────────────────────────────────────────
7471

75-
def setup_temp_portable_godot():
76-
original_path = Path(ORIGINAL_GODOT).resolve()
72+
def setup_temp_portable_godot( original_path:Path ):
7773
if not original_path.is_file():
7874
print(f"Warning: Original Godot not found — using as-is.")
7975
return ORIGINAL_GODOT
@@ -178,12 +174,12 @@ def run_godot(
178174

179175
if verbose:
180176
print(full_output.rstrip())
181-
print(f"→ Exit code: {exit_code}")
177+
print(f"\n{'─' * 10} {desc} - exit:{exit_code:#x} {'─' * 10}")
182178

183179
if timeout:
184180
return 124, "TIMEOUT", f'After {timeout_sec}s', full_output
185181

186-
return exit_code, "DONE", f'Exit code: {exit_code}', full_output
182+
return exit_code, "DONE", f'Exit code: {exit_code:#x}', full_output
187183

188184
except Exception as exc:
189185
stdout = stdout_path.read_text("utf-8", errors="replace")
@@ -215,50 +211,98 @@ def pre_import_project(godot_bin: str, verbose: bool = False):
215211
return exit_code != 0
216212

217213

218-
def run_tests(mode: str, godot_bin: str, verbose: bool = False) -> bool:
219-
success = True
214+
def run_integration_tests(godot_bin: str, verbose: bool = False) -> bool:
215+
print("→ Unit/Integration Tests", end=' ', flush=True)
220216

221-
if mode in ("unit", "full"):
222-
print("→ Unit/Integration Tests", end=' ', flush=True)
217+
args = [
218+
"--path", str(GODOT_PROJECT),
219+
"--debug", "--headless", "--quit"]
220+
exitcode, strcode, msg, output = run_godot(
221+
args, "Unit/Integration tests", godot_bin, verbose=verbose
222+
)
223223

224-
args = ["--path", str(GODOT_PROJECT), "--debug", "--headless", "--quit"]
225-
exitcode, strcode, msg, output = run_godot(
226-
args, "Unit tests", godot_bin, verbose=verbose
227-
)
224+
def is_successful(output: str) -> bool:
225+
return END_MARKER in output and PASSED_MARKER in output and FAILED_MARKER not in output
228226

229-
if not verbose:
230-
print(f"[ {strcode} ]", end=' ')
231-
print(f"- {msg}" if msg else '')
227+
if not verbose:
228+
print(f"[ {strcode} ]", end=' ')
229+
print(f"- {msg}" if msg else '')
232230

233-
if exitcode == 127:
234-
print("→ Unit phase: TIMEOUT")
235-
success = False
236-
elif not is_successful(output):
237-
print("→ Unit phase: FAILED")
238-
success = False
231+
if exitcode == 127:
232+
print("→ Unit phase: TIMEOUT")
233+
return False
234+
elif not is_successful(output):
235+
print("→ Unit phase: FAILED")
236+
return False
237+
else:
238+
return True
239239

240-
return success
241240

241+
def generate_extension_docs(godot_bin: str, verbose: bool = False) -> bool:
242+
print("→ GDExtension XML DocGen", end=' ', flush=True)
243+
244+
# Run from inside project/ (demo/), pointing --doctool at ../
245+
args = [
246+
"--path", str(PROJECT_DIR),
247+
"--doctool", "..", "--gdextension-docs",
248+
"--headless", "--quit",
249+
]
250+
exitcode, strcode, msg, output = run_godot(
251+
args, "GDExtension XML DocGen", godot_bin, verbose=verbose
252+
)
253+
254+
# print the completion of the non verbose line.
255+
if not verbose:
256+
print(f"[ {strcode} ]", end=' ')
257+
print(f"- {msg}" if msg else '')
258+
259+
if strcode == 'TIMEOUT':
260+
if verbose: print("→ DocGen phase: TIMEOUT")
261+
return False
262+
263+
doc_path = (PROJECT_DIR.parent / "doc_classes").resolve()
264+
if doc_path.exists():
265+
xml_files = list(doc_path.glob('*.xml'))
266+
if len(xml_files) > 0:
267+
if verbose:
268+
print(f"→ DocGen doc_classes/ created at: {doc_path} ({len(xml_files)} XML files)")
269+
for file in xml_files: print(file)
270+
return True
271+
if verbose: print("→ Warning: DocGen Command succeeded but no doc_classes/*.xml found")
272+
return False
273+
else:
274+
print("→ DocGen phase: FAILED")
275+
return False
242276

243277
# ──────────────────────────────────────────────
244278
# Main
245279
# ──────────────────────────────────────────────
246280

247281
def main():
248282
parser = argparse.ArgumentParser(description="Run godot-cpp test suite")
249-
parser.add_argument("--unit-only", action="store_const", const="unit", dest="mode")
283+
parser.add_argument("--tests-only", action="store_const", const="unit", dest="mode",
284+
help="Only run the integration tests (skip doc xml generation)")
285+
parser.add_argument("--docs-only", action="store_const", const="docs", dest="mode",
286+
help="Only generate GDExtension XML documentation (skip tests)")
250287
parser.add_argument("--verbose", action="store_true", default=False,
251288
help="Show full unfiltered Godot output")
252289
parser.add_argument("--quiet", action="store_true", default=False,
253290
help="Only exit code (0=success, >0=failure); no output")
291+
parser.add_argument("--editor-bin", default=ORIGINAL_GODOT,
292+
help="Path to Godot editor binary for --doctool (default: same as test Godot)")
254293
args = parser.parse_args()
255294

256295
# store a reference to print
257296
original_print = builtins.print
258297

298+
godot_path = Path(ORIGINAL_GODOT).resolve()
299+
editor_path = Path(args.editor_bin).resolve()
300+
# TODO test godot bin to make sure its ok.
301+
259302
mode = args.mode or "full"
260303
verbose = args.verbose
261304

305+
262306
if args.quiet:
263307
def silent(*_args, **_kwargs):
264308
pass
@@ -277,14 +321,19 @@ def silent(*_args, **_kwargs):
277321
print(f"Mode: {mode}")
278322
print(f"Verbose: {verbose}\n")
279323

280-
godot_bin = setup_temp_portable_godot()
281-
# TODO test godot bin to make sure its ok.
324+
godot_bin = setup_temp_portable_godot(godot_path)
282325

283326
pre_clean = cleanup_godot_cache(verbose=verbose)
284-
285327
pre_import = pre_import_project(godot_bin, verbose=verbose)
328+
# NOTE: the above arent strictly necessary , and the import will always fail anyway.
286329

287-
success = run_tests(mode, godot_bin, verbose=verbose)
330+
success = True
331+
if mode in ("unit", "full") and success:
332+
success = run_integration_tests(godot_bin, verbose=verbose)
333+
334+
if mode in ("docs", "full") and success:
335+
editor_bin = godot_bin if editor_path == godot_path else setup_temp_portable_godot(editor_path)
336+
success = generate_extension_docs(editor_bin, verbose=verbose)
288337

289338
cleanup_temp_portable()
290339

@@ -300,3 +349,25 @@ def silent(*_args, **_kwargs):
300349

301350
if __name__ == "__main__":
302351
main()
352+
353+
#
354+
# try:
355+
# godot_bin = setup_temp_portable_godot() # still use temp copy for tests
356+
#
357+
# if args.generate_docs_only:
358+
# # Standalone mode — use possibly different editor binary
359+
# editor_bin = args.godot_editor
360+
# success = generate_extension_docs(editor_bin)
361+
# else:
362+
# # Normal test run
363+
# all_passed = run_tests(mode, godot_bin)
364+
#
365+
# if all_passed and mode == "full": # only do docs in full mode, after tests pass
366+
# print("\nAll tests passed → generating GDExtension docs as final step...")
367+
# success = generate_extension_docs(godot_bin) # reuse test Godot binary
368+
# all_passed = all_passed and success
369+
# else:
370+
# success = all_passed # no docs run → status is just tests
371+
#
372+
# finally:
373+
# cleanup_temp_portable()

0 commit comments

Comments
 (0)