159 lines
5.5 KiB
Dart
159 lines
5.5 KiB
Dart
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);
|
|
});
|
|
});
|
|
}
|