90 lines
4.2 KiB
Dart
90 lines
4.2 KiB
Dart
// subtitle_editor_panes.dart 약속 시험: 실제 SubtitleEditorController 로 조각의 입력 · 출력 (편집기 · 콜백) · 오류 표시를 본다.
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/app/subtitle_editor_controller.dart';
|
|
import 'package:jj_mkvmaker/core/srt.dart';
|
|
import 'package:jj_mkvmaker/ui/subtitle_editor_panes.dart';
|
|
|
|
SubtitleEditorController _editor() => SubtitleEditorController([
|
|
Cue(const Duration(seconds: 1), const Duration(seconds: 2), '첫 줄'),
|
|
Cue(const Duration(seconds: 3), const Duration(seconds: 4), '둘째 줄'),
|
|
], saveCharset: 'UTF-8');
|
|
|
|
Widget _host(Widget child) => MaterialApp(home: Scaffold(body: child));
|
|
|
|
void main() {
|
|
testWidgets('SubtitleCueTable: 번호를 누르면 onSelect · 시간 고치기 · 틀린 형식 · 줄 추가 · 삭제는 편집기로', (tester) async {
|
|
tester.view.physicalSize = const Size(1200, 700);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final e = _editor();
|
|
final active = ValueNotifier<Cue?>(null);
|
|
final picked = <Cue>[];
|
|
await tester.pumpWidget(_host(ListenableBuilder(
|
|
listenable: e, builder: (_, _) => SubtitleCueTable(editor: e, active: active, onSelect: picked.add))));
|
|
await tester.tap(find.text('2'));
|
|
expect(picked, [e.cues[1]]);
|
|
|
|
await tester.enterText(find.text('00:00:01,000'), '00:00:01,500');
|
|
expect(e.cues[0].start, const Duration(milliseconds: 1500));
|
|
await tester.enterText(find.text('00:00:03,000'), '말도 안 됨');
|
|
await tester.pump();
|
|
expect(find.text('형식 오류'), findsOneWidget);
|
|
expect(e.cues[1].start, const Duration(seconds: 3));
|
|
|
|
await tester.tap(find.byTooltip('아래에 줄 추가').first);
|
|
await tester.pump();
|
|
expect(e.cues.length, 3);
|
|
await tester.tap(find.byTooltip('줄 삭제').last);
|
|
await tester.pump();
|
|
expect(e.cues.length, 2);
|
|
});
|
|
|
|
testWidgets('SubtitleTransportBar: 고른 줄이 없으면 줄 단추 꺼짐 · 누르면 콜백', (tester) async {
|
|
// 줄 단추가 모두 보이는 넓은 화면 (좁으면 밀어서 본다)
|
|
tester.view.physicalSize = const Size(1800, 600);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final calls = <String>[];
|
|
Widget bar(bool sel) => _host(SubtitleTransportBar(
|
|
position: ValueNotifier(const Duration(seconds: 5)),
|
|
duration: const Duration(minutes: 1),
|
|
playing: false,
|
|
rate: 1.0,
|
|
hasSelection: sel,
|
|
onSeekBy: (ms) => calls.add('seek $ms'),
|
|
onPlayPause: () => calls.add('play'),
|
|
onRate: (r) => calls.add('rate $r'),
|
|
onInsert: () => calls.add('insert'),
|
|
onPlaySelected: () => calls.add('playSel'),
|
|
onSetStart: () => calls.add('start'),
|
|
onSetEnd: () => calls.add('end'),
|
|
onAlign: () => calls.add('align'),
|
|
));
|
|
await tester.pumpWidget(bar(false));
|
|
expect(find.text('00:00:05,000 / 00:01:00,000'), findsOneWidget);
|
|
expect(tester.widget<OutlinedButton>(find.widgetWithText(OutlinedButton, '시작 = 현재')).onPressed, isNull);
|
|
await tester.tap(find.byIcon(Icons.replay_5));
|
|
await tester.tap(find.byIcon(Icons.play_circle));
|
|
await tester.tap(find.text('+ 여기에 새 줄'));
|
|
await tester.pumpWidget(bar(true));
|
|
await tester.tap(find.text('끝 = 현재'));
|
|
await tester.tap(find.text('1.0x'));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('2.0x').last);
|
|
await tester.pumpAndSettle();
|
|
expect(calls, ['seek -5000', 'play', 'insert', 'end', 'rate 2.0']);
|
|
});
|
|
|
|
testWidgets('SubtitleVideoPane: 지금 위치의 줄 · 재생 오류를 겹쳐 보인다', (tester) async {
|
|
final e = _editor();
|
|
final pos = ValueNotifier(const Duration(milliseconds: 1200));
|
|
await tester.pumpWidget(_host(SubtitleVideoPane(view: const SizedBox(), editor: e, position: pos, error: '열 수 없음')));
|
|
expect(find.text('첫 줄'), findsOneWidget);
|
|
expect(find.textContaining('열 수 없음'), findsOneWidget);
|
|
pos.value = const Duration(milliseconds: 2500);
|
|
await tester.pump();
|
|
expect(find.text('첫 줄'), findsNothing);
|
|
});
|
|
}
|