import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/app/app_controller.dart'; import 'package:jj_mkvmaker/app/download_manager.dart'; import 'package:jj_mkvmaker/app/settings.dart'; import 'package:jj_mkvmaker/core/models.dart'; import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart'; import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart'; import 'package:jj_mkvmaker/services/platform_services.dart'; import 'package:jj_mkvmaker/ui/downloads_page.dart'; import 'package:jj_mkvmaker/ui/explorer_page.dart'; import 'package:jj_mkvmaker/ui/home_page.dart'; import 'package:jj_mkvmaker/ui/monitor_page.dart'; import 'package:jj_mkvmaker/ui/settings_page.dart'; import 'package:path/path.dart' as p; /// 253: 글자를 크게 (기기 설정 글꼴 크기 · 접근성) 해도 화면이 넘치지 않는다 - 줄 높이가 고정이던 목록이 넘쳤다 void main() { late Directory tmp; setUp(() => tmp = Directory.systemTemp.createTempSync('jj_big_')); tearDown(() => tmp.deleteSync(recursive: true)); final pages = { 'MKV': (c, d) => HomePage(c: c), '파일 탐색기': (c, d) => ExplorerPage(c: c), 'Rsync': (c, d) => ExplorerPage(c: c, rsync: true), '모니터링': (c, d) => MonitorPage(c: c), '다운로드': (c, d) => DownloadsPage(d: d), '환경 설정': (c, d) => SettingsPage(c: c), }; for (final MapEntry(key: name, value: page) in pages.entries) { for (final size in [const Size(412, 900), const Size(900, 412), const Size(1280, 800)]) { testWidgets('253: $name (${size.width.round()}×${size.height.round()}, 글자 1.6배) 넘치지 않는다', (tester) async { tester.view.physicalSize = size; tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); const pp = MethodChannel('plugins.flutter.io/path_provider'); tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(pp, (_) async => tmp.path); addTearDown(() => tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(pp, null)); File(p.join(tmp.path, '아주 긴 이름의 동영상 파일 - 시험용 2026.mp4')).writeAsStringSync('v'); Directory(p.join(tmp.path, 'sub')).createSync(); final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService())); c.settings ..explorerPaths = [tmp.path, tmp.path] ..rsyncPaths = [tmp.path, tmp.path] ..copyTasks = [CopyTask(id: '1', sources: [tmp.path], dest: p.join(tmp.path, 'sub'), method: 'rsync', options: '-av')] ..liveSyncPairs = [LiveSyncPair(tmp.path, p.join(tmp.path, 'x'))]; c.videos.add(VideoItem(p.join(tmp.path, '아주 긴 이름의 동영상 파일 - 시험용 2026.mp4'))); c.selected = c.videos.first; final d = DownloadManager(backends: const [], settings: () => c.settings, readClipboard: () async => null); addTearDown(d.dispose); await tester.runAsync(() => tester.pumpWidget(MaterialApp( builder: (ctx, child) => MediaQuery(data: MediaQuery.of(ctx).copyWith(textScaler: const TextScaler.linear(1.6)), child: child!), home: page(c, d)))); for (var i = 0; i < 15; i++) { await tester.runAsync(() => Future.delayed(const Duration(milliseconds: 30))); await tester.pump(); } expect(tester.takeException(), isNull); // 화면을 내리고 남은 타이머 (탐색기 목록 읽기 등) 가 끝나게 await tester.pumpWidget(const SizedBox()); await tester.pump(const Duration(seconds: 1)); }); } } }