380 lines
22 KiB
Dart
380 lines
22 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/app/settings.dart';
|
|
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
|
import 'package:jj_mkvmaker/ui/quick_look.dart';
|
|
import 'package:jj_mkvmaker/ui/explorer_drag.dart';
|
|
import 'package:jj_mkvmaker/ui/storage_page.dart';
|
|
import 'package:path/path.dart' as p;
|
|
import 'support/fake_recycle_bin.dart';
|
|
import 'package:jj_mkvmaker/platform/windows/recycle_bin.dart' show recycleBinForTest;
|
|
import 'support/explorer_harness.dart';
|
|
|
|
/// E5e: 예전 explorer_test.dart 에서 나눈 탐색기 화면 시험 - 단축키 (TC · Windows 탐색기) · 창 사이 끌어 놓기 · 진행 패널 · 빠른 보기 · 저장 공간 분석 · 열 머리 정렬
|
|
void main() {
|
|
useExplorerFixture();
|
|
|
|
testWidgets('83: Total Commander 모양 단축키 - F5 복사 · F7 새 폴더 · Space/Insert 표시 (Space 는 빠른 필터가 아님)', (tester) async {
|
|
File(p.join(left, 'e.txt')).writeAsStringSync('e');
|
|
c.settings.explorerStyle = 'totalcmd';
|
|
await open(tester);
|
|
await act(tester, () => tester.tap(find.text('doc')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
// Insert: 표시하고 다음 줄 (e.txt) 로, Space: 지금 줄 (e.txt) 표시
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.insert));
|
|
await calm(tester);
|
|
expect(find.textContaining('1개 표시함'), findsOneWidget);
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.space));
|
|
await calm(tester);
|
|
expect(find.textContaining('2개 표시함'), findsOneWidget, reason: 'Insert 뒤 다음 줄이 표시됨');
|
|
expect(find.byIcon(Icons.filter_alt), findsNothing, reason: 'Space 가 빠른 필터를 열지 않는다');
|
|
// F5 = 복사 (확인 창) - 취소
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f5));
|
|
await calm(tester);
|
|
expect(find.widgetWithText(FilledButton, '복사'), findsOneWidget);
|
|
await tester.tap(find.text('취소').last);
|
|
await calm(tester);
|
|
// F7 = 새 폴더
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f7));
|
|
await calm(tester);
|
|
expect(find.text('새 폴더'), findsWidgets);
|
|
await tester.tap(find.text('취소').last);
|
|
await calm(tester);
|
|
});
|
|
|
|
testWidgets('83 (28 지적): Total Commander 모양 F8 = 지우기 - 확인 창 [취소] 면 그대로, [휴지통으로] 면 휴지통으로', (tester) async {
|
|
final bin = recycleBinForTest;
|
|
if (bin is! FakeRecycleBin) return markTestSkipped('실제 휴지통 (JJ_TEST_REAL_RECYCLE=1) 에서는 건너뜀');
|
|
if (!Platform.isWindows) return markTestSkipped('휴지통은 Windows 만 (Android 는 앱 휴지통 시험)');
|
|
final victim = File(p.join(left, 'tcdel.txt'))..writeAsStringSync('x');
|
|
c.settings.explorerStyle = 'totalcmd';
|
|
await open(tester);
|
|
await settle(tester, () => find.text('tcdel').evaluate().isNotEmpty);
|
|
await act(tester, () => tester.tap(find.text('tcdel')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
|
|
// F8 → 확인 창 → [취소]: 아무것도 지우지 않음
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f8));
|
|
await calm(tester);
|
|
expect(find.text('휴지통으로 보내기'), findsOneWidget);
|
|
expect(find.widgetWithText(FilledButton, '휴지통으로'), findsOneWidget, reason: '처음 값은 휴지통 (영구 삭제 아님)');
|
|
await tester.tap(find.text('취소').last);
|
|
await calm(tester);
|
|
expect(victim.existsSync(), isTrue);
|
|
expect(bin.items, isEmpty);
|
|
|
|
// F8 → [휴지통으로]: 휴지통 길로 (영구 삭제가 아님)
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f8));
|
|
await calm(tester);
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '휴지통으로')));
|
|
await settle(tester, () => !victim.existsSync() && find.byType(SnackBar).evaluate().isNotEmpty);
|
|
expect(victim.existsSync(), isFalse);
|
|
expect(bin.items.keys, [victim.path], reason: '휴지통으로 보냄 (되돌릴 수 있음)');
|
|
expect(File(p.join(left, 'doc.txt')).existsSync(), isTrue, reason: '고른 것만');
|
|
expect(find.text('되돌리기'), findsOneWidget);
|
|
await calm(tester);
|
|
});
|
|
|
|
testWidgets('83: Windows 탐색기 모양 단축키 - Ctrl+A 모두 표시 · Ctrl+C 담기 · Ctrl+V 붙여넣기', (tester) async {
|
|
c.settings.explorerStyle = 'windows';
|
|
await open(tester);
|
|
await act(tester, () => tester.tap(find.text('doc.txt')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
await act(tester, () async {
|
|
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
|
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyA);
|
|
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
|
|
});
|
|
await calm(tester);
|
|
expect(find.textContaining('2개 표시함'), findsOneWidget, reason: 'doc.txt · sub');
|
|
await act(tester, () async {
|
|
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
|
|
await tester.sendKeyEvent(LogicalKeyboardKey.keyC);
|
|
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
|
|
});
|
|
await calm(tester);
|
|
expect(find.textContaining('담았습니다'), findsOneWidget);
|
|
});
|
|
|
|
group('82 창 사이 끌어 놓기', () {
|
|
test('놓을 수 있는 곳: 같은 창 · 자기 안 · 원본 폴더 자신은 안 됨', () {
|
|
final a = p.join('C:', 'x', 'a'), f = p.join('C:', 'x', 'f.txt');
|
|
expect(canDropInto(DragLoad(0, [f]), 1, p.join('C:', 'y')), isTrue);
|
|
expect(canDropInto(DragLoad(0, [f]), 0, p.join('C:', 'y')), isFalse, reason: '같은 창');
|
|
expect(canDropInto(DragLoad(0, [a]), 1, p.join(a, 'in')), isFalse, reason: '자기 안');
|
|
expect(canDropInto(DragLoad(0, [f]), 1, p.join('C:', 'x')), isFalse, reason: '원본 폴더 자신');
|
|
});
|
|
|
|
/// 오른쪽 창에 보이는 [name] 줄 (두 창 모두 같은 이름이 보이면 오른쪽 것)
|
|
Offset rightOf(WidgetTester tester, String name) {
|
|
final all = find.text(name).evaluate().map((e) => tester.getCenter(find.byWidget(e.widget).first)).toList()
|
|
..sort((x, y) => x.dx.compareTo(y.dx));
|
|
return all.last;
|
|
}
|
|
|
|
Future<void> mouseDrag(WidgetTester tester, Offset from, Offset to) async {
|
|
final g = await tester.startGesture(from, kind: PointerDeviceKind.mouse);
|
|
await g.moveBy(const Offset(20, 0));
|
|
await tester.pump();
|
|
await g.moveTo(to);
|
|
await tester.pump();
|
|
await g.up();
|
|
await calm(tester);
|
|
}
|
|
|
|
testWidgets('짧게 움직이면 고르기 · 같은 창에는 놓아도 아무 일 없음 · 묻기 [취소] 도 아무 일 없음', (tester) async {
|
|
await open(tester);
|
|
final doc = tester.getCenter(find.text('doc.txt').first);
|
|
// 4px 만 움직임 = 누르기 (끌기 아님)
|
|
final g = await tester.startGesture(doc, kind: PointerDeviceKind.mouse);
|
|
await g.moveBy(const Offset(4, 0));
|
|
await g.up();
|
|
await calm(tester);
|
|
expect(find.byType(AlertDialog), findsNothing);
|
|
// 같은 창의 sub 위에 놓기 - 못 놓음
|
|
await mouseDrag(tester, doc, tester.getCenter(find.text('sub').first));
|
|
expect(find.byType(AlertDialog), findsNothing, reason: '같은 창에는 놓지 않는다');
|
|
// 오른쪽 창 (right 폴더) 에 놓기 → 묻기 → 취소
|
|
await mouseDrag(tester, doc, rightOf(tester, 'right'));
|
|
expect(find.text('1개 항목을 놓았습니다'), findsOneWidget);
|
|
await tester.tap(find.text('취소').last);
|
|
await calm(tester);
|
|
expect(File(p.join(left, 'doc.txt')).existsSync(), isTrue);
|
|
expect(File(p.join(right, 'doc.txt')).existsSync(), isFalse);
|
|
});
|
|
|
|
testWidgets('이동 → 같은 이름을 덮어쓴 파일은 되돌리지 않는다고 파일로 알림 (15 지적)', (tester) async {
|
|
File(p.join(right, 'doc.txt')).writeAsStringSync('old');
|
|
File(p.join(left, 'e.txt')).writeAsStringSync('e');
|
|
c.settings
|
|
..explorerDropAction = 'move'
|
|
..copyConflict = 'overwrite';
|
|
await open(tester);
|
|
// 전체 시험 중 (부하) 에는 목록을 늦게 읽어 e.txt 를 못 찾았다 - 두 파일이 보일 때까지
|
|
await settle(tester, () => find.text('e.txt').evaluate().isNotEmpty && find.text('doc.txt').evaluate().isNotEmpty);
|
|
await act(tester, () => tester.tap(find.text('선택').first));
|
|
await act(tester, () => tester.tap(markOf('doc.txt')));
|
|
await act(tester, () => tester.tap(markOf('e.txt')));
|
|
await calm(tester);
|
|
await mouseDrag(tester, tester.getCenter(find.text('e.txt').first), rightOf(tester, 'right'));
|
|
await settle(tester, () => find.widgetWithText(FilledButton, '이동').evaluate().isNotEmpty);
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '이동')));
|
|
await settle(tester, () => find.text('되돌리기').evaluate().isNotEmpty);
|
|
expect(find.textContaining('같은 이름을 덮어쓴 파일 1개는 되돌리지 않습니다'), findsOneWidget);
|
|
expect(find.textContaining('합친 폴더'), findsNothing);
|
|
ScaffoldMessenger.of(tester.element(find.byType(ExplorerPage))).clearSnackBars();
|
|
await calm(tester);
|
|
await tester.pump(const Duration(seconds: 2)); // 진행 막대가 내려가는 시간 (1.2초) 까지
|
|
});
|
|
|
|
testWidgets('이동 → [되돌리기]: 새로 생긴 것은 통째로, 이미 있던 폴더에 합친 것은 옮긴 파일만', (tester) async {
|
|
// 오른쪽에 이미 sub 폴더 (원래 파일 하나) - 합치기
|
|
File(p.join(right, 'sub', 'mine.txt'))
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('mine');
|
|
c.settings
|
|
..explorerDropAction = 'move'
|
|
..copyConflict = 'overwrite';
|
|
await open(tester);
|
|
await act(tester, () => tester.tap(find.text('선택').first));
|
|
await act(tester, () => tester.tap(markOf('doc.txt')));
|
|
await act(tester, () => tester.tap(markOf('sub')));
|
|
await calm(tester);
|
|
await mouseDrag(tester, tester.getCenter(find.text('doc.txt').first), rightOf(tester, 'right'));
|
|
// (놓은 뒤 대상에 이미 있는 이름을 실제 파일로 확인하므로 실제 시간을 흘려 기다린다)
|
|
await settle(tester, () => find.widgetWithText(FilledButton, '이동').evaluate().isNotEmpty);
|
|
// 지금의 이동 확인 창 그대로
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '이동')));
|
|
await settle(tester, () => find.text('되돌리기').evaluate().isNotEmpty);
|
|
expect(File(p.join(right, 'doc.txt')).existsSync(), isTrue);
|
|
expect(File(p.join(right, 'sub', 'inner.txt')).existsSync(), isTrue);
|
|
expect(Directory(p.join(left, 'sub')).existsSync(), isFalse);
|
|
// 되돌리기: 원래 폴더마다 지금의 이동 (확인 창)
|
|
await act(tester, () => tester.tap(find.text('되돌리기')));
|
|
// 원래 폴더가 둘 (left · left/sub) 이라 이동 확인 창도 둘
|
|
for (var i = 0; i < 2; i++) {
|
|
await settle(tester, () => find.widgetWithText(FilledButton, '이동').evaluate().isNotEmpty);
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '이동')));
|
|
await settle(tester, () => find.byType(AlertDialog).evaluate().isEmpty, rounds: 50);
|
|
}
|
|
await settle(tester, () => File(p.join(left, 'doc.txt')).existsSync() && File(p.join(left, 'sub', 'inner.txt')).existsSync());
|
|
expect(File(p.join(left, 'doc.txt')).readAsStringSync(), 'hello');
|
|
expect(File(p.join(left, 'sub', 'inner.txt')).readAsStringSync(), 'inner');
|
|
expect(File(p.join(right, 'sub', 'mine.txt')).readAsStringSync(), 'mine', reason: '원래 있던 폴더 · 파일은 그대로 (폴더째 옮기지 않음)');
|
|
expect(File(p.join(right, 'sub', 'inner.txt')).existsSync(), isFalse);
|
|
ScaffoldMessenger.of(tester.element(find.byType(ExplorerPage))).clearSnackBars();
|
|
await calm(tester);
|
|
});
|
|
});
|
|
|
|
testWidgets('85: 진행 패널 [숨기기] → 아래 작은 표시 (누르면 다시) · 끝난 알림의 [폴더 열기]', (tester) async {
|
|
await open(tester);
|
|
await act(tester, () => tester.tap(find.text('doc.txt')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
await act(tester, () => tester.tap(find.text('복사').first));
|
|
await calm(tester);
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '복사')));
|
|
await settle(tester, () => File(p.join(right, 'doc.txt')).existsSync() && find.text('폴더 열기').evaluate().isNotEmpty);
|
|
expect(find.text('폴더 열기'), findsOneWidget, reason: '끝난 알림에 [폴더 열기]');
|
|
// 패널은 끝난 뒤 잠깐 남는다 - [숨기기]
|
|
expect(find.text('숨기기'), findsOneWidget);
|
|
// 패널 · 작은 표시는 끝나고 1.2초 (시험 시계) 뒤 내려간다. pumpAndSettle (calm) 은 애니메이션이 있는 동안 시계를 그만큼
|
|
// 넘길 수 있어 (PC 가 바쁠 때 흔들림 - 관리자 지시), 정해진 횟수 대신 조건이 될 때까지 시계를 조금씩만 돌린다
|
|
Future<void> until(bool Function() done) async {
|
|
for (var i = 0; i < 100 && !done(); i++) {
|
|
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 20)));
|
|
await tester.pump(const Duration(milliseconds: 10));
|
|
}
|
|
}
|
|
|
|
await act(tester, () => tester.tap(find.text('숨기기')));
|
|
await until(() => c.settings.explorerProgressHidden && find.text('복사 · 이동 끝').evaluate().isNotEmpty);
|
|
expect(c.settings.explorerProgressHidden, isTrue, reason: '숨김은 기억');
|
|
expect(find.text('숨기기'), findsNothing);
|
|
expect(find.text('복사 · 이동 끝'), findsOneWidget, reason: '아래 작은 표시');
|
|
// 작은 표시를 누름 (아래 알림이 덮고 있어도 - 알림이 닫히기를 기다리면 그사이 작은 표시가 내려갈 수 있다)
|
|
tester.widget<TransferProgressChip>(find.byType(TransferProgressChip)).onTap();
|
|
await until(() => !c.settings.explorerProgressHidden);
|
|
ScaffoldMessenger.of(tester.element(find.byType(ExplorerPage))).clearSnackBars();
|
|
expect(c.settings.explorerProgressHidden, isFalse, reason: '누르면 다시 펼침');
|
|
ScaffoldMessenger.of(tester.element(find.byType(ExplorerPage))).clearSnackBars();
|
|
await calm(tester);
|
|
});
|
|
|
|
testWidgets('81: 빠른 보기 (글 파일 앞부분) - Windows 는 TC 키 F3 (규칙 1), Android 는 Space · 필터에 치는 중에는 그냥 빈칸', (tester) async {
|
|
c.settings.explorerStyle = 'windows';
|
|
await open(tester);
|
|
await act(tester, () => tester.tap(find.text('doc.txt')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
await act(tester, () => tester.sendKeyEvent(Platform.isWindows ? LogicalKeyboardKey.f3 : LogicalKeyboardKey.space));
|
|
await settle(tester, () => find.byType(QuickLook).evaluate().isNotEmpty);
|
|
expect(find.byType(QuickLook), findsOneWidget);
|
|
await settle(tester, () => find.text('hello').evaluate().isNotEmpty);
|
|
expect(find.text('hello'), findsOneWidget, reason: '글 파일 앞부분');
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.escape));
|
|
await calm(tester);
|
|
expect(find.byType(QuickLook), findsNothing);
|
|
|
|
// 빠른 필터에 치는 중이면 Space 는 칸의 글자 (빠른 보기를 열지 않음)
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.keyD));
|
|
await calm(tester);
|
|
expect(find.byType(TextField), findsOneWidget);
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.space));
|
|
await calm(tester);
|
|
expect(find.byType(QuickLook), findsNothing);
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.escape));
|
|
await calm(tester);
|
|
|
|
// TC: F3
|
|
await c.updateSettings((s) => s.explorerStyle = 'totalcmd');
|
|
await calm(tester);
|
|
await act(tester, () => tester.tap(find.text('doc')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f3));
|
|
await settle(tester, () => find.byType(QuickLook).evaluate().isNotEmpty);
|
|
expect(find.byType(QuickLook), findsOneWidget);
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.escape));
|
|
await calm(tester);
|
|
});
|
|
|
|
// P0 (15 지적 10/17): 글자 칸에 치는 중에는 파일 단축키가 키를 가로채지 않는다 (예전: 필터 칸의 Delete → 파일 지우기 창)
|
|
for (final style in const ['windows', 'xplore', 'totalcmd']) {
|
|
testWidgets('P0 $style: 빠른 필터 칸에서 Ctrl+A · C · V · Delete · Space · F8 · Backspace 는 파일에 쓰이지 않는다', (tester) async {
|
|
c.settings.explorerStyle = style;
|
|
await open(tester);
|
|
await act(tester, () => tester.tap(find.text(style == 'totalcmd' ? 'doc' : 'doc.txt')));
|
|
await settle(tester, () => false, rounds: 15);
|
|
// Ctrl+F 로 필터 칸 열고 글자
|
|
Future<void> ctrl(LogicalKeyboardKey k) => act(tester, () async {
|
|
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
|
|
await tester.sendKeyEvent(k);
|
|
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
|
|
});
|
|
await ctrl(LogicalKeyboardKey.keyF);
|
|
await calm(tester);
|
|
final field = find.byType(TextField);
|
|
expect(field, findsOneWidget);
|
|
await tester.enterText(field, 'do');
|
|
await calm(tester);
|
|
await ctrl(LogicalKeyboardKey.keyA);
|
|
await calm(tester);
|
|
final ctl = tester.widget<TextField>(field).controller!;
|
|
expect(ctl.selection, const TextSelection(baseOffset: 0, extentOffset: 2), reason: 'Ctrl+A 는 칸의 글 전체 선택');
|
|
await ctrl(LogicalKeyboardKey.keyC);
|
|
await calm(tester);
|
|
await ctrl(LogicalKeyboardKey.keyV);
|
|
await calm(tester);
|
|
for (final k in [LogicalKeyboardKey.delete, LogicalKeyboardKey.space, LogicalKeyboardKey.f8, LogicalKeyboardKey.backspace]) {
|
|
await act(tester, () => tester.sendKeyEvent(k));
|
|
await calm(tester);
|
|
}
|
|
expect(find.textContaining('표시함'), findsNothing, reason: '파일이 표시되지 않음');
|
|
expect(find.textContaining('담았습니다'), findsNothing, reason: '파일을 담지 않음');
|
|
expect(find.textContaining('휴지통'), findsNothing, reason: '지우기 창이 뜨지 않음');
|
|
expect(find.textContaining('지울까요'), findsNothing);
|
|
expect(File(p.join(left, 'doc.txt')).existsSync(), isTrue);
|
|
expect(field, findsOneWidget, reason: '칸은 그대로 열려 있음 (Backspace 로 위 폴더로 가지 않음)');
|
|
// Esc 는 지금처럼 필터를 닫는다
|
|
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.escape));
|
|
await calm(tester);
|
|
expect(find.byType(TextField), findsNothing);
|
|
ScaffoldMessenger.of(tester.element(find.byType(ExplorerPage))).clearSnackBars();
|
|
await calm(tester);
|
|
});
|
|
}
|
|
|
|
testWidgets('87: 폴더 길게 누르기 [저장 공간 분석] → 큰 파일을 누르면 탐색기에서 그 자리로', (tester) async {
|
|
File(p.join(left, 'sub', 'big.bin')).writeAsBytesSync(List.filled(4000, 1));
|
|
await open(tester);
|
|
await tester.longPress(find.text('sub').first);
|
|
await calm(tester);
|
|
await act(tester, () => tester.tap(find.text('저장 공간 분석')));
|
|
await settle(tester, () => find.text('큰 파일').evaluate().isNotEmpty);
|
|
await act(tester, () => tester.tap(find.text('큰 파일')));
|
|
await calm(tester);
|
|
await act(tester, () => tester.tap(find.text('big.bin')));
|
|
await settle(tester, () => find.byType(StorageAnalysisPage).evaluate().isEmpty && find.text('big.bin').evaluate().isNotEmpty);
|
|
await calm(tester);
|
|
expect(find.byType(StorageAnalysisPage), findsNothing);
|
|
expect(find.text('big.bin'), findsWidgets, reason: '탐색기에서 그 자리 (sub 안) 가 보인다');
|
|
});
|
|
|
|
testWidgets('84: 열 머리를 누르면 그 기준으로 · 다시 누르면 거꾸로 (처음: 모든 폴더 같은 정렬)', (tester) async {
|
|
File(p.join(left, 'a_big.txt')).writeAsStringSync('x' * 50);
|
|
c.settings.explorerStyle = 'windows';
|
|
await open(tester);
|
|
double y(String name) => tester.getTopLeft(find.text(name).first).dy;
|
|
expect(y('a_big.txt'), lessThan(y('doc.txt')), reason: '처음: 이름순');
|
|
await act(tester, () => tester.tap(find.text('크기').first));
|
|
await calm(tester);
|
|
expect((c.settings.explorerSort, c.settings.explorerSortDesc), ('size', false));
|
|
expect(y('doc.txt'), lessThan(y('a_big.txt')), reason: '크기 오름차순: doc.txt (5) 가 먼저');
|
|
await act(tester, () => tester.tap(find.text('크기').first));
|
|
await calm(tester);
|
|
expect(c.settings.explorerSortDesc, isTrue, reason: '같은 열을 다시 누르면 거꾸로');
|
|
// (거꾸로면 트리에 펼쳐진 위 폴더 (Temp 등) 의 차례도 바뀌어 시험 폴더가 화면 밖으로 갈 수 있어 줄 위치는 보지 않는다)
|
|
expect(find.byIcon(Icons.arrow_drop_down), findsWidgets, reason: '지금 정렬 열에 ▼');
|
|
});
|
|
|
|
testWidgets('84: "정렬을 폴더마다 기억" 을 켜면 그 폴더에만 (전체 정렬 · 다른 창은 그대로)', (tester) async {
|
|
c.settings
|
|
..explorerStyle = 'totalcmd'
|
|
..explorerSortPerFolder = true;
|
|
await open(tester);
|
|
// 왼쪽 창에서 날짜 열
|
|
await act(tester, () => tester.tap(find.text('날짜').first));
|
|
await calm(tester);
|
|
expect(c.settings.explorerSort, 'name', reason: '전체 정렬은 그대로');
|
|
expect(c.settings.explorerFolderSorts.values, contains('date|0'));
|
|
expect(c.settings.explorerFolderSorts.length, 1);
|
|
// 저장 · 읽기
|
|
expect(AppSettings.fromJson(c.settings.toJson()).explorerFolderSorts, c.settings.explorerFolderSorts);
|
|
expect(AppSettings.fromJson(c.settings.toJson()).explorerSortPerFolder, isTrue);
|
|
expect(AppSettings.fromJson({'explorerFolderSorts': 'broken'}).explorerFolderSorts, isEmpty, reason: '틀린 값은 비움');
|
|
});
|
|
}
|