371 lines
21 KiB
Dart
371 lines
21 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/app/app_controller.dart';
|
|
import 'package:jj_mkvmaker/app/settings.dart';
|
|
import 'package:jj_mkvmaker/core/file_ops.dart' show uncRoot;
|
|
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
|
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
|
import 'package:jj_mkvmaker/services/platform_services.dart';
|
|
import 'package:jj_mkvmaker/ui/explorer_page.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
import 'support/explorer_harness.dart' show act, settle, calm;
|
|
import 'support/test_explorer_device.dart';
|
|
|
|
/// 23: 앞의 복사가 끝나지 않아도 다음 복사를 함께 시작한다 (막지 않음, 진행 막대가 둘)
|
|
void main() {
|
|
late TestExplorerDevice device;
|
|
setUp(() => device = TestExplorerDevice());
|
|
testWidgets('복사 중에 다른 파일 복사 → 둘 다 진행 · 둘 다 끝남', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_parallel_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final left = p.join(tmp.path, 'left'), right = p.join(tmp.path, 'right');
|
|
File(p.join(left, 'big.bin'))
|
|
..createSync(recursive: true)
|
|
..writeAsBytesSync(List.filled(3 << 20, 7));
|
|
File(p.join(left, 'doc.txt')).writeAsStringSync('hello');
|
|
Directory(right).createSync();
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.paths = [left, right]
|
|
..copy.bandwidthKBps = 512; // 큰 파일이 6초쯤 걸리게
|
|
tester.view.physicalSize = const Size(1600, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c))));
|
|
await settle(tester, () => find.text('doc.txt').evaluate().isNotEmpty);
|
|
|
|
Future<void> copy(String name) async {
|
|
await act(tester, () => tester.tap(find.text(name).first));
|
|
await settle(tester, () => false, rounds: 15);
|
|
await act(tester, () => tester.tap(find.text('복사').first));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '복사')));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
}
|
|
|
|
await copy('big.bin');
|
|
await settle(tester, () => find.textContaining('복사하는 중').evaluate().isNotEmpty, rounds: 30);
|
|
await copy('doc.txt');
|
|
expect(find.text('앞의 복사 · 이동이 끝난 뒤에 하세요.'), findsNothing);
|
|
// 둘이 함께 돈다 (진행 막대 두 줄)
|
|
expect(find.textContaining('복사하는 중'), findsNWidgets(2));
|
|
await settle(tester, () => File(p.join(right, 'doc.txt')).existsSync(), rounds: 100);
|
|
await settle(tester,
|
|
() => File(p.join(right, 'big.bin')).existsSync() && find.byType(LinearProgressIndicator).evaluate().isEmpty,
|
|
rounds: 400);
|
|
expect(File(p.join(right, 'big.bin')).lengthSync(), 3 << 20);
|
|
expect(File(p.join(right, 'doc.txt')).readAsStringSync(), 'hello');
|
|
});
|
|
|
|
testWidgets('191: 좁은 Rsync 화면 (폴드 접은 화면) 은 창 하나씩 - [왼쪽 | 오른쪽] 으로 바꿔 보기, 넓으면 두 창', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_rsync_narrow_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final l = p.join(tmp.path, 'L'), r = p.join(tmp.path, 'R');
|
|
Directory(p.join(l, 'sub')).createSync(recursive: true);
|
|
Directory(p.join(r, 'rsub')).createSync(recursive: true);
|
|
device.volumes = () => [(tmp.path, 'T:')];
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.orientation = 'side'
|
|
..copy.rsyncPaths = [l, r];
|
|
tester.view.physicalSize = const Size(400, 860);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c, rsync: true))));
|
|
await settle(tester, () => find.text('sub').evaluate().isNotEmpty);
|
|
// 왼쪽 창만 (오른쪽 폴더는 안 보임) · 방향 버튼은 보임
|
|
expect(find.text('왼쪽 · L'), findsOneWidget);
|
|
expect(find.text('오른쪽 · R'), findsOneWidget);
|
|
expect(find.text('rsub'), findsNothing);
|
|
expect(find.text('좌 → 우'), findsOneWidget);
|
|
// 창 하나가 화면 폭을 다 쓴다 (예전에는 약 140px)
|
|
expect(tester.getSize(find.ancestor(of: find.text('sub'), matching: find.byType(ListView)).first).width, greaterThan(300));
|
|
await tester.tap(find.text('오른쪽 · R'));
|
|
await settle(tester, () => find.text('rsub').evaluate().isNotEmpty);
|
|
expect(find.text('rsub'), findsOneWidget);
|
|
expect(find.text('sub'), findsNothing);
|
|
// 넓으면 두 창 그대로
|
|
tester.view.physicalSize = const Size(1280, 800);
|
|
await settle(tester, () => find.text('sub').evaluate().isNotEmpty);
|
|
expect(find.text('sub'), findsOneWidget);
|
|
expect(find.text('rsub'), findsOneWidget);
|
|
expect(find.text('왼쪽 · L'), findsNothing);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('28 확인 (10/20): 좁은 Rsync 화면의 [오른쪽] 탭 · 넓게 바꾼 두 창도 그 창의 지금 폴더가 보인다 (저장 장치 맨 위에 머물지 않음)', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_rsync_reveal_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
// 맨 위에 폴더가 많고 (C: 처럼) 두 창의 지금 폴더는 깊은 곳 - 펼쳐도 스크롤하지 않으면 화면 밖
|
|
for (var i = 0; i < 80; i++) {
|
|
Directory(p.join(tmp.path, 'a${i.toString().padLeft(2, '0')}')).createSync();
|
|
}
|
|
final l = p.join(tmp.path, 'zz', 'deep', 'L'), r = p.join(tmp.path, 'zz', 'deep', 'R');
|
|
Directory(p.join(l, 'sub')).createSync(recursive: true);
|
|
Directory(p.join(r, 'rsub')).createSync(recursive: true);
|
|
device.volumes = () => [(tmp.path, 'T:')];
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.orientation = 'side'
|
|
..copy.rsyncPaths = [l, r];
|
|
tester.view.physicalSize = const Size(412, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c, rsync: true))));
|
|
await settle(tester, () => find.text('sub').hitTestable().evaluate().isNotEmpty);
|
|
expect(find.text('sub').hitTestable(), findsOneWidget, reason: '왼쪽은 처음부터 지금 폴더');
|
|
// [오른쪽] 탭을 처음 보면 그 창의 지금 폴더 (R) 로 - 예전에는 맨 위 (a00 …) 에서 시작
|
|
await tester.tap(find.text('오른쪽 · R'));
|
|
await settle(tester, () => find.text('rsub').hitTestable().evaluate().isNotEmpty, rounds: 40);
|
|
expect(find.text('rsub').hitTestable(), findsOneWidget);
|
|
// 넓게 바꾸면 두 창 - 둘 다 지금 폴더가 보임
|
|
tester.view.physicalSize = const Size(1280, 800);
|
|
await settle(tester, () => find.text('sub').hitTestable().evaluate().isNotEmpty && find.text('rsub').hitTestable().evaluate().isNotEmpty,
|
|
rounds: 40);
|
|
expect(find.text('sub').hitTestable(), findsOneWidget);
|
|
expect(find.text('rsub').hitTestable(), findsOneWidget);
|
|
// 다시 좁게 → [왼쪽] 탭 (지금 보이는 창) 도 지금 폴더
|
|
tester.view.physicalSize = const Size(412, 900);
|
|
await settle(tester, () => find.text('왼쪽 · L').evaluate().isNotEmpty);
|
|
await tester.tap(find.text('왼쪽 · L'));
|
|
await settle(tester, () => find.text('sub').hitTestable().evaluate().isNotEmpty, rounds: 40);
|
|
expect(find.text('sub').hitTestable(), findsOneWidget);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('208: 폰 가로 (낮은 화면) Rsync 화면에서도 방향 실행 버튼 · 모니터링은 늘 보인다 ([더 보기] 로 가는 것은 뒤쪽)', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_rsync_low_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final l = p.join(tmp.path, 'L'), r = p.join(tmp.path, 'R');
|
|
Directory(l).createSync(recursive: true);
|
|
Directory(r).createSync(recursive: true);
|
|
device.volumes = () => [(tmp.path, 'T:')];
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.orientation = 'side'
|
|
..copy.rsyncPaths = [l, r];
|
|
tester.view.physicalSize = const Size(860, 400);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c, rsync: true))));
|
|
await settle(tester, () => find.text('좌 → 우').evaluate().isNotEmpty);
|
|
for (final t in ['좌 → 우', '좌 ← 우', '좌 ⇄ 우', '모니터링']) {
|
|
expect(find.text(t), findsOneWidget, reason: t);
|
|
}
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('221: 폰 세로 Rsync (한 창) 의 저장소 탭은 글이 다 보인다 (SD 카드가 잘리지 않음)', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_rsync_tabs_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final inner = p.join(tmp.path, 'inner'), sd = p.join(tmp.path, 'sd');
|
|
Directory(p.join(inner, 'L')).createSync(recursive: true);
|
|
Directory(p.join(sd, 'R')).createSync(recursive: true);
|
|
device.volumes = () => [(inner, '내장 저장소'), (sd, 'SD 카드')];
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.orientation = 'side'
|
|
..copy.rsyncPaths = [p.join(inner, 'L'), p.join(sd, 'R')];
|
|
tester.view.physicalSize = const Size(412, 880);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c, rsync: true))));
|
|
await settle(tester, () => find.text('SD 카드').evaluate().isNotEmpty);
|
|
// 탭 글은 눌리지 않는다 (글 폭 그대로) - 넘치면 옆으로 밀어서 다 보인다 (202 와 같은 방식)
|
|
final plain = TextPainter(text: const TextSpan(text: 'SD 카드'), textDirection: TextDirection.ltr)..layout();
|
|
expect(tester.getSize(find.text('SD 카드').first).width, greaterThanOrEqualTo(plain.width * 0.9), reason: '"(" 처럼 눌리지 않음');
|
|
final tabs = find.ancestor(of: find.text('SD 카드').first, matching: find.byType(ListView)).first;
|
|
await tester.drag(tabs, const Offset(-400, 0));
|
|
await settle(tester, () => false, rounds: 10);
|
|
expect(tester.getRect(find.text('SD 카드').first).right, lessThanOrEqualTo(tester.getRect(tabs).right + 1), reason: '밀면 끝까지 보임');
|
|
expect(find.byTooltip('경로 입력 · 네트워크 서버'), findsOneWidget, reason: '끝 버튼은 [⋮] 하나');
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('25: Rsync 화면 폴더도 길게 누르면 메뉴 (고르기 · 열기 · 이름 변경 · 삭제 · 정보)', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_rsync_menu_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final l = p.join(tmp.path, 'L'), r = p.join(tmp.path, 'R');
|
|
Directory(p.join(l, 'sub')).createSync(recursive: true);
|
|
Directory(p.join(r, 'rsub')).createSync(recursive: true);
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.layout = 'single'
|
|
..copy.rsyncPaths = [l, r];
|
|
tester.view.physicalSize = const Size(1600, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c, rsync: true))));
|
|
await settle(tester, () => find.text('sub').evaluate().isNotEmpty);
|
|
await tester.longPress(find.text('sub'));
|
|
await calm(tester);
|
|
for (final t in ['rsync 에 고르기', '열기', '다른 창에서 열기', '이름 변경', '삭제', '정보']) {
|
|
expect(find.text(t), findsOneWidget, reason: t);
|
|
}
|
|
expect(find.text('다른 앱으로 열기'), findsNothing); // 파일 메뉴는 없음
|
|
await act(tester, () => tester.tap(find.text('rsync 에 고르기')));
|
|
await settle(tester, () => false, rounds: 5);
|
|
expect(find.byTooltip('고르기 취소'), findsOneWidget);
|
|
});
|
|
|
|
test('37: 네트워크 공유 경로의 맨 위', () {
|
|
expect(uncRoot(r'\\NAS\영상\드라마\1화.mkv'), r'\\NAS\영상');
|
|
expect(uncRoot(r'\\NAS\영상'), r'\\NAS\영상');
|
|
});
|
|
|
|
testWidgets('37: 경로를 직접 넣어 가기 · 없는 경로는 알림', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_enter_path_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final l = p.join(tmp.path, 'L'), deep = p.join(l, 'a', 'b');
|
|
File(p.join(deep, 'deep.txt'))
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('d');
|
|
File(p.join(l, 'top.txt')).writeAsStringSync('t');
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.layout = 'single'
|
|
..explorer.paths = [l, l];
|
|
tester.view.physicalSize = const Size(1600, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c))));
|
|
await settle(tester, () => find.text('top.txt').evaluate().isNotEmpty);
|
|
await tester.tap(find.byTooltip('경로 입력').first);
|
|
await calm(tester);
|
|
await tester.enterText(find.byType(TextField).last, p.join(tmp.path, 'none'));
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '확인')));
|
|
await settle(tester, () => find.textContaining('폴더가 없거나 열 수 없습니다').evaluate().isNotEmpty, rounds: 20);
|
|
expect(find.textContaining('폴더가 없거나 열 수 없습니다'), findsOneWidget);
|
|
// 146: 창은 열린 채 - 그 칸에서 고쳐 넣는다
|
|
expect(find.byType(AlertDialog), findsOneWidget);
|
|
await tester.enterText(find.byType(TextField).last, deep);
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '확인')));
|
|
await settle(tester, () => find.text('deep.txt').evaluate().isNotEmpty);
|
|
expect(find.text('deep.txt'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('122: 앱 밖에서 만든 폴더도 경로 입력으로 가면 새로 읽어 펼치고 화면에 보인다', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_enter_fresh_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final dl = p.join(tmp.path, 'Download');
|
|
// 앞쪽에 파일이 많아 새 폴더가 화면 아래로 밀리는 Download
|
|
for (var i = 0; i < 60; i++) {
|
|
File(p.join(dl, 'a$i.txt'))
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('$i');
|
|
}
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.layout = 'single'
|
|
..explorer.paths = [dl, dl];
|
|
tester.view.physicalSize = const Size(1600, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c))));
|
|
await settle(tester, () => find.text('a0.txt').evaluate().isNotEmpty);
|
|
// 앱이 Download 를 읽은 뒤에 다른 앱이 만든 폴더 (이름 순으로 맨 뒤)
|
|
final made = p.join(dl, 'zz_jjsup');
|
|
File(p.join(made, 'pg1.png'))
|
|
..createSync(recursive: true)
|
|
..writeAsBytesSync([1, 2, 3]);
|
|
await tester.tap(find.byTooltip('경로 입력').first);
|
|
await calm(tester);
|
|
await tester.enterText(find.byType(TextField).last, made);
|
|
await act(tester, () => tester.tap(find.widgetWithText(FilledButton, '확인')));
|
|
await settle(tester, () => find.text('pg1.png').evaluate().isNotEmpty, rounds: 300);
|
|
expect(find.text('zz_jjsup'), findsOneWidget);
|
|
expect(find.text('pg1.png').hitTestable(), findsOneWidget, reason: '그 자리로 스크롤되어 보임');
|
|
});
|
|
|
|
testWidgets('38: 좁고 낮은 창 (접은 폴드 · 위아래 두 창) 에서 안내가 있어도 목록이 보인다', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_notice_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final l = p.join(tmp.path, 'L');
|
|
for (var i = 0; i < 4; i++) {
|
|
File(p.join(l, 'part$i.mkv.jjpart'))
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('x')
|
|
..setLastModifiedSync(DateTime.now().subtract(const Duration(hours: 1)));
|
|
}
|
|
File(p.join(l, 'zz_file.txt')).writeAsStringSync('t');
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.layout = 'dual'
|
|
..explorer.orientation = 'stacked'
|
|
..explorer.paths = [l, l];
|
|
tester.view.physicalSize = const Size(420, 640);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c))));
|
|
await settle(tester, () => find.textContaining('만들다 만 파일').evaluate().isNotEmpty);
|
|
expect(tester.takeException(), isNull); // 넘침 (overflow) 없음
|
|
// 목록 (창마다) 이 밀려 사라지지 않고 높이가 남아 있다
|
|
final lists = find.byWidgetPredicate((w) => w is ListView && w.scrollDirection == Axis.vertical);
|
|
expect(lists, findsWidgets);
|
|
for (final e in lists.evaluate()) {
|
|
expect(tester.getSize(find.byWidget(e.widget)).height, greaterThan(80));
|
|
}
|
|
});
|
|
|
|
test('118: 두 창 배치 처음 값은 좌우 · 예전 "화면 모양 따라" 는 한 번 좌우로 (알림) · 고른 위아래는 그대로', () {
|
|
expect(AppSettings().explorer.orientation, 'side');
|
|
expect(AppSettings.fromJson({}).explorer.orientation, 'side');
|
|
final old = AppSettings.fromJson({'explorerOrientation': 'auto'});
|
|
expect(old.explorer.orientation, 'side');
|
|
expect(old.migrated, contains('explorerOrientation'));
|
|
final stacked = AppSettings.fromJson({'explorerOrientation': 'stacked'});
|
|
expect(stacked.explorer.orientation, 'stacked');
|
|
expect(stacked.migrated, isNot(contains('explorerOrientation')));
|
|
// 옮긴 뒤 사용자가 다시 '화면 모양 따라' 를 고르면 그대로
|
|
final again = AppSettings.fromJson((AppSettings()..explorer.orientation = 'auto').toJson());
|
|
expect(again.explorer.orientation, 'auto');
|
|
expect(again.migrated, isEmpty);
|
|
});
|
|
|
|
testWidgets('118: 가운데 버튼 [좌우 ⇆ / 위아래 ⇅] - 한 번 눌러 바로 바뀜 · 한 창이면 두 창 (좌우) 으로', (tester) async {
|
|
final tmp = Directory.systemTemp.createTempSync('jj_orient_');
|
|
addTearDown(() => tmp.deleteSync(recursive: true));
|
|
final l = p.join(tmp.path, 'L');
|
|
File(p.join(l, 'a.txt'))
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('a');
|
|
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
c.settings
|
|
..explorer.layout = 'single'
|
|
..explorer.paths = [l, l];
|
|
// 폰 세로처럼 좁고 긴 화면
|
|
tester.view.physicalSize = const Size(500, 1000);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
await tester.runAsync(() => tester.pumpWidget(MaterialApp(home: ExplorerPage(device: device, c: c))));
|
|
await settle(tester, () => find.text('a.txt').evaluate().isNotEmpty);
|
|
// 그 버튼을 누른다: 버튼 줄에 있으면 바로, 다 들어가지 않아 [더 보기] 메뉴에 있으면 메뉴에서 (147)
|
|
Future<void> press(String tooltip, String label) async {
|
|
if (find.byTooltip(tooltip).evaluate().isNotEmpty) {
|
|
await act(tester, () => tester.tap(find.byTooltip(tooltip)));
|
|
} else {
|
|
await tester.tap(find.text('더 보기'));
|
|
await calm(tester);
|
|
expect(find.text(label), findsOneWidget, reason: '[더 보기] 메뉴에 지금 배치가 보임: $label');
|
|
await act(tester, () => tester.tap(find.text(label)));
|
|
}
|
|
await settle(tester, () => false, rounds: 5);
|
|
}
|
|
|
|
await press('두 창으로 보기 (좌우)', '두 창으로');
|
|
expect((c.settings.explorer.layout, c.settings.explorer.orientation), ('dual', 'side'), reason: '폰 세로에서도 좌우');
|
|
expect(find.text('a.txt'), findsNWidgets(2));
|
|
final left = tester.getCenter(find.text('a.txt').first), right = tester.getCenter(find.text('a.txt').last);
|
|
expect(right.dx, greaterThan(left.dx));
|
|
await press('창 배치: 좌우 (누르면 위아래)', '좌우 ⇆');
|
|
expect(c.settings.explorer.orientation, 'stacked');
|
|
final top = tester.getCenter(find.text('a.txt').first), bottom = tester.getCenter(find.text('a.txt').last);
|
|
expect(bottom.dy, greaterThan(top.dy));
|
|
await press('창 배치: 위아래 (누르면 좌우)', '위아래 ⇅');
|
|
expect(c.settings.explorer.orientation, 'side');
|
|
});
|
|
}
|