Initial commit: 2125_GCE project
This commit is contained in:
Executable
+307
@@ -0,0 +1,307 @@
|
||||
#!/usr/bin/env python3
|
||||
"""End-to-end integration test for glyph superpower system.
|
||||
|
||||
Tests:
|
||||
1. Load superpowers → Assign to glyphs → Emit telemetry → Verify output
|
||||
2. Test all 8 specialized types
|
||||
3. Test G001 (Ledo) with 152 powers
|
||||
4. Test edge cases (min/max metrics, power counts)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
sys.path.insert(0, str(Path.cwd()))
|
||||
|
||||
from glyphs.superpower_registry import load_all_superpowers, get_superpower, calculate_boost
|
||||
from glyphs.superpower_assigner import assign_superpowers, calculate_power_count
|
||||
from glyphs.specialized_types import get_specialized_type
|
||||
from integrations.fedmart.glyph_telemetry import get_adapter, GlyphActivationEvent
|
||||
|
||||
|
||||
def test_g001_ledo():
|
||||
"""Test G001 (Ledo) has all 152 superpowers."""
|
||||
print("\n=== Test: G001 (Ledo) ===")
|
||||
|
||||
# Load superpowers
|
||||
load_all_superpowers()
|
||||
|
||||
# Assign G001
|
||||
metrics = {
|
||||
"power": 100,
|
||||
"resonance": 100,
|
||||
"stability": 100,
|
||||
"connectivity": 100,
|
||||
"affinity": 100,
|
||||
}
|
||||
|
||||
superpower_ids = assign_superpowers("G001", metrics, "", "aether_node")
|
||||
|
||||
assert len(superpower_ids) == 152, f"Expected 152 powers, got {len(superpower_ids)}"
|
||||
|
||||
# Calculate boost
|
||||
boost = calculate_boost(superpower_ids)
|
||||
assert boost > 387, f"Expected boost > 387, got {boost}"
|
||||
|
||||
print(f" ✅ G001: {len(superpower_ids)} superpowers")
|
||||
print(f" ✅ Boost: {boost:.2f}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_all_specialized_types():
|
||||
"""Test all 8 specialized types are assigned correctly."""
|
||||
print("\n=== Test: All Specialized Types ===")
|
||||
|
||||
load_all_superpowers()
|
||||
|
||||
# Test each type with metrics that trigger it
|
||||
type_tests = [
|
||||
# frost_circuit_logic: stability >= 80, power >= 75
|
||||
("G100", {"power": 85, "resonance": 75, "stability": 90, "connectivity": 80, "affinity": 70}, "frost_circuit_logic"),
|
||||
# orbital_thread_network: connectivity >= 85, power >= 70
|
||||
("G200", {"power": 75, "resonance": 70, "stability": 70, "connectivity": 90, "affinity": 70}, "orbital_thread_network"),
|
||||
# star_bloom_creativity: power >= 80, complexity >= 75
|
||||
("G300", {"power": 85, "resonance": 70, "stability": 70, "connectivity": 70, "affinity": 70, "complexity": 80}, "star_bloom_creativity"),
|
||||
# frost_steel_stabilizer: stability >= 70, resonance >= 60
|
||||
("G400", {"power": 60, "resonance": 70, "stability": 75, "connectivity": 60, "affinity": 60}, "frost_steel_stabilizer"),
|
||||
# mirror_weave_reasoning: power >= 75, connectivity >= 80 (but NOT stability >= 70 AND resonance >= 60)
|
||||
("G500", {"power": 80, "resonance": 55, "stability": 65, "connectivity": 82, "affinity": 70}, "mirror_weave_reasoning"),
|
||||
# solar_veil_memory: affinity >= 70, stability >= 65 (but NOT stability >= 70 AND resonance >= 60)
|
||||
("G150", {"power": 60, "resonance": 55, "stability": 68, "connectivity": 60, "affinity": 80}, "solar_veil_memory"),
|
||||
# twin_vector_identity: affinity >= 75, connectivity >= 70
|
||||
("G250", {"power": 60, "resonance": 60, "stability": 60, "connectivity": 75, "affinity": 80}, "twin_vector_identity"),
|
||||
# monument_grade_equilibrium: G600 special case
|
||||
("G600", {"power": 75, "resonance": 75, "stability": 75, "connectivity": 75, "affinity": 75}, "monument_grade_equilibrium"),
|
||||
]
|
||||
|
||||
for glyph_id, metrics, expected_type in type_tests:
|
||||
# Get the specialized type
|
||||
actual_type = get_specialized_type(glyph_id, metrics)
|
||||
|
||||
assert actual_type == expected_type, f"{glyph_id}: expected {expected_type}, got {actual_type}"
|
||||
|
||||
# Assign superpowers
|
||||
superpower_ids = assign_superpowers(glyph_id, metrics)
|
||||
assert 5 <= len(superpower_ids) <= 25, f"{glyph_id}: power count out of range"
|
||||
|
||||
print(f" ✅ {glyph_id}: {actual_type} ({len(superpower_ids)} powers)")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_power_count_formula():
|
||||
"""Test power count formula: 5 + int((avg_metric / 100) * 20)."""
|
||||
print("\n=== Test: Power Count Formula ===")
|
||||
|
||||
load_all_superpowers()
|
||||
|
||||
# Test cases: (avg_metric, expected_count)
|
||||
# Note: formula is 5 + int((avg / 100) * 20), so:
|
||||
# avg=0 -> 5 + 0 = 5
|
||||
# avg=50 -> 5 + 10 = 15
|
||||
# avg=100 -> 5 + 20 = 25
|
||||
# avg=25 -> 5 + 5 = 10
|
||||
# avg=75 -> 5 + 15 = 20
|
||||
# Note: specialized type min/max may override, so test with no type override
|
||||
test_cases = [
|
||||
(0, 5, 8), # Minimum (type min may override)
|
||||
(50, 14, 16), # Mid-range
|
||||
(100, 22, 25), # Maximum (type max may override)
|
||||
(25, 9, 11), # Low
|
||||
(75, 19, 21), # High
|
||||
]
|
||||
|
||||
for avg_metric, expected_low, expected_high in test_cases:
|
||||
# Create metrics that average to avg_metric
|
||||
# Use metrics that won't trigger specialized type overrides
|
||||
metrics = {
|
||||
"power": avg_metric,
|
||||
"resonance": avg_metric,
|
||||
"stability": avg_metric,
|
||||
"connectivity": avg_metric,
|
||||
"affinity": avg_metric,
|
||||
}
|
||||
|
||||
count = calculate_power_count(metrics)
|
||||
|
||||
# Allow for specialized type min/max overrides
|
||||
assert expected_low <= count <= expected_high, f"avg={avg_metric}: expected {expected_low}-{expected_high}, got {count}"
|
||||
print(f" ✅ avg={avg_metric}: {count} powers")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_telemetry_emission():
|
||||
"""Test telemetry emission with actual event."""
|
||||
print("\n=== Test: Telemetry Emission ===")
|
||||
|
||||
load_all_superpowers()
|
||||
|
||||
# Assign a glyph
|
||||
metrics = {
|
||||
"power": 75,
|
||||
"resonance": 70,
|
||||
"stability": 65,
|
||||
"connectivity": 80,
|
||||
}
|
||||
|
||||
superpower_ids = assign_superpowers("G001", metrics)
|
||||
|
||||
# Emit telemetry
|
||||
adapter = get_adapter(local_mode=True)
|
||||
|
||||
event = GlyphActivationEvent(
|
||||
glyph_id="G001",
|
||||
superpower_ids=superpower_ids,
|
||||
specialized_type="aether_node",
|
||||
metrics=metrics,
|
||||
)
|
||||
|
||||
emitted = adapter.emit_glyph_activation(event)
|
||||
|
||||
assert emitted, "Telemetry emission failed"
|
||||
assert event.glyph_id == "G001"
|
||||
assert len(event.superpower_ids) == 152
|
||||
|
||||
print(f" ✅ Emitted: {event.glyph_id} ({len(event.superpower_ids)} powers)")
|
||||
print(f" ✅ Type: {event.specialized_type}")
|
||||
print(f" ✅ Metrics: power={event.metrics['power']}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_power_boost_calculation():
|
||||
"""Test power boost calculation with known values."""
|
||||
print("\n=== Test: Power Boost Calculation ===")
|
||||
|
||||
load_all_superpowers()
|
||||
|
||||
# Test 1: Single power (ID 1)
|
||||
boost1 = calculate_boost([1])
|
||||
assert boost1 > 0, "Boost should be positive"
|
||||
print(f" ✅ Single power (ID 1): {boost1:.2f}")
|
||||
|
||||
# Test 2: Multiple powers (1-10)
|
||||
boost10 = calculate_boost(list(range(1, 11)))
|
||||
assert boost10 > boost1, "More powers should have higher boost"
|
||||
print(f" ✅ 10 powers: {boost10:.2f}")
|
||||
|
||||
# Test 3: All 152 powers
|
||||
boost152 = calculate_boost(list(range(1, 153)))
|
||||
assert boost152 > boost10, "All powers should have highest boost"
|
||||
assert boost152 > 387, f"Expected boost > 387, got {boost152}"
|
||||
print(f" ✅ 152 powers: {boost152:.2f}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_edge_cases():
|
||||
"""Test edge cases and boundary conditions."""
|
||||
print("\n=== Test: Edge Cases ===")
|
||||
|
||||
load_all_superpowers()
|
||||
|
||||
# Edge case 1: Minimum metrics (0)
|
||||
# Note: specialized type may have min_powers override
|
||||
metrics_min = {"power": 0, "resonance": 0, "stability": 0, "connectivity": 0, "affinity": 0}
|
||||
superpower_ids_min = assign_superpowers("G999", metrics_min)
|
||||
# Default type frost_steel_stabilizer has min_powers=8
|
||||
assert 5 <= len(superpower_ids_min) <= 15, f"Min metrics should have 5-15 powers, got {len(superpower_ids_min)}"
|
||||
print(f" ✅ Min metrics (0): {len(superpower_ids_min)} powers")
|
||||
|
||||
# Edge case 2: Maximum metrics (100)
|
||||
# Note: specialized type may have max_powers override
|
||||
metrics_max = {"power": 100, "resonance": 100, "stability": 100, "connectivity": 100, "affinity": 100}
|
||||
superpower_ids_max = assign_superpowers("G998", metrics_max)
|
||||
# Should be in 15-25 range due to type overrides
|
||||
assert 15 <= len(superpower_ids_max) <= 25, f"Max metrics should have 15-25 powers, got {len(superpower_ids_max)}"
|
||||
print(f" ✅ Max metrics (100): {len(superpower_ids_max)} powers")
|
||||
|
||||
# Edge case 3: Invalid superpower ID (should not exist)
|
||||
power = get_superpower(153)
|
||||
assert power is None, "ID 153 should not exist"
|
||||
print(f" ✅ Invalid ID (153): None")
|
||||
|
||||
# Edge case 4: Valid superpower ID
|
||||
power = get_superpower(1)
|
||||
assert power is not None, "ID 1 should exist"
|
||||
assert "name" in power, "Power should have name"
|
||||
print(f" ✅ Valid ID (1): {power['name']}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_data_files():
|
||||
"""Test that all data files are valid JSON."""
|
||||
print("\n=== Test: Data Files ===")
|
||||
|
||||
files = [
|
||||
"/home/dave/superdave/glyphs/superpowers.json",
|
||||
"/home/dave/superdave/glyphs/supercharged_glyphs.json",
|
||||
]
|
||||
|
||||
for file_path in files:
|
||||
with open(file_path) as f:
|
||||
data = json.load(f)
|
||||
assert data, f"{file_path} is empty"
|
||||
print(f" ✅ {file_path}: valid JSON")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def run_all_tests():
|
||||
"""Run all integration tests."""
|
||||
print("=" * 70)
|
||||
print("GLYPH SUPERPOWER INTEGRATION TESTS")
|
||||
print("=" * 70)
|
||||
|
||||
tests = [
|
||||
("G001 (Ledo)", test_g001_ledo),
|
||||
("Specialized Types", test_all_specialized_types),
|
||||
("Power Count Formula", test_power_count_formula),
|
||||
("Telemetry Emission", test_telemetry_emission),
|
||||
("Power Boost Calc", test_power_boost_calculation),
|
||||
("Edge Cases", test_edge_cases),
|
||||
("Data Files", test_data_files),
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for name, test_func in tests:
|
||||
try:
|
||||
passed = test_func()
|
||||
results.append((name, passed, None))
|
||||
except Exception as e:
|
||||
results.append((name, False, str(e)))
|
||||
print(f" ❌ FAILED: {e}")
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 70)
|
||||
print("TEST SUMMARY")
|
||||
print("=" * 70)
|
||||
|
||||
passed = sum(1 for _, p, _ in results if p)
|
||||
total = len(results)
|
||||
|
||||
for name, test_passed, error in results:
|
||||
status = "✅ PASS" if test_passed else "❌ FAIL"
|
||||
print(f" {status}: {name}")
|
||||
if error:
|
||||
print(f" Error: {error}")
|
||||
|
||||
print(f"\nResults: {passed}/{total} passed")
|
||||
|
||||
if passed == total:
|
||||
print("\n✅ All integration tests passed!")
|
||||
return True
|
||||
else:
|
||||
print(f"\n❌ {total - passed} tests failed")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = run_all_tests()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user