115 lines
5.7 KiB
Dart
115 lines
5.7 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jj_mkvmaker/app/settings.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
void main() {
|
|
late Directory dir;
|
|
late String file;
|
|
setUp(() {
|
|
dir = Directory.systemTemp.createTempSync('jj_settings_');
|
|
file = p.join(dir.path, 'settings.json');
|
|
});
|
|
tearDown(() => dir.deleteSync(recursive: true));
|
|
|
|
test('저장: 임시 파일에 쓴 뒤 바꿔치기 · 직전 정상본은 .bak · 남는 임시 파일 없음', () async {
|
|
final store = SettingsStore(file);
|
|
await store.save(AppSettings()..homeUrl = 'https://a.example');
|
|
await store.save(AppSettings()..homeUrl = 'https://b.example');
|
|
expect((await SettingsStore(file).load()).homeUrl, 'https://b.example');
|
|
expect(File('$file.bak').readAsStringSync(), contains('https://a.example'));
|
|
expect(File('$file.tmp').existsSync(), isFalse);
|
|
// 여러 번 빠르게 저장해도 마지막 것이 남는다 (순서대로)
|
|
await Future.wait([for (var i = 0; i < 5; i++) store.save(AppSettings()..homeUrl = 'https://$i.example')]);
|
|
expect((await SettingsStore(file).load()).homeUrl, 'https://4.example');
|
|
});
|
|
|
|
test('깨진 설정 파일: 백업으로 되살리고, 깨진 파일은 보관 · 알림 정보', () async {
|
|
final store = SettingsStore(file);
|
|
await store.save(AppSettings()..homeUrl = 'https://good.example');
|
|
await store.save(AppSettings()..homeUrl = 'https://good2.example'); // .bak = good
|
|
File(file).writeAsStringSync('{"homeUrl": "https://half'); // 반쯤 쓰다 끊긴 파일
|
|
final s = await store.load();
|
|
expect(s.homeUrl, 'https://good.example');
|
|
expect(store.problem!.restoredFromBackup, isTrue);
|
|
final kept = store.problem!.brokenCopy!;
|
|
expect(File(kept).readAsStringSync(), '{"homeUrl": "https://half');
|
|
// 다음 저장이 좋은 백업을 깨진 파일로 덮지 않는다
|
|
await store.save(s);
|
|
expect(File('$file.bak').readAsStringSync(), contains('good'));
|
|
});
|
|
|
|
test('깨졌고 백업도 없음: 처음 설정 + 알림, 깨진 파일 보관 / settings.json 만 없으면 백업으로', () async {
|
|
File(file).writeAsStringSync('not json');
|
|
final store = SettingsStore(file);
|
|
final s = await store.load();
|
|
expect(s.homeUrl, AppSettings().homeUrl);
|
|
expect(store.problem!.restoredFromBackup, isFalse);
|
|
expect(File(store.problem!.brokenCopy!).readAsStringSync(), 'not json');
|
|
|
|
// 바꿔치기 도중 끝나 settings.json 이 없고 .bak 만 있는 경우
|
|
File(file).deleteSync();
|
|
File('$file.bak').writeAsStringSync('{"homeUrl": "https://bak.example"}');
|
|
final again = SettingsStore(file);
|
|
expect((await again.load()).homeUrl, 'https://bak.example');
|
|
expect(again.problem!.restoredFromBackup, isTrue);
|
|
// 정상이면 알림 없음
|
|
await again.save(AppSettings());
|
|
await again.load();
|
|
expect(again.problem, isNull);
|
|
});
|
|
|
|
test('업데이트로 옮긴 기본값: 예전 파일에 그 값이 있을 때만 알림 목록에, 새로 저장한 파일은 다시 옮기지 않음', () {
|
|
final old = AppSettings.fromJson({
|
|
'screenOrientation': 'landscape',
|
|
'explorerLayout': 'dual',
|
|
'explorerClick': 'select',
|
|
'zipComic': true,
|
|
'imageExts': ['jpg'],
|
|
'runInBackground': false,
|
|
});
|
|
expect(old.screenOrientation, 'auto');
|
|
expect(old.explorerLayout, 'auto');
|
|
expect(old.zipComic, isFalse);
|
|
expect(old.migrated, containsAll(['orientation', 'explorerLayout', 'zipComic']));
|
|
// 다시 저장 · 읽기: 이제 사용자가 고른 값으로 보고 그대로 · 알림 없음
|
|
final again = AppSettings.fromJson((old
|
|
..explorerLayout = 'dual'
|
|
..screenOrientation = 'landscape')
|
|
.toJson());
|
|
expect(again.explorerLayout, 'dual');
|
|
expect(again.screenOrientation, 'landscape');
|
|
expect(again.migrated, isEmpty);
|
|
// 처음 설치 (빈 설정) 는 알릴 것 없음
|
|
expect(AppSettings.fromJson({}).migrated, isEmpty);
|
|
});
|
|
|
|
test('193: 예전 판에서 올라오면 바뀐 동작 (229 받는 쪽이 더 새것이면 건너뜀 · robocopy 링크) 을 한 번 알린다', () {
|
|
final old = AppSettings.fromJson({'copyMethodFolder': 'robocopy', 'explorerV2': true});
|
|
expect(old.migrated, contains('copySkipNewer'));
|
|
expect(old.migrated.contains('robocopyLinks'), Platform.isWindows, reason: 'robocopy 는 Windows 만');
|
|
// 저장 뒤 다시 읽으면 알리지 않음
|
|
final again = AppSettings.fromJson(old.toJson());
|
|
expect(again.migrated, isNot(contains('copySkipNewer')));
|
|
expect(again.migrated, isNot(contains('robocopyLinks')));
|
|
// robocopy 를 쓰지 않던 사람에게는 링크 알림 없음
|
|
expect(AppSettings.fromJson({'explorerV2': true}).migrated, isNot(contains('robocopyLinks')));
|
|
});
|
|
|
|
test('193: 그 설정이 없던 예전 판 (10.03 모양 - 키 없음) 에서 올라오면 바로 겪는 동작 변화를 알린다 · 처음 설치는 없음', () {
|
|
// 10.03 의 설정 파일: 탐색기 · 화면 이동 · 백그라운드 설정이 아직 없던 때 (있는 것은 그때의 항목들)
|
|
final old = AppSettings.fromJson({'theme': 'dark', 'outputFolderName': 'jj_mkv'});
|
|
expect(old.migrated, contains('swipeNav'));
|
|
if (Platform.isAndroid) {
|
|
expect(old.migrated, containsAll(['explorerClickNew', 'orientation', 'background']));
|
|
} else {
|
|
expect(old.migrated, isNot(contains('explorerClickNew')), reason: 'PC 는 처음 값이 한 번 누르면 고르기 (바뀐 것 없음)');
|
|
}
|
|
// 저장 뒤 다시 읽으면 알리지 않음
|
|
expect(AppSettings.fromJson(old.toJson()).migrated, isEmpty);
|
|
// 처음 설치 (설정 파일 없음) 는 알릴 것 없음
|
|
expect(AppSettings.fromJson({}).migrated, isEmpty);
|
|
});
|
|
}
|