401 lines
10 KiB
Python
401 lines
10 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Tests for Supercharged Glyph Registry (LedoGlyph600)
|
||
|
|
|
||
|
|
Tests verify:
|
||
|
|
- load_all_supercharged loads exactly 600 glyphs
|
||
|
|
- get_super returns correct glyph data
|
||
|
|
- list_super_ids returns all glyph IDs
|
||
|
|
- search_super works across supercharged fields
|
||
|
|
- super_stats reports correct metadata
|
||
|
|
- Helper functions work correctly
|
||
|
|
"""
|
||
|
|
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
sys.path.insert(0, str(Path.cwd()))
|
||
|
|
|
||
|
|
from glyphs.super_registry import (
|
||
|
|
load_all_supercharged,
|
||
|
|
get_super,
|
||
|
|
list_super_ids,
|
||
|
|
search_super,
|
||
|
|
super_stats,
|
||
|
|
get_super_field,
|
||
|
|
list_super_by_category,
|
||
|
|
get_super_by_band,
|
||
|
|
get_glyphs_by_score_range,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_load_all_supercharged():
|
||
|
|
"""Test loading all 600 supercharged glyphs."""
|
||
|
|
load_all_supercharged()
|
||
|
|
stats = super_stats()
|
||
|
|
|
||
|
|
if stats["total_glyphs"] != 600:
|
||
|
|
print(f"FAIL: Expected 600 glyphs, got {stats['total_glyphs']}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if not stats["loaded"]:
|
||
|
|
print("FAIL: Registry not marked as loaded")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Loaded 600 glyphs")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_super():
|
||
|
|
"""Test retrieving individual glyphs by ID."""
|
||
|
|
load_all_supercharged()
|
||
|
|
ids = list_super_ids()
|
||
|
|
|
||
|
|
if not ids:
|
||
|
|
print("FAIL: No glyph IDs available")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Test first glyph
|
||
|
|
first_id = ids[0]
|
||
|
|
glyph = get_super(first_id)
|
||
|
|
|
||
|
|
if glyph is None:
|
||
|
|
print(f"FAIL: Could not get glyph {first_id}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Check required fields
|
||
|
|
required_fields = ["id", "name", "category", "band", "score"]
|
||
|
|
for field in required_fields:
|
||
|
|
if field not in glyph:
|
||
|
|
print(f"FAIL: Glyph missing field: {field}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if glyph["id"] != first_id:
|
||
|
|
print(f"FAIL: Glyph ID mismatch: {glyph['id']} != {first_id}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Retrieved glyph {first_id} with all required fields")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_super_nonexistent():
|
||
|
|
"""Test retrieving non-existent glyph returns None."""
|
||
|
|
load_all_supercharged()
|
||
|
|
glyph = get_super("NONEXISTENT")
|
||
|
|
|
||
|
|
if glyph is not None:
|
||
|
|
print("FAIL: Should return None for nonexistent glyph")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print("PASS: Returns None for nonexistent glyph")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_list_super_ids():
|
||
|
|
"""Test listing all glyph IDs."""
|
||
|
|
load_all_supercharged()
|
||
|
|
ids = list_super_ids()
|
||
|
|
|
||
|
|
if len(ids) != 600:
|
||
|
|
print(f"FAIL: Expected 600 IDs, got {len(ids)}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if ids != sorted(ids):
|
||
|
|
print("FAIL: IDs are not sorted")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if not all(isinstance(id, str) for id in ids):
|
||
|
|
print("FAIL: Not all IDs are strings")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Listed 600 sorted glyph IDs")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_search_super_basic():
|
||
|
|
"""Test basic search functionality."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
# Search by ID
|
||
|
|
results = search_super("G001", fields=["id"])
|
||
|
|
if len(results) == 0:
|
||
|
|
print("FAIL: Could not find G001")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if results[0]["id"] != "G001":
|
||
|
|
print("FAIL: First result is not G001")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Found G001 by ID search")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_search_super_case_insensitive():
|
||
|
|
"""Test case-insensitive search."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
# Get a known glyph
|
||
|
|
first_glyph = get_super("G001")
|
||
|
|
if first_glyph is None:
|
||
|
|
print("FAIL: Could not load reference glyph")
|
||
|
|
return False
|
||
|
|
|
||
|
|
name = first_glyph.get("name", "").lower()
|
||
|
|
if not name:
|
||
|
|
print("FAIL: Reference glyph has no name")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Search with uppercase
|
||
|
|
results = search_super(name.upper(), fields=["name"])
|
||
|
|
if len(results) == 0:
|
||
|
|
print(f"FAIL: Case-insensitive search failed for {name.upper()}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Case-insensitive search works")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_search_super_limit():
|
||
|
|
"""Test search limit parameter."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
# Search for common category
|
||
|
|
results = search_super("", fields=["category"], limit=5)
|
||
|
|
|
||
|
|
# Note: empty query won't match, but we can test limit on real results
|
||
|
|
ids = list_super_ids()
|
||
|
|
|
||
|
|
# Search for first 10 IDs with limit
|
||
|
|
for test_id in ids[:10]:
|
||
|
|
results = search_super(test_id, limit=3)
|
||
|
|
if len(results) > 3:
|
||
|
|
print(f"FAIL: Got {len(results)} results, limit was 3")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print("PASS: Search limit respected")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_super_stats():
|
||
|
|
"""Test statistics reporting."""
|
||
|
|
load_all_supercharged()
|
||
|
|
stats = super_stats()
|
||
|
|
|
||
|
|
# Verify stats keys
|
||
|
|
required_keys = [
|
||
|
|
"total_glyphs",
|
||
|
|
"fields_present",
|
||
|
|
"sample_ids",
|
||
|
|
"categories",
|
||
|
|
"loaded",
|
||
|
|
"load_path",
|
||
|
|
]
|
||
|
|
|
||
|
|
for key in required_keys:
|
||
|
|
if key not in stats:
|
||
|
|
print(f"FAIL: Missing stats key: {key}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Verify values
|
||
|
|
if stats["total_glyphs"] != 600:
|
||
|
|
print(f"FAIL: total_glyphs != 600")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if not isinstance(stats["fields_present"], list):
|
||
|
|
print("FAIL: fields_present is not a list")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if not isinstance(stats["sample_ids"], list):
|
||
|
|
print("FAIL: sample_ids is not a list")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Check supercharged fields are present
|
||
|
|
supercharged_fields = [
|
||
|
|
"id",
|
||
|
|
"name",
|
||
|
|
"activation",
|
||
|
|
"lineage",
|
||
|
|
"praw",
|
||
|
|
"originalMetrics",
|
||
|
|
]
|
||
|
|
|
||
|
|
missing = [f for f in supercharged_fields if f not in stats["fields_present"]]
|
||
|
|
if missing:
|
||
|
|
print(f"FAIL: Missing supercharged fields: {missing}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if stats["loaded"] != True:
|
||
|
|
print("FAIL: loaded should be True")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if stats["sample_ids"] != list_super_ids()[:5]:
|
||
|
|
print("FAIL: sample_ids mismatch")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Stats complete with {len(stats['categories'])} categories")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_super_field():
|
||
|
|
"""Test nested field retrieval."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
glyph = get_super("G001")
|
||
|
|
if glyph is None:
|
||
|
|
print("FAIL: Could not load G001")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Test direct field
|
||
|
|
name = get_super_field("G001", "name")
|
||
|
|
if name != glyph["name"]:
|
||
|
|
print(f"FAIL: Direct field mismatch")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Test nested field (if present)
|
||
|
|
if "activation" in glyph:
|
||
|
|
score = get_super_field("G001", "activation.score")
|
||
|
|
if score != glyph.get("activation", {}).get("score"):
|
||
|
|
print(f"FAIL: Nested field mismatch")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Test default value
|
||
|
|
missing = get_super_field("G001", "nonexistent.field", default="DEFAULT")
|
||
|
|
if missing != "DEFAULT":
|
||
|
|
print(f"FAIL: Default value not returned")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print("PASS: Nested field retrieval works")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_list_super_by_category():
|
||
|
|
"""Test filtering by category."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
stats = super_stats()
|
||
|
|
categories = stats.get("categories", [])
|
||
|
|
|
||
|
|
if not categories:
|
||
|
|
print("SKIP: No categories found")
|
||
|
|
return True
|
||
|
|
|
||
|
|
# Test first category
|
||
|
|
category = categories[0]
|
||
|
|
glyphs = list_super_by_category(category)
|
||
|
|
|
||
|
|
if len(glyphs) == 0:
|
||
|
|
print(f"FAIL: No glyphs found in category {category}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Verify all returned glyphs are in that category
|
||
|
|
for glyph in glyphs:
|
||
|
|
if glyph.get("category") != category:
|
||
|
|
print(f"FAIL: Glyph in wrong category")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Found {len(glyphs)} glyphs in category '{category}'")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_super_by_band():
|
||
|
|
"""Test filtering by frequency band."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
# Get first glyph to find a band
|
||
|
|
first = get_super(list_super_ids()[0])
|
||
|
|
if first is None:
|
||
|
|
print("FAIL: Could not load first glyph")
|
||
|
|
return False
|
||
|
|
|
||
|
|
band = first.get("band")
|
||
|
|
glyphs = get_super_by_band(band)
|
||
|
|
|
||
|
|
if len(glyphs) == 0:
|
||
|
|
print(f"FAIL: No glyphs found in band {band}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Verify all are in same band
|
||
|
|
for glyph in glyphs:
|
||
|
|
if glyph.get("band") != band:
|
||
|
|
print(f"FAIL: Glyph in wrong band")
|
||
|
|
return False
|
||
|
|
|
||
|
|
print(f"PASS: Found {len(glyphs)} glyphs in band {band}")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def test_get_glyphs_by_score_range():
|
||
|
|
"""Test filtering by score range."""
|
||
|
|
load_all_supercharged()
|
||
|
|
|
||
|
|
glyphs = get_glyphs_by_score_range(100, 200)
|
||
|
|
|
||
|
|
if len(glyphs) == 0:
|
||
|
|
print("SKIP: No glyphs in score range 100-200")
|
||
|
|
return True
|
||
|
|
|
||
|
|
# Verify all are in range and sorted
|
||
|
|
prev_score = float('inf')
|
||
|
|
for glyph in glyphs:
|
||
|
|
score = glyph.get("score", 0)
|
||
|
|
if not (100 <= score <= 200):
|
||
|
|
print(f"FAIL: Glyph score {score} out of range")
|
||
|
|
return False
|
||
|
|
|
||
|
|
if score > prev_score:
|
||
|
|
print(f"FAIL: Results not sorted descending")
|
||
|
|
return False
|
||
|
|
|
||
|
|
prev_score = score
|
||
|
|
|
||
|
|
print(f"PASS: Found {len(glyphs)} glyphs in score range [100-200]")
|
||
|
|
return True
|
||
|
|
|
||
|
|
|
||
|
|
def main_test():
|
||
|
|
print("[TEST SUITE] test_supercharged_registry.py")
|
||
|
|
print()
|
||
|
|
|
||
|
|
tests = [
|
||
|
|
("Load all supercharged", test_load_all_supercharged),
|
||
|
|
("Get single glyph", test_get_super),
|
||
|
|
("Get nonexistent glyph", test_get_super_nonexistent),
|
||
|
|
("List all glyph IDs", test_list_super_ids),
|
||
|
|
("Search by ID", test_search_super_basic),
|
||
|
|
("Case-insensitive search", test_search_super_case_insensitive),
|
||
|
|
("Search limit", test_search_super_limit),
|
||
|
|
("Statistics reporting", test_super_stats),
|
||
|
|
("Get nested field", test_get_super_field),
|
||
|
|
("Filter by category", test_list_super_by_category),
|
||
|
|
("Filter by band", test_get_super_by_band),
|
||
|
|
("Filter by score range", test_get_glyphs_by_score_range),
|
||
|
|
]
|
||
|
|
|
||
|
|
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")
|
||
|
|
continue
|
||
|
|
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())
|