Skip to content

Commit

Permalink
Update tests using qtagg for Github actions
Browse files Browse the repository at this point in the history
  • Loading branch information
jrrobison1 committed Jul 27, 2024
1 parent 3e243cd commit 3628b47
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
4 changes: 2 additions & 2 deletions novel_ai_module_tools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
DEFAULT_REPLACEMENTS_FILE_PREFIX = "replaced_"
DEFAULT_STITCHED_PREFIX = "stitched_"
DEFAULT_NER_MODEL = "en_core_web_sm"
DEFAULT_PRIMARY_PATTERN = "\sthis\s"
DEFAULT_SECONDARY_PATTERN = "\sexample\s"
DEFAULT_PRIMARY_PATTERN = r"\sthis\s"
DEFAULT_SECONDARY_PATTERN = r"\sexample\s"
DEFAULT_PRIMARY_SCORE_FIRST_THRESHOLD = 2
DEFAULT_SECONDARY_SCORE_FIRST_THRESHOLD = 15
DEFAULT_PRIMARY_SCORE_SECOND_THRESHOLD = 1
Expand Down
23 changes: 16 additions & 7 deletions novel_ai_module_tools/pick_and_choose.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
import logging
from matplotlib import pyplot
import matplotlib
import os

# Check if running in a headless environment (like GitHub Actions)
if os.environ.get("GITHUB_ACTIONS") or not os.environ.get("DISPLAY"):
matplotlib.use("Agg") # Use the 'Agg' backend for non-GUI environments
else:
matplotlib.use("qt5agg") # Use 'qt5agg' for GUI environments

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QApplication,
Expand All @@ -30,8 +38,6 @@

logger = logging.getLogger(__name__)

matplotlib.use("qt5agg")

WINDOW_TITLE = "Pick and Choose"
WINDOW_GEOMETRY = (100, 100, 800, 600)
TEXT_AREA_MIN_SIZE = (800, 500)
Expand All @@ -42,6 +48,7 @@
TAB_STOP_WIDTH = 30
SECTION_SEPARATOR = "***"


