Files
LEDMatrix/test_core_logic.py
2025-09-15 14:21:09 -04:00

155 lines
5.9 KiB
Python

#!/usr/bin/env python3
"""
Test the core logic of the web interface without Flask dependencies.
"""
import json
class DictWrapper:
"""Wrapper to make dictionary accessible via dot notation for Jinja2 templates."""
def __init__(self, data=None):
# Store the original data
object.__setattr__(self, '_data', data if isinstance(data, dict) else {})
# Set attributes from the dictionary
if isinstance(data, dict):
for key, value in data.items():
if isinstance(value, dict):
object.__setattr__(self, key, DictWrapper(value))
elif isinstance(value, list):
object.__setattr__(self, key, value)
else:
object.__setattr__(self, key, value)
def __getattr__(self, name):
# Return a new empty DictWrapper for missing attributes
# This allows chaining like main_config.display.hardware.rows
return DictWrapper({})
def __str__(self):
# Return empty string for missing values to avoid template errors
data = object.__getattribute__(self, '_data')
if not data:
return ''
return str(data)
def __int__(self):
# Return 0 for missing numeric values
data = object.__getattribute__(self, '_data')
if not data:
return 0
try:
return int(data)
except (ValueError, TypeError):
return 0
def __bool__(self):
# Return False for missing boolean values
data = object.__getattribute__(self, '_data')
if not data:
return False
return bool(data)
def get(self, key, default=None):
# Support .get() method like dictionaries
data = object.__getattribute__(self, '_data')
if data and key in data:
return data[key]
return default
def safe_get(obj, key_path, default=''):
"""Safely access nested dictionary values using dot notation."""
try:
keys = key_path.split('.')
current = obj
for key in keys:
if hasattr(current, key):
current = getattr(current, key)
elif isinstance(current, dict) and key in current:
current = current[key]
else:
return default
return current if current is not None else default
except (AttributeError, KeyError, TypeError):
return default
def safe_config_get(config, *keys, default=''):
"""Safely get nested config values with fallback."""
try:
current = config
for key in keys:
if hasattr(current, key):
current = getattr(current, key)
# Check if we got an empty DictWrapper
if isinstance(current, DictWrapper):
data = object.__getattribute__(current, '_data')
if not data: # Empty DictWrapper means missing config
return default
elif isinstance(current, dict) and key in current:
current = current[key]
else:
return default
# Final check for empty values
if current is None or (hasattr(current, '_data') and not object.__getattribute__(current, '_data')):
return default
return current
except (AttributeError, KeyError, TypeError):
return default
def simulate_template_rendering():
"""Simulate how the template would render configuration values."""
print("Simulating template rendering with actual config...")
# Load actual config
with open('config/config.json', 'r') as f:
config_data = json.load(f)
main_config = DictWrapper(config_data)
# Simulate template expressions that would be used
template_tests = [
# Input field values
("safe_config_get(main_config, 'display', 'hardware', 'rows', default=32)", 32),
("safe_config_get(main_config, 'display', 'hardware', 'cols', default=64)", 64),
("safe_config_get(main_config, 'display', 'hardware', 'brightness', default=95)", 95),
("safe_config_get(main_config, 'display', 'hardware', 'chain_length', default=2)", 2),
("safe_config_get(main_config, 'display', 'hardware', 'parallel', default=1)", 1),
("safe_config_get(main_config, 'display', 'hardware', 'hardware_mapping', default='adafruit-hat-pwm')", 'adafruit-hat-pwm'),
# Checkbox states
("safe_config_get(main_config, 'display', 'hardware', 'disable_hardware_pulsing', default=False)", False),
("safe_config_get(main_config, 'display', 'hardware', 'inverse_colors', default=False)", False),
("safe_config_get(main_config, 'display', 'hardware', 'show_refresh_rate', default=False)", False),
("safe_config_get(main_config, 'display', 'use_short_date_format', default=True)", True),
]
all_passed = True
for expression, expected in template_tests:
try:
result = eval(expression)
status = "" if result == expected else ""
print(f" {status} {expression.split('(')[0]}(...): {result} (expected: {expected})")
if result != expected:
all_passed = False
except Exception as e:
print(f"{expression}: ERROR - {e}")
all_passed = False
return all_passed
if __name__ == "__main__":
print("=" * 70)
print("Testing Core Web Interface Logic")
print("=" * 70)
success = simulate_template_rendering()
print("\n" + "=" * 70)
if success:
print("✓ ALL TEMPLATE SIMULATIONS PASSED!")
print("✓ The web interface should correctly display all config values!")
else:
print("✗ SOME TEMPLATE SIMULATIONS FAILED!")
print("✗ There may be issues with config display in the web interface!")
print("=" * 70)