76 lines
3.4 KiB
Dart
76 lines
3.4 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/app/delete_ops.dart';
|
|
import 'package:jj_mkvmaker/core/app_trash.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
import 'support/fake_recycle_bin.dart' show realRecycleSkip;
|
|
|
|
/// E5b 약속 시험: lib/app/delete_ops.dart 맨 위 약속. 시험 폴더의 실제 파일 · 실제 앱 휴지통 (가짜 없음).
|
|
/// Windows 휴지통은 실제 사용자 휴지통이라 JJ_TEST_REAL_RECYCLE=1 일 때만 (끝나면 되살려 흔적 없음).
|
|
void main() {
|
|
if (!Platform.isWindows) return; // 열려 있는 파일을 못 지우는 것은 Windows
|
|
late Directory tmp;
|
|
late String a, b, dir, locked;
|
|
late RandomAccessFile hold;
|
|
setUp(() {
|
|
tmp = Directory.systemTemp.createTempSync('jj_del_');
|
|
a = p.join(tmp.path, 'a.txt');
|
|
b = p.join(tmp.path, 'b.txt');
|
|
dir = p.join(tmp.path, 'Show');
|
|
locked = p.join(tmp.path, 'locked.txt');
|
|
File(a).writeAsStringSync('a');
|
|
File(b).writeAsStringSync('b');
|
|
Directory(dir).createSync();
|
|
File(p.join(dir, 'ep.mkv')).writeAsStringSync('x');
|
|
File(locked).writeAsStringSync('l');
|
|
hold = File(locked).openSync(mode: FileMode.append); // Windows: 열려 있는 파일은 지울 수 없다
|
|
});
|
|
tearDown(() {
|
|
hold.closeSync();
|
|
tmp.deleteSync(recursive: true);
|
|
});
|
|
|
|
test('영구: 하나가 실패해도 나머지는 지우고 실패를 이유와 함께 (열려 있는 파일)', () async {
|
|
final r = await deletePaths([a, locked, dir], permanent: true);
|
|
expect(File(a).existsSync(), isFalse);
|
|
expect(Directory(dir).existsSync(), isFalse);
|
|
expect([for (final (x, _) in r.failed) x], [locked]);
|
|
expect(File(locked).existsSync(), isTrue);
|
|
expect(r.failed.single.$2, isNotEmpty);
|
|
expect([r.sent, r.trashed, r.tooLong], everyElement(isEmpty));
|
|
});
|
|
|
|
test('앱 휴지통: 보내고 되살림 · 못 보낸 것은 몰래 지우지 않고 보고 · deleteForever', () async {
|
|
final trash = AppTrash([tmp.path]);
|
|
final outside = Directory.systemTemp.createTempSync('jj_del_out_');
|
|
addTearDown(() => outside.deleteSync(recursive: true));
|
|
final far = p.join(outside.path, 'far.txt');
|
|
File(far).writeAsStringSync('f');
|
|
final r = await deletePaths([a, dir, far], permanent: false, trash: trash);
|
|
expect([File(a).existsSync(), Directory(dir).existsSync()], [false, false]);
|
|
expect(r.undoable, [a, dir]);
|
|
expect(r.recycled, 2);
|
|
expect([for (final (x, _) in r.notTrashed) x], [far], reason: '저장 장치 밖');
|
|
expect(File(far).existsSync(), isTrue, reason: '몰래 영구 삭제하지 않음');
|
|
final back = await undoTrash(trash, r.trashed);
|
|
expect(back.length, 2);
|
|
expect([File(a).existsSync(), File(p.join(dir, 'ep.mkv')).existsSync()], [true, true]);
|
|
expect([for (final (x, _) in await deleteForever([far, locked])) x], [locked]);
|
|
expect(File(far).existsSync(), isFalse);
|
|
expect(deleteFailReason(const FileSystemException('x', 'y', OSError('잠김', 32))), '잠김');
|
|
});
|
|
|
|
test('Windows 휴지통: 보내고 되돌림 (실제 휴지통)', () async {
|
|
final r = await deletePaths([a, b], permanent: false);
|
|
expect(r.sent, [a, b]);
|
|
expect(r.recycled, 2);
|
|
expect(File(a).existsSync(), isFalse);
|
|
final u = undoRecycle(r.sent, r.since);
|
|
expect(u.back, 2);
|
|
expect(u.failed, isEmpty);
|
|
expect([File(a).existsSync(), File(b).existsSync()], [true, true]);
|
|
}, skip: realRecycleSkip);
|
|
}
|