JJ_MKVMaker/test/folder_size_test.dart

91 lines
3.3 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:jj_mkvmaker/core/file_ops.dart';
import 'package:jj_mkvmaker/core/folder_size.dart';
import 'package:path/path.dart' as p;
/// 80: 폴더 크기 - 필요할 때 계산 · 기억, 읽지 못한 곳은 "+", 바뀌면 그 폴더와 위 폴더를 잊음, 크기순 정렬
void main() {
late Directory tmp;
setUp(() {
tmp = Directory.systemTemp.createTempSync('jj_fsize80_');
File(p.join(tmp.path, 'a', 'x.bin'))
..createSync(recursive: true)
..writeAsBytesSync(List.filled(1000, 0));
File(p.join(tmp.path, 'a', 'deep', 'y.bin'))
..createSync(recursive: true)
..writeAsBytesSync(List.filled(24, 0));
File(p.join(tmp.path, 'b', 'z.bin'))
..createSync(recursive: true)
..writeAsBytesSync(List.filled(5, 0));
});
tearDown(() => tmp.deleteSync(recursive: true));
Future<void> idle(FolderSizes s, String path) async {
for (var i = 0; i < 200 && s.of(path) == null; i++) {
await Future<void>.delayed(const Duration(milliseconds: 10));
}
}
test('안쪽 폴더까지 합 · 기억 · 바뀌면 그 폴더와 위 폴더를 잊음', () async {
var reads = 0;
final s = FolderSizes(list: (d) {
reads++;
return listEntries(d, showHidden: true);
});
final a = p.join(tmp.path, 'a');
s.request(a);
expect(s.busy(a), isTrue);
await idle(s, a);
expect(s.of(a)!.bytes, 1024);
expect(s.of(a)!.partial, isFalse);
final first = reads;
s.request(a);
await Future<void>.delayed(const Duration(milliseconds: 20));
expect(reads, first, reason: '아는 것은 다시 읽지 않는다');
// 안쪽 폴더 크기만 잊어도 위 폴더 (a) 도 잊는다
s.request(p.join(a, 'deep'));
await idle(s, p.join(a, 'deep'));
s.forget(p.join(a, 'deep'));
expect(s.of(a), isNull);
expect(s.of(p.join(a, 'deep')), isNull);
// 위 폴더를 잊으면 (새로 고침) 안쪽 폴더도
s.request(p.join(a, 'deep'));
await idle(s, p.join(a, 'deep'));
s.forget(tmp.path);
expect(s.of(p.join(a, 'deep')), isNull);
s.dispose();
});
test('읽지 못한 폴더가 있으면 "+" (실제보다 작을 수 있음)', () async {
final a = p.join(tmp.path, 'a');
final s = FolderSizes(list: (d) {
if (p.basename(d) == 'deep') throw const FileSystemException('권한 없음');
return listEntries(d, showHidden: true);
});
s.request(a);
await idle(s, a);
expect(s.of(a)!.bytes, 1000);
expect(s.of(a)!.label, '1000B+');
s.dispose();
});
test('크기순 정렬: 아는 폴더는 그 크기로, 모르는 폴더는 가장 작게 (폴더는 늘 위)', () {
final now = DateTime(2026);
final list = [
FileEntry('/r/f.bin', isDir: false, size: 10, modified: now),
FileEntry('/r/small', isDir: true, modified: now),
FileEntry('/r/big', isDir: true, modified: now),
FileEntry('/r/unknown', isDir: true, modified: now),
];
final sizes = {'/r/small': 5, '/r/big': 5000};
final up = sortEntries(list, SortBy.size, dirSize: (d) => sizes[d.path]);
expect(up.map((e) => e.name), ['unknown', 'small', 'big', 'f.bin']);
final down = sortEntries(list, SortBy.size, descending: true, dirSize: (d) => sizes[d.path]);
expect(down.map((e) => e.name), ['big', 'small', 'unknown', 'f.bin']);
});
}