WIP 통합 시험 · 캡처의 임시 폴더: 시험 끝에 (실패해도) 지우기 · test_temp_check 가 통합 시험에도 (검토 대기)
관리자 지시 (10/19, 28 이 찾음): Windows 캡처 · 통합 시험 (integration_test, -d windows) 이 %TEMP%\jj_* 시험 폴더를 남겼다
(시험 본문 끝의 deleteSync 는 실패하면 건너뛰고, 앱 · WebView 가 파일을 잡고 있으면 지우기가 실패했다).
- 새 integration_test/support/temp_dir.dart: testTempDir(prefix, {base}) - 만들면서 addTearDown 으로 지우기를 걸어 실패해도 지운다.
잠겨 있으면 0.25초씩 20번 다시 (실제 시간 - 가짜 시계 밖), 긴 경로는 \?\, 끝내 못 지우면 알리기만.
통합 시험 26개 파일의 Directory.systemTemp.createTempSync('jj…') 를 모두 이것으로 (JJ_SHOT_TMP 를 쓰는 캡처 도우미 포함).
- tool/test_temp_check.ps1: integration_test 의 이름 (testTempDir 포함) 도 모은다. 넘겨받은 .dart 파일이 있으면 그 파일과 그것이 import 하는
support 파일의 이름만 센다 - 같은 때 다른 세션 · worktree 가 돌린 시험의 폴더 (jj_explorer_ · jj_sync_ · jj_fake_recycle_) 를 세던 거짓 실패를 없앰.
시험 소스에 없는 이름의 새 jj 폴더는 참고로만 보인다. 사용: test_temp_check.ps1 integration_test\windows_b6_shot_test.dart -d windows
- com_guard_test 의 쓰지 않는 dart:io import 정리 (analyze).
시험: windows_b6 · windows_xplore · windows_ftp · windows_wifi 캡처 통과 · 새로 남은 것 0 (test_temp_check), analyze 문제 없음.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
next2
parent
58254e42b2
commit
25a0cd3c96
|
|
@ -7,6 +7,7 @@ import 'package:jj_mkvmaker/core/languages.dart';
|
||||||
import 'package:jj_mkvmaker/core/models.dart';
|
import 'package:jj_mkvmaker/core/models.dart';
|
||||||
import 'package:jj_mkvmaker/core/output_paths.dart';
|
import 'package:jj_mkvmaker/core/output_paths.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 Whisper + NLLB 로 AI 자막 → MKV (모델이 JJ_MKVMAKER_MODELS 에 있어야 함)
|
/// 실제 Whisper + NLLB 로 AI 자막 → MKV (모델이 JJ_MKVMAKER_MODELS 에 있어야 함)
|
||||||
|
|
@ -16,7 +17,7 @@ void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('영어 음성 영상 → AI 자막(ko/en/ja) → MKV', (tester) async {
|
testWidgets('영어 음성 영상 → AI 자막(ko/en/ja) → MKV', (tester) async {
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_e2e_');
|
final dir = testTempDir('jj_e2e_');
|
||||||
final video = p.join(dir.path, '영어 강의.mp4');
|
final video = p.join(dir.path, '영어 강의.mp4');
|
||||||
final speech = p.join(Directory.current.path, 'test_assets', 'speech_en.wav');
|
final speech = p.join(Directory.current.path, 'test_assets', 'speech_en.wav');
|
||||||
final r = await Process.run('ffmpeg', [
|
final r = await Process.run('ffmpeg', [
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 Edge(WebView2): MKV 화면 ↔ 브라우저를 여러 번 오가도 보던 페이지를 다시 읽지 않고 그대로 이어진다
|
/// 실제 Edge(WebView2): MKV 화면 ↔ 브라우저를 여러 번 오가도 보던 페이지를 다시 읽지 않고 그대로 이어진다
|
||||||
|
|
@ -27,7 +28,7 @@ void main() {
|
||||||
await req.response.close();
|
await req.response.close();
|
||||||
});
|
});
|
||||||
final url = 'http://127.0.0.1:${server.port}/page';
|
final url = 'http://127.0.0.1:${server.port}/page';
|
||||||
final dataDir = Directory.systemTemp.createTempSync('jj_keep_').path;
|
final dataDir = testTempDir('jj_keep_').path;
|
||||||
|
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
c.settings
|
c.settings
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/ytdlp_backend.dart';
|
import 'package:jj_mkvmaker/platform/windows/ytdlp_backend.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 Edge(WebView2): 페이지 열기 · 동영상 감지 · 쿠키 저장 → yt-dlp 가 같은 쿠키를 읽는지
|
/// 실제 Edge(WebView2): 페이지 열기 · 동영상 감지 · 쿠키 저장 → yt-dlp 가 같은 쿠키를 읽는지
|
||||||
|
|
@ -31,7 +32,7 @@ void main() {
|
||||||
await req.response.close();
|
await req.response.close();
|
||||||
});
|
});
|
||||||
final url = 'http://127.0.0.1:${server.port}/';
|
final url = 'http://127.0.0.1:${server.port}/';
|
||||||
final dataDir = Directory.systemTemp.createTempSync('jj_webview_').path;
|
final dataDir = testTempDir('jj_webview_').path;
|
||||||
|
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
c.settings.webViewDataDir = dataDir;
|
c.settings.webViewDataDir = dataDir;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/app_actions.dart';
|
import 'package:jj_mkvmaker/ui/app_actions.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 망 (Windows): DNS 강제 (8.8.8.8) 상태에서 Chrome 엔진 (CEF) 이 앱 안 프록시의 인증 (비밀값) 에 답해 페이지를 여는지.
|
/// 실제 망 (Windows): DNS 강제 (8.8.8.8) 상태에서 Chrome 엔진 (CEF) 이 앱 안 프록시의 인증 (비밀값) 에 답해 페이지를 여는지.
|
||||||
|
|
@ -33,7 +34,7 @@ void main() {
|
||||||
}
|
}
|
||||||
CefRuntime.rememberStartState();
|
CefRuntime.rememberStartState();
|
||||||
expect(CefRuntime.readyThisRun, isTrue);
|
expect(CefRuntime.readyThisRun, isTrue);
|
||||||
final data = Platform.environment['JJ_MKVMAKER_DATA'] ?? Directory.systemTemp.createTempSync('jj_cef_real_').path;
|
final data = Platform.environment['JJ_MKVMAKER_DATA'] ?? testTempDir('jj_cef_real_').path;
|
||||||
Directory(data).createSync(recursive: true);
|
Directory(data).createSync(recursive: true);
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
c.settings
|
c.settings
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/com_guard.dart';
|
import 'package:jj_mkvmaker/platform/windows/com_guard.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
|
|
||||||
/// 실제 Edge(WebView2): 다른 구성 요소가 COM 준비 상태를 풀어 버린 상황을 만들고
|
/// 실제 Edge(WebView2): 다른 구성 요소가 COM 준비 상태를 풀어 버린 상황을 만들고
|
||||||
/// (브라우저가 "CoInitialize 가 호출되지 않았습니다" 로 안 뜨던 문제) 그래도 브라우저 환경이 만들어지는지
|
/// (브라우저가 "CoInitialize 가 호출되지 않았습니다" 로 안 뜨던 문제) 그래도 브라우저 환경이 만들어지는지
|
||||||
|
|
@ -26,7 +25,7 @@ void main() {
|
||||||
for (var i = 0; i < 8; i++) {
|
for (var i = 0; i < 8; i++) {
|
||||||
ComGuard.releaseForTest();
|
ComGuard.releaseForTest();
|
||||||
}
|
}
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_com_').path;
|
final dir = testTempDir('jj_com_').path;
|
||||||
final raw = await tester.runAsync<Object?>(() async {
|
final raw = await tester.runAsync<Object?>(() async {
|
||||||
try {
|
try {
|
||||||
await WebViewEnvironment.create(settings: WebViewEnvironmentSettings(userDataFolder: '${dir}_raw'));
|
await WebViewEnvironment.create(settings: WebViewEnvironmentSettings(userDataFolder: '${dir}_raw'));
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/app_actions.dart';
|
import 'package:jj_mkvmaker/ui/app_actions.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 250 실제 엔진 (Windows Edge WebView2): DNS 강제 서버에 닿지 않으면 (TEST-NET 192.0.2.1) 엔진의 오류 화면
|
/// 250 실제 엔진 (Windows Edge WebView2): DNS 강제 서버에 닿지 않으면 (TEST-NET 192.0.2.1) 엔진의 오류 화면
|
||||||
|
|
@ -20,7 +21,7 @@ void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('250: 닿지 않는 DNS → 브라우저에 앱 덮개 (Edge 실제)', (tester) async {
|
testWidgets('250: 닿지 않는 DNS → 브라우저에 앱 덮개 (Edge 실제)', (tester) async {
|
||||||
final data = Platform.environment['JJ_MKVMAKER_DATA'] ?? Directory.systemTemp.createTempSync('jj_dns_block_').path;
|
final data = Platform.environment['JJ_MKVMAKER_DATA'] ?? testTempDir('jj_dns_block_').path;
|
||||||
Directory(data).createSync(recursive: true);
|
Directory(data).createSync(recursive: true);
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
c.settings
|
c.settings
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import 'package:jj_mkvmaker/platform/windows/desktop_shell.dart';
|
||||||
import 'package:jj_mkvmaker/services/media_player.dart';
|
import 'package:jj_mkvmaker/services/media_player.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
|
|
||||||
/// 실제 mpv 플레이어 + 창 모드
|
/// 실제 mpv 플레이어 + 창 모드
|
||||||
void main() {
|
void main() {
|
||||||
|
|
@ -16,7 +17,7 @@ void main() {
|
||||||
|
|
||||||
testWidgets('재생 목록 · 자막 트랙 · 음량 · 전체 화면 · 팝업 · 창 크기', (tester) async {
|
testWidgets('재생 목록 · 자막 트랙 · 음량 · 전체 화면 · 팝업 · 창 크기', (tester) async {
|
||||||
MediaKitPreviewPlayer.ensureInitialized();
|
MediaKitPreviewPlayer.ensureInitialized();
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_fp_');
|
final dir = testTempDir('jj_fp_');
|
||||||
final srt = p.join(dir.path, 's.srt');
|
final srt = p.join(dir.path, 's.srt');
|
||||||
File(srt).writeAsStringSync('1\n00:00:00,000 --> 00:00:05,000\n내장 자막\n');
|
File(srt).writeAsStringSync('1\n00:00:00,000 --> 00:00:05,000\n내장 자막\n');
|
||||||
final ext = p.join(dir.path, 'ep1_ko.srt');
|
final ext = p.join(dir.path, 'ep1_ko.srt');
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/monitor_page.dart';
|
import 'package:jj_mkvmaker/ui/monitor_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/schedule_editor.dart';
|
import 'package:jj_mkvmaker/ui/schedule_editor.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 모니터링 화면 (복사 진행 중 · lsync · 일정 격자) 을 실제 글꼴로 그려 PNG 로 (JJ_SHOT_DIR). 화면 배치 확인용.
|
/// 모니터링 화면 (복사 진행 중 · lsync · 일정 격자) 을 실제 글꼴로 그려 PNG 로 (JJ_SHOT_DIR). 화면 배치 확인용.
|
||||||
|
|
@ -21,7 +22,7 @@ void main() {
|
||||||
|
|
||||||
testWidgets('모니터링 화면 그림', (tester) async {
|
testWidgets('모니터링 화면 그림', (tester) async {
|
||||||
final out = Platform.environment['JJ_SHOT_DIR'] ?? Directory.systemTemp.path;
|
final out = Platform.environment['JJ_SHOT_DIR'] ?? Directory.systemTemp.path;
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_monshot_');
|
final tmp = testTempDir('jj_monshot_');
|
||||||
final src = p.join(tmp.path, '영상 원본'), dst = p.join(tmp.path, '백업');
|
final src = p.join(tmp.path, '영상 원본'), dst = p.join(tmp.path, '백업');
|
||||||
for (var i = 0; i < 6; i++) {
|
for (var i = 0; i < 6; i++) {
|
||||||
File(p.join(src, i < 3 ? 'A' : 'B', 'clip$i.mkv'))
|
File(p.join(src, i < 3 ? 'A' : 'B', 'clip$i.mkv'))
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:jj_mkvmaker/core/reader_sources.dart';
|
import 'package:jj_mkvmaker/core/reader_sources.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 pdfium: 그림 → PDF, 열기 · 그리기, 페이지 지우기 · 그림 넣기 · 저장
|
/// 실제 pdfium: 그림 → PDF, 열기 · 그리기, 페이지 지우기 · 그림 넣기 · 저장
|
||||||
|
|
@ -12,8 +13,7 @@ void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('PDF: 만들기 · 열기 · 지우기 · 넣기 · 저장', (tester) async {
|
testWidgets('PDF: 만들기 · 열기 · 지우기 · 넣기 · 저장', (tester) async {
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_pdf_');
|
final dir = testTempDir('jj_pdf_');
|
||||||
addTearDown(() => dir.deleteSync(recursive: true));
|
|
||||||
String image(String name, int w, int h, {bool jpg = false}) {
|
String image(String name, int w, int h, {bool jpg = false}) {
|
||||||
final im = img.Image(width: w, height: h);
|
final im = img.Image(width: w, height: h);
|
||||||
img.fill(im, color: img.ColorRgb8(200, 50, 50));
|
img.fill(im, color: img.ColorRgb8(200, 50, 50));
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:jj_mkvmaker/platform/common/media_kit_player.dart';
|
import 'package:jj_mkvmaker/platform/common/media_kit_player.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 Windows 앱에서 libmpv 재생 확인
|
/// 실제 Windows 앱에서 libmpv 재생 확인
|
||||||
|
|
@ -14,7 +15,7 @@ void main() {
|
||||||
testWidgets('media_kit: 영상 열기 · 재생 · 이동', (tester) async {
|
testWidgets('media_kit: 영상 열기 · 재생 · 이동', (tester) async {
|
||||||
MediaKitPreviewPlayer.ensureInitialized();
|
MediaKitPreviewPlayer.ensureInitialized();
|
||||||
|
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_play_');
|
final dir = testTempDir('jj_play_');
|
||||||
final video = p.join(dir.path, '재생 테스트.mp4');
|
final video = p.join(dir.path, '재생 테스트.mp4');
|
||||||
final r = await Process.run('ffmpeg', [
|
final r = await Process.run('ffmpeg', [
|
||||||
'-y', '-f', 'lavfi', '-i', 'testsrc=size=320x240:rate=25',
|
'-y', '-f', 'lavfi', '-i', 'testsrc=size=320x240:rate=25',
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/monitor_page.dart';
|
import 'package:jj_mkvmaker/ui/monitor_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// Rsync 화면을 실제 rsync (앱에 들어 있는 것) 로: → 한 방향, ⇄ 양쪽 (-u), 모니터링에 남는지. 화면은 JJ_SHOT_DIR 에 PNG.
|
/// Rsync 화면을 실제 rsync (앱에 들어 있는 것) 로: → 한 방향, ⇄ 양쪽 (-u), 모니터링에 남는지. 화면은 JJ_SHOT_DIR 에 PNG.
|
||||||
|
|
@ -20,7 +21,7 @@ void main() {
|
||||||
|
|
||||||
testWidgets('Rsync 화면: → · ⇄ 실제 실행', (tester) async {
|
testWidgets('Rsync 화면: → · ⇄ 실제 실행', (tester) async {
|
||||||
final out = Platform.environment['JJ_SHOT_DIR'] ?? Directory.systemTemp.path;
|
final out = Platform.environment['JJ_SHOT_DIR'] ?? Directory.systemTemp.path;
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_rsyncpage_');
|
final tmp = testTempDir('jj_rsyncpage_');
|
||||||
final a = p.join(tmp.path, '왼쪽 폴더'), b = p.join(tmp.path, 'right');
|
final a = p.join(tmp.path, '왼쪽 폴더'), b = p.join(tmp.path, 'right');
|
||||||
File(p.join(a, 'sub', '한글 파일.txt'))
|
File(p.join(a, 'sub', '한글 파일.txt'))
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
|
|
@ -108,7 +109,7 @@ void main() {
|
||||||
|
|
||||||
testWidgets('원본 파일 지우기 (--remove-source-files) · 빈 폴더 정리 · lsync 최종 정리', (tester) async {
|
testWidgets('원본 파일 지우기 (--remove-source-files) · 빈 폴더 정리 · lsync 최종 정리', (tester) async {
|
||||||
final out = Platform.environment['JJ_SHOT_DIR'] ?? Directory.systemTemp.path;
|
final out = Platform.environment['JJ_SHOT_DIR'] ?? Directory.systemTemp.path;
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_rsyncmove_');
|
final tmp = testTempDir('jj_rsyncmove_');
|
||||||
final a = p.join(tmp.path, 'srcA'), b = p.join(tmp.path, 'dstB');
|
final a = p.join(tmp.path, 'srcA'), b = p.join(tmp.path, 'dstB');
|
||||||
final cDir = p.join(tmp.path, 'liveC'), d = p.join(tmp.path, 'liveD');
|
final cDir = p.join(tmp.path, 'liveC'), d = p.join(tmp.path, 'liveD');
|
||||||
for (final (dir, name) in [(a, 'x'), (cDir, 'y')]) {
|
for (final (dir, name) in [(a, 'x'), (cDir, 'y')]) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:jj_mkvmaker/services/secret_store.dart';
|
import 'package:jj_mkvmaker/services/secret_store.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
|
|
||||||
/// 54: 이 기기의 안전 저장소 (Windows DPAPI · Android Keystore) 에 실제로 쓰고 읽고 지운다.
|
/// 54: 이 기기의 안전 저장소 (Windows DPAPI · Android Keystore) 에 실제로 쓰고 읽고 지운다.
|
||||||
/// 시험용 열쇠 하나만 쓰고 끝에 지운다 (사용자가 저장한 값은 건드리지 않음).
|
/// 시험용 열쇠 하나만 쓰고 끝에 지운다 (사용자가 저장한 값은 건드리지 않음).
|
||||||
|
|
@ -13,7 +14,7 @@ void main() {
|
||||||
Directory? tmp;
|
Directory? tmp;
|
||||||
SecretStore store() {
|
SecretStore store() {
|
||||||
if (!Platform.isWindows) return SecretStore.platform();
|
if (!Platform.isWindows) return SecretStore.platform();
|
||||||
return SecretStore.dpapiAt((tmp ??= Directory.systemTemp.createTempSync('jj_secretit_')).path);
|
return SecretStore.dpapiAt((tmp ??= testTempDir('jj_secretit_')).path);
|
||||||
}
|
}
|
||||||
|
|
||||||
tearDownAll(() {
|
tearDownAll(() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
/// 관리자 지시 (10/19, 28 이 찾음): 통합 시험 · 캡처가 %TEMP%\jj_* 시험 폴더를 남겼다 - 시험 끝 (실패해도) 에 지운다.
|
||||||
|
/// [base] 가 있으면 그 아래 (짧은 경로가 필요한 캡처). 반드시 시험 (testWidgets · test) 안에서 부른다 (addTearDown).
|
||||||
|
Directory testTempDir(String prefix, {String? base}) {
|
||||||
|
final root = base == null || base.isEmpty ? Directory.systemTemp : (Directory(base)..createSync(recursive: true));
|
||||||
|
final dir = root.createTempSync(prefix);
|
||||||
|
addTearDown(() => deleteTestTemp(dir));
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 시험 폴더 지우기 - 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');
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@ import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/app_actions.dart';
|
import 'package:jj_mkvmaker/ui/app_actions.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/tor_page.dart';
|
import 'package:jj_mkvmaker/ui/tor_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 망 (Windows): DNS 강제 (8.8.8.8) 로 앱의 HTTP · 일반 브라우저 (Edge) 가 이름을 푸는지, 닿지 않는 DNS 는 실패로 알리는지,
|
/// 실제 망 (Windows): DNS 강제 (8.8.8.8) 로 앱의 HTTP · 일반 브라우저 (Edge) 가 이름을 푸는지, 닿지 않는 DNS 는 실패로 알리는지,
|
||||||
|
|
@ -26,7 +27,7 @@ void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('DNS 강제 · Tor 화면 실제 연결', (tester) async {
|
testWidgets('DNS 강제 · Tor 화면 실제 연결', (tester) async {
|
||||||
final data = Platform.environment['JJ_MKVMAKER_DATA'] ?? Directory.systemTemp.createTempSync('jj_tor_real_').path;
|
final data = Platform.environment['JJ_MKVMAKER_DATA'] ?? testTempDir('jj_tor_real_').path;
|
||||||
Directory(data).createSync(recursive: true);
|
Directory(data).createSync(recursive: true);
|
||||||
ComponentStore.dataDirectory = data;
|
ComponentStore.dataDirectory = data;
|
||||||
ComponentStore.shared = ComponentStore(data);
|
ComponentStore.shared = ComponentStore(data);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import 'package:jj_mkvmaker/core/models.dart';
|
||||||
import 'package:jj_mkvmaker/core/output_paths.dart';
|
import 'package:jj_mkvmaker/core/output_paths.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 NLLB + 실제 Edge(WebView2): 브라우저를 보면서 영어 자막 → 한국어 번역 → MKV 를
|
/// 실제 NLLB + 실제 Edge(WebView2): 브라우저를 보면서 영어 자막 → 한국어 번역 → MKV 를
|
||||||
|
|
@ -19,7 +20,7 @@ void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('브라우저 + 작업 현황: 영어 자막 → 한국어 번역 → MKV (대기열)', (tester) async {
|
testWidgets('브라우저 + 작업 현황: 영어 자막 → 한국어 번역 → MKV (대기열)', (tester) async {
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_split_');
|
final dir = testTempDir('jj_split_');
|
||||||
final video = p.join(dir.path, 'movie.mp4');
|
final video = p.join(dir.path, 'movie.mp4');
|
||||||
final r = await Process.run('ffmpeg', [
|
final r = await Process.run('ffmpeg', [
|
||||||
'-y', '-f', 'lavfi', '-i', 'testsrc=size=320x240:rate=10', '-f', 'lavfi', '-i', 'sine',
|
'-y', '-f', 'lavfi', '-i', 'testsrc=size=320x240:rate=10', '-f', 'lavfi', '-i', 'sine',
|
||||||
|
|
@ -42,7 +43,7 @@ void main() {
|
||||||
await c.init();
|
await c.init();
|
||||||
await c.addVideos([video]);
|
await c.addVideos([video]);
|
||||||
});
|
});
|
||||||
c.settings.webViewDataDir = Directory.systemTemp.createTempSync('jj_webview_').path;
|
c.settings.webViewDataDir = testTempDir('jj_webview_').path;
|
||||||
final v = c.videos.single;
|
final v = c.videos.single;
|
||||||
// 같은 폴더의 movie.en.srt 가 자동으로 잡힘
|
// 같은 폴더의 movie.en.srt 가 자동으로 잡힘
|
||||||
final s = v.subtitles.firstWhere((x) => x.path != null && p.equals(x.path!, en));
|
final s = v.subtitles.firstWhere((x) => x.path != null && p.equals(x.path!, en));
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import 'package:jj_mkvmaker/core/output_paths.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
import 'package:jj_mkvmaker/ui/video_adjust_dialog.dart';
|
import 'package:jj_mkvmaker/ui/video_adjust_dialog.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 FFmpeg: 가로 영상 → 화면 · 색 보정 창 미리보기 → 세로 9:16 + 채도 MKV 만들기
|
/// 실제 FFmpeg: 가로 영상 → 화면 · 색 보정 창 미리보기 → 세로 9:16 + 채도 MKV 만들기
|
||||||
|
|
@ -19,7 +20,7 @@ void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
testWidgets('화면 · 색 보정: 미리보기와 세로 9:16 MKV', (tester) async {
|
testWidgets('화면 · 색 보정: 미리보기와 세로 9:16 MKV', (tester) async {
|
||||||
final dir = Directory.systemTemp.createTempSync('jj_adj_e2e_');
|
final dir = testTempDir('jj_adj_e2e_');
|
||||||
final video = p.join(dir.path, '가로 영상.mp4');
|
final video = p.join(dir.path, '가로 영상.mp4');
|
||||||
final ffmpeg = p.join(Directory.current.path, 'third_party', 'ffmpeg', 'windows', 'ffmpeg.exe');
|
final ffmpeg = p.join(Directory.current.path, 'third_party', 'ffmpeg', 'windows', 'ffmpeg.exe');
|
||||||
final r = await Process.run(ffmpeg, [
|
final r = await Process.run(ffmpeg, [
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 실제 웹뷰 (Windows: Edge WebView2 · Android: 시스템 WebView) + 실제 Google 번역:
|
/// 실제 웹뷰 (Windows: Edge WebView2 · Android: 시스템 WebView) + 실제 Google 번역:
|
||||||
|
|
@ -50,7 +51,7 @@ void main() {
|
||||||
await req.response.close();
|
await req.response.close();
|
||||||
});
|
});
|
||||||
final url = 'http://127.0.0.1:${server.port}/';
|
final url = 'http://127.0.0.1:${server.port}/';
|
||||||
final dataDir = Directory.systemTemp.createTempSync('jj_webview_').path;
|
final dataDir = testTempDir('jj_webview_').path;
|
||||||
|
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
c.settings
|
c.settings
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:whisper_ggml/whisper_ggml.dart';
|
import 'package:whisper_ggml/whisper_ggml.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
|
|
||||||
/// whisper.cpp 동작 확인 (스마트 앱 컨트롤·속도)
|
/// whisper.cpp 동작 확인 (스마트 앱 컨트롤·속도)
|
||||||
void main() {
|
void main() {
|
||||||
|
|
@ -14,7 +15,7 @@ void main() {
|
||||||
'whisper', 'ggml-base.bin');
|
'whisper', 'ggml-base.bin');
|
||||||
final assets = p.join(Directory.current.path, 'test_assets');
|
final assets = p.join(Directory.current.path, 'test_assets');
|
||||||
for (final name in ['speech_en.wav', 'speech_ko.wav']) {
|
for (final name in ['speech_en.wav', 'speech_ko.wav']) {
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_w_');
|
final tmp = testTempDir('jj_w_');
|
||||||
final wav = File(p.join(assets, name)).copySync(p.join(tmp.path, name)).path;
|
final wav = File(p.join(assets, name)).copySync(p.join(tmp.path, name)).path;
|
||||||
final sw = Stopwatch()..start();
|
final sw = Stopwatch()..start();
|
||||||
final r = await tester.runAsync(() => const Whisper(model: WhisperModel.base).transcribe(
|
final r = await tester.runAsync(() => const Whisper(model: WhisperModel.base).transcribe(
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import 'package:jj_mkvmaker/ui/app_actions.dart';
|
||||||
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
import 'package:jj_mkvmaker/ui/browser_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/home_page.dart';
|
import 'package:jj_mkvmaker/ui/home_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 66-2 기기 감독 확인용 (Windows): 지금 화면 아이콘 (넓은 · 좁은 화면) · 처음으로 알림 · 브라우저 안내 한 줄을 PNG (JJ_SHOT_DIR) 로.
|
/// 66-2 기기 감독 확인용 (Windows): 지금 화면 아이콘 (넓은 · 좁은 화면) · 처음으로 알림 · 브라우저 안내 한 줄을 PNG (JJ_SHOT_DIR) 로.
|
||||||
|
|
@ -83,9 +84,7 @@ void main() {
|
||||||
..components = ['mkv', 'browser', 'explorer', 'rsync']
|
..components = ['mkv', 'browser', 'explorer', 'rsync']
|
||||||
..navOrder = ['mkv', 'browser', 'explorer', 'rsync'];
|
..navOrder = ['mkv', 'browser', 'explorer', 'rsync'];
|
||||||
final base = Platform.environment['JJ_SHOT_TMP'];
|
final base = Platform.environment['JJ_SHOT_TMP'];
|
||||||
final dir = (base == null || base.isEmpty ? Directory.systemTemp : (Directory(base)..createSync(recursive: true)))
|
final dir = testTempDir('jj_shot_662_', base: base);
|
||||||
.createTempSync('jj_shot_662_');
|
|
||||||
addTearDown(() => dir.deleteSync(recursive: true));
|
|
||||||
final bm = BookmarksController(p.join(dir.path, 'bookmarks.json'));
|
final bm = BookmarksController(p.join(dir.path, 'bookmarks.json'));
|
||||||
t.view.physicalSize = const Size(1280, 800);
|
t.view.physicalSize = const Size(1280, 800);
|
||||||
t.view.devicePixelRatio = 1;
|
t.view.devicePixelRatio = 1;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../test/support/fake_recycle_bin.dart';
|
import '../test/support/fake_recycle_bin.dart';
|
||||||
import '../test/support/recycle_leftovers.dart';
|
import '../test/support/recycle_leftovers.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
|
|
||||||
/// 묶음 3 (데이터 쪽) 기기 감독 확인용 (Windows): 실제 앱 화면을 띄워 누르고 단계마다 PNG (JJ_SHOT_DIR) 로 남긴다.
|
/// 묶음 3 (데이터 쪽) 기기 감독 확인용 (Windows): 실제 앱 화면을 띄워 누르고 단계마다 PNG (JJ_SHOT_DIR) 로 남긴다.
|
||||||
/// 165 (드라이브 · 연결 안 됨) · 48 (같은 이름) · 52 (돌아와도 진행 막대) · 148 (휴지통 되돌리기) · 144 (긴 경로).
|
/// 165 (드라이브 · 연결 안 됨) · 48 (같은 이름) · 52 (돌아와도 진행 막대) · 148 (휴지통 되돌리기) · 144 (긴 경로).
|
||||||
|
|
@ -23,9 +24,7 @@ void main() {
|
||||||
final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_b3');
|
final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_b3');
|
||||||
Directory tempDir(String prefix) {
|
Directory tempDir(String prefix) {
|
||||||
final base = Platform.environment['JJ_SHOT_TMP'];
|
final base = Platform.environment['JJ_SHOT_TMP'];
|
||||||
if (base == null || base.isEmpty) return Directory.systemTemp.createTempSync(prefix);
|
return testTempDir(prefix, base: base);
|
||||||
Directory(base).createSync(recursive: true);
|
|
||||||
return Directory(base).createTempSync(prefix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final key = GlobalKey();
|
final key = GlobalKey();
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 관리자 지시 9 (10/17): 82 끌어 놓기 · 75 마우스 4 · 5 번을 Windows 실제 빌드에서 가짜 포인터로 (실제 마우스 · 키보드는 쓰지 않음).
|
/// 관리자 지시 9 (10/17): 82 끌어 놓기 · 75 마우스 4 · 5 번을 Windows 실제 빌드에서 가짜 포인터로 (실제 마우스 · 키보드는 쓰지 않음).
|
||||||
|
|
@ -26,7 +27,7 @@ void main() {
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
await i18n.apply('ko', save: false);
|
await i18n.apply('ko', save: false);
|
||||||
tmp = Directory.systemTemp.createTempSync('jj_b6input_');
|
tmp = testTempDir('jj_b6input_');
|
||||||
left = p.join(tmp.path, 'left');
|
left = p.join(tmp.path, 'left');
|
||||||
right = p.join(tmp.path, 'right');
|
right = p.join(tmp.path, 'right');
|
||||||
File(p.join(left, 'doc.txt'))
|
File(p.join(left, 'doc.txt'))
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import 'package:jj_mkvmaker/ui/explorer_search.dart';
|
||||||
import 'package:jj_mkvmaker/ui/quick_look.dart';
|
import 'package:jj_mkvmaker/ui/quick_look.dart';
|
||||||
import 'package:jj_mkvmaker/ui/storage_page.dart';
|
import 'package:jj_mkvmaker/ui/storage_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 관리자 지시 5 (10/17): 기기 없이 15 가 볼 수 있게 묶음6 새 화면을 PNG 로 (JJ_SHOT_DIR, 없으면 임시 폴더).
|
/// 관리자 지시 5 (10/17): 기기 없이 15 가 볼 수 있게 묶음6 새 화면을 PNG 로 (JJ_SHOT_DIR, 없으면 임시 폴더).
|
||||||
|
|
@ -38,8 +39,7 @@ void main() {
|
||||||
addTearDown(t.view.reset);
|
addTearDown(t.view.reset);
|
||||||
await t.runAsync(() => i18n.apply(lang, save: false));
|
await t.runAsync(() => i18n.apply(lang, save: false));
|
||||||
addTearDown(() => i18n.apply('ko', save: false));
|
addTearDown(() => i18n.apply('ko', save: false));
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_b6shot_');
|
final tmp = testTempDir('jj_b6shot_');
|
||||||
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
||||||
// 시험 파일
|
// 시험 파일
|
||||||
File(p.join(tmp.path, 'Show', 'ep01.mkv'))
|
File(p.join(tmp.path, 'Show', 'ep01.mkv'))
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../test/support/fake_recycle_bin.dart';
|
import '../test/support/fake_recycle_bin.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
|
|
||||||
/// 기기 감독 (Windows) 확인용: 실제 앱 화면을 띄워 누르고 단계마다 PNG (JJ_SHOT_DIR) 로 남긴다.
|
/// 기기 감독 (Windows) 확인용: 실제 앱 화면을 띄워 누르고 단계마다 PNG (JJ_SHOT_DIR) 로 남긴다.
|
||||||
/// 65 · 94 · 98 (휴지통 · 휴지통 없는 위치 · 오류 문구), 37 (경로 입력), 124 · 130 (마스터 · 최상), 123 (AI 그림).
|
/// 65 · 94 · 98 (휴지통 · 휴지통 없는 위치 · 오류 문구), 37 (경로 입력), 124 · 130 (마스터 · 최상), 123 (AI 그림).
|
||||||
|
|
@ -30,9 +31,7 @@ void main() {
|
||||||
// 시험 폴더: 항목이 아주 많은 시스템 임시 폴더 대신 (JJ_SHOT_TMP, 없으면 시스템 임시 폴더)
|
// 시험 폴더: 항목이 아주 많은 시스템 임시 폴더 대신 (JJ_SHOT_TMP, 없으면 시스템 임시 폴더)
|
||||||
Directory tempDir(String prefix) {
|
Directory tempDir(String prefix) {
|
||||||
final base = Platform.environment['JJ_SHOT_TMP'];
|
final base = Platform.environment['JJ_SHOT_TMP'];
|
||||||
if (base == null || base.isEmpty) return Directory.systemTemp.createTempSync(prefix);
|
return testTempDir(prefix, base: base);
|
||||||
Directory(base).createSync(recursive: true);
|
|
||||||
return Directory(base).createTempSync(prefix);
|
|
||||||
}
|
}
|
||||||
final key = GlobalKey();
|
final key = GlobalKey();
|
||||||
const sizes = [('narrow', Size(700, 900)), ('wide', Size(1280, 800))];
|
const sizes = [('narrow', Size(700, 900)), ('wide', Size(1280, 800))];
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:jj_mkvmaker/app/i18n_controller.dart';
|
import 'package:jj_mkvmaker/app/i18n_controller.dart';
|
||||||
import 'package:jj_mkvmaker/ui/file_tools.dart';
|
import 'package:jj_mkvmaker/ui/file_tools.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 관리자 지시 (10/18): X-plore P3 화면을 PNG 로 (JJ_SHOT_DIR, 없으면 임시 폴더) - 해시 창 · 폴더 속성 · 16진 보기.
|
/// 관리자 지시 (10/18): X-plore P3 화면을 PNG 로 (JJ_SHOT_DIR, 없으면 임시 폴더) - 해시 창 · 폴더 속성 · 16진 보기.
|
||||||
|
|
@ -23,8 +24,7 @@ void main() {
|
||||||
addTearDown(t.view.reset);
|
addTearDown(t.view.reset);
|
||||||
await t.runAsync(() => i18n.apply(lang, save: false));
|
await t.runAsync(() => i18n.apply(lang, save: false));
|
||||||
addTearDown(() => i18n.apply('ko', save: false));
|
addTearDown(() => i18n.apply('ko', save: false));
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_p3shot_');
|
final tmp = testTempDir('jj_p3shot_');
|
||||||
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
||||||
final file = File(p.join(tmp.path, '영상 폴더', 'ep01 긴 이름의 동영상 파일.mkv'))
|
final file = File(p.join(tmp.path, '영상 폴더', 'ep01 긴 이름의 동영상 파일.mkv'))
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
..writeAsBytesSync(List.generate(5000, (i) => i % 256));
|
..writeAsBytesSync(List.generate(5000, (i) => i % 256));
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
import 'package:jj_mkvmaker/ui/wifi_share_page.dart';
|
import 'package:jj_mkvmaker/ui/wifi_share_page.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// 관리자 지시 (10/18): 89 Wi-Fi 공유 화면을 PNG 로 (JJ_SHOT_DIR) - 켜기 전 · 켠 뒤 (코드 · 주소 · QR · 남은 시간 · 접속 기록).
|
/// 관리자 지시 (10/18): 89 Wi-Fi 공유 화면을 PNG 로 (JJ_SHOT_DIR) - 켜기 전 · 켠 뒤 (코드 · 주소 · QR · 남은 시간 · 접속 기록).
|
||||||
|
|
@ -37,8 +38,7 @@ void main() {
|
||||||
WifiShare.debugLoopbackOnly = false;
|
WifiShare.debugLoopbackOnly = false;
|
||||||
WifiShare.debugAddresses = null;
|
WifiShare.debugAddresses = null;
|
||||||
});
|
});
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_wifishot_');
|
final tmp = testTempDir('jj_wifishot_');
|
||||||
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
||||||
final dir = Directory(p.join(tmp.path, '여행 사진'))..createSync();
|
final dir = Directory(p.join(tmp.path, '여행 사진'))..createSync();
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||||
final shotKey = GlobalKey();
|
final shotKey = GlobalKey();
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||||
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// X-plore 비교 P1 (관리자 지시 10/18): X-plore 스타일 탐색기를 PNG 로 (JJ_SHOT_DIR, 없으면 임시 폴더).
|
/// X-plore 비교 P1 (관리자 지시 10/18): X-plore 스타일 탐색기를 PNG 로 (JJ_SHOT_DIR, 없으면 임시 폴더).
|
||||||
|
|
@ -31,8 +32,7 @@ void main() {
|
||||||
addTearDown(t.view.reset);
|
addTearDown(t.view.reset);
|
||||||
await t.runAsync(() => i18n.apply(lang, save: false));
|
await t.runAsync(() => i18n.apply(lang, save: false));
|
||||||
addTearDown(() => i18n.apply('ko', save: false));
|
addTearDown(() => i18n.apply('ko', save: false));
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_xpshot_');
|
final tmp = testTempDir('jj_xpshot_');
|
||||||
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
||||||
final a = Directory(p.join(tmp.path, 'Videos'))..createSync();
|
final a = Directory(p.join(tmp.path, 'Videos'))..createSync();
|
||||||
final b = Directory(p.join(tmp.path, 'Backup'))..createSync();
|
final b = Directory(p.join(tmp.path, 'Backup'))..createSync();
|
||||||
for (final n in ['Show S01', 'Movies']) {
|
for (final n in ['Show S01', 'Movies']) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import 'package:jj_mkvmaker/ui/explorer_grid.dart';
|
||||||
import 'package:jj_mkvmaker/ui/storage_page.dart';
|
import 'package:jj_mkvmaker/ui/storage_page.dart';
|
||||||
import 'package:jj_mkvmaker/ui/text_viewer.dart';
|
import 'package:jj_mkvmaker/ui/text_viewer.dart';
|
||||||
import 'package:jj_mkvmaker/ui/theme.dart';
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
||||||
|
import 'support/temp_dir.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
/// X-plore 비교 g · h · i · P3 (관리자 지시 10/18): 격자 보기 · 글 뷰어 · 일괄 이름 (날짜) · 저장 공간 그림을 PNG 로
|
/// X-plore 비교 g · h · i · P3 (관리자 지시 10/18): 격자 보기 · 글 뷰어 · 일괄 이름 (날짜) · 저장 공간 그림을 PNG 로
|
||||||
|
|
@ -31,8 +32,7 @@ void main() {
|
||||||
addTearDown(t.view.reset);
|
addTearDown(t.view.reset);
|
||||||
await t.runAsync(() => i18n.apply(lang, save: false));
|
await t.runAsync(() => i18n.apply(lang, save: false));
|
||||||
addTearDown(() => i18n.apply('ko', save: false));
|
addTearDown(() => i18n.apply('ko', save: false));
|
||||||
final tmp = Directory.systemTemp.createTempSync('jj_xptshot_');
|
final tmp = testTempDir('jj_xptshot_');
|
||||||
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
||||||
// 그림 (색이 다른 작은 그림) · 동영상 이름 · 글 (CP949)
|
// 그림 (색이 다른 작은 그림) · 동영상 이름 · 글 (CP949)
|
||||||
final pics = <String>[];
|
final pics = <String>[];
|
||||||
for (var i = 0; i < 7; i++) {
|
for (var i = 0; i < 7; i++) {
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,33 @@
|
||||||
# - 다른 worktree · 세션이 같은 시험을 동시에 돌리면 그쪽 폴더가 섞일 수 있다 (이름으로 확인).
|
# - 다른 worktree · 세션이 같은 시험을 동시에 돌리면 그쪽 폴더가 섞일 수 있다 (이름으로 확인).
|
||||||
# - 이미 있던 폴더는 건드리지 않는다 (지우지 않음).
|
# - 이미 있던 폴더는 건드리지 않는다 (지우지 않음).
|
||||||
# 사용 (app 폴더에서): powershell -ExecutionPolicy Bypass -File tool\test_temp_check.ps1 [flutter test 인자…]
|
# 사용 (app 폴더에서): powershell -ExecutionPolicy Bypass -File tool\test_temp_check.ps1 [flutter test 인자…]
|
||||||
|
# 통합 시험 · 캡처도 (관리자 지시 10/19, 28 이 찾음): … test_temp_check.ps1 integration_test\windows_b6_shot_test.dart -d windows
|
||||||
|
# - 폴더 이름 앞부분은 test 와 integration_test 두 곳의 시험 소스에서 모은다
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
$app = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
$app = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
||||||
$temp = [System.IO.Path]::GetTempPath()
|
$temp = [System.IO.Path]::GetTempPath()
|
||||||
|
|
||||||
# 시험 소스가 쓰는 임시 폴더 이름 앞부분 (createTemp('jj_x_') · createTempSync('jj_x_'))
|
# 시험 소스가 쓰는 임시 폴더 이름 앞부분 (createTemp('jj_x_') · createTempSync('jj_x_'))
|
||||||
$prefixes = @(Get-ChildItem (Join-Path $app 'test') -Recurse -Filter *.dart |
|
# 넘겨받은 시험 파일 (.dart) 이 있으면 그 파일들과 support 폴더만 본다 - 다른 세션 · worktree 가 같은 때 돌린 시험의 폴더를 세지 않게
|
||||||
ForEach-Object { [regex]::Matches((Get-Content $_.FullName -Raw -Encoding utf8), 'createTemp(?:Sync)?\(''(jj[^''$]*)''') } |
|
# (10/19: b6 캡처 앞뒤에 다른 세션의 단위 시험 폴더 jj_explorer_ · jj_sync_ 가 섞여 거짓 실패)
|
||||||
|
$named = @($args | Where-Object { "$_" -like '*.dart' } | ForEach-Object { Join-Path $app "$_" } | Where-Object { Test-Path $_ })
|
||||||
|
$sources = if ($named.Count -gt 0) {
|
||||||
|
# 그 파일들이 가져다 쓰는 support 파일만 함께 (import 'support/…') - 다른 세션의 시험과 이름이 겹치지 않게 (10/19: jj_fake_recycle_)
|
||||||
|
$support = @($named | ForEach-Object {
|
||||||
|
$dir = Split-Path $_
|
||||||
|
[regex]::Matches((Get-Content $_ -Raw -Encoding utf8), "import '(support/[^']+\.dart)'") |
|
||||||
|
ForEach-Object { Join-Path $dir $_.Groups[1].Value } })
|
||||||
|
@($named) + @($support | Where-Object { Test-Path $_ })
|
||||||
|
} else {
|
||||||
|
@(@('test', 'integration_test') | ForEach-Object { Join-Path $app $_ } | Where-Object { Test-Path $_ } |
|
||||||
|
ForEach-Object { Get-ChildItem $_ -Recurse -Filter *.dart | ForEach-Object { $_.FullName } })
|
||||||
|
}
|
||||||
|
# 이름이 하나도 없으면 (임시 폴더를 만들지 않는 시험) 새 jj 폴더는 참고로만 보인다
|
||||||
|
# 이름 앞부분: createTemp('jj_x_') · createTempSync('jj_x_') · testTempDir('jj_x_') (integration_test/support/temp_dir.dart)
|
||||||
|
$prefixes = @($sources |
|
||||||
|
ForEach-Object { [regex]::Matches((Get-Content $_ -Raw -Encoding utf8), '(?:createTemp(?:Sync)?|testTempDir)\(''(jj[^''$]*)''') } |
|
||||||
ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique)
|
ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique)
|
||||||
if ($prefixes.Count -eq 0) { throw '시험 소스에서 임시 폴더 이름을 찾지 못했습니다' }
|
if ($prefixes.Count -eq 0 -and $named.Count -eq 0) { throw '시험 소스에서 임시 폴더 이름을 찾지 못했습니다' }
|
||||||
|
|
||||||
function Get-TestTemp {
|
function Get-TestTemp {
|
||||||
@(Get-ChildItem $temp -Directory -Filter 'jj*' -ErrorAction SilentlyContinue | ForEach-Object { $_.Name })
|
@(Get-ChildItem $temp -Directory -Filter 'jj*' -ErrorAction SilentlyContinue | ForEach-Object { $_.Name })
|
||||||
|
|
@ -34,6 +52,12 @@ $left = @(Get-TestTemp | Where-Object { -not $before.ContainsKey($_) } | Where-O
|
||||||
$n = $_
|
$n = $_
|
||||||
@($prefixes | Where-Object { $n.StartsWith($_) }).Count -gt 0
|
@($prefixes | Where-Object { $n.StartsWith($_) }).Count -gt 0
|
||||||
})
|
})
|
||||||
|
# 참고: 시험 소스의 이름이 아닌 새 jj 폴더 (앱 코드가 만든 것일 수 있음 - 실패로 세지 않고 보이기만)
|
||||||
|
$other = @(Get-TestTemp | Where-Object { -not $before.ContainsKey($_) -and $left -notcontains $_ })
|
||||||
|
if ($other.Count -gt 0) {
|
||||||
|
Write-Host ("참고 - 시험 소스에 없는 이름의 새 jj 폴더 {0}개:" -f $other.Count)
|
||||||
|
$other | Sort-Object | ForEach-Object { Write-Host " $_" }
|
||||||
|
}
|
||||||
if ($left.Count -gt 0) {
|
if ($left.Count -gt 0) {
|
||||||
Write-Host ("시험이 남긴 임시 폴더 {0}개 (%TEMP%):" -f $left.Count)
|
Write-Host ("시험이 남긴 임시 폴더 {0}개 (%TEMP%):" -f $left.Count)
|
||||||
$left | Sort-Object | ForEach-Object { Write-Host " $_" }
|
$left | Sort-Object | ForEach-Object { Write-Host " $_" }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue