83 lines
4.9 KiB
Dart
83 lines
4.9 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
|
|
|
/// 관리자 지시 (10/19, 28 이 찾음): 통합 시험 · 캡처가 %TEMP%\jj_* 시험 폴더를 남겼다 - 시험 끝 (실패해도) 에 지운다.
|
|
/// [base] 가 있으면 그 아래 (짧은 경로가 필요한 캡처). 반드시 시험 (testWidgets · test) 안에서 부른다 (addTearDown).
|
|
/// [heldByApp]: 앱이 끝날 때까지 놓지 않는 폴더 (Edge 사용자 데이터 - Windows 판 플러그인에는 환경 닫기가 없다).
|
|
/// 이름 앞에 jj_held_ 를 붙이고, tool/test_temp_check.ps1 은 이것을 실패로 세지 않고 앱이 끝난 뒤 실행 폴더와 함께 지운다
|
|
Directory testTempDir(String prefix, {String? base, bool heldByApp = false}) {
|
|
final root = base == null || base.isEmpty ? Directory.systemTemp : (Directory(base)..createSync(recursive: true));
|
|
final dir = root.createTempSync(heldByApp ? 'jj_held_$prefix' : prefix);
|
|
addTearDown(() => deleteTestTemp(dir));
|
|
if (base == null || base.isEmpty) expectInTaggedTemp(dir);
|
|
return dir;
|
|
}
|
|
|
|
/// 관리자 지시 (10/20): 앱 임시 폴더 ([DesktopStorageService.tempDirectory] = %TEMP%\jj_mkvmaker) 를 이 시험 폴더 아래로 돌린다
|
|
/// (ai_e2e 가 남겨 test_temp_check 가 exit 2). 시험 끝에 기준을 되돌리고, 폴더는 [testTempDir] 의 정리가 함께 지운다
|
|
/// (addTearDown 은 나중에 넣은 것부터 돌아 앱 기준을 먼저 되돌린다). 사용자 %TEMP%\jj_mkvmaker 는 건드리지 않는다
|
|
void appTempInto(Directory dir) {
|
|
final before = DesktopStorageService.tempRoot;
|
|
DesktopStorageService.tempRoot = dir.path;
|
|
addTearDown(() => DesktopStorageService.tempRoot = before);
|
|
}
|
|
|
|
/// 관리자 지시 (10/20): tool/test_temp_check.ps1 이 TEMP · TMP 를 실행 폴더 (%TEMP%\t_jjrun_<표>) 로 돌리고 표를 JJ_TEST_TMP_TAG 로 넘긴다.
|
|
/// 표가 있는데 임시 폴더가 그 밖에 생기면 (환경 변수가 시험 · 앱까지 오지 않음) 다른 세션 시험과 섞이므로 시험을 실패시킨다
|
|
void expectInTaggedTemp(Directory dir) {
|
|
final tag = Platform.environment['JJ_TEST_TMP_TAG'] ?? '';
|
|
if (tag.isEmpty) return;
|
|
expect(dir.absolute.path.toLowerCase(), contains('t_jjrun_$tag'.toLowerCase()),
|
|
reason: 'TEMP 가 시험 실행 폴더로 오지 않음 (JJ_TEST_TMP_TAG=$tag)');
|
|
}
|
|
|
|
/// 시험 폴더 지우기 - Windows 에서 앱 · WebView · 백신이 파일을 잠깐 잡고 있으면 몇 번 다시 해 본다 (기다림은 실제 시간: 가짜 시계 밖).
|
|
/// 긴 경로는 \\?\ 로. 끝내 못 지우면 알리기만 하고 시험은 실패시키지 않는다 (tool/test_temp_check.ps1 이 남은 것을 잡는다)
|
|
void deleteTestTemp(Directory dir) {
|
|
final path = dir.absolute.path;
|
|
final target = Platform.isWindows && !path.startsWith(r'\\?\') ? Directory('\\\\?\\$path') : dir;
|
|
for (var i = 0; i < 20; i++) {
|
|
try {
|
|
if (!target.existsSync()) return;
|
|
target.deleteSync(recursive: true);
|
|
return;
|
|
} on FileSystemException {
|
|
sleep(const Duration(milliseconds: 250));
|
|
}
|
|
}
|
|
stderr.writeln('시험 임시 폴더를 지우지 못함: $path');
|
|
}
|
|
|
|
/// 관리자 지시 (10/24): 캡처 비교가 흔들리지 않게 이름이 늘 같은 시험 폴더 ([testTempDir] 는 끝에 임의 글자가 붙어 경로 막대 · 공유 경로가 실행마다 달랐다).
|
|
/// 있으면 지우고 새로 만들고, 시험 끝 (실패해도) 에 지운다. [base] 는 [testTempDir] 와 같다. 반드시 시험 안에서 부른다
|
|
Directory testFixedTempDir(String name, {String? base}) {
|
|
final root = base == null || base.isEmpty ? Directory.systemTemp : (Directory(base)..createSync(recursive: true));
|
|
final dir = Directory('${root.path}${Platform.pathSeparator}$name');
|
|
deleteTestTemp(dir);
|
|
dir.createSync(recursive: true);
|
|
addTearDown(() => deleteTestTemp(dir));
|
|
if (base == null || base.isEmpty) expectInTaggedTemp(dir);
|
|
return dir;
|
|
}
|
|
|
|
/// 캡처용: [dir] 아래 파일 · 폴더의 바뀐 시각을 [at] 으로 고정 (목록의 날짜 칸이 실행마다 같게).
|
|
/// Dart 는 폴더 시각을 못 바꿔 폴더는 PowerShell 로 (Windows 만). 긴 경로는 \\?\ 로
|
|
void pinTestTimes(Directory dir, {DateTime? at}) {
|
|
final when = at ?? DateTime(2026, 10, 22, 9);
|
|
final path = dir.absolute.path;
|
|
final long = Platform.isWindows && !path.startsWith(r'\\') ? Directory('\\\\?\\$path') : dir;
|
|
for (final f in long.listSync(recursive: true).whereType<File>()) {
|
|
f.setLastModifiedSync(when);
|
|
}
|
|
if (!Platform.isWindows) return;
|
|
String two(int v) => v.toString().padLeft(2, '0');
|
|
final stamp = '${when.year}-${two(when.month)}-${two(when.day)} ${two(when.hour)}:${two(when.minute)}';
|
|
Process.runSync('powershell', [
|
|
'-NoProfile',
|
|
'-Command',
|
|
"Get-ChildItem -LiteralPath '$path' -Recurse -Directory -Force | ForEach-Object { \$_.LastWriteTime = [datetime]'$stamp' }",
|
|
]);
|
|
}
|