JJ_MKVMaker/test/ai_confirm_test.dart

83 lines
4.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:jj_mkvmaker/app/app_controller.dart';
import 'package:jj_mkvmaker/core/languages.dart';
import 'package:jj_mkvmaker/core/models.dart';
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
import 'package:jj_mkvmaker/services/model_store.dart';
import 'package:jj_mkvmaker/services/platform_services.dart';
import 'package:jj_mkvmaker/ui/ai_dialog.dart';
/// 138: [MKV 만들기] 와 헷갈려 오래 걸리는 AI 작업이 돌지 않게 - AI 쪽은 늘 할 일 · 대상 수 · 자막 언어 · 예상 시간을 보이고 묻는다
void main() {
test('예상 시간: 영상 1시간 ≈ 음성인식 15~30분 + 번역할 언어마다 10~20분', () {
expect(aiEstimateMinutes(const Duration(hours: 1), 0), (15, 30));
expect(aiEstimateMinutes(const Duration(hours: 2), 2), (70, 140));
expect(aiEstimateMinutes(Duration.zero, 2), isNull);
// 197: 짧은 동영상은 '약 1~1분' 이 아니라 '1분 안', 같은 수면 하나만
expect(aiEstimateText(aiEstimateMinutes(const Duration(seconds: 30), 0)!), '1분 안');
expect(aiEstimateText((3, 3)), '약 3분');
expect(aiEstimateText((15, 30)), '약 15~30분');
final ko = languageOf('ko'), en = languageOf('en'), ja = languageOf('ja');
expect(aiTranslateCount(AiOptions(source: ko, targets: {ko, en, ja}, whisper: whisperModels.first)), 2);
expect(aiTranslateCount(AiOptions(targets: {ko, en, ja}, whisper: whisperModels.first)), 2, reason: '자동 감지면 하나는 원어로');
});
testWidgets('"매번 묻기" 를 끄면 묻지 않되 (사용자 설정) 3초 알림 [취소] 뒤에 시작 - [취소] 면 시작하지 않음', (tester) async {
tester.view.physicalSize = const Size(1400, 1000);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
c.settings.askAiOptions = false;
final v1 = VideoItem(r'C:\v\a.mp4')..info = const MediaInfo(duration: Duration(minutes: 30));
final v2 = VideoItem(r'C:\v\b.mp4')..info = const MediaInfo(duration: Duration(minutes: 30));
late BuildContext ctx;
await tester.pumpWidget(MaterialApp(home: Scaffold(body: Builder(builder: (context) {
ctx = context;
return const SizedBox();
}))));
final logs0 = c.logs.length;
final done = showAiDialog(ctx, c, v1, targets: [v1, v2], thenBuild: true);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
expect(find.byType(AlertDialog), findsNothing, reason: '묻는 창은 띄우지 않는다 (사용자 설정)');
expect(find.text('AI 자막 → MKV (동영상 2개 · 약 35~70분) 을 시작합니다'), findsOneWidget);
expect(c.busy, isFalse, reason: '3초 동안은 시작하지 않음');
await tester.tap(find.text('취소'));
await tester.pump(const Duration(seconds: 4));
await done;
expect(c.busy, isFalse);
expect(c.logs.length, logs0, reason: '[취소] 면 아무것도 하지 않음');
});
test('3초 알림 글: 길이를 모르면 시간 없이', () {
final o = AiOptions(targets: {languageOf('ko')}, whisper: whisperModels.first);
expect(aiStartNotice([VideoItem(r'C:\v\a.mp4')], o, thenBuild: false), 'AI 자막 (동영상 1개) 을 시작합니다');
});
testWidgets('묻기가 켜져 있으면 (처음 값) 설정 창 맨 위에 계획 (할 일 · 대상 · 언어 · 예상 시간)', (tester) async {
tester.view.physicalSize = const Size(1400, 1000);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
expect(c.settings.askAiOptions, isTrue);
final v1 = VideoItem(r'C:\v\a.mp4')..info = const MediaInfo(duration: Duration(hours: 1));
late BuildContext ctx;
await tester.pumpWidget(MaterialApp(home: Scaffold(body: Builder(builder: (context) {
ctx = context;
return const SizedBox();
}))));
final done = showAiDialog(ctx, c, v1, targets: [v1]);
await tester.pumpAndSettle();
expect(find.text('AI 자막 만들기 (MKV 는 만들지 않음)'), findsOneWidget);
expect(find.text('동영상 1개'), findsOneWidget);
expect(find.text('예상 시간'), findsOneWidget);
expect(find.textContaining('1시간 0분'), findsOneWidget);
await tester.tap(find.text('취소'));
await tester.pumpAndSettle();
await done;
expect(c.busy, isFalse);
});
}