Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 4 additions & 61 deletions docs/agents/TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,7 @@

未完了タスクは [ ]、完了タスクは [x]

## 目的

テストカバレッジ向上のため、優先施策に基づき段階的にテストを追加する。

## フェーズ 0: 準備

- [x] 既存テスト構成・命名規則の確認(tests を階層化し日本語命名方針)
- [x] 既存のテストユーティリティ/fixture の再利用可否を整理(conftest: COM/Render 判定)
- [x] 追加対象の関数・分岐を一覧化(coverage.xml の低カバレッジ)

## フェーズ 1: 純粋関数/ユーティリティ(高優先)

- [x] core/shapes.py: \_should_include_shape の分岐テスト(standard/light/verbose)
- [x] core/shapes.py: compute_line_angle_deg, angle_to_compass, has_arrow の境界値テスト
- [x] core/cells.py: \_coerce_numeric_preserve_format の入力パターンテスト
- [x] core/backends/com_backend.py: \_split_csv_respecting_quotes の引用符対応テスト
- [x] core/backends/com_backend.py: \_normalize_area_for_sheet の補正ロジックテスト

## フェーズ 2: パース/分岐ロジック(高優先)

- [x] core/charts.py: parse_series_formula の正常系パターン(カンマ/セミコロン区切り)
- [x] core/charts.py: parse_series_formula の異常系(空/非 SERIES)
- [x] core/pipeline.py: COM 不可時のフォールバック分岐(openpyxl 経由の結果検証)
- [x] core/pipeline.py: COM 失敗時のフォールバック分岐(例外誘発の分岐確認)
- [x] core/pipeline.py: include_auto_page_breaks フラグの計画分岐

## フェーズ 3: バックエンド/検出ロジック(中優先)

- [x] core/cells.py: detect_tables の .xlsx / .xls 分岐(openpyxl/COM の呼び分け)
- [x] core/backends/openpyxl_backend.py: extract_print_areas 複数範囲の処理
- [x] core/backends/openpyxl_backend.py: extract_colors_map の例外時 None 返却
- [x] core/backends/com_backend.py: extract_print_areas の例外処理分岐

## フェーズ 4: 疑似 COM オブジェクトでの網羅(中優先)

- [x] core/shapes.py: get_shapes_with_position のフィルタリング動作(ダミー shape)
- [x] core/charts.py: get_charts の Chart/Series 生成(ダミー chart)
- [x] core/backends/com_backend.py: extract_auto_page_breaks の失敗分岐

## フェーズ 5: 統合テスト(低優先)

- [x] 既存の openpyxl 作成テストの延長(簡易 workbook の抽出/エクスポート)
- [x] CLI/Engine の最小 E2E(JSON 生成の基本構造のみ検証)

## 追加カバレッジ強化: cells.py / workbook.py

### cells.py(低カバレッジ重点)

- [x] \_normalize_color_key / \_normalize_rgb の正規化パターン(#/ARGB/auto/theme/indexed)
- [x] \_normalize_ignore_colors の空/重複/不正キーの除外
- [x] \_resolve_cell_background / \_resolve_fill_color_key の既定背景/None/パターン種別分岐
- [x] \_color_to_key の theme/indexed/auto 分岐(openpyxl Color 風ダミー)
- [x] \_header_like_row / \_table_signal_score / \_count_nonempty_cells の境界ケース
- [x] \_collect_table_candidates_from_values の検出閾値と空入力(min_nonempty_cells)

### workbook.py(低カバレッジ重点)

- [x] openpyxl_workbook の close 失敗時の例外抑制(close が例外でも継続)
- [x] xlwings_workbook の既存ブック検出経路(\_find_open_workbook が返す場合)
- [x] \_find_open_workbook の fullname 例外・resolve 例外のハンドリング
- [x] \_find_open_workbook の全体例外時に None を返す経路
- [x] src/exstruct/render/__init__.py の主要分岐と例外経路を洗い出す(_require_excel_app/_require_pdfium/export_pdf/export_sheet_images/_sanitize_sheet_filename)
- [x] xlwings・pypdfium2 をモックして export_pdf/export_sheet_images の成功/失敗ケースを単体テスト化する
- [x] 依存不足・予期例外のエラーメッセージ/例外型を検証するテストを追加する
- [x] シート名のサニタイズ規則と出力ファイル名生成のテストを追加する
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ markers = [
ruff = "ruff check ."
ruff-fix = "ruff check . --fix"
mypy = "mypy src/exstruct --strict"
test = "pytest -vv --cov=exstruct --cov-report=term-missing --cov-report=xml"
test = "pytest -vv --cov=exstruct --cov-report=term-missing --cov-report=xml" # uv sync --extra render --extra toon
test-unit = "pytest -vv -m \"not com and not render\" --cov=exstruct --cov-report=term-missing --cov-report=xml"
test-com = "pytest -vv -m \"com\" --cov=exstruct --cov-report=term-missing --cov-report=xml"
codecov-unit = "codecov-cli upload-process -f coverage.xml -F unit -C %CODECOV_SHA% -t %CODECOV_TOKEN%"
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ def _render_skip_reason() -> str | None:

def pytest_runtest_setup(item: pytest.Item) -> None:
"""Skip tests based on resource markers and environment availability."""
if "render" in item.keywords:
if item.get_closest_marker("render") is not None:
reason = _render_skip_reason()
if reason:
pytest.skip(reason)
return
if "com" in item.keywords:
if item.get_closest_marker("com") is not None:
reason = _com_skip_reason()
if reason:
pytest.skip(reason)
Loading
Loading