-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,3 +24,6 @@ pywin32==303 | |
six==1.16.0 | ||
tzdata==2024.2 | ||
wincertstore==0.2 | ||
pytest | ||
pytest-mock | ||
pytest-cov |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
import pytest | ||
from unittest.mock import Mock, patch | ||
import os | ||
import pandas as pd | ||
import fitz | ||
import tempfile | ||
import shutil | ||
from src.pdf_util import PDFUtility | ||
from src.pdf_compiler import PDFCompiler | ||
|
||
|
||
@pytest.fixture | ||
def mock_gui(): | ||
"""Fixture to provide a mock GUI instance""" | ||
gui = Mock() | ||
gui.entry_var1 = Mock(get=Mock(return_value="/test/path")) | ||
gui.entry_var2 = Mock(get=Mock(return_value="/test/metadata.csv")) | ||
gui.entry_var5 = Mock(get=Mock(return_value="test_password")) | ||
gui.final_run_var = Mock(get=Mock(return_value=False)) | ||
gui.logger = Mock() | ||
return gui | ||
|
||
|
||
@pytest.fixture | ||
def pdf_util(mock_gui): | ||
"""Fixture to provide a PDFUtility instance""" | ||
return PDFUtility(mock_gui) | ||
|
||
|
||
@pytest.fixture | ||
def test_dir(): | ||
"""Fixture to provide a temporary directory""" | ||
temp_dir = tempfile.mkdtemp() | ||
yield temp_dir | ||
shutil.rmtree(temp_dir, ignore_errors=True) | ||
|
||
|
||
@pytest.fixture | ||
def test_files(test_dir): | ||
"""Fixture to create and provide test files""" | ||
# Create test PDF | ||
pdf_path = os.path.join(test_dir, "test.pdf") | ||
doc = fitz.open() | ||
page = doc.new_page() | ||
page.insert_text((50, 50), "Test PDF") | ||
doc.save(pdf_path) | ||
doc.close() | ||
|
||
# Create test RTF | ||
rtf_path = os.path.join(test_dir, "test.rtf") | ||
with open(rtf_path, "w") as f: | ||
f.write(r"{\rtf1\ansi\Test RTF}") | ||
|
||
# Create test metadata CSV | ||
csv_path = os.path.join(test_dir, "test_metadata.csv") | ||
test_data = { | ||
'TLF': ['F', 'F'], | ||
'Title3': ['Test1', 'Test2'], | ||
'Title4': ['Description1', 'Description2'], | ||
'Title5': ['Pop1', 'Pop2'], | ||
'ProgName': ['prog1', 'prog2'], | ||
'Seq': [1, 2], | ||
'OutputName': ['F_14.1', 'F_14.2'], | ||
'Order': [1, 2] | ||
} | ||
pd.DataFrame(test_data).to_csv(csv_path, index=False) | ||
|
||
return pdf_path, rtf_path, csv_path | ||
|
||
|
||
class TestPDFUtility: | ||
def test_meta_data_to_dict(self, test_dir): | ||
"""Test metadata parsing with and without population""" | ||
test_data = { | ||
'Title3': ['Figure 1', 'Table 2'], | ||
'Title4': ['Description 1', 'Description 2'], | ||
'Title5': ['Population 1', 'Population 2'] | ||
} | ||
test_df = pd.DataFrame(test_data) | ||
csv_path = os.path.join(test_dir, 'test_metadata.csv') | ||
test_df.to_csv(csv_path, index=False) | ||
|
||
# Test with population included | ||
result = PDFUtility.meta_data_to_dict(csv_path, title_sep="-", add_popul=True) | ||
assert len(result) == 2 | ||
assert all(isinstance(k, str) for k in result.keys()) | ||
assert all(isinstance(v, str) for v in result.values()) | ||
assert any('Population' in v for v in result.values()) | ||
|
||
# Test without population | ||
result = PDFUtility.meta_data_to_dict(csv_path, title_sep="-", add_popul=False) | ||
assert len(result) == 2 | ||
assert not any('Population' in v for v in result.values()) | ||
|
||
def test_get_tlf_list(self, test_files): | ||
"""Test TLF list extraction from metadata""" | ||
_, _, csv_path = test_files | ||
files, count = PDFUtility.get_tlf_list(csv_path) | ||
|
||
assert count == 2 | ||
assert len(files) == 2 | ||
assert all(f.endswith('.rtf') for f in files) | ||
assert all('F_' in f for f in files) | ||
|
||
def test_combine_pdfs_simple(self, pdf_util, test_dir): | ||
"""Test PDF combination without TOC""" | ||
# Create test PDFs | ||
test_pdfs = [] | ||
for i in range(2): | ||
pdf_path = os.path.join(test_dir, f'test{i}.pdf') | ||
doc = fitz.open() | ||
page = doc.new_page() | ||
page.insert_text((50, 50), f"Test PDF {i}") | ||
doc.save(pdf_path) | ||
doc.close() | ||
test_pdfs.append(pdf_path) | ||
|
||
# Test without password | ||
output_path = os.path.join(test_dir, 'combined.pdf') | ||
result = pdf_util.combine_pdfs_simple( | ||
test_pdfs, | ||
output_path, | ||
use_password=False | ||
) | ||
|
||
assert result is True | ||
assert os.path.exists(output_path) | ||
|
||
with fitz.open(output_path) as doc: | ||
assert doc.page_count == 2 | ||
|
||
# Test with password protection | ||
output_path_protected = os.path.join(test_dir, 'combined_protected.pdf') | ||
result = pdf_util.combine_pdfs_simple( | ||
test_pdfs, | ||
output_path_protected, | ||
use_password=True, | ||
password="test_password" | ||
) | ||
|
||
assert result is True | ||
assert os.path.exists(output_path_protected) | ||
|
||
@pytest.mark.parametrize("file_count", [1, 5, 10]) | ||
def test_combine_multiple_pdfs(self, pdf_util, test_dir, file_count): | ||
"""Test combining different numbers of PDFs""" | ||
test_pdfs = [] | ||
for i in range(file_count): | ||
pdf_path = os.path.join(test_dir, f'test{i}.pdf') | ||
doc = fitz.open() | ||
page = doc.new_page() | ||
page.insert_text((50, 50), f"Test PDF {i}") | ||
doc.save(pdf_path) | ||
doc.close() | ||
test_pdfs.append(pdf_path) | ||
|
||
output_path = os.path.join(test_dir, 'combined.pdf') | ||
result = pdf_util.combine_pdfs_simple(test_pdfs, output_path) | ||
|
||
assert result is True | ||
with fitz.open(output_path) as doc: | ||
assert doc.page_count == file_count | ||
|
||
|
||
class TestPDFCompiler: | ||
@pytest.fixture | ||
def pdf_compiler(self, mock_gui): | ||
"""Fixture to provide a PDFCompiler instance""" | ||
util_mock = Mock() | ||
return PDFCompiler(mock_gui, util_mock) | ||
|
||
def test_get_toc_page_numb(self, test_dir): | ||
"""Test TOC page number extraction""" | ||
pdf_path = os.path.join(test_dir, 'test_toc.pdf') | ||
doc = fitz.open() | ||
for i in range(3): | ||
page = doc.new_page() | ||
page.insert_text((50, 50), f"Test Page {i}") | ||
doc.save(pdf_path) | ||
doc.close() | ||
|
||
page_count = PDFCompiler.get_toc_page_numb(pdf_path) | ||
assert page_count == 3 | ||
|
||
def test_update_toc_pages(self, test_dir): | ||
"""Test TOC page number updating""" | ||
test_content = ( | ||
"Title 1 *page:1\n" | ||
"Title 2 *page:2\n" | ||
"Title 3 *page:3\n" | ||
) | ||
|
||
input_file = os.path.join(test_dir, 'test_toc.txt') | ||
with open(input_file, 'w', encoding='latin-1') as f: | ||
f.write(test_content) | ||
|
||
updated_content = PDFCompiler.update_toc_pages( | ||
input_file=input_file, | ||
page_char="*page:", | ||
w_page=50, | ||
page_numb_to_add=2 | ||
) | ||
|
||
assert "*page:3" in updated_content | ||
assert "*page:4" in updated_content | ||
assert "*page:5" in updated_content | ||
|
||
@pytest.mark.parametrize("page_width,expected", [ | ||
(50, True), # Normal width | ||
(10, True), # Very narrow | ||
(200, True) # Very wide | ||
]) | ||
def test_update_toc_pages_different_widths(self, test_dir, page_width, expected): | ||
"""Test TOC page updating with different page widths""" | ||
test_content = "Title 1 *page:1\n" | ||
input_file = os.path.join(test_dir, 'test_toc.txt') | ||
with open(input_file, 'w', encoding='latin-1') as f: | ||
f.write(test_content) | ||
|
||
updated_content = PDFCompiler.update_toc_pages( | ||
input_file=input_file, | ||
page_char="*page:", | ||
w_page=page_width, | ||
page_numb_to_add=1 | ||
) | ||
|
||
assert bool(updated_content) is expected | ||
|
||
@pytest.mark.parametrize("test_input,expected", [ | ||
("normal.pdf", True), | ||
("missing.pdf", False) | ||
]) | ||
def test_file_existence_handling(self, test_dir, test_input, expected): | ||
"""Test handling of different file inputs""" | ||
if expected: | ||
# Create test file if it should exist | ||
pdf_path = os.path.join(test_dir, test_input) | ||
doc = fitz.open() | ||
doc.new_page() | ||
doc.save(pdf_path) | ||
doc.close() | ||
|
||
assert os.path.exists(os.path.join(test_dir, test_input)) == expected | ||
|
||
|
||
if __name__ == '__main__': | ||
pytest.main(['-v']) |