---
generated_at: 2026-02-03 10:00:00
metrics:
  claims_total: 60
  claims_with_evidence: 57
  claims_without_evidence: 3
confidence_derived: 0.95
---

# 根拠レポート：plugins-analysis-phonenumber 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された設計書・ドキュメントの信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

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

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.95**
  - 根拠あり：57 / 60、根拠なし：3
- 優先レビュー（高）
  1. **C-47 (入力が+のみの場合)**: ソースコードの境界処理が明示されていないため推測による
  2. **C-48 (tel:プレフィックスのみの入力)**: 空文字列に対するPhoneNumberUtil.parseの挙動が未確認
  3. **C-50 (@のみを含むsip入力)**: @の前が空の場合のsubstringの動作を推測

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `plugins/analysis-phonenumber/src/main/java/org/opensearch/analysis/phone/PhoneNumberAnalyzer.java` - Analyzerクラス定義（コンストラクタ、createComponents）
- E-02: `plugins/analysis-phonenumber/src/main/java/org/opensearch/analysis/phone/PhoneNumberAnalyzerProvider.java` - AnalyzerProviderクラス定義（コンストラクタ、get）
- E-03: `plugins/analysis-phonenumber/src/main/java/org/opensearch/analysis/phone/PhoneNumberAnalysisPlugin.java` - Pluginクラス定義（getAnalyzers、getTokenizers）
- E-04: `plugins/analysis-phonenumber/src/main/java/org/opensearch/analysis/phone/PhoneNumberTermTokenizer.java` - Tokenizerクラス定義（コンストラクタ、reset、incrementToken、getTokens）
- E-05: `plugins/analysis-phonenumber/src/main/java/org/opensearch/analysis/phone/PhoneNumberTermTokenizerFactory.java` - TokenizerFactoryクラス定義（コンストラクタ、create）
- E-06: `plugins/analysis-phonenumber/src/test/java/org/opensearch/analysis/phone/PhoneNumberAnalyzerTests.java` - 既存テストクラス（各種電話番号フォーマットのテスト）

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | addNgrams=trueでPhoneNumberAnalyzerインスタンスが正常に生成される | E-01 | ○ |
| C-02 | addNgrams=falseでPhoneNumberAnalyzerインスタンスが正常に生成される | E-01 | ○ |
| C-03 | createComponentsがTokenStreamComponentsを正しく生成する | E-01 | ○ |
| C-04 | TokenStreamComponentsのsourceとresultが同一インスタンスである | E-01 (L49: `new Analyzer.TokenStreamComponents(tokenizer, tokenizer)`) | ○ |
| C-05 | addNgrams=trueでPhoneNumberAnalyzerProviderが正常に生成される | E-02 | ○ |
| C-06 | addNgrams=falseでPhoneNumberAnalyzerProviderが正常に生成される | E-02 | ○ |
| C-07 | get()がPhoneNumberAnalyzerインスタンスを返却する | E-02 (L39-41) | ○ |
| C-08 | get()が毎回同じインスタンスを返却する | E-02 (L21: `private final PhoneNumberAnalyzer analyzer`) | ○ |
| C-09 | getAnalyzers()に"phone"キーが含まれる | E-03 (L31) | ○ |
| C-10 | getAnalyzers()に"phone-search"キーが含まれる | E-03 (L34-37) | ○ |
| C-11 | getAnalyzers()が2つのエントリを返す | E-03 (L29-38) | ○ |
| C-12 | phoneアナライザのaddNgramsがtrue | E-03 (L32: `true`) | ○ |
| C-13 | phone-searchアナライザのaddNgramsがfalse | E-03 (L36: `false`) | ○ |
| C-14 | getTokenizers()に"phone"キーが含まれる | E-03 (L44-47) | ○ |
| C-15 | getTokenizers()に"phone-search"キーが含まれる | E-03 (L48-56) | ○ |
| C-16 | getTokenizers()が2つのエントリを返す | E-03 (L43-57) | ○ |
| C-17 | PhoneNumberTermTokenizerFactoryが正常に生成される | E-05 | ○ |
| C-18 | create()がPhoneNumberTermTokenizerを返却する | E-05 (L41-43) | ○ |
| C-19 | create()が呼び出しごとに新しいインスタンスを返す | E-05 (L42: `new PhoneNumberTermTokenizer(...)`) | ○ |
| C-20 | PhoneNumberTermTokenizerが正常に生成される | E-04 (L54-58) | ○ |
| C-21 | reset後にtokenIteratorがnullになる | E-04 (L63-64) | ○ |
| C-22 | tel:+441344840400が正しくトークン化される | E-04, E-06 (testEuropeDetailled) | ○ |
| C-23 | 検索モードでtel:+441344840400が正しくトークン化される | E-04, E-06 (testEuropeDetailledSearch) | ○ |
| C-24 | ドイツの電話番号が正しくトークン化される | E-04, E-06 (testGermanCastle) | ○ |
| C-25 | オーストラリアの電話番号が正しくトークン化される | E-04, E-06 (testBMWofSydney) | ○ |
| C-26 | アイルランドの電話番号が正しくトークン化される | E-04, E-06 (testCoffeeShopInIreland) | ○ |
| C-27 | 米国の電話番号が正しくトークン化される | E-04, E-06 (testTelWithCountryCode) | ○ |
| C-28 | 米国トールフリー番号が正しくトークン化される | E-04, E-06 (testNewTollFreeNumber) | ○ |
| C-29 | sip数値ユーザー名が正しくトークン化される | E-04, E-06 (testSipWithNumericUsername) | ○ |
| C-30 | sipアルファベットユーザー名が正しくトークン化される | E-04, E-06 (testSipWithAlphabeticUsername) | ○ |
| C-31 | sip国際番号が正しくトークン化される | E-04, E-06 (testSipWithCountryCode) | ○ |
| C-32 | sip内線番号付き番号が正しくトークン化される | E-04, E-06 (testSipWithTelephoneExtension) | ○ |
| C-33 | sipユーザー名が正しくトークン化される | E-04, E-06 (testSipWithUsername) | ○ |
| C-34 | +プレフィックスのみの電話番号が正しくトークン化される | E-04, E-06 (testPhoneNumberWithoutPrefix) | ○ |
| C-35 | 国コードなしの電話番号がトークン化される | E-04, E-06 (testMissingCountryCode) | ○ |
| C-36 | 短縮番号がトークン化される | E-04, E-06 (testTruncatedNumber) | ○ |
| C-37 | telプレフィックスが独立トークンとして生成される | E-04 (L101-103), E-06 (testTelPrefix) | ○ |
| C-38 | phone-region=CHでスイス国際番号が正しくトークン化される | E-04 (L126), E-06 (testInternationalPrefixWithCH) | ○ |
| C-39 | phone-region=CHで00プレフィックス番号が正しくトークン化される | E-04, E-06 (testNationalPrefixWithCH) | ○ |
| C-40 | phone-region=CHでローカル番号が正しくトークン化される | E-04, E-06 (testLocalNumberWithCH) | ○ |
| C-41 | 検索モードでCHスイス国際番号が正しくトークン化される | E-04, E-06 (testSearchInternationalPrefixWithCH) | ○ |
| C-42 | 検索モードでCHローカル番号が正しくトークン化される | E-04, E-06 (testSearchLocalNumberWithCH) | ○ |
| C-43 | sipドメインなし番号が正しくトークン化される | E-04, E-06 (testSipWithoutDomainPart) | ○ |
| C-44 | 非電話番号文字列でもトークンが生成される | E-04 (L97, L151-153), E-06 (testGarbageInGarbageOut) | ○ |
| C-45 | 空文字列入力のハンドリング | E-04 (L97: `tokens.add(input)`) | ○ |
| C-46 | 不正な電話番号形式でNumberParseExceptionが適切に処理される | E-04 (L151: `catch (NumberParseException | StringIndexOutOfBoundsException)`) | ○ |
| C-47 | 入力が+のみの場合の処理 | **根拠なし** | △ |
| C-48 | tel:プレフィックスのみの入力の処理 | **根拠なし** | △ |
| C-49 | sip:プレフィックスのみの入力の処理 | E-04 (L100-105) | ○ |
| C-50 | @のみを含むsip入力の処理 | **根拠なし** | △ |
| C-51 | 1桁の電話番号のトークン化 | E-04 (L156-163) | ○ |
| C-52 | 非常に長い電話番号のトークン化 | E-04 (L151-153) | ○ |
| C-53 | ngramが正しく生成される（1桁から全桁まで） | E-04 (L156-163), E-06 (testNumberPrefix) | ○ |
| C-54 | 国コード付きngramが正しく生成される | E-04 (L161: `countryCode.ifPresent(s -> tokens.add(s + token))`) | ○ |
| C-55 | 検索モードではngramが生成されない | E-04 (L156: `if (this.addNgrams && ...)`) | ○ |
| C-56 | 検索モードではtelプレフィックスが独立トークンとして生成されない | E-04 (L101: `if (addNgrams)`), E-06 (testTelPrefixSearch) | ○ |
| C-57 | 検索モードでは国コードが独立トークンとして生成されない | E-04 (L136-148: `if (addNgrams)`) | ○ |
| C-58 | 重複トークンが排除される（HashSet使用） | E-04 (L93: `new HashSet<String>()`) | ○ |
| C-59 | reset後に再度incrementTokenで新しい入力が処理される | E-04 (L62-65, L69-79) | ○ |
| C-60 | 全トークン返却後にincrementTokenがfalseを返す | E-04 (L74-78) | ○ |

