Populate the 13 domain files with a starter Knowledge Base (188 entries) covering the reference test scenarios (single/two characters, interactions, indoor/outdoor, fantasy, modern) per MASTER_SPEC §16. - appearance.json: character identity, general appearance, hair, eyes, face. - clothing.json: garments plus worn accessories. - anatomy.json (body), expressions.json, poses.json, actions.json, interactions.json, objects.json, environments.json, camera.json, lighting.json. - quality.json / style.json: reserved, empty in V1 (not auto-generated). - Synonym aliases (girl/woman/lady -> female, boy/man -> male, etc.). - Exactly two deterministic expansions: school_uniform -> blazer + pleated_skirt; twin_braids -> braid. No speculative expansions. - Exactly one valid category per entry; no subjective concepts. The whole dataset validates with zero findings via the KB validation tooling (#9), so the loader (#7) accepts it. A test loads the shipped dataset, asserts clean load, checks core concepts across every reference scenario, verifies synonym aliases resolve, confirms the deterministic expansions and their targets, and guards against subjective concepts. Co-authored-by: kunail0804 <kunail0804@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
"""Tests for the shipped Illustrious Knowledge Base dataset (issue #10)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from compiler.common.knowledge_base import load_knowledge_base
|
|
|
|
KB_DIR = Path(__file__).resolve().parent.parent / "knowledge_base"
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def kb():
|
|
# Loading succeeds only if the whole dataset validates cleanly (delegated to #9).
|
|
return load_knowledge_base(KB_DIR)
|
|
|
|
|
|
def test_dataset_loads_and_validates_cleanly(kb) -> None:
|
|
assert len(kb) > 100 # a substantive starter set
|
|
|
|
|
|
# Core concepts spanning every reference scenario (single/two characters,
|
|
# interactions, indoor/outdoor, fantasy, modern).
|
|
CORE_CONCEPTS = [
|
|
"female",
|
|
"male",
|
|
"multiple_girls",
|
|
"long_hair",
|
|
"blue_eyes",
|
|
"dress",
|
|
"school_uniform",
|
|
"smile",
|
|
"standing",
|
|
"walking",
|
|
"hug",
|
|
"holding_hands",
|
|
"chair",
|
|
"sword",
|
|
"classroom",
|
|
"forest",
|
|
"castle",
|
|
"city",
|
|
"beach",
|
|
"close_up",
|
|
"sunset",
|
|
"armor",
|
|
"cat_ears",
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("concept", CORE_CONCEPTS)
|
|
def test_core_concept_is_known(kb, concept: str) -> None:
|
|
assert kb.get(concept) is not None, f"core concept '{concept}' missing from the dataset"
|
|
|
|
|
|
# Frequent synonyms must resolve to their canonical id.
|
|
ALIASES = {
|
|
"girl": "female",
|
|
"woman": "female",
|
|
"lady": "female",
|
|
"boy": "male",
|
|
"man": "male",
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize(("alias", "canonical"), list(ALIASES.items()))
|
|
def test_alias_resolves(kb, alias: str, canonical: str) -> None:
|
|
assert kb.resolve_alias(alias) == canonical
|
|
|
|
|
|
def test_deterministic_expansions_present(kb) -> None:
|
|
assert set(kb.get("school_uniform").expand) == {"blazer", "pleated_skirt"}
|
|
assert kb.get("twin_braids").expand == ("braid",)
|
|
# Expansion targets exist (the loader would have failed otherwise).
|
|
for target in kb.get("school_uniform").expand:
|
|
assert kb.get(target) is not None
|
|
|
|
|
|
def test_no_subjective_concepts(kb) -> None:
|
|
banned = {"beautiful", "cute", "pretty", "sexy", "gorgeous", "handsome", "hot", "ugly"}
|
|
names = set(kb.by_id) | {alias for entry in kb.by_id.values() for alias in entry.aliases}
|
|
assert banned.isdisjoint(names)
|
|
|
|
|
|
def test_every_entry_has_exactly_one_valid_category(kb) -> None:
|
|
from compiler.common.categories import is_valid_category
|
|
|
|
for entry in kb.by_id.values():
|
|
assert isinstance(entry.category, str)
|
|
assert is_valid_category(entry.category)
|