import 'package:flutter_test/flutter_test.dart'; import 'package:mini_tias/services/raw_capture_service.dart'; void main() { group('QuantitativeCaptureResult.fromMap', () { test('最小限のマップから正しくインスタンス化できる', () { final map = { 'dngPath': '/storage/emulated/0/Pictures/MiniTIAS/test.dng', 'dngFileSize': 16000000, 'metadata': {}, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.dngPath, '/storage/emulated/0/Pictures/MiniTIAS/test.dng'); expect(result.dngFileSize, 16000000); expect(result.metadata, isEmpty); expect(result.lscMap, isNull); expect(result.lscMapRowCount, isNull); expect(result.lscMapColumnCount, isNull); }); test('dngFileSize が int として渡された場合でも正しく変換される', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 12345678, // Dart の int 'metadata': {}, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.dngFileSize, 12345678); expect(result.dngFileSize, isA()); }); test('dngFileSize が long 経由の num として渡された場合でも正しく int 変換される', () { // Kotlin の Long は Dart で num として渡される final map = { 'dngPath': '/test.dng', 'dngFileSize': 16777216.0, // num (double として渡される場合) 'metadata': {}, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.dngFileSize, 16777216); expect(result.dngFileSize, isA()); }); test('metadata がネスト構造を含む場合,全階層が Map 型になる', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': { 'settings': { 'exposure_time_ns': 10000000, 'iso': 400, }, 'actual': {'frame_duration_ns': 33333333}, }, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.metadata, isA>()); expect(result.metadata['settings'], isA>()); expect(result.metadata['actual'], isA>()); final settings = result.metadata['settings'] as Map; expect(settings['exposure_time_ns'], 10000000); expect(settings['iso'], 400); }); test('metadata 内のリスト要素も再帰変換される', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': { 'colorMatrix': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], 'nested': { 'tags': ['tag1', 'tag2'], }, }, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.metadata['colorMatrix'], isA>()); final nested = result.metadata['nested'] as Map; expect(nested['tags'], isA>()); }); test('lscMap が null の場合,フィールド lscMap も null になる', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': {}, 'lscMap': null, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.lscMap, isNull); }); test('lscMap が List> (List 経由) の場合,正しく変換される', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': {}, 'lscMap': [ [1.1, 1.2, 1.3], [1.4, 1.5, 1.6], ], 'lscMapRowCount': 2, 'lscMapColumnCount': 3, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.lscMap, isNotNull); expect(result.lscMap, hasLength(2)); expect(result.lscMap![0], hasLength(3)); expect(result.lscMap![0][0], closeTo(1.1, 0.0001)); expect(result.lscMap![1][2], closeTo(1.6, 0.0001)); expect(result.lscMapRowCount, 2); expect(result.lscMapColumnCount, 3); }); test('lscMap に Float (num) の値が含まれる場合でも double に正しくキャストされる', () { // Kotlin の Float は Dart で num 経由で渡される final map = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': {}, 'lscMap': [ [ 1.0, // double 2, // int も num として変換される 3.14, // 精度のある double ], ], 'lscMapRowCount': 1, 'lscMapColumnCount': 3, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.lscMap, isNotNull); final row = result.lscMap![0]; expect(row[0], isA()); expect(row[1], isA()); expect(row[2], isA()); expect(row[1], closeTo(2.0, 0.0001)); expect(row[2], closeTo(3.14, 0.0001)); }); // --- previewPath / previewFileSize 関連テスト --- test('previewPath と previewFileSize が両方 non-null の場合,フィールドに値がセットされる', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 16000000, 'metadata': {}, 'previewPath': '/storage/emulated/0/Pictures/MiniTIAS/test.preview.jpg', 'previewFileSize': 204800, }; final result = QuantitativeCaptureResult.fromMap(map); expect( result.previewPath, '/storage/emulated/0/Pictures/MiniTIAS/test.preview.jpg', ); expect(result.previewFileSize, 204800); expect(result.previewFileSize, isA()); }); test('previewPath が null の場合,previewPath は null になる', () { final map = { 'dngPath': '/test.dng', 'dngFileSize': 16000000, 'metadata': {}, 'previewPath': null, 'previewFileSize': null, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.previewPath, isNull); expect(result.previewFileSize, isNull); }); test( 'map に previewPath / previewFileSize キー自体が存在しない場合でも fromMap が成功し両フィールドが null になる', () { // 後方互換: プレビュー生成前の Kotlin が返す map にキーが存在しない場合 final map = { 'dngPath': '/test.dng', 'dngFileSize': 16000000, 'metadata': {}, }; final result = QuantitativeCaptureResult.fromMap(map); expect(result.previewPath, isNull); expect(result.previewFileSize, isNull); }, ); test('previewFileSize が int 直接でも num 経由でも正しく int に変換される', () { // int 直接のケース final mapInt = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': {}, 'previewPath': '/test.preview.jpg', 'previewFileSize': 204800, // Dart int }; final resultInt = QuantitativeCaptureResult.fromMap(mapInt); expect(resultInt.previewFileSize, 204800); expect(resultInt.previewFileSize, isA()); // num (double) 経由のケース final mapDouble = { 'dngPath': '/test.dng', 'dngFileSize': 100, 'metadata': {}, 'previewPath': '/test.preview.jpg', 'previewFileSize': 204800.0, // double として渡される場合 }; final resultDouble = QuantitativeCaptureResult.fromMap(mapDouble); expect(resultDouble.previewFileSize, 204800); expect(resultDouble.previewFileSize, isA()); }); }); }