cq-test / test_schema.py
NANI-Nithin's picture
Phase 1: establish the baseline
eaf7eca
Raw
History Blame Contribute Delete
8.95 kB
"""
Test the game JSON schema and validation utilities.
Run this script to:
1. Test the schema against example games from the dataset
2. Validate schema structure
3. Test minimal game templates
4. Display validation results
"""
import json
from app.services.retrieval import load_games_dataset, normalize_game_record
from app.services.schema_validator import (
load_schema,
validate_game_schema,
validate_task_structure,
validate_safety_structure,
create_minimal_game_template
)
def test_schema_structure():
"""Test that the schema itself is valid."""
print("=" * 80)
print("SCHEMA STRUCTURE TEST")
print("=" * 80)
try:
schema = load_schema("game_schema.json")
print("βœ“ Game schema loaded successfully")
print(f" Title: {schema.get('title')}")
print(f" Type: {schema.get('type')}")
print(f" Required fields: {', '.join(schema.get('required', []))}")
return True
except Exception as e:
print(f"βœ— Failed to load schema: {e}")
return False
def test_minimal_template():
"""Test validation of a minimal game template."""
print("\n" + "=" * 80)
print("MINIMAL GAME TEMPLATE TEST")
print("=" * 80)
template = create_minimal_game_template()
is_valid, errors = validate_game_schema(template)
if is_valid:
print("βœ“ Minimal template is valid against schema")
print(f" Game ID: {template['game_id']}")
print(f" Title: {template['title']}")
print(f" Tasks: {len(template['tasks'])}")
print(f" Rules: {len(template['rules'])}")
return True
else:
print(f"βœ— Minimal template validation failed:")
for error in errors:
print(f" - {error}")
return False
def test_dataset_games():
"""Test validation of example games from the dataset."""
print("\n" + "=" * 80)
print("DATASET GAMES VALIDATION TEST")
print("=" * 80)
# Load dataset
raw_records = load_games_dataset("app/data/games_dataset.json")
# Convert raw records to game schema format for testing
tested_count = 0
valid_count = 0
invalid_games = []
for raw in raw_records[:3]: # Test first 3 as sample
try:
# Extract expected output as game structure
output = raw.get('expected_output', {})
input_data = raw.get('input', {})
# Build game in schema format
# Transform tasks to include required title field
tasks_transformed = []
for task in output.get('tasks', []):
task_copy = task.copy()
# Add title if missing
if 'title' not in task_copy:
task_copy['title'] = task_copy.get('description', 'Task')[:50]
# Ensure all required fields exist
task_copy.setdefault('proof_type', 'observation')
task_copy.setdefault('hint', 'See location hint above')
task_copy.setdefault('safety_note', 'Follow general safety rules')
tasks_transformed.append(task_copy)
game = {
"game_id": raw.get('id'),
"title": f"Game {raw.get('id')}",
"theme": "discovery",
"setup": {
"city": input_data.get('location', {}).get('city', 'Paris'),
"area": input_data.get('location', {}).get('area', ''),
"meeting_point": "Central meeting point",
"duration_minutes": input_data.get('preferences', {}).get('duration_minutes', 45),
"num_players": input_data.get('preferences', {}).get('num_players', 4)
},
"rules": output.get('rules', []),
"tasks": tasks_transformed,
"global_hints": output.get('hints', [[]])[0] if output.get('hints') else [],
"score_rules": ["Standard scoring"],
"tie_breaker": "Most tasks completed",
"safety": {
"allowed_zone": "Public area",
"forbidden_behaviors": [],
"adult_supervision": input_data.get('preferences', {}).get('age_group') == 'kids',
"stop_conditions": ["Emergency", "Weather"]
},
"story_seed": {
"tone": "playful",
"motifs": [],
"recap_style": "episode_recap"
}
}
tested_count += 1
is_valid, errors = validate_game_schema(game)
if is_valid:
valid_count += 1
print(f"βœ“ {game['game_id']}: Valid")
else:
invalid_games.append({
'id': game['game_id'],
'errors': errors
})
print(f"βœ— {game['game_id']}: Invalid")
for error in errors[:2]: # Show first 2 errors
print(f" {error}")
except Exception as e:
tested_count += 1
print(f"βœ— {raw.get('id')}: Exception - {str(e)[:60]}")
print(f"\nResults: {valid_count}/{tested_count} games valid")
if invalid_games:
print("\nInvalid games details:")
for game_info in invalid_games:
print(f" {game_info['id']}: {game_info['errors']}")
return valid_count == tested_count
def test_task_validation():
"""Test task-level validation."""
print("\n" + "=" * 80)
print("TASK VALIDATION TEST")
print("=" * 80)
test_cases = [
{
"name": "Valid task",
"task": {
"task_id": "t1",
"title": "Find landmark",
"description": "Locate and photograph the fountain",
"location_hint": "Look in the central square",
"points": 25,
"time_limit_minutes": 15,
"proof_type": "photo",
"hint": "It's in the middle",
"safety_note": "Stay on paths"
},
"expect_valid": True
},
{
"name": "Invalid proof_type",
"task": {
"task_id": "t2",
"title": "Task",
"description": "Do something",
"location_hint": "Somewhere",
"points": 10,
"time_limit_minutes": 5,
"proof_type": "video", # Invalid
"hint": "Hint",
"safety_note": "Safe"
},
"expect_valid": False
},
{
"name": "Missing safety_note",
"task": {
"task_id": "t3",
"title": "Task",
"description": "Do something",
"location_hint": "Somewhere",
"points": 10,
"time_limit_minutes": 5,
"proof_type": "observation",
"hint": "Hint"
# Missing safety_note
},
"expect_valid": False
}
]
for test in test_cases:
is_valid, errors = validate_task_structure(test['task'])
status = "βœ“" if is_valid == test['expect_valid'] else "βœ—"
print(f"{status} {test['name']}: {is_valid}")
if errors:
for error in errors[:1]:
print(f" {error}")
def test_safety_validation():
"""Test safety object validation."""
print("\n" + "=" * 80)
print("SAFETY VALIDATION TEST")
print("=" * 80)
valid_safety = {
"allowed_zone": "Public park and streets",
"forbidden_behaviors": [
"Entering buildings",
"Crossing roads unsafely"
],
"adult_supervision": True,
"stop_conditions": [
"Injury",
"Emergency"
]
}
is_valid, errors = validate_safety_structure(valid_safety)
print(f"{'βœ“' if is_valid else 'βœ—'} Valid safety object: {is_valid}")
if errors:
for error in errors:
print(f" {error}")
def main():
print("\nGAME SCHEMA AND VALIDATION TESTS\n")
# Run all tests
schema_ok = test_schema_structure()
template_ok = test_minimal_template()
dataset_ok = test_dataset_games()
test_task_validation()
test_safety_validation()
# Summary
print("\n" + "=" * 80)
print("TEST SUMMARY")
print("=" * 80)
print(f"Schema structure: {'βœ“ PASS' if schema_ok else 'βœ— FAIL'}")
print(f"Minimal template: {'βœ“ PASS' if template_ok else 'βœ— FAIL'}")
print(f"Dataset games: {'βœ“ PASS' if dataset_ok else 'βœ— FAIL'}")
print("\nSchema validation is ready for use in game generation and validation.")
if __name__ == "__main__":
main()