80 lines
3.7 KiB
Dart
80 lines
3.7 KiB
Dart
import 'dart:io';
|
|
import 'dart:ui' as ui;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:integration_test/integration_test.dart';
|
|
import 'package:jj_mkvmaker/app/i18n_controller.dart';
|
|
import 'package:jj_mkvmaker/core/sync_tools.dart';
|
|
import 'package:jj_mkvmaker/ui/sync_preview_view.dart';
|
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
/// 관리자 지시 (10/20, 28 지적): 알아볼 수 없는 옵션 안내 - 끝 문구가 문제 종류에 맞는지, 412 에서 넘치지 않는지.
|
|
/// 확인 창의 빨간 글 (OptionProblemNote) 과 설정 칸 아래 글 (errorText, 3줄까지) 을 크기 412 · 960, 언어 ko · en · ja 로 찍는다.
|
|
/// 실행: flutter test integration_test\windows_option_problem_shot_test.dart -d windows (JJ_SHOT_DIR 에 PNG)
|
|
void main() {
|
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_optproblem');
|
|
const cases = [
|
|
'-a --delete --exclude="a.tmp --exclude=keep.txt', // 닫히지 않은 따옴표
|
|
'-a delete', // 경로로 읽힘
|
|
'-a --delete --exclude', // 값 없음
|
|
'-a ---delete «x»', // 이상한 글자
|
|
'-av delete --exclude', // 여러 종류
|
|
];
|
|
for (final lang in ['ko', 'en', 'ja']) {
|
|
for (final (w, hh) in [(412, 900), (960, 600)]) {
|
|
testWidgets('옵션 안내 $lang ${w}x$hh', (t) async {
|
|
t.view.physicalSize = Size(w.toDouble(), hh.toDouble());
|
|
t.view.devicePixelRatio = 1;
|
|
addTearDown(t.view.reset);
|
|
await t.runAsync(() => i18n.apply(lang, save: false));
|
|
addTearDown(() => i18n.apply('ko', save: false));
|
|
final shotKey = GlobalKey();
|
|
await t.pumpWidget(RepaintBoundary(
|
|
key: shotKey,
|
|
child: MaterialApp(
|
|
theme: buildTheme(),
|
|
debugShowCheckedModeBanner: false,
|
|
home: Scaffold(
|
|
body: ListView(padding: const EdgeInsets.all(16), children: [
|
|
for (final o in cases) ...[
|
|
Text(o, style: const TextStyle(fontFamily: 'monospace', fontSize: 12)),
|
|
OptionProblemNote(optionProblems(o)),
|
|
const SizedBox(height: 8),
|
|
],
|
|
// 설정 칸 (copy_sync_settings 의 rsync 옵션 칸과 같은 폭 · 글 줄 수)
|
|
SizedBox(
|
|
width: 380,
|
|
child: TextField(
|
|
controller: TextEditingController(text: cases.last),
|
|
decoration: InputDecoration(
|
|
isDense: true,
|
|
border: const OutlineInputBorder(),
|
|
errorText: optionProblemText(optionProblems(cases.last)),
|
|
errorMaxLines: 3,
|
|
),
|
|
),
|
|
),
|
|
]),
|
|
),
|
|
),
|
|
));
|
|
for (var i = 0; i < 4; i++) {
|
|
await t.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 60)));
|
|
await t.pump(const Duration(milliseconds: 60));
|
|
}
|
|
expect(t.takeException(), isNull, reason: '넘침');
|
|
expect(find.byType(OptionProblemNote), findsNWidgets(cases.length));
|
|
final b = shotKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
|
|
final img = await t.runAsync(() => b.toImage());
|
|
final bytes = await t.runAsync(() => img!.toByteData(format: ui.ImageByteFormat.png));
|
|
Directory(out).createSync(recursive: true);
|
|
File(p.join(out, 'optproblem_${lang}_$w.png')).writeAsBytesSync(bytes!.buffer.asUint8List());
|
|
});
|
|
}
|
|
}
|
|
}
|