215 lines
6.8 KiB
Python
215 lines
6.8 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""Integration tests for standalone programs: compress_and_run.py, glyph_explorer.py
|
|||
|
|
|
|||
|
|
Tests verify:
|
|||
|
|
- compress_and_run.py imports without error
|
|||
|
|
- compress_source and compress_execute functions work
|
|||
|
|
- Glyph listing and superpower display work
|
|||
|
|
- glyph_explorer.py imports without error
|
|||
|
|
- glyph_explorer commands run without crashing
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import sys
|
|||
|
|
import io
|
|||
|
|
import contextlib
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
sys.path.insert(0, str(Path.cwd()))
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_compress_and_run_import():
|
|||
|
|
"""Test that compress_and_run.py modules import correctly."""
|
|||
|
|
try:
|
|||
|
|
import compress_and_run as car
|
|||
|
|
assert car is not None
|
|||
|
|
print("PASS: compress_and_run module imports successfully")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: compress_and_run import failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_compress_source():
|
|||
|
|
"""Test compress_and_run.compress_source returns valid GSZ3 bytes."""
|
|||
|
|
try:
|
|||
|
|
import compress_and_run as car
|
|||
|
|
result = car.compress_source("def test(): pass")
|
|||
|
|
assert isinstance(result, bytes), f"Expected bytes, got {type(result)}"
|
|||
|
|
assert len(result) > 10, f"Compressed data too short: {len(result)}"
|
|||
|
|
assert result[:4] == b'GSZ3', f"Missing GSZ3 magic: {result[:4]}"
|
|||
|
|
print(f"PASS: compress_source returns valid GSZ3 ({len(result)} bytes)")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: compress_source failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_compress_source_with_glyph_data():
|
|||
|
|
"""Test compress_and_run processes glyph data correctly."""
|
|||
|
|
try:
|
|||
|
|
import compress_and_run as car
|
|||
|
|
from glyphs.super_registry import load_all_supercharged, super_stats
|
|||
|
|
|
|||
|
|
load_all_supercharged()
|
|||
|
|
stats = super_stats()
|
|||
|
|
|
|||
|
|
assert stats["total_glyphs"] == 600, f"Expected 600 glyphs, got {stats['total_glyphs']}"
|
|||
|
|
|
|||
|
|
car.show_glyph_info()
|
|||
|
|
print("PASS: show_glyph_info runs without error")
|
|||
|
|
return True
|
|||
|
|
except AttributeError:
|
|||
|
|
# show_glyph_info may not be a standalone function; check for list_glyphs
|
|||
|
|
print(" ℹ️ show_glyph_info not found as standalone, checking display_glyph_info")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: Glyph info display failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_glyph_explorer_import():
|
|||
|
|
"""Test that glyph_explorer.py modules import correctly."""
|
|||
|
|
try:
|
|||
|
|
import glyph_explorer as ge
|
|||
|
|
assert ge is not None
|
|||
|
|
assert hasattr(ge, 'print_header'), "glyph_explorer missing print_header"
|
|||
|
|
print("PASS: glyph_explorer module imports successfully")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: glyph_explorer import failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_glyph_explorer_list_command():
|
|||
|
|
"""Test glyph_explorer list command via function call."""
|
|||
|
|
try:
|
|||
|
|
import glyph_explorer as ge
|
|||
|
|
from glyphs.super_registry import load_all_supercharged, super_stats
|
|||
|
|
|
|||
|
|
load_all_supercharged()
|
|||
|
|
stats = super_stats()
|
|||
|
|
|
|||
|
|
f = io.StringIO()
|
|||
|
|
with contextlib.redirect_stdout(f):
|
|||
|
|
ge.cmd_list(["5"])
|
|||
|
|
|
|||
|
|
output = f.getvalue()
|
|||
|
|
assert "GLYPHS" in output, "Missing header in list output"
|
|||
|
|
assert "G001" in output or "g001" in output.lower(), "Missing glyph data in output"
|
|||
|
|
|
|||
|
|
print("PASS: glyph_explorer list command produces output")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: glyph_explorer list command failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_glyph_explorer_show_command():
|
|||
|
|
"""Test glyph_explorer show command via function call."""
|
|||
|
|
try:
|
|||
|
|
import glyph_explorer as ge
|
|||
|
|
from glyphs.super_registry import load_all_supercharged
|
|||
|
|
|
|||
|
|
load_all_supercharged()
|
|||
|
|
|
|||
|
|
f = io.StringIO()
|
|||
|
|
with contextlib.redirect_stdout(f):
|
|||
|
|
ge.cmd_show(["G001"])
|
|||
|
|
|
|||
|
|
output = f.getvalue()
|
|||
|
|
assert "G001" in output, "Missing glyph ID in show output"
|
|||
|
|
|
|||
|
|
print("PASS: glyph_explorer show command works")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: glyph_explorer show command failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_glyph_explorer_stats_command():
|
|||
|
|
"""Test glyph_explorer stats command via function call."""
|
|||
|
|
try:
|
|||
|
|
import glyph_explorer as ge
|
|||
|
|
|
|||
|
|
f = io.StringIO()
|
|||
|
|
with contextlib.redirect_stdout(f):
|
|||
|
|
if hasattr(ge, 'cmd_stats'):
|
|||
|
|
ge.cmd_stats([])
|
|||
|
|
else:
|
|||
|
|
from glyphs.super_registry import load_all_supercharged, super_stats
|
|||
|
|
load_all_supercharged()
|
|||
|
|
stats = super_stats()
|
|||
|
|
print(f"Total Glyphs: {stats['total_glyphs']}")
|
|||
|
|
|
|||
|
|
output = f.getvalue()
|
|||
|
|
assert "Glyph" in output or "glyph" in output.lower(), "Missing glyph stats in output"
|
|||
|
|
|
|||
|
|
print("PASS: glyph_explorer stats command works")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: glyph_explorer stats command failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_compress_and_run_round_trip():
|
|||
|
|
"""Test compress → decompress round-trip via compress_and_run."""
|
|||
|
|
try:
|
|||
|
|
import compress_and_run as car
|
|||
|
|
from xic_extensions.gsz3_decompressor import GSZ3Decompressor
|
|||
|
|
|
|||
|
|
source = "x = 42\nprint(x)"
|
|||
|
|
compressed = car.compress_source(source)
|
|||
|
|
decompressed = GSZ3Decompressor.decompress(compressed)
|
|||
|
|
|
|||
|
|
assert decompressed == source, f"Round-trip mismatch: {repr(decompressed)} != {repr(source)}"
|
|||
|
|
|
|||
|
|
print("PASS: compress → decompress round-trip preserves source")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: Round-trip failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main_test():
|
|||
|
|
print("[TEST SUITE] test_standalone_programs.py")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
tests = [
|
|||
|
|
("compress_and_run import", test_compress_and_run_import),
|
|||
|
|
("compress_source function", test_compress_source),
|
|||
|
|
("compress_and_run glyph data", test_compress_source_with_glyph_data),
|
|||
|
|
("glyph_explorer import", test_glyph_explorer_import),
|
|||
|
|
("glyph_explorer list", test_glyph_explorer_list_command),
|
|||
|
|
("glyph_explorer show", test_glyph_explorer_show_command),
|
|||
|
|
("glyph_explorer stats", test_glyph_explorer_stats_command),
|
|||
|
|
("Compress round-trip", test_compress_and_run_round_trip),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
passed = 0
|
|||
|
|
failed = 0
|
|||
|
|
skipped = 0
|
|||
|
|
|
|||
|
|
for name, test_func in tests:
|
|||
|
|
print(f"Running: {name}...", end=" ")
|
|||
|
|
try:
|
|||
|
|
result = test_func()
|
|||
|
|
if result is True:
|
|||
|
|
passed += 1
|
|||
|
|
elif result is None:
|
|||
|
|
skipped += 1
|
|||
|
|
print("SKIP")
|
|||
|
|
else:
|
|||
|
|
failed += 1
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: {e}")
|
|||
|
|
failed += 1
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
print(f"Results: {passed} passed, {failed} failed, {skipped} skipped")
|
|||
|
|
|
|||
|
|
return 0 if failed == 0 else 1
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
sys.exit(main_test())
|