import 'package:flutter_test/flutter_test.dart'; import 'package:ponshu_room_lite/services/gemini_service.dart'; void main() { group('SakeAnalysisResult.fromJson', () { test('正常なJSONから全フィールドを正しくパースする', () { final json = { 'name': '獺祭', 'brand': '旭酒造', 'prefecture': '山口県', 'type': '純米大吟醸', 'description': 'フルーティーで華やかな香り', 'catchCopy': '磨きその先へ', 'confidenceScore': 92, 'flavorTags': ['フルーティー', '辛口'], 'tasteStats': {'aroma': 5, 'sweetness': 2, 'acidity': 3, 'bitterness': 2, 'body': 3}, 'alcoholContent': 16.0, 'polishingRatio': 23, 'sakeMeterValue': 3.0, 'riceVariety': '山田錦', 'yeast': 'きょうかい9号', 'manufacturingYearMonth': '2024.01', }; final result = SakeAnalysisResult.fromJson(json); expect(result.name, '獺祭'); expect(result.brand, '旭酒造'); expect(result.prefecture, '山口県'); expect(result.type, '純米大吟醸'); expect(result.confidenceScore, 92); expect(result.flavorTags, ['フルーティー', '辛口']); expect(result.alcoholContent, 16.0); expect(result.polishingRatio, 23); expect(result.riceVariety, '山田錦'); expect(result.manufacturingYearMonth, '2024.01'); expect(result.isFromCache, false); }); test('フィールドが全てnullの場合にデフォルト値が設定される', () { final result = SakeAnalysisResult.fromJson({}); expect(result.name, isNull); expect(result.brand, isNull); expect(result.prefecture, isNull); expect(result.flavorTags, isEmpty); expect(result.isFromCache, false); }); test('tasteStats: 範囲外の値(0, 6)が1〜5にクランプされる', () { final json = { 'tasteStats': { 'aroma': 0, 'sweetness': 6, 'acidity': -1, 'bitterness': 10, 'body': 3, }, }; final result = SakeAnalysisResult.fromJson(json); expect(result.tasteStats['aroma'], 1); expect(result.tasteStats['sweetness'], 5); expect(result.tasteStats['acidity'], 1); expect(result.tasteStats['bitterness'], 5); expect(result.tasteStats['body'], 3); }); test('tasteStats: 一部キーが欠損していると3で補完される', () { final json = { 'tasteStats': { 'aroma': 5, // sweetness, acidity, bitterness, body が欠損 }, }; final result = SakeAnalysisResult.fromJson(json); expect(result.tasteStats['aroma'], 5); expect(result.tasteStats['sweetness'], 3); expect(result.tasteStats['acidity'], 3); expect(result.tasteStats['bitterness'], 3); expect(result.tasteStats['body'], 3); }); test('tasteStats: nullまたは不正な型の場合は全キーが3になる', () { final json = {'tasteStats': null}; final result = SakeAnalysisResult.fromJson(json); expect(result.tasteStats['aroma'], 3); expect(result.tasteStats['sweetness'], 3); expect(result.tasteStats['body'], 3); }); test('alcoholContent: intで渡された場合もdoubleとして取得できる', () { final json = {'alcoholContent': 15}; final result = SakeAnalysisResult.fromJson(json); expect(result.alcoholContent, 15.0); }); test('flavorTags: nullの場合は空リストになる', () { final json = {'flavorTags': null}; final result = SakeAnalysisResult.fromJson(json); expect(result.flavorTags, isEmpty); }); }); group('SakeAnalysisResult.asCached', () { test('asCached()はisFromCache=trueを返す', () { final original = SakeAnalysisResult(name: '獺祭', brand: '旭酒造'); final cached = original.asCached(); expect(cached.isFromCache, true); expect(cached.name, '獺祭'); expect(cached.brand, '旭酒造'); }); test('元のインスタンスはisFromCache=falseを維持する', () { final original = SakeAnalysisResult(name: '久保田'); original.asCached(); expect(original.isFromCache, false); }); }); group('SakeAnalysisResult.toJson / fromJson 往復', () { test('toJson → fromJson で値が保持される', () { final original = SakeAnalysisResult( name: '八海山', brand: '八海醸造', prefecture: '新潟県', type: '特別本醸造', confidenceScore: 80, flavorTags: ['辛口', 'すっきり'], tasteStats: {'aroma': 2, 'sweetness': 2, 'acidity': 3, 'bitterness': 3, 'body': 3}, alcoholContent: 15.5, polishingRatio: 55, ); final json = original.toJson(); final restored = SakeAnalysisResult.fromJson(json); expect(restored.name, original.name); expect(restored.brand, original.brand); expect(restored.prefecture, original.prefecture); expect(restored.confidenceScore, original.confidenceScore); expect(restored.flavorTags, original.flavorTags); expect(restored.alcoholContent, original.alcoholContent); expect(restored.polishingRatio, original.polishingRatio); }); test('toJson に isFromCache は含まれない', () { final result = SakeAnalysisResult(name: 'テスト').asCached(); final json = result.toJson(); expect(json.containsKey('isFromCache'), false); }); }); }