import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/core/files/any_transfer.dart'; import 'package:jj_mkvmaker/core/files/local_transfer.dart'; import 'package:jj_mkvmaker/core/files/same_file.dart'; import 'package:jj_mkvmaker/core/files/transfer_control.dart'; import 'package:jj_mkvmaker/core/sync_preview.dart'; import 'package:path/path.dart' as p; /// modular_sync F2 약속: "같은 파일" 판단은 SameFile 하나 - 실행 전 미리 보기와 실제 맞추기가 같은 결과를 낸다 (실제 파일 · 실제 맞추기) void main() { final t0 = DateTime(2026, 10, 1, 12); test('판단 표: 크기 · 2초 안 · 받는 쪽이 더 새것 (올린 때 · 이동)', () { bool same(SameFile s, {int size = 5, Duration dt = Duration.zero}) => s.same(size: 5, modified: t0, targetSize: size, targetModified: t0.add(dt)); const exact = SameFile(); const upload = SameFile(uploadTime: true); expect([same(exact, size: 6), same(upload, size: 6)], [false, false], reason: '크기가 다르면 다름'); expect([same(exact, dt: const Duration(seconds: 2)), same(exact, dt: const Duration(seconds: -2))], [true, true]); expect([same(exact, dt: const Duration(minutes: 1)), same(upload, dt: const Duration(minutes: 1))], [false, true], reason: '받는 쪽이 더 새것'); expect([same(exact, dt: const Duration(minutes: -1)), same(upload, dt: const Duration(minutes: -1))], [false, false], reason: '받는 쪽이 더 예전'); expect([SameFile.forAppSync(remote: true, move: false).uploadTime, SameFile.forAppSync(remote: true, move: true).uploadTime, SameFile.forAppSync(remote: false, move: false).uploadTime], [true, false, false]); expect([SameFile.targetNewer(t0.add(const Duration(seconds: 3)), t0), SameFile.targetNewer(t0.add(const Duration(seconds: 2)), t0)], [true, false]); }); group('미리 보기 = 실제 맞추기 (받는 쪽 같은 크기 · 1분 더 새것)', () { late Directory tmp; late String s, m; setUp(() { tmp = Directory.systemTemp.createTempSync('jj_samefile_'); s = p.join(tmp.path, 's'); m = p.join(tmp.path, 'm'); File(p.join(s, 'a.txt')) ..createSync(recursive: true) ..writeAsStringSync('SRC') ..setLastModifiedSync(t0); File(p.join(m, 'a.txt')) ..createSync(recursive: true) ..writeAsStringSync('DST') ..setLastModifiedSync(t0.add(const Duration(minutes: 1))); }); tearDown(() => tmp.deleteSync(recursive: true)); String there() => File(p.join(m, 'a.txt')).readAsStringSync(); test('원격이 낀 앱 맞추기: 미리 보기에 없고 · 실제로도 보내지 않음', () async { final items = await previewSync(s, m, toRight: true, same: SameFile.forAppSync(remote: true, move: false)); expect(items, isEmpty); expect(await anyMirror(TransferControl(), s, m), 0); expect(there(), 'DST'); }); test('이동 (원본을 지움): 미리 보기에 "바뀜 (더 새 것)" · 실제로도 보냄', () async { final items = await previewSync(s, m, toRight: true, same: SameFile.forAppSync(remote: true, move: true)); expect([items.single.action, items.single.newer], [PreviewAction.update, true]); expect(await anyMirror(TransferControl(), s, m, strict: true), 1); expect(there(), 'SRC'); }); test('로컬끼리: 미리 보기에 "바뀜 (더 새 것)" · 실제로도 보냄', () async { final items = await previewSync(s, m, toRight: true); expect([items.single.action, items.single.newer], [PreviewAction.update, true]); expect(await localMirror(TransferControl(), s, m), 1); expect(there(), 'SRC'); }); }); }