Spaces:
Sleeping
Sleeping
| # ============================================================ | |
| # FILE : test_ner.py | |
| # FUNGSI: Unit test rule-based NER dan fungsi pendukungnya | |
| # AUTHOR: Ariel Jonathan | |
| # ============================================================ | |
| from __future__ import annotations | |
| import pytest | |
| from ner.ner_detector import ( | |
| IndonesianNER, | |
| NEREntity, | |
| _chunk_text, | |
| _has_preceding_title, | |
| _merge_entities, | |
| ) | |
| class TestChunkText: | |
| def test_teks_pendek_satu_potongan(self): | |
| chunks = _chunk_text("Ahmad bekerja di Jakarta.") | |
| assert len(chunks) == 1 | |
| assert chunks[0][1] == 0 | |
| def test_teks_panjang_beberapa_potongan(self): | |
| text = "Budi pergi ke pasar. " * 120 | |
| chunks = _chunk_text(text) | |
| assert len(chunks) > 1 | |
| def test_offset_potongan_cocok_dengan_teks_asli(self): | |
| text = "Budi pergi ke pasar. " * 120 | |
| for chunk, offset in _chunk_text(text): | |
| assert text[offset:offset + len(chunk)] == chunk | |
| class TestPrecedingTitle: | |
| def test_gelar_terdeteksi(self): | |
| assert _has_preceding_title("Pak ", 4) is True | |
| assert _has_preceding_title("Ibu ", 4) is True | |
| def test_kata_biasa_bukan_gelar(self): | |
| assert _has_preceding_title("Bunga ", 6) is False | |
| def ner(): | |
| # Rule-only, tanpa model ML, agar test cepat dan deterministik | |
| return IndonesianNER() | |
| class TestRegresiNamaAwalKalimat: | |
| """Regresi B8: nama satu kata yang juga kata umum tidak ditandai di awal kalimat.""" | |
| def test_bunga_di_awal_kalimat_bersih(self, ner): | |
| orang = [e for e in ner.predict("Bunga bank ditetapkan lima persen.") | |
| if e.label == "ORANG"] | |
| assert orang == [] | |
| def test_nama_dua_kata_tetap_terdeteksi(self, ner): | |
| orang = [e.word for e in ner.predict("Ahmad Santoso memimpin rapat.") | |
| if e.label == "ORANG"] | |
| assert "Ahmad Santoso" in orang | |
| def test_nama_dengan_gelar_terdeteksi(self, ner): | |
| orang = [e.word for e in ner.predict("Ibu Bunga mengajar kelas VIII.") | |
| if e.label == "ORANG"] | |
| assert any("Bunga" in w for w in orang) | |
| class TestRegresiOrganisasiInggris: | |
| """Regresi B11: organisasi Inggris terdeteksi via akronim dan sufiks.""" | |
| def test_akronim_global_terdeteksi(self, ner): | |
| org = [e.word for e in ner.predict("UNESCO mengeluarkan pedoman baru.") | |
| if e.label == "ORGANISASI"] | |
| assert "UNESCO" in org | |
| def test_sufiks_badan_usaha_terdeteksi(self, ner): | |
| org = [e.word for e in ner.predict("Dia bekerja di OpenAI Inc. mulai besok.") | |
| if e.label == "ORGANISASI"] | |
| assert any("OpenAI" in w for w in org) | |
| class TestRegresiSpanEntitas: | |
| """Regresi: entitas tidak boleh membawa tanda baca tepi.""" | |
| def test_rule_organisasi_tidak_membawa_koma(self, ner): | |
| org = [e.word for e in ner.predict("Dia bekerja di PT Maju Bersama, sejak 2024.") | |
| if e.label == "ORGANISASI"] | |
| assert "PT Maju Bersama" in org | |
| assert all(not w.endswith(",") for w in org) | |
| def test_rule_spesifik_mengalahkan_fragmen_ml(self): | |
| ml = [NEREntity("Universitas", "ORGANISASI", 0.99, 20, 31, "ml")] | |
| rules = [NEREntity("Universitas Indonesia", "ORGANISASI", 0.90, 20, 41, "rule")] | |
| merged = _merge_entities(ml, rules) | |
| assert [e.word for e in merged] == ["Universitas Indonesia"] | |