| """Tests for the instrument knowledge base.""" |
| import os |
| import sys |
| import pytest |
|
|
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) |
|
|
| from backend.knowledge_base import INSTRUMENT_KNOWLEDGE_BASE, STEM_ANALYSIS_PROMPT |
|
|
|
|
| def test_knowledge_base_is_non_empty_string(): |
| """INSTRUMENT_KNOWLEDGE_BASE must be a non-empty string.""" |
| assert isinstance(INSTRUMENT_KNOWLEDGE_BASE, str) |
| assert len(INSTRUMENT_KNOWLEDGE_BASE) > 0 |
|
|
|
|
| def test_knowledge_base_contains_guitar(): |
| """Knowledge base must reference the guitar instrument family.""" |
| assert "guitar" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_contains_piano(): |
| """Knowledge base must reference the piano instrument family.""" |
| assert "piano" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_contains_violin(): |
| """Knowledge base must reference the violin instrument.""" |
| assert "violin" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_contains_drums(): |
| """Knowledge base must reference drums.""" |
| assert "drum" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_stem_analysis_prompt_is_non_empty(): |
| """STEM_ANALYSIS_PROMPT must be a non-empty string.""" |
| assert isinstance(STEM_ANALYSIS_PROMPT, str) |
| assert len(STEM_ANALYSIS_PROMPT) > 0 |
|
|
|
|
| def test_knowledge_base_contains_confidence_calibration(): |
| """Knowledge base must contain confidence calibration guidance.""" |
| assert "confidence" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
| assert "calibrat" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_mentions_high_confidence(): |
| """Knowledge base must mention 'high' confidence explicitly.""" |
| assert "HIGH CONFIDENCE" in INSTRUMENT_KNOWLEDGE_BASE or "high confidence" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_mentions_medium_confidence(): |
| """Knowledge base must mention 'medium' confidence explicitly.""" |
| assert "medium" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_mentions_low_confidence(): |
| """Knowledge base must mention 'low' confidence explicitly.""" |
| assert "LOW CONFIDENCE" in INSTRUMENT_KNOWLEDGE_BASE or "low confidence" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_mentions_rhodes(): |
| """Knowledge base must mention Rhodes electric piano.""" |
| assert "rhodes" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_mentions_wurlitzer(): |
| """Knowledge base must mention Wurlitzer electric piano.""" |
| assert "wurlitzer" in INSTRUMENT_KNOWLEDGE_BASE.lower() |
|
|
|
|
| def test_knowledge_base_length_comprehensive(): |
| """Knowledge base must be comprehensive (>5000 characters).""" |
| assert len(INSTRUMENT_KNOWLEDGE_BASE) > 5000, ( |
| f"Knowledge base is only {len(INSTRUMENT_KNOWLEDGE_BASE)} chars, expected >5000" |
| ) |
|
|
|
|
| def test_knowledge_base_no_placeholder_text(): |
| """Knowledge base must not contain placeholder text like TODO or FIXME.""" |
| kb_upper = INSTRUMENT_KNOWLEDGE_BASE.upper() |
| assert "TODO" not in kb_upper, "Knowledge base contains 'TODO' placeholder" |
| assert "FIXME" not in kb_upper, "Knowledge base contains 'FIXME' placeholder" |
|
|
|
|
| def test_knowledge_base_mentions_new_world_instruments(): |
| """Knowledge base must mention the new world/rare instruments added in v3.""" |
| kb_lower = INSTRUMENT_KNOWLEDGE_BASE.lower() |
| assert "hang" in kb_lower, "Hang drum / handpan not mentioned" |
| assert "kalimba" in kb_lower, "Kalimba not mentioned" |
| assert "didgeridoo" in kb_lower, "Didgeridoo not mentioned" |
| assert "theremin" in kb_lower, "Theremin not mentioned" |
| assert "bagpipe" in kb_lower, "Bagpipes not mentioned" |
|
|
|
|
| def test_stem_analysis_prompt_directs_the_model_to_the_tool(): |
| """STEM_ANALYSIS_PROMPT must tell the model how to answer. |
| |
| It used to require the word "json", because the answer was JSON parsed out |
| of prose. That shape now lives in the submit_stem_analysis tool schema, and |
| the prompt must point there instead — a prompt that spells out a rival |
| shape is exactly what made Sonnet run past its token ceiling. |
| """ |
| assert "submit_stem_analysis" in STEM_ANALYSIS_PROMPT |
|
|
|
|
| def test_knowledge_base_mentions_spectral_features(): |
| """Knowledge base must reference key spectral features used in analysis.""" |
| kb_lower = INSTRUMENT_KNOWLEDGE_BASE.lower() |
| assert "spectral_centroid" in kb_lower or "spectral centroid" in kb_lower |
| assert "harmonic_ratio" in kb_lower or "harmonic ratio" in kb_lower |
|
|