279 lines
11 KiB
Python
279 lines
11 KiB
Python
# Unit tests for pronunciation_dictionary_manager.py.
|
|
#
|
|
# Copyright 2026 Igalia, S.L.
|
|
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the
|
|
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
|
# Boston MA 02110-1301 USA.
|
|
|
|
# pylint: disable=wrong-import-position
|
|
# pylint: disable=protected-access
|
|
# pylint: disable=import-outside-toplevel
|
|
|
|
"""Unit tests for pronunciation_dictionary_manager.py."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
import pytest
|
|
|
|
if TYPE_CHECKING:
|
|
from cthulhu_test_context import CthulhuTestContext
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestPronunciationDictionaryManager:
|
|
"""Test PronunciationDictionaryManager class."""
|
|
|
|
def _setup_manager(self, test_context: CthulhuTestContext):
|
|
"""Set up mocks for pronunciation_dictionary_manager dependencies."""
|
|
|
|
additional_modules = [
|
|
"cthulhu.guilabels",
|
|
"cthulhu.messages",
|
|
"cthulhu.preferences_grid_base",
|
|
"cthulhu.script_manager",
|
|
"cthulhu.speech_manager",
|
|
]
|
|
essential_modules = test_context.setup_shared_dependencies(additional_modules)
|
|
|
|
# Set up guilabels with required constants
|
|
guilabels = essential_modules["cthulhu.guilabels"]
|
|
guilabels.PRONUNCIATION = "Pronunciation"
|
|
guilabels.PRONUNCIATION_DICTIONARY = "Pronunciation Dictionary"
|
|
guilabels.PRONUNCIATION_DICTIONARY_INFO = "Add custom pronunciations."
|
|
guilabels.DICTIONARY_NEW_ENTRY = "New Entry"
|
|
guilabels.DICTIONARY_DELETE = "Delete"
|
|
guilabels.DICTIONARY_EMPTY = "No entries"
|
|
guilabels.DICTIONARY_ACTUAL_STRING = "Actual String"
|
|
guilabels.DICTIONARY_REPLACEMENT_STRING = "Replacement String"
|
|
guilabels.ADD_NEW_PRONUNCIATION = "Add New Pronunciation"
|
|
guilabels.EDIT_PRONUNCIATION = "Edit Pronunciation"
|
|
guilabels.DIALOG_CANCEL = "Cancel"
|
|
guilabels.DIALOG_ADD = "Add"
|
|
guilabels.DIALOG_EDIT = "Edit"
|
|
|
|
# Set up messages
|
|
messages = essential_modules["cthulhu.messages"]
|
|
messages.PRONUNCIATION_DELETED = "Pronunciation %s deleted"
|
|
|
|
# Set up speech_manager
|
|
speech_manager_mock = essential_modules["cthulhu.speech_manager"]
|
|
speech_instance = speech_manager_mock.get_manager.return_value
|
|
speech_instance.get_use_pronunciation_dictionary.return_value = True
|
|
speech_instance.set_use_pronunciation_dictionary.return_value = True
|
|
|
|
# Import and return the module
|
|
from cthulhu import pronunciation_dictionary_manager
|
|
|
|
return pronunciation_dictionary_manager, essential_modules
|
|
|
|
def test_get_manager_returns_singleton(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test get_manager returns the same instance."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager1 = module.get_manager()
|
|
manager2 = module.get_manager()
|
|
|
|
assert manager1 is manager2
|
|
|
|
def test_manager_initial_state(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test manager initializes with empty dictionary."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
|
|
# Reset the dictionary to ensure clean state
|
|
manager.set_dictionary({})
|
|
|
|
assert manager.get_dictionary() == {}
|
|
|
|
def test_get_pronunciation_returns_word_when_not_found(
|
|
self,
|
|
test_context: CthulhuTestContext,
|
|
) -> None:
|
|
"""Test get_pronunciation returns the original word when not in dictionary."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
result = manager.get_pronunciation("hello")
|
|
|
|
assert result == "hello"
|
|
|
|
def test_get_pronunciation_returns_replacement_when_found(
|
|
self,
|
|
test_context: CthulhuTestContext,
|
|
) -> None:
|
|
"""Test get_pronunciation returns replacement when word is in dictionary."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
manager.set_pronunciation("hello", "hi there")
|
|
result = manager.get_pronunciation("hello")
|
|
|
|
assert result == "hi there"
|
|
|
|
def test_get_pronunciation_is_case_insensitive(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test get_pronunciation lookup is case insensitive."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
manager.set_pronunciation("HELLO", "hi there")
|
|
|
|
assert manager.get_pronunciation("hello") == "hi there"
|
|
assert manager.get_pronunciation("Hello") == "hi there"
|
|
assert manager.get_pronunciation("HELLO") == "hi there"
|
|
|
|
def test_set_pronunciation_stores_lowercase_key(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test set_pronunciation stores key as lowercase."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
manager.set_pronunciation("MixedCase", "replacement")
|
|
|
|
dictionary = manager.get_dictionary()
|
|
assert "mixedcase" in dictionary
|
|
assert "MixedCase" not in dictionary
|
|
|
|
def test_set_dictionary_replaces_entire_dictionary(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test set_dictionary replaces the entire dictionary."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
|
|
manager.set_pronunciation("old", "old replacement")
|
|
manager.set_dictionary({"new": "new replacement"})
|
|
|
|
dictionary = manager.get_dictionary()
|
|
assert "old" not in dictionary
|
|
assert dictionary.get("new") == "new replacement"
|
|
|
|
def test_multiple_pronunciations(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test manager handles multiple pronunciations correctly."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
manager.set_pronunciation("word1", "replacement1")
|
|
manager.set_pronunciation("word2", "replacement2")
|
|
manager.set_pronunciation("word3", "replacement3")
|
|
|
|
assert manager.get_pronunciation("word1") == "replacement1"
|
|
assert manager.get_pronunciation("word2") == "replacement2"
|
|
assert manager.get_pronunciation("word3") == "replacement3"
|
|
assert len(manager.get_dictionary()) == 3
|
|
|
|
def test_set_pronunciation_overwrites_existing(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test set_pronunciation overwrites existing entry for same word."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
manager.set_pronunciation("word", "first replacement")
|
|
manager.set_pronunciation("word", "second replacement")
|
|
|
|
assert manager.get_pronunciation("word") == "second replacement"
|
|
assert len(manager.get_dictionary()) == 1
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestPronunciationDictionaryManagerIntegration:
|
|
"""Integration tests for pronunciation dictionary manager."""
|
|
|
|
def _setup_manager(self, test_context: CthulhuTestContext):
|
|
"""Set up mocks for pronunciation_dictionary_manager dependencies."""
|
|
|
|
additional_modules = [
|
|
"cthulhu.guilabels",
|
|
"cthulhu.messages",
|
|
"cthulhu.preferences_grid_base",
|
|
"cthulhu.script_manager",
|
|
"cthulhu.speech_manager",
|
|
]
|
|
essential_modules = test_context.setup_shared_dependencies(additional_modules)
|
|
|
|
# Set up guilabels with required constants
|
|
guilabels = essential_modules["cthulhu.guilabels"]
|
|
guilabels.PRONUNCIATION = "Pronunciation"
|
|
guilabels.PRONUNCIATION_DICTIONARY = "Pronunciation Dictionary"
|
|
guilabels.PRONUNCIATION_DICTIONARY_INFO = "Add custom pronunciations."
|
|
guilabels.DICTIONARY_NEW_ENTRY = "New Entry"
|
|
guilabels.DICTIONARY_DELETE = "Delete"
|
|
guilabels.DICTIONARY_EMPTY = "No entries"
|
|
guilabels.DICTIONARY_ACTUAL_STRING = "Actual String"
|
|
guilabels.DICTIONARY_REPLACEMENT_STRING = "Replacement String"
|
|
guilabels.ADD_NEW_PRONUNCIATION = "Add New Pronunciation"
|
|
guilabels.EDIT_PRONUNCIATION = "Edit Pronunciation"
|
|
guilabels.DIALOG_CANCEL = "Cancel"
|
|
guilabels.DIALOG_ADD = "Add"
|
|
guilabels.DIALOG_EDIT = "Edit"
|
|
|
|
# Set up messages
|
|
messages = essential_modules["cthulhu.messages"]
|
|
messages.PRONUNCIATION_DELETED = "Pronunciation %s deleted"
|
|
|
|
# Set up speech_manager
|
|
speech_manager_mock = essential_modules["cthulhu.speech_manager"]
|
|
speech_instance = speech_manager_mock.get_manager.return_value
|
|
speech_instance.get_use_pronunciation_dictionary.return_value = True
|
|
speech_instance.set_use_pronunciation_dictionary.return_value = True
|
|
|
|
# Import and return the module
|
|
from cthulhu import pronunciation_dictionary_manager
|
|
|
|
return pronunciation_dictionary_manager, essential_modules
|
|
|
|
def test_pronunciation_application_to_text(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test that pronunciation dictionary can be used to process text."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
manager.set_pronunciation("github", "git hub")
|
|
manager.set_pronunciation("cli", "command line interface")
|
|
|
|
# Simulate applying pronunciations to a sentence
|
|
words = ["Check", " ", "out", " ", "the", " ", "GitHub", " ", "CLI"]
|
|
result = "".join(map(manager.get_pronunciation, words))
|
|
|
|
# GitHub becomes "git hub" because lookup is case insensitive
|
|
assert "git hub" in result
|
|
# CLI becomes "command line interface"
|
|
assert "command line interface" in result
|
|
|
|
def test_empty_dictionary_returns_original_words(self, test_context: CthulhuTestContext) -> None:
|
|
"""Test that empty dictionary returns all original words unchanged."""
|
|
|
|
module, _mocks = self._setup_manager(test_context)
|
|
manager = module.get_manager()
|
|
manager.set_dictionary({})
|
|
|
|
words = ["Hello", " ", "world", "!"]
|
|
result = "".join(map(manager.get_pronunciation, words))
|
|
|
|
assert result == "Hello world!"
|