aztext / tests /test_aztext.py
kamaalg's picture
Upload tests/test_aztext.py with huggingface_hub
1216a5c verified
Raw
History Blame Contribute Delete
4.96 kB
"""Tests for aztext. Runs under pytest OR as a plain script (python test_aztext.py).
python -m pytest aztext/tests -q # if pytest is available
python aztext/tests/test_aztext.py # dependency-free fallback
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import aztext
from aztext import alphabet
import aztext.deasciify # ensure submodule is imported (name is shadowed by the func export)
deasc = sys.modules["aztext.deasciify"] # the MODULE, not the re-exported function
# --- Turkic i-family case mapping (the thing Python gets wrong) --------------
def test_az_upper_i_family():
assert alphabet.az_upper("i") == "İ"
assert alphabet.az_upper("ı") == "I"
assert alphabet.az_upper("işıq") == "İŞIQ"
def test_az_lower_i_family():
assert alphabet.az_lower("İ") == "i"
assert alphabet.az_lower("I") == "ı"
assert alphabet.az_lower("İŞIQ") == "işıq"
def test_i_distinction_never_collapses():
# the four characters must stay pairwise distinct through case round-trips
assert alphabet.az_lower(alphabet.az_upper("i")) == "i"
assert alphabet.az_lower(alphabet.az_upper("ı")) == "ı"
# --- number to words --------------------------------------------------------
def test_num_to_words():
cases = {
0: "sıfır", 1: "bir", 7: "yeddi", 10: "on", 11: "on bir",
20: "iyirmi", 25: "iyirmi beş", 100: "yüz", 101: "yüz bir",
200: "iki yüz", 1000: "min", 2000: "iki min",
1234: "min iki yüz otuz dörd", 1_000_000: "bir milyon",
}
for n, expected in cases.items():
assert aztext.num_to_words(n) == expected, (n, aztext.num_to_words(n))
def test_num_to_words_negative():
assert aztext.num_to_words(-5) == "mənfi beş"
# --- language id ------------------------------------------------------------
def test_langid_az_vs_tr():
assert aztext.is_azerbaijani("Mən Azərbaycan dilini öyrənirəm.")
# Turkish sentence (no ə, Turkish function words) must NOT be Azerbaijani
lang, _ = aztext.detect_language("Ben Türkçe öğreniyorum ve kitap okuyorum.")
assert lang == "tr", lang
def test_langid_rejects_cyrillic():
lang, _ = aztext.detect_language("Привет как дела")
assert lang == "other", lang
# --- normalize --------------------------------------------------------------
def test_normalize_idempotent_and_preserves_az():
s = "Gözəl şəhər — “Bakı”."
once = aztext.normalize(s)
assert aztext.normalize(once) == once # idempotent
for ch in "əöşıü":
pass
assert "ə" in once and "ş" in once and "ı" in once # az letters preserved
assert '"' in once and "'" not in once # curly quotes -> ascii
# --- deasciify --------------------------------------------------------------
def test_deasciify_known_words():
assert deasc.deasciify("ucun") == "üçün"
assert deasc.deasciify("cixis") == "çıxış"
assert deasc.deasciify("mekteb") == "məktəb"
assert deasc.deasciify("usaq") == "uşaq"
# casing preserved
assert deasc.deasciify("Mekteb") == "Məktəb"
# already-diacritic words pass through untouched
assert deasc.deasciify("gözəl") == "gözəl"
# unknown words untouched
assert deasc.deasciify("xyzzy") == "xyzzy"
def test_ascii_fold():
assert deasc.ascii_fold("gözəl çıxış") == "gozel cixis"
assert deasc.ascii_fold("işıq") == "isiq"
# --- tokenize / script ------------------------------------------------------
def test_tokenize():
assert aztext.word_tokenize("Bakı, Azərbaycanın paytaxtıdır.") == \
["Bakı", "Azərbaycanın", "paytaxtıdır"]
assert len(aztext.sent_tokenize("Bir. İki! Üç?")) == 3
def test_is_latin_azerbaijani():
assert aztext.is_latin_azerbaijani("Azərbaycan dili")
assert not aztext.is_latin_azerbaijani("Азәрбајҹан дили")
# --- dictionary integrity: no homoglyph / non-Azerbaijani letters -----------
def test_dictionary_is_clean_azerbaijani():
bad = []
for w in deasc._CORRECT_WORDS:
for ch in w:
if ch.isalpha() and ch not in alphabet.AZ_LETTERS:
bad.append((w, ch, hex(ord(ch))))
assert not bad, f"non-Azerbaijani letters in deasciify dict: {bad}"
def _run_all():
fns = [v for k, v in sorted(globals().items()) if k.startswith("test_") and callable(v)]
failed = 0
for fn in fns:
try:
fn()
print(f"PASS {fn.__name__}")
except AssertionError as e:
failed += 1
print(f"FAIL {fn.__name__}: {e}")
except Exception as e: # noqa: BLE001
failed += 1
print(f"ERROR {fn.__name__}: {type(e).__name__}: {e}")
print(f"\n{len(fns) - failed}/{len(fns)} passed")
return failed
if __name__ == "__main__":
sys.exit(1 if _run_all() else 0)