import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/core/file_ops.dart'; import 'package:jj_mkvmaker/core/models.dart'; import 'package:jj_mkvmaker/ui/quick_look.dart'; import 'package:path/path.dart' as p; /// 81: 빠른 보기 - 글 파일은 앞 64KB (깨지면 "미리 볼 수 없음"), ← → 로 앞 · 다음, Space 로 닫기, [열기] void main() { late Directory tmp; setUp(() => tmp = Directory.systemTemp.createTempSync('jj_ql81_')); tearDown(() => tmp.deleteSync(recursive: true)); test('글 앞부분: UTF-8 은 그대로 · 다른 글자 코드 (CP949) 는 null · 64KB 끝에서 잘린 한 글자는 괜찮음', () async { final a = File(p.join(tmp.path, 'a.txt'))..writeAsStringSync('안녕 hello'); expect(await readTextHead(a.path), '안녕 hello'); final b = File(p.join(tmp.path, 'b.smi'))..writeAsBytesSync([0xBE, 0xC8, 0xB3, 0xE7]); // CP949 "안녕" expect(await readTextHead(b.path), isNull); // 64KB 경계에 3바이트 글자가 걸리게 final c = File(p.join(tmp.path, 'c.txt'))..writeAsStringSync('${'x' * (64 * 1024 - 1)}가나다'); final head = await readTextHead(c.path); expect(head, isNotNull); expect(head!.length, 64 * 1024 - 1); }); testWidgets('← → 로 앞 · 다음 (보이는 차례), Space 로 닫기, [열기]', (tester) async { tester.view.physicalSize = const Size(1000, 800); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); final now = DateTime(2026, 10, 17); final entries = [ FileEntry(p.join(tmp.path, 'one.bin'), isDir: false, size: 10, modified: now), FileEntry(p.join(tmp.path, 'two.bin'), isDir: false, size: 20, modified: now), ]; final opened = []; final nav = GlobalKey(); await tester.pumpWidget(MaterialApp(navigatorKey: nav, home: const Scaffold())); showDialog( context: nav.currentContext!, builder: (_) => QuickLook( entries: entries, index: 0, probe: (_) async => const MediaInfo(streams: []), thumbnail: (_) async => null, imageExts: const ['jpg'], onOpen: (e) => opened.add(e.name), ), ); await tester.pumpAndSettle(); expect(find.text('one.bin'), findsOneWidget); expect(find.text('1/2'), findsOneWidget); await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight); await tester.pumpAndSettle(); expect(find.text('two.bin'), findsOneWidget); await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight); await tester.pumpAndSettle(); expect(find.text('2/2'), findsOneWidget, reason: '끝에서 더 가지 않음'); await tester.tap(find.text('열기 · 재생')); await tester.pumpAndSettle(); expect(opened, ['two.bin']); expect(find.byType(QuickLook), findsNothing); showDialog( context: nav.currentContext!, builder: (_) => QuickLook( entries: entries, index: 1, probe: (_) async => const MediaInfo(streams: []), thumbnail: (_) async => null, imageExts: const ['jpg'], onOpen: (_) {}, ), ); await tester.pumpAndSettle(); await tester.sendKeyEvent(LogicalKeyboardKey.space); await tester.pumpAndSettle(); expect(find.byType(QuickLook), findsNothing, reason: 'Space 로 닫기'); }); }