## 4) 不足情報（Unknown / Missing）
- C-47: `+`のみが入力された場合、`input.startsWith("+")` は true となり `startIndex=1` で `input.substring(1)` が空文字列となる。PhoneNumberUtil.parseに空文字列が渡された場合の挙動はlibphonenumberの実装に依存するため、実際のテスト実行による確認が必要。
  - 候補：libphonenumberのドキュメント / PhoneNumberUtil.parseのソースコード
- C-48: `tel:`のみが入力された場合、プレフィックス除去後に空文字列となる。`Strings.isDigits("")`の戻り値とPhoneNumberUtil.parseの挙動が未確認。
  - 候補：OpenSearchのStrings.isDigitsの実装 / libphonenumberのドキュメント
- C-50: `sip:@domain.com`が入力された場合、`@`の位置でsubstringが行われるが、sip:除去後の入力が`@domain.com`となり、`posAt=0`で`input.substring(0, 0)`が空文字列になる挙動は推測による。
  - 候補：実際のテスト実行による確認

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - クラス構造（PhoneNumberAnalyzer, PhoneNumberAnalyzerProvider, PhoneNumberAnalysisPlugin, PhoneNumberTermTokenizerFactory）のテストケースはソースコードに直接基づいており信頼性が高い
- 0: 低リスク - 既存テスト（PhoneNumberAnalyzerTests.java）で確認済みの正常系テストケース（C-22~C-43）
- 1: 中リスク - 境界値テストケース（C-47, C-48, C-50）は実際のPhoneNumberUtilの挙動に依存するため、テスト実行時に期待結果の調整が必要な可能性がある

## 6) レビュアーチェックリスト（最小）
- [ ] 境界値テストケース（C-47, C-48, C-50）の期待結果がPhoneNumberUtilの実際の挙動と一致するか確認
- [ ] phone-region設定のテストケース（C-38~C-42）で、ZZ以外のリージョンコードが正しく検証されているか確認
- [ ] 既存テスト（PhoneNumberAnalyzerTests.java）のカバー範囲とCSVのテストケースに抜け漏れがないか確認
- [ ] ngram生成のテストケースが、国コード付き/なしの両パターンを網羅しているか確認
- [ ] SIPプロトコル関連のエッジケース（ユーザー名にセミコロンやパラメータが含まれる場合等）が十分にカバーされているか確認
