Spaces:
Sleeping
Sleeping
| import os | |
| import pytest | |
| from unittest.mock import MagicMock, patch | |
| def csv_file(tmp_path): | |
| p = tmp_path / "index.csv" | |
| p.write_text( | |
| "path,token,phrase,word\n" | |
| "video_dir/hello.mp4,HELLO,,\n" | |
| "video_dir/thank_you.mp4,THANK-YOU,,\n" | |
| "video_dir/good_morning.mp4,,GOOD MORNING,\n" | |
| ) | |
| return str(p) | |
| def dict_dir(tmp_path): | |
| d = tmp_path / "dictionary" | |
| d.mkdir() | |
| (d / "hello.mp4").write_bytes(b"") | |
| (d / "thank_you.mp4").write_bytes(b"") | |
| (d / "good_morning.mp4").write_bytes(b"") | |
| return str(d) | |
| def _mock_vi(result=None): | |
| vi = MagicMock() | |
| vi.query_gloss.return_value = result or [] | |
| return vi | |
| def test_ensure_extracted_skips_when_dir_exists(tmp_path): | |
| """Does nothing if dictionary directory already exists.""" | |
| (tmp_path / "dictionary").mkdir() | |
| from mapping import ensure_dictionary_extracted | |
| with patch("mapping.zipfile.ZipFile") as mock_zip: | |
| ensure_dictionary_extracted( | |
| zip_path=str(tmp_path / "dict.zip"), | |
| extract_to=str(tmp_path), | |
| ) | |
| mock_zip.assert_not_called() | |
| def test_ensure_extracted_unzips_when_missing(tmp_path): | |
| """Extracts zip when dictionary directory is absent.""" | |
| zip_path = str(tmp_path / "dict.zip") | |
| from mapping import ensure_dictionary_extracted | |
| with patch("mapping.zipfile.ZipFile") as mock_zip_cls: | |
| ensure_dictionary_extracted(zip_path=zip_path, extract_to=str(tmp_path)) | |
| mock_zip_cls.assert_called_once_with(zip_path) | |
| mock_zip_cls.return_value.__enter__.return_value.extractall.assert_called_once_with( | |
| str(tmp_path) | |
| ) | |
| def test_exact_single_token_match(csv_file, dict_dir): | |
| """get_paths returns path on exact single-token match.""" | |
| with patch("mapping.ensure_dictionary_extracted"): | |
| from mapping import ASLDictionary | |
| d = ASLDictionary(csv_path=csv_file, dictionary_dir=dict_dir, vector_index=_mock_vi()) | |
| paths = d.get_paths(["hello"]) | |
| assert len(paths) == 1 | |
| assert paths[0].endswith("hello.mp4") | |
| def test_greedy_phrase_match(csv_file, dict_dir): | |
| """get_paths greedily matches multi-word phrase tokens.""" | |
| with patch("mapping.ensure_dictionary_extracted"): | |
| from mapping import ASLDictionary | |
| d = ASLDictionary(csv_path=csv_file, dictionary_dir=dict_dir, vector_index=_mock_vi()) | |
| paths = d.get_paths(["good", "morning"]) | |
| assert len(paths) == 1 | |
| assert paths[0].endswith("good_morning.mp4") | |
| def test_semantic_fallback_on_exact_miss(csv_file, dict_dir): | |
| """get_paths calls VectorIndex when exact match fails.""" | |
| vi = _mock_vi(result=[("HELLO", 0.85, "hello.mp4")]) | |
| with patch("mapping.ensure_dictionary_extracted"): | |
| from mapping import ASLDictionary | |
| d = ASLDictionary(csv_path=csv_file, dictionary_dir=dict_dir, vector_index=vi) | |
| paths = d.get_paths(["HI"]) | |
| assert len(paths) == 1 | |
| assert paths[0].endswith("hello.mp4") | |
| vi.query_gloss.assert_called_once_with("HI", top_k=1) | |
| def test_fuzzy_fallback_on_semantic_miss(csv_file, dict_dir): | |
| """get_paths uses difflib when semantic search returns nothing.""" | |
| vi = _mock_vi(result=[]) | |
| with patch("mapping.ensure_dictionary_extracted"): | |
| from mapping import ASLDictionary | |
| d = ASLDictionary(csv_path=csv_file, dictionary_dir=dict_dir, vector_index=vi) | |
| # "HELO" scores ~0.89 vs "HELLO" with difflib — above default cutoff 0.6 | |
| paths = d.get_paths(["HELO"]) | |
| assert len(paths) == 1 | |
| assert paths[0].endswith("hello.mp4") | |
| def test_no_match_returns_empty(csv_file, dict_dir): | |
| """get_paths skips token when all three tiers fail.""" | |
| vi = _mock_vi(result=[]) | |
| with patch("mapping.ensure_dictionary_extracted"), \ | |
| patch.dict(os.environ, {"FUZZY_CUTOFF": "0.99"}): | |
| from mapping import ASLDictionary | |
| d = ASLDictionary(csv_path=csv_file, dictionary_dir=dict_dir, vector_index=vi) | |
| paths = d.get_paths(["XYZZY"]) | |
| assert paths == [] | |