---
generated_at: 2026-01-28 15:30:00
metrics:
  claims_total: 143
  claims_with_evidence: 143
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート: wikipedia-readinglist 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim: 主張）を検証しています:

1. **根拠の有無確認**: 各テストケースに対して、ソースコード内の対象メソッド・クラスが実在するか
2. **根拠との整合性**: テストケースの入力値・期待結果がコードの実装と矛盾していないか
3. **網羅性**: 主要なクラス・メソッドを適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」: 根拠あり、「△」: 根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）: **1.00**
  - 根拠あり: 143 / 143、根拠なし: 0
- 優先レビュー（高）
  1. **なし**: 全テストケースに根拠あり
  2. **同期処理関連テスト（UT-RDL-073〜094）**: 複雑な非同期処理のため実装確認推奨
  3. **API連携テスト（UT-RDL-055〜072）**: ネットワーク依存のためモック設計が重要

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙

- E-01: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingList+CoreDataClass.swift`
- E-02: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingList+CoreDataProperties.swift`
- E-03: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListEntry+CoreDataClass.swift`
- E-04: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListEntry+CoreDataProperties.swift`
- E-05: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/ReadingListsController.swift`
- E-06: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListsAPIController.swift`
- E-07: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListsSyncOperation.swift`
- E-08: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListsOperation.swift`
- E-09: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingList+JSON.swift`
- E-10: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListEntry+JSON.swift`
- E-11: `/Users/tomoka.baba/Work/wikipedia-ios-main/WMF Framework/ReadingListAlertType.swift`
- E-12: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/ReadingListsViewController.swift`
- E-13: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/ReadingListDetailViewController.swift`
- E-14: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/ReadingListsFunnel.swift`
- E-15: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/ReadingListsAlertController.swift`
- E-16: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/ReadingListHintController.swift`
- E-17: `/Users/tomoka.baba/Work/wikipedia-ios-main/Wikipedia/Code/CreateReadingListViewController.swift`

## 3) Claims と根拠の対応（レビューの主戦場）

### ReadingList モデル（UT-RDL-001〜017）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | ReadingList.articleKeys が削除されていないエントリのkeyを返す | E-01 (line 12-21) | ○ |
| C-02 | articleKeys が isDeletedLocally=true を除外 | E-01 (line 15-17) | ○ |
| C-03 | articleKeys が空entries時に空配列を返す | E-01 (line 13) | ○ |
| C-04 | articleKeys が nil entries時に空配列を返す | E-01 (line 13) | ○ |
| C-05 | updateArticlesAndEntries が countOfEntries を更新 | E-01 (line 51, 77) | ○ |
| C-06 | updateArticlesAndEntries が previewArticles を4件に制限 | E-01 (line 65-75) | ○ |
| C-07 | updateArticlesAndEntries が画像なし記事を除外 | E-01 (line 70-72) | ○ |
| C-08 | entriesLimitReached 時に通知が発火 | E-01 (line 24-31, 82-84) | ○ |
| C-09 | 削除エントリの記事が articles から除外 | E-01 (line 41-47) | ○ |
| C-10 | name getter が isDefault 時にデフォルト名を返す | E-02 (line 28-30) | ○ |
| C-11 | name getter が通常時に canonicalName を返す | E-02 (line 30) | ○ |
| C-12 | name setter が Unicode 正規化を適用 | E-02 (line 33) | ○ |
| C-13 | APIError が errorCode から生成される | E-02 (line 37-42) | ○ |
| C-14 | APIError が nil errorCode 時に nil を返す | E-02 (line 38) | ○ |
| C-15 | update(with:) が APIReadingList から更新 | E-09 (line 8-33) | ○ |
| C-16 | update(with:) が名前衝突時にアノテーション追加 | E-09 (line 10-17) | ○ |
| C-17 | update(with:) が ISO8601 日付を変換 | E-09 (line 22-27) | ○ |

### ReadingListEntry モデル（UT-RDL-018〜022）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-18 | inMemoryKey が WMFInMemoryURLKey を生成 | E-03 (line 5-10) | ○ |
| C-19 | inMemoryKey が nil articleKey 時に nil を返す | E-03 (line 6-7) | ○ |
| C-20 | APIError が errorCode から生成される | E-03 (line 12-17) | ○ |
| C-21 | update(with:) が APIReadingListEntry から更新 | E-10 (line 4-12) | ○ |
| C-22 | update(with:) が errorCode をクリア | E-10 (line 10) | ○ |

### WMFReadingListsController（UT-RDL-023〜054）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-23 | createReadingList が新規リストを作成 | E-05 (line 159-177) | ○ |
| C-24 | createReadingList が重複時にエラー | E-05 (line 201-204) | ○ |
| C-25 | createReadingList がリスト上限時にエラー | E-05 (line 168-172) | ○ |
| C-26 | listExists が同名リスト存在時に true | E-05 (line 218-225) | ○ |
| C-27 | listExists が存在しない場合に false | E-05 (line 224) | ○ |
| C-28 | listExists が Unicode 正規化後に比較 | E-05 (line 219) | ○ |
| C-29 | updateReadingList が名前と説明を更新 | E-05 (line 227-247) | ○ |
| C-30 | updateReadingList がデフォルトリストを拒否 | E-05 (line 229-232) | ○ |
| C-31 | markLocalDeletion が削除フラグを設定 | E-05 (line 253-259) | ○ |
| C-32 | markLocalDeletion がエントリの削除フラグを設定 | E-05 (line 265-294) | ○ |
| C-33 | markLocalDeletion がリストの updateArticlesAndEntries を呼ぶ | E-05 (line 286-288) | ○ |
| C-34 | delete が markLocalDeletion と sync を実行 | E-05 (line 296-308) | ○ |
| C-35 | add(articles:to:in:) が記事をエントリとして追加 | E-05 (line 356-387) | ○ |
| C-36 | add が既存キーの記事を除外 | E-05 (line 366-368) | ○ |
| C-37 | add が空配列時に何もしない | E-05 (line 357-359) | ○ |
| C-38 | add がエントリ上限時にエラー | E-05 (line 389-398) | ○ |
| C-39 | remove(articles:readingList:) が記事を削除 | E-05 (line 650-659) | ○ |
| C-40 | remove(entries:) が markLocalDeletion と sync を実行 | E-05 (line 661-669) | ○ |
| C-41 | syncState getter が UserDefaults から取得 | E-05 (line 400-405) | ○ |
| C-42 | syncState setter が UserDefaults に保存 | E-05 (line 406-416) | ○ |
| C-43 | isSyncEnabled が needsSync/needsUpdate 時に true | E-05 (line 444-448) | ○ |
| C-44 | isSyncEnabled が両方なしで false | E-05 (line 447) | ○ |
| C-45 | userSave が記事をデフォルトリストに追加 | E-05 (line 675-688) | ○ |
| C-46 | userSave が通知を発火 | E-05 (line 683) | ○ |
| C-47 | userUnsave が全エントリを削除マーク | E-05 (line 690-709) | ○ |
| C-48 | userUnsave が savedVariant なしで処理しない | E-05 (line 694-697) | ○ |
| C-49 | unsave が articleKey 一致の全エントリを削除マーク | E-05 (line 715-725) | ○ |
| C-50 | throwLimitErrorIfNecessary が複合エラーを投げる | E-05 (line 179-198) | ○ |
| C-51 | setSyncEnabled が有効化時に needsRemoteEnable と needsSync を設定 | E-05 (line 558-561) | ○ |
| C-52 | setSyncEnabled が無効化時に needsRemoteDisable を設定 | E-05 (line 563-567) | ○ |
| C-53 | eraseAllSavedArticlesAndReadingLists が同期有効時にリモート無効→有効化を設定 | E-05 (line 518-545) | ○ |
| C-54 | eraseAllSavedArticlesAndReadingLists が同期無効時にローカルクリアを設定 | E-05 (line 532-535) | ○ |

### ReadingListsAPIController（UT-RDL-055〜072）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-55 | setupReadingLists が setup API を呼ぶ | E-06 (line 201-207) | ○ |
| C-56 | teardownReadingLists が teardown API を呼ぶ | E-06 (line 209-215) | ○ |
| C-57 | createList がリスト ID を返す | E-06 (line 227-237) | ○ |
| C-58 | createList が失敗時にエラー | E-06 (line 231-233) | ○ |
| C-59 | createLists がバッチでリスト ID 配列を返す | E-06 (line 247-291) | ○ |
| C-60 | createLists が空配列時に空配列を返す | E-06 (line 248-251) | ○ |
| C-61 | addEntryToList がエントリ ID を返す | E-06 (line 303-336) | ○ |
| C-62 | addEntryToList が重複時に既存 ID を返す | E-06 (line 309-319) | ○ |
| C-63 | addEntriesToList がバッチでエントリ ID 配列を返す | E-06 (line 347-400) | ○ |
| C-64 | removeEntry がエントリを削除 | E-06 (line 411-420) | ○ |
| C-65 | deleteList がリストを削除 | E-06 (line 429-437) | ○ |
| C-66 | deleteList が失敗時にエラー | E-06 (line 431-433) | ○ |
| C-67 | updateList がリストを更新 | E-06 (line 448-456) | ○ |
| C-68 | getAllReadingLists が全リストを取得 | E-06 (line 512-532) | ○ |
| C-69 | getAllReadingLists がページネーションで結合 | E-06 (line 526-528) | ○ |
| C-70 | getAllEntriesForReadingListWithID が全エントリを取得 | E-06 (line 534-553) | ○ |
| C-71 | updatedListsAndEntries が更新を取得 | E-06 (line 472-501) | ○ |
| C-72 | updatedListsAndEntries が 1000 超で needsFullSync | E-06 (line 492-494) | ○ |

### ReadingListsSyncOperation（UT-RDL-073〜093）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-73 | executeSync が needsRemoteDisable 時に teardown を呼ぶ | E-07 (line 71-88) | ○ |
| C-74 | executeSync が needsRemoteEnable 時に setup を呼ぶ | E-07 (line 210-228) | ○ |
| C-75 | executeSync が needsLocalReset 時にローカル ID をクリア | E-07 (line 113-134) | ○ |
| C-76 | executeSync が needsLocalListClear 時にリストを削除マーク | E-07 (line 136-147) | ○ |
| C-77 | executeSync が needsLocalArticleClear 時に記事を削除マーク | E-07 (line 149-160) | ○ |
| C-78 | executeFullSync がリモートリストをローカルに同期 | E-07 (line 254-317) | ○ |
| C-79 | executeFullSync がリモートエントリをローカルに同期 | E-07 (line 299-301) | ○ |
| C-80 | executeUpdate が差分同期を実行 | E-07 (line 319-365) | ○ |
| C-81 | processLocalUpdates がローカル作成リストをリモートに作成 | E-07 (line 543-584) | ○ |
| C-82 | processLocalUpdates がローカル更新リストをリモートに更新 | E-07 (line 526-538) | ○ |
| C-83 | processLocalUpdates がローカル削除リストをリモートから削除 | E-07 (line 513-525) | ○ |
| C-84 | processLocalUpdates がローカル削除エントリをリモートから削除 | E-07 (line 634-657) | ○ |
| C-85 | createOrUpdate(remoteReadingLists:) がリモートリストを作成 | E-07 (line 986-1003) | ○ |
| C-86 | createOrUpdate(remoteReadingLists:) が既存リストを更新 | E-07 (line 971-974) | ○ |
| C-87 | createOrUpdate(remoteReadingLists:) が deleted フラグ付きを削除 | E-07 (line 966-970) | ○ |
| C-88 | createOrUpdate(remoteReadingListEntries:) がリモートエントリを作成 | E-07 (line 1080-1091) | ○ |
| C-89 | createOrUpdate(remoteReadingListEntries:) が deleted フラグ付きを削除 | E-07 (line 1057-1060) | ○ |
| C-90 | locallyCreate がエントリを作成 | E-07 (line 756-912) | ○ |
| C-91 | locallyCreate が記事サマリーをフェッチ | E-07 (line 792-804) | ○ |
| C-92 | split がリストを分割 | E-07 (line 433-477) | ○ |
| C-93 | split が通知を発火 | E-07 (line 472-473) | ○ |

### その他（UT-RDL-094〜143）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-94 | ReadingListSyncState が OptionSet として動作 | E-05 (line 20-41) | ○ |
| C-95 | needsEnable が正しい組み合わせ | E-05 (line 36) | ○ |
| C-96 | ReadingListError.localizedDescription が適切なメッセージ | E-05 (line 56-84) | ○ |
| C-97 | entryLimitReached がパラメータを含む | E-05 (line 73-74) | ○ |
| C-98 | APIReadingListError.localizedDescription が適切なメッセージ | E-06 (line 25-34) | ○ |
| C-99 | APIReadingListEntry.articleURL が URL を生成 | E-06 (line 120-125) | ○ |
| C-100 | APIReadingListEntry.articleKey が databaseKey を返す | E-06 (line 127-129) | ○ |
| C-101 | fetchOrCreateDefaultReadingList が存在しない場合に作成 | E-05 (line 808-821) | ○ |
| C-102 | fetchOrCreateDefaultReadingList が存在する場合に返却 | E-05 (line 810) | ○ |
| C-103 | defaultReadingList が isDefault=true のリストを返す | E-05 (line 823-825) | ○ |
| C-104 | wmf_readingListsConfigMaxEntriesPerList が設定値を返す | E-05 (line 847-858) | ○ |
| C-105 | wmf_readingListsConfigMaxEntriesPerList がデフォルト 5000 | E-05 (line 849) | ○ |
| C-106 | wmf_readingListsConfigMaxListsPerUser が設定値を返す | E-05 (line 861-872) | ○ |
| C-107 | wmf_readingListsConfigMaxListsPerUser がデフォルト 100 | E-05 (line 863) | ○ |
| C-108 | allReadingListsCount が削除されていないリスト数を返す | E-05 (line 875-880) | ○ |
| C-109 | addToDefaultReadingList がエントリを追加 | E-05 (line 729-754) | ○ |
| C-110 | addToDefaultReadingList が既存時に追加しない | E-05 (line 734-736) | ○ |
| C-111 | readingListsDidChange が空時に savedDate=nil | E-05 (line 776-783) | ○ |
| C-112 | readingListsDidChange が追加時に savedDate 設定 | E-05 (line 780-781) | ○ |
| C-113 | isOnlyInDefaultList がデフォルトのみで true | E-05 (line 792-794) | ○ |
| C-114 | isOnlyInDefaultList が複数リストで false | E-05 (line 793) | ○ |
| C-115 | userCreatedReadingListsCount がカスタムリスト数を返す | E-05 (line 800-802) | ○ |
| C-116 | ReadingListAlertType Equatable が同じタイプで true | E-11 (line 9-22) | ○ |
| C-117 | ReadingListAlertType Equatable が異なるタイプで false | E-11 (line 18-19) | ○ |
| C-118 | logArticleSaveInCurrentArticle が save イベントを送信 | E-14 (line 38-40) | ○ |
| C-119 | logArticleUnsaveInCurrentArticle が unsave イベントを送信 | E-14 (line 42-44) | ○ |
| C-120 | logCreateInReadingLists が createList イベントを送信 | E-14 (line 142-144) | ○ |
| C-121 | logDeleteInReadingLists が deleteList イベントを送信 | E-14 (line 138-140) | ○ |
| C-122 | logStartImport が receiveStart イベントを送信 | E-14 (line 158-160) | ○ |
| C-123 | logCompletedImport が receiveFinish イベントを送信 | E-14 (line 166-168) | ○ |
| C-124 | ReadingListHintController.toggle が保存時にヒント表示 | E-16 (line 16-38) | ○ |
| C-125 | ReadingListHintController.toggle が解除時にヒント非表示 | E-16 (line 37) | ○ |
| C-126 | ReadingListHintController.toggle が別記事時にリセット | E-16 (line 29-34) | ○ |
| C-127 | ReadingListsAlertController.showAlert がアラート表示 | E-15 (line 36-44) | ○ |
| C-128 | shouldPresentAlertForArticles がデフォルトのみで false | E-15 (line 46-51) | ○ |
| C-129 | shouldPresentAlertForReadingLists が 0 件で false | E-15 (line 53-58) | ○ |
| C-130 | createReadingListButtonPressed がデリゲートを呼ぶ | E-17 (line 152-158) | ○ |
| C-131 | createReadingListButtonPressed が空名前で処理しない | E-17 (line 153-155) | ○ |
| C-132 | handleReadingListNameError がエラー表示 | E-17 (line 134-139) | ○ |
| C-133 | articlesFromEncodedPageIds が記事を取得 | E-17 (line 277-301) | ○ |
| C-134 | articlesFromEncodedPageIds がデコード失敗でエラー | E-17 (line 279-281) | ○ |
| C-135 | decodedReadingListFromEncodedPageIds がデコード | E-17 (line 303-310) | ○ |
| C-136 | ImportedReadingList が Codable | E-17 (line 5-9) | ○ |
| C-137 | ReadingListsViewController.createReadingList が VC を present | E-12 (line 189-199) | ○ |
| C-138 | didSelectItemAt が addArticlesToReadingList モードで記事追加 | E-12 (line 306-311) | ○ |
| C-139 | didSelectItemAt が readingListsTab モードで詳細遷移 | E-12 (line 315-318) | ○ |
| C-140 | deleteReadingLists が controller.delete を呼ぶ | E-12 (line 456-469) | ○ |
| C-141 | readingListDetailHeaderView didEdit がリスト更新 | E-13 (line 229-232) | ○ |
| C-142 | showImportSharedReadingListSurveyPromptIfNeeded がプロンプト表示 | E-13 (line 376-418) | ○ |
| C-143 | showImportSharedReadingListSurveyPromptIfNeeded がタップ済みで表示しない | E-13 (line 382-384) | ○ |

## 4) 不足情報（Unknown / Missing）
- なし: 全テストケースがソースコードの実装に基づいている

## 5) リスクフラグ（レビュー観点）
- **0 (低リスク)**: モデルクラスのプロパティ・アクセサテスト（UT-RDL-001〜022）
- **0 (低リスク)**: 分析イベントテスト（UT-RDL-118〜123）
- **1 (中リスク)**: API連携テスト（UT-RDL-055〜072）- ネットワークモックが必要
- **1 (中リスク)**: UI関連テスト（UT-RDL-124〜143）- UIテスト環境が必要
- **2 (高リスク)**: 同期処理テスト（UT-RDL-073〜093）- 複雑な非同期処理、CoreDataコンテキスト管理

## 6) レビュアーチェックリスト（最小）
- [ ] ReadingList.updateArticlesAndEntries のエントリ上限通知ロジックが正しく検証されているか
- [ ] WMFReadingListsController のスレッド安全性（assert(Thread.isMainThread)）がテストで考慮されているか
- [ ] ReadingListsSyncOperation の isCancelled チェックが適切にテストされているか
- [ ] API エラーハンドリング（APIReadingListError の各ケース）が網羅されているか
- [ ] CoreData の NSManagedObjectContext 操作が適切にモックされるか確認
- [ ] Unicode 正規化（precomposedStringWithCanonicalMapping）のテストデータが適切か
