import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/core/app_trash.dart'; import 'package:path/path.dart' as p; /// X-plore 비교 e: Android 앱 휴지통 (저장 장치의 .jj_trash) - Windows 임시 폴더로 시험 void main() { late Directory tmp; late AppTrash trash; setUp(() { tmp = Directory.systemTemp.createTempSync('jj_trash_e_'); trash = AppTrash([p.join(tmp.path, 'vol')]); Directory(p.join(tmp.path, 'vol', 'a', 'sub')).createSync(recursive: true); File(p.join(tmp.path, 'vol', 'a', 'f.txt')).writeAsStringSync('hello'); File(p.join(tmp.path, 'vol', 'a', 'sub', 'g.txt')).writeAsStringSync('gg'); }); tearDown(() => tmp.deleteSync(recursive: true)); test('파일 · 폴더를 휴지통으로 (같은 저장 장치의 .jj_trash, .nomedia) → 목록 → 되살리기 (자리에 같은 이름이면 "(되살림)")', () async { final f = p.join(tmp.path, 'vol', 'a', 'f.txt'); final sub = p.join(tmp.path, 'vol', 'a', 'sub'); final i1 = await trash.moveToTrash(f, now: DateTime(2026, 10, 1)); final i2 = await trash.moveToTrash(sub, now: DateTime(2026, 10, 2)); expect(File(f).existsSync(), isFalse); expect(Directory(sub).existsSync(), isFalse); expect(File(p.join(tmp.path, 'vol', trashFolderName, '.nomedia')).existsSync(), isTrue); expect(trash.isInTrash(i1.stored), isTrue); final list = await trash.list(); expect(list.map((x) => x.original), [sub, f], reason: '최근 것부터'); expect((list.last.size, list.first.isDir, list.first.size), (5, true, 2)); // 자리에 같은 이름이 새로 생겼으면 그것은 두고 다른 이름으로 File(f).writeAsStringSync('new'); final back = await trash.restore(list.last); expect(p.basename(back), 'f (되살림).txt'); expect(File(back).readAsStringSync(), 'hello'); expect(File(f).readAsStringSync(), 'new'); expect(await trash.restore(i2), sub); expect(File(p.join(sub, 'g.txt')).readAsStringSync(), 'gg'); expect(await trash.list(), isEmpty); }); test('보관 일이 지난 것만 지운다 · 영구 삭제 · 저장 장치 밖 · 휴지통 안의 것은 다시 보내지 않음', () async { final f = p.join(tmp.path, 'vol', 'a', 'f.txt'); final g = p.join(tmp.path, 'vol', 'a', 'sub', 'g.txt'); await trash.moveToTrash(f, now: DateTime(2026, 9, 1)); await trash.moveToTrash(g, now: DateTime(2026, 10, 15)); expect(await trash.purgeOlderThan(14, now: DateTime(2026, 10, 18)), 1); final left = await trash.list(); expect(left.single.original, g); await trash.purge(left.single); expect(await trash.list(), isEmpty); // 어느 저장 장치에도 없는 경로 → 옮기지 못함 (원래 것 그대로) final out = File(p.join(tmp.path, 'outside.txt'))..writeAsStringSync('x'); expect(() => trash.moveToTrash(out.path), throwsA(isA())); expect(out.existsSync(), isTrue); expect(trash.isInTrash(p.join(tmp.path, 'vol', trashFolderName, 'x')), isTrue); expect(trash.isTrashRoot(p.join(tmp.path, 'vol', trashFolderName)), isTrue); }); }