69 lines
3.8 KiB
Dart
69 lines
3.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/ui/jj_title_bar.dart';
|
|
import 'package:jj_mkvmaker/ui/tail_text.dart';
|
|
|
|
/// W 공용 위젯 약속 (JjTitleBar): 제목은 한 줄 (넘치면 "…", 경로는 끝이 보이게) · 좁으면 뒤 단추들을 둘째 줄로 (숨기지 않음) ·
|
|
/// 300 · 412 폭 · 글자 배율 2 에서 넘치지 않음. 위젯 하나에 대해 한 번만 둔다 (설계 7-2)
|
|
void main() {
|
|
const long = '휴지통 · 1234개 · 56.7 GB - 아주 긴 제목이 이어져 한 줄에 다 들어가지 않는 경우';
|
|
|
|
Future<void> show(WidgetTester t, PreferredSizeWidget Function(BuildContext) bar, {double width = 412, double scale = 1}) async {
|
|
t.view.physicalSize = Size(width, 800);
|
|
t.view.devicePixelRatio = 1;
|
|
addTearDown(t.view.reset);
|
|
await t.pumpWidget(MaterialApp(
|
|
home: MediaQuery(
|
|
data: MediaQueryData(size: Size(width, 800), textScaler: TextScaler.linear(scale)),
|
|
child: Builder(builder: (ctx) => Scaffold(appBar: bar(ctx), body: const SizedBox.expand())),
|
|
),
|
|
));
|
|
}
|
|
|
|
List<Widget> wide() => [
|
|
OutlinedButton.icon(onPressed: () {}, icon: const Icon(Icons.create_new_folder_outlined), label: const Text('새 폴더')),
|
|
FilledButton(onPressed: () {}, child: const Text('이 폴더 고르기')),
|
|
IconButton(tooltip: '보이기', icon: const Icon(Icons.visibility_off_outlined), onPressed: () {}),
|
|
];
|
|
|
|
for (final width in [300.0, 412.0]) {
|
|
for (final scale in [1.0, 2.0]) {
|
|
testWidgets('폭 $width · 배율 $scale: 긴 제목 한 줄 · 넘치지 않음', (t) async {
|
|
await show(t, (ctx) => jjTitleBar(ctx, title: long, actions: [IconButton(icon: const Icon(Icons.refresh), onPressed: () {})]),
|
|
width: width, scale: scale);
|
|
expect(t.takeException(), isNull);
|
|
final text = t.widget<Text>(find.text(long));
|
|
expect([text.maxLines, text.overflow], [1, TextOverflow.ellipsis]);
|
|
expect(t.getRect(find.byIcon(Icons.refresh)).right, lessThanOrEqualTo(width));
|
|
});
|
|
|
|
testWidgets('폭 $width · 배율 $scale: 넓은 단추는 좁으면 둘째 줄 - 모두 보이고 넘치지 않음', (t) async {
|
|
await show(t, (ctx) => jjTitleBar(ctx, title: long, lowerActions: wide(), actions: [IconButton(icon: const Icon(Icons.save), onPressed: () {})], twoLinesBelow: 480), width: width, scale: scale);
|
|
expect(t.takeException(), isNull);
|
|
final title = t.getRect(find.text(long));
|
|
for (final f in [find.text('새 폴더'), find.text('이 폴더 고르기'), find.byIcon(Icons.visibility_off_outlined)]) {
|
|
expect(f, findsOneWidget);
|
|
final r = t.getRect(f);
|
|
expect(r.top, greaterThan(title.bottom), reason: '제목 아래 줄');
|
|
expect([r.left >= 0, r.right <= width], [true, true], reason: '화면 안에 다 보임');
|
|
}
|
|
expect(t.getRect(find.byIcon(Icons.save)).bottom, lessThanOrEqualTo(title.bottom + 20), reason: '[actions] 는 위 줄에 남음');
|
|
});
|
|
}
|
|
}
|
|
|
|
testWidgets('넓은 화면에서는 한 줄 (둘째 줄 없음)', (t) async {
|
|
await show(t, (ctx) => jjTitleBar(ctx, title: '제목', lowerActions: wide(), twoLinesBelow: 480), width: 960);
|
|
expect(t.takeException(), isNull);
|
|
expect((t.getRect(find.text('새 폴더')).center.dy - t.getRect(find.text('제목')).center.dy).abs(), lessThan(4));
|
|
});
|
|
|
|
testWidgets('경로 제목은 끝 (지금 폴더) 이 보임', (t) async {
|
|
const path = 'NAS / 동영상 / 2026 / 여름 휴가 / 바다에서 찍은 것';
|
|
await show(t, (ctx) => jjTitleBar(ctx, title: path, path: true), width: 300);
|
|
expect(t.takeException(), isNull);
|
|
expect(find.byType(TailText), findsOneWidget);
|
|
expect(find.textContaining('바다에서 찍은 것'), findsOneWidget);
|
|
});
|
|
}
|