219 lines
6.4 KiB
Python
219 lines
6.4 KiB
Python
from pathlib import Path
|
|
|
|
from extract_and_rename import (
|
|
check_dependencies,
|
|
check_external_tools,
|
|
run_queue,
|
|
select_template_file,
|
|
)
|
|
|
|
|
|
def test_select_template_file_picks_first_by_name(tmp_path):
|
|
(tmp_path / "b_template.png").write_bytes(b"x")
|
|
(tmp_path / "a_template.png").write_bytes(b"x")
|
|
(tmp_path / "note.txt").write_bytes(b"x") # 対象外拡張子
|
|
|
|
result = select_template_file(tmp_path)
|
|
|
|
assert result == tmp_path / "a_template.png"
|
|
|
|
|
|
def test_select_template_file_no_candidates_raises(tmp_path):
|
|
(tmp_path / "note.txt").write_bytes(b"x")
|
|
|
|
try:
|
|
select_template_file(tmp_path)
|
|
assert False, "FileNotFoundErrorが送出されるべき"
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
|
|
def test_check_dependencies_detects_missing_module():
|
|
result = check_dependencies(("this_module_does_not_exist_xyz",))
|
|
assert result == ["this_module_does_not_exist_xyz"]
|
|
|
|
|
|
def test_check_dependencies_detects_installed_module():
|
|
result = check_dependencies(("os",))
|
|
assert result == []
|
|
|
|
|
|
def test_check_external_tools_detects_missing(tmp_path):
|
|
tesseract = tmp_path / "tools" / "tesseract" / "tesseract.exe"
|
|
poppler = tmp_path / "tools" / "poppler" / "pdftoppm.exe"
|
|
|
|
result = check_external_tools(tesseract, poppler)
|
|
|
|
assert str(tesseract) in result
|
|
assert str(poppler) in result
|
|
|
|
|
|
def test_check_external_tools_all_present(tmp_path):
|
|
tesseract = tmp_path / "tesseract.exe"
|
|
poppler = tmp_path / "pdftoppm.exe"
|
|
tesseract.write_bytes(b"x")
|
|
poppler.write_bytes(b"x")
|
|
|
|
result = check_external_tools(tesseract, poppler)
|
|
|
|
assert result == []
|
|
|
|
|
|
def _make_dirs(tmp_path):
|
|
dirs = {
|
|
"scan": tmp_path / "スキャン",
|
|
"output": tmp_path / "アウトプット",
|
|
"success": tmp_path / "成功",
|
|
"failed": tmp_path / "失敗",
|
|
"log": tmp_path / "ログ",
|
|
}
|
|
dirs["scan"].mkdir()
|
|
return dirs
|
|
|
|
|
|
def test_run_queue_success_moves_and_copies(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
pdf = dirs["scan"] / "scan001.pdf"
|
|
pdf.write_bytes(b"dummy")
|
|
|
|
def fake_process_pdf(path, boxes, margin):
|
|
return ("氏名A", "20260802")
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=fake_process_pdf,
|
|
key_check=lambda: False,
|
|
sleep_func=lambda s: None,
|
|
)
|
|
|
|
assert (dirs["output"] / "氏名A" / "氏名A_20260802.pdf").exists()
|
|
assert (dirs["success"] / "scan001.pdf").exists()
|
|
assert not pdf.exists()
|
|
|
|
from datetime import datetime
|
|
log_content = (dirs["log"] / f"{datetime.now().strftime('%Y-%m-%d')}.log").read_text(encoding="utf-8-sig")
|
|
assert "結果=成功" in log_content
|
|
|
|
|
|
def test_run_queue_missing_name_moves_to_failed(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
pdf = dirs["scan"] / "scan002.pdf"
|
|
pdf.write_bytes(b"dummy")
|
|
|
|
def fake_process_pdf(path, boxes, margin):
|
|
return (None, "20260802")
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=fake_process_pdf,
|
|
key_check=lambda: False,
|
|
sleep_func=lambda s: None,
|
|
)
|
|
|
|
assert (dirs["failed"] / "scan002.pdf").exists()
|
|
assert not pdf.exists()
|
|
|
|
|
|
def test_run_queue_exception_moves_to_failed(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
pdf = dirs["scan"] / "scan003.pdf"
|
|
pdf.write_bytes(b"dummy")
|
|
|
|
def fake_process_pdf(path, boxes, margin):
|
|
raise RuntimeError("OCRエラー")
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=fake_process_pdf,
|
|
key_check=lambda: False,
|
|
sleep_func=lambda s: None,
|
|
)
|
|
|
|
assert (dirs["failed"] / "scan003.pdf").exists()
|
|
|
|
|
|
def test_run_queue_stops_on_key_press(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
pdf = dirs["scan"] / "scan004.pdf"
|
|
pdf.write_bytes(b"dummy")
|
|
|
|
calls = []
|
|
|
|
def fake_process_pdf(path, boxes, margin):
|
|
calls.append(path)
|
|
return ("氏名A", "20260802")
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=fake_process_pdf,
|
|
key_check=lambda: True, # 常に押下扱い
|
|
sleep_func=lambda s: None,
|
|
)
|
|
|
|
assert calls == []
|
|
assert pdf.exists() # 処理されず残る
|
|
|
|
|
|
def test_run_queue_skips_file_deleted_before_processing(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
pdf = dirs["scan"] / "scan005.pdf"
|
|
pdf.write_bytes(b"dummy")
|
|
|
|
calls = []
|
|
|
|
def fake_process_pdf(path, boxes, margin):
|
|
calls.append(path)
|
|
return ("氏名A", "20260802")
|
|
|
|
def key_check_and_delete():
|
|
if pdf.exists():
|
|
pdf.unlink()
|
|
return False
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=fake_process_pdf,
|
|
key_check=key_check_and_delete,
|
|
sleep_func=lambda s: None,
|
|
)
|
|
|
|
assert calls == []
|
|
|
|
|
|
def test_run_queue_empty_scan_dir_returns_immediately(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=lambda p, b, m: ("氏名A", "20260802"),
|
|
key_check=lambda: False,
|
|
sleep_func=lambda s: None,
|
|
)
|
|
# 例外が出ずに戻ることのみ確認
|
|
|
|
|
|
def test_run_queue_name_collision_gets_suffix(tmp_path):
|
|
dirs = _make_dirs(tmp_path)
|
|
existing_output_dir = dirs["output"] / "氏名A"
|
|
existing_output_dir.mkdir(parents=True)
|
|
(existing_output_dir / "氏名A_20260802.pdf").write_bytes(b"old")
|
|
|
|
pdf = dirs["scan"] / "scan006.pdf"
|
|
pdf.write_bytes(b"dummy")
|
|
|
|
run_queue(
|
|
dirs["scan"], dirs["output"], dirs["success"], dirs["failed"], dirs["log"],
|
|
boxes=[], margin=0.1, stable_wait_sec=0, stable_retries=1,
|
|
process_pdf_func=lambda p, b, m: ("氏名A", "20260802"),
|
|
key_check=lambda: False,
|
|
sleep_func=lambda s: None,
|
|
)
|
|
|
|
assert (existing_output_dir / "氏名A_20260802(2).pdf").exists()
|