import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/ui/file_tools.dart'; import 'package:path/path.dart' as p; /// X-plore 비교 P3: 해시 · 16진 보기 · 폴더 속성 void main() { late Directory tmp; setUp(() => tmp = Directory.systemTemp.createTempSync('jj_ftools_')); tearDown(() => tmp.deleteSync(recursive: true)); test('P3 해시: 알려진 값 (MD5 · SHA-256 "abc") · 취소면 null', () async { final f = File(p.join(tmp.path, 'abc.txt'))..writeAsStringSync('abc'); final h = await fileHashes(f.path); expect(h!.md5, '900150983cd24fb0d6963f7d28e17f72'); expect(h.sha256, 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'); expect(await fileHashes(f.path, cancelled: () => true), isNull); }); test('P3 16진 보기 한 줄 · 폴더 속성 (파일 · 폴더 수 · 크기)', () async { expect(HexViewerPage.line(16, 'AB\n'.codeUnits), startsWith('00000010 41 42 0a')); expect(HexViewerPage.line(16, 'AB\n'.codeUnits), endsWith(' AB.')); Directory(p.join(tmp.path, 'd', 'e')).createSync(recursive: true); File(p.join(tmp.path, 'd', 'a.bin')).writeAsBytesSync(List.filled(10, 1)); File(p.join(tmp.path, 'd', 'e', 'b.bin')).writeAsBytesSync(List.filled(5, 1)); final s = await folderStats(p.join(tmp.path, 'd')); expect((s.files, s.folders, s.bytes), (2, 1, 15)); }); // 4273868 (wiki_tests) 에서 옮김 testWidgets('위키 974 3절 (10/20): 16진 보기 - 폰 세로 (412) 는 한 줄 8바이트 · 넓으면 16바이트', (tester) async { final dir = Directory.systemTemp.createTempSync('jj_hex_'); addTearDown(() => dir.deleteSync(recursive: true)); final f = File(p.join(dir.path, 'a.bin'))..writeAsBytesSync([for (var i = 0; i < 40; i++) 0x41 + i % 26]); for (final (w, per) in [(412.0, 8), (960.0, 16)]) { tester.view.physicalSize = Size(w, 800); tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); await tester.pumpWidget(MaterialApp(key: ValueKey(w), home: HexViewerPage(path: f.path))); // 파일은 진짜 입출력으로 읽는다 - 다 읽어 그릴 때까지 for (var i = 0; i < 20 && find.textContaining(RegExp('^00000000 ')).evaluate().isEmpty; i++) { await tester.runAsync(() => Future.delayed(const Duration(milliseconds: 50))); await tester.pump(); } // 둘째 줄의 시작 자리 = per final second = per.toRadixString(16).padLeft(8, '0'); expect(find.textContaining(RegExp('^$second ')), findsOneWidget, reason: '$w 폭: 한 줄 $per 바이트'); expect(tester.takeException(), isNull); // 글자 칸까지 화면 안인지는 실제 글꼴로 - Windows 캡처 (15, 412 폭) 가 본다 (시험 글꼴은 모든 글자가 정사각형) } }); }