import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/core/rsync_filter.dart'; import 'package:jj_mkvmaker/core/sync_tools.dart'; import 'package:jj_mkvmaker/ui/sync_preview_view.dart'; /// 관리자 지시 (10/20, 28 지적): 경고 글 안의 옵션 (--filter=H a.txt) 이 좁은 창에서 "--" 와 "filter=…" 로 갈리던 것 void main() { double widest(String s, {bool min = true}) { final tp = TextPainter(text: TextSpan(text: s, style: const TextStyle(fontSize: 12)), textDirection: TextDirection.ltr)..layout(); final w = min ? tp.minIntrinsicWidth : tp.maxIntrinsicWidth; tp.dispose(); return w; } test('옵션 글은 줄바꿈 자리가 없다 (가장 좁게 접어도 한 줄 폭)', () { for (final o in ['--filter=H a.txt', '-f"- *.log"', '--files-from=list/a b.txt', '-C']) { final u = unbreakableOption(o); expect(widest(u), closeTo(widest(u, min: false), 0.01), reason: o); expect(u.replaceAll('\u2060', '').replaceAll('\u00A0', ' '), o, reason: '보이는 글은 그대로'); } // 묶지 않은 글은 줄이 갈릴 수 있다 (시험이 실제로 무언가를 보는지) expect(widest('--filter=H a.txt'), lessThan(widest('--filter=H a.txt', min: false))); }); // 관리자 지시 (10/20): 묶은 글을 복사해 옵션 칸에 붙여 넣어도 rsync 가 같은 인수로 읽는다 test('묶은 옵션 글 · 다른 곳의 글을 붙여 넣어도 인수는 원래대로', () { const o = '-a --delete --filter="H a.txt" -f"- *.log"'; final pasted = unbreakableOption(o); expect(pasted, isNot(o)); expect(cleanOptionText(pasted), o); expect(splitOptions(pasted), splitOptions(o)); expect(splitOptions(pasted), ['-a', '--delete', '--filter=H a.txt', '-f- *.log']); // 따옴표 안의 줄바꿈 없는 빈칸도 보통 빈칸 (거르기 규칙 "H a.txt" 가 그대로) expect(RsyncFilter.parse(pasted).unsupported, RsyncFilter.parse(o).unsupported); expect(RsyncFilter.parse(pasted).excluded('old.log', isDir: false), isTrue); // 웹 · 문서에서 온 글 (U+202F · U+200B · U+FEFF) expect(splitOptions('\uFEFF-av\u202F--delete\u200B'), ['-av', '--delete']); }); testWidgets('옵션 칸 (OptionTextFormatter): 붙여 넣은 묶은 글을 고쳐 받고 커서는 끝에', (tester) async { final ctl = TextEditingController(); await tester.pumpWidget(MaterialApp( home: Scaffold(body: TextField(controller: ctl, inputFormatters: const [OptionTextFormatter()])))); final pasted = unbreakableOption('--filter=H a.txt'); await tester.enterText(find.byType(TextField), pasted); await tester.pump(); expect(ctl.text, '--filter=H a.txt'); expect(ctl.selection.baseOffset, ctl.text.length); ctl.dispose(); }); }