def get_score(text: str, pattern: re.Pattern) -> float:
"""
Compute the score based on the pattern match count per 1000 words.
Expand Down Expand Up @@ -76,7 +83,7 @@ def get_file(filename: str) -> str:
IOError: If there's an error reading the file.
"""
try:
with open(filename, 'r', encoding='utf-8') as f:
with open(filename, "r", encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
logger.error(f"File not found: {filename}")
Expand Down Expand Up @@ -301,12 +308,14 @@ def handle_button_click(self) -> None:
self.update_temp_full_text()

if self.section_index > len(self.sections) - 1:
logger.info(f"End of sections; writing out to file: {self.output_filename}")
logger.info(
f"End of sections; writing out to file: {self.output_filename}"
)
logger.info(f"section_index: [{self.section_index}]")
logger.info(f"len(sections - 1): [{len(self.sections) - 1}]")
# Write file out
try:
with open(self.output_filename, "w", encoding='utf-8') as f:
with open(self.output_filename, "w", encoding="utf-8") as f:
f.write(self.current_full_text)
except IOError as e:
logger.error(f"Error writing to file {self.output_filename}: {e}")
Expand Down Expand Up @@ -406,7 +415,7 @@ def closeEvent(self, event) -> None:
"""
logger.info(f"Closing the application, writing to: {self.output_filename}")
try:
with open(self.output_filename, "w", encoding='utf-8') as f:
with open(self.output_filename, "w", encoding="utf-8") as f:
f.write(self.current_full_text)
except IOError as e:
logger.error(f"Error writing to file {self.output_filename}: {e}")
Expand Down Expand Up @@ -449,4 +458,4 @@ def closeEvent(self, event) -> None:
print(f"An unexpected error occurred: {e}")
logger.error(f"Unexpected error in main: {e}")
logger.error(traceback.format_exc())
sys.exit(1)
sys.exit(1)
44 changes: 40 additions & 4 deletions tests/test_pick_and_choose.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import pytest
import re
from unittest.mock import Mock, mock_open, patch

# Mock matplotlib and PyQt5 before importing the module
with patch.dict("os.environ", {"GITHUB_ACTIONS": "true"}):
with patch("matplotlib.use") as mock_use:
from novel_ai_module_tools.pick_and_choose import (
get_score,
get_file,
MatplotlibCanvas,
MainWindow,
PRIMARY_PATTERN,
SECONDARY_PATTERN,
)

from PyQt5.QtWidgets import QApplication
from matplotlib.figure import Figure
from matplotlib.axes import Axes
Expand All @@ -13,28 +26,34 @@
SECONDARY_PATTERN,
)


# Mock QApplication to avoid creating a real Qt application
@pytest.fixture(scope="module")
def qapp():
return Mock(spec=QApplication)


@pytest.fixture
def sample_text():
return "This is the sample text. The quick brown fox jumps over the lazy dog. Another sentence here."


@pytest.fixture
def primary_pattern():
return re.compile(PRIMARY_PATTERN, re.IGNORECASE)


@pytest.fixture
def secondary_pattern():
return re.compile(SECONDARY_PATTERN, re.IGNORECASE)


def test_get_score(sample_text, primary_pattern, secondary_pattern):
assert get_score(sample_text, primary_pattern) == pytest.approx(176.47, 0.01)
assert get_score(sample_text, secondary_pattern) == pytest.approx(58.82, 0.01)
assert get_score("Short text", primary_pattern) == 0 # Below threshold


def test_get_file():
with patch("builtins.open", mock_open(read_data="Test content")) as mock_file:
assert get_file("test.txt") == "Test content"
Expand All @@ -48,81 +67,98 @@ def test_get_file():
with patch("builtins.open", side_effect=IOError()):
get_file("error.txt")


@pytest.fixture
def matplotlib_canvas(qapp):
with patch("novel_ai_module_tools.pick_and_choose.FigureCanvas"):
return MatplotlibCanvas("Test section")


def test_matplotlib_canvas_init(matplotlib_canvas):
assert isinstance(matplotlib_canvas.fig, Figure)
assert isinstance(matplotlib_canvas.ax, Axes)


def test_matplotlib_canvas_plot(matplotlib_canvas):
with patch.object(matplotlib_canvas, "draw") as mock_draw:
matplotlib_canvas.plot("New section text")
mock_draw.assert_called_once()


def test_matplotlib_canvas_get_paragraph_scores_figure():
fig, ax = MatplotlibCanvas.get_paragraph_scores_figure("Test\nparagraph\ntext")
assert isinstance(fig, Figure)
assert isinstance(ax, Axes)


@pytest.fixture
def main_window(qapp):
sections = ["Section 1", "Section 2"]
current_full_text = "Section 1\n***\nSection 2"
return MainWindow(sections, current_full_text, 1.0, 1.0, "output.txt")


def test_main_window_init(main_window):
assert main_window.sections == ["Section 1", "Section 2"]
assert main_window.current_full_text == "Section 1\n***\nSection 2"
assert main_window.section_index == 0
assert main_window.output_filename == "output.txt"


def test_main_window_get_section_with_tabs(main_window):
assert main_window.get_section_with_tabs() == "\tSection 1"


def test_main_window_update_temp_full_text(main_window):
main_window.update_temp_full_text()
assert main_window.current_full_text == "Section 1\n***\nSection 2\n***\n"


def test_main_window_get_book_primary_score(main_window):
assert isinstance(main_window.get_book_primary_score(), float)


def test_main_window_get_book_secondary_score(main_window):
assert isinstance(main_window.get_book_secondary_score(), float)


def test_main_window_get_section_primary_score(main_window):
assert isinstance(main_window.get_section_primary_score(), float)


def test_main_window_get_section_secondary_score(main_window):
assert isinstance(main_window.get_section_secondary_score(), float)


def test_main_window_on_keep_button_clicked(main_window):
with patch.object(main_window, "handle_button_click") as mock_handle:
main_window.on_keep_button_clicked()
assert main_window.sections[0] == main_window.text_area.toPlainText()
mock_handle.assert_called_once()


def test_main_window_on_trash_button_clicked(main_window):
with patch.object(main_window, "handle_button_click") as mock_handle:
main_window.on_trash_button_clicked()
assert main_window.sections[0] == "***"
mock_handle.assert_called_once()


def test_main_window_handle_button_click(main_window):
with patch.object(main_window, "update_temp_full_text"), \
patch.object(main_window.canvas, "plot"), \
patch.object(main_window.text_area, "setText"):
with patch.object(main_window, "update_temp_full_text"), patch.object(
main_window.canvas, "plot"
), patch.object(main_window.text_area, "setText"):
main_window.handle_button_click()
assert main_window.section_index == 1


def test_main_window_close_event(main_window):
mock_event = Mock()
with patch("builtins.open", mock_open()) as mock_file:
main_window.closeEvent(mock_event)
mock_file.assert_called_once_with("output.txt", "w", encoding="utf-8")
mock_event.accept.assert_called_once()


if __name__ == "__main__":
pytest.main()
pytest.main()

0 comments on commit 3628b47

Please sign in to comment.