File size: 4,970 Bytes
d7b0955 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | """Regression tests for SmolLM2 / hybrid pipeline (no model download required)."""
from __future__ import annotations
import os
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
from app.config import GENERATIVE_BACKEND, PIPELINE_MODE
from app.pipeline.alignment import align_documents, align_paragraph_sentences
from app.pipeline.candidate_validator import validate_candidate
from app.pipeline.generative import backend_kind, _clean_gen_text
from app.pipeline.grammar_fix import correct_text
from app.pipeline.orchestrator import rewrite_text
def test_backend_defaults() -> None:
# Defaults come from env at import time; kind helper mirrors config
assert backend_kind() in {"seq2seq", "causal"}
assert GENERATIVE_BACKEND in {"seq2seq", "causal"}
assert PIPELINE_MODE in {"hybrid", "generative", "classical"}
print("backend defaults OK:", GENERATIVE_BACKEND, PIPELINE_MODE)
def test_clean_causal_wrappers() -> None:
assert _clean_gen_text('Assistant: Hello there.') == "Hello there."
assert _clean_gen_text('"Rewritten sentence."') == "Rewritten sentence."
assert _clean_gen_text("Paraphrase: People live healthier lives.") == (
"People live healthier lives."
)
print("clean wrappers OK")
def test_alignment_1to1() -> None:
src = "Alpha is first. Beta is second."
cand = "Alpha comes first. Beta comes second."
units = align_paragraph_sentences(src, cand)
assert len(units) == 2
assert all(u.kind == "1:1" for u in units)
print("alignment 1:1 OK")
def test_alignment_preserves_paragraphs() -> None:
src = "One. Two.\n\nThree."
cand = "Uno. Dos.\n\nTres."
units = align_documents(src, cand)
idxs = {u.paragraph_index for u in units}
assert 0 in idxs and 1 in idxs
print("alignment paragraphs OK:", len(units), "units")
def test_truncated_rejected() -> None:
orig = (
"Nowadays many people are living an unhealthy life because they don't have enough time. "
"Eating fast foods is becoming very common and people don't realize how much it affects their health."
)
truncated = (
"Fast food is becoming very common because many people don't realize "
"how much it affects their health."
)
v = validate_candidate(orig, truncated, min_meaning=0.5)
assert not v.ok
assert "length" in v.reasons or "coverage" in v.reasons
print("truncated rejected OK")
def test_hybrid_classical_without_ml() -> None:
orig = (
"Nowadays many peoples are living unhealthy life because they don't have enough times. "
"Eating fast foods are becoming very common and peoples don't realizes how much it affect their health."
)
r = rewrite_text(
orig,
tone="Neutral",
strength=1,
preserve_length=True,
ml_polish=False,
)
out = r.text.lower()
assert "peoples" not in out
assert "an unhealthy life" in out
assert "affects" in out
assert "enough time" in out
# Both claims should survive classical path
assert "unhealthy" in out
assert "fast food" in out or "fast foods" in out
assert r.pipeline_mode == "classical"
print("hybrid classical-without-ml OK:", r.engine)
def test_hybrid_mode_with_ml_no_model() -> None:
"""When generative fails to load, hybrid still returns safe classical output."""
orig = (
"Nowadays many peoples are living unhealthy life because they don't have enough times. "
"Eating fast foods are becoming very common and peoples don't realizes how much it affect their health."
)
# Force unavailable generative by not requiring it; hybrid runs classical+validate
r = rewrite_text(
orig,
tone="Neutral",
strength=1,
preserve_length=True,
ml_polish=True,
)
out = r.text.lower()
assert "unhealthy" in out
assert "health" in out
# Must not collapse to single truncated claim only
g = correct_text(orig).lower()
assert "enough time" in out or "enough time" in g
print("hybrid ml path OK mode=", r.pipeline_mode, "engine=", r.engine)
if r.hybrid:
print(
" units=",
r.hybrid.units,
"kept=",
r.hybrid.classical_kept,
"regen=",
r.hybrid.regenerated,
"accepted=",
r.hybrid.gen_accepted,
"reverted=",
r.hybrid.reverted_source,
)
if __name__ == "__main__":
test_backend_defaults()
test_clean_causal_wrappers()
test_alignment_1to1()
test_alignment_preserves_paragraphs()
test_truncated_rejected()
test_hybrid_classical_without_ml()
test_hybrid_mode_with_ml_no_model()
print("\nALL SMOLLM2 / HYBRID PIPELINE TESTS PASSED")
|