Files
pj_supermarket_cloud/test/face_readiness_cache_test.dart
T
2026-10-23 15:53:43 +08:00

172 lines
5.5 KiB
Dart

import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:pj_supermarket_cloud/common/utils/app/face_readiness_cache.dart';
void main() {
test('已就绪的重复读取直接使用缓存,不再次加载', () async {
final cache = FaceReadinessCache<String>();
var calls = 0;
Future<String> load() async {
calls++;
return 'ready';
}
expect(await cache.read(load, canCache: (_) => true), 'ready');
expect(await cache.read(load, canCache: (_) => true), 'ready');
expect(cache.value, 'ready');
expect(calls, 1);
});
test('同一代次的并发读取只发起一次加载', () async {
final cache = FaceReadinessCache<String>();
final source = Completer<String>();
var calls = 0;
Future<String> load() {
calls++;
return source.future;
}
final first = cache.read(load, canCache: (_) => true);
final second = cache.read(load, canCache: (_) => true);
expect(identical(first, second), isTrue);
expect(calls, 1);
source.complete('ready');
expect(await Future.wait([first, second]), ['ready', 'ready']);
expect(cache.value, 'ready');
});
test('相同数量的样本替换仍会在失效后重新检查', () async {
final cache = FaceReadinessCache<List<int>>();
var sampleIds = <int>[1, 2];
var calls = 0;
Future<List<int>> load() async {
calls++;
return List.unmodifiable(sampleIds);
}
expect(await cache.read(load, canCache: (_) => true), [1, 2]);
sampleIds = [1, 3];
cache.invalidate();
expect(cache.value, isNull);
expect(await cache.read(load, canCache: (_) => true), [1, 3]);
expect(calls, 2);
});
test('查询中失效会创建新查询,旧查询完成不能清除新查询', () async {
final cache = FaceReadinessCache<String>();
final oldSource = Completer<String>();
final newSource = Completer<String>();
var calls = 0;
Future<String> load() {
calls++;
return calls == 1 ? oldSource.future : newSource.future;
}
final oldRead = cache.read(load, canCache: (_) => true);
cache.invalidate();
final newRead = cache.read(load, canCache: (_) => true);
expect(identical(oldRead, newRead), isFalse);
expect(calls, 2);
oldSource.complete('old');
expect(await oldRead, 'old');
expect(cache.value, isNull);
final joined = cache.read(load, canCache: (_) => true);
expect(identical(joined, newRead), isTrue);
expect(calls, 2);
newSource.complete('new');
expect(await newRead, 'new');
expect(await joined, 'new');
expect(cache.value, 'new');
});
test('旧查询晚于新查询完成时不能覆盖新缓存', () async {
final cache = FaceReadinessCache<String>();
final oldSource = Completer<String>();
final oldRead = cache.read(() => oldSource.future, canCache: (_) => true);
cache.invalidate();
expect(await cache.read(() async => 'new', canCache: (_) => true), 'new');
oldSource.complete('old');
expect(await oldRead, 'old');
expect(cache.value, 'new');
});
test('嵌套变更全部结束后才允许缓存,中途读到就绪也不缓存', () async {
final cache = FaceReadinessCache<String>();
var calls = 0;
Future<String> load() async {
calls++;
return 'ready';
}
await cache.read(load, canCache: (_) => true);
cache.beginMutation();
cache.beginMutation();
expect(cache.mutationDepth, 2);
expect(cache.value, isNull);
expect(await cache.read(load, canCache: (_) => true), 'ready');
expect(cache.value, isNull);
cache.endMutation();
expect(cache.mutationDepth, 1);
expect(await cache.read(load, canCache: (_) => true), 'ready');
expect(cache.value, isNull);
cache.endMutation();
expect(cache.mutationDepth, 0);
expect(await cache.read(load, canCache: (_) => true), 'ready');
expect(cache.value, 'ready');
expect(calls, 4);
expect(cache.endMutation, throwsStateError);
expect(cache.mutationDepth, 0);
});
test('变更期间发起的查询在变更结束后完成也不能缓存', () async {
final cache = FaceReadinessCache<String>();
cache.beginMutation();
final source = Completer<String>();
final duringMutation =
cache.read(() => source.future, canCache: (_) => true);
cache.endMutation();
source.complete('ready');
expect(await duringMutation, 'ready');
expect(cache.value, isNull);
expect(await cache.read(() async => 'checked', canCache: (_) => true),
'checked');
expect(cache.value, 'checked');
});
test('加载失败不缓存失败结果,下一次读取可以重试', () async {
final cache = FaceReadinessCache<String>();
var calls = 0;
Future<String> load() async {
calls++;
if (calls == 1) throw StateError('sdk unavailable');
return 'ready';
}
await expectLater(
cache.read(load, canCache: (_) => true), throwsStateError);
expect(cache.value, isNull);
expect(await cache.read(load, canCache: (_) => true), 'ready');
expect(calls, 2);
});
test('未就绪的正常结果不缓存,后续就绪结果才会缓存', () async {
final cache = FaceReadinessCache<bool>();
var calls = 0;
Future<bool> load() async => ++calls > 1;
expect(await cache.read(load, canCache: (ready) => ready), isFalse);
expect(cache.value, isNull);
expect(await cache.read(load, canCache: (ready) => ready), isTrue);
expect(await cache.read(load, canCache: (ready) => ready), isTrue);
expect(cache.value, isTrue);
expect(calls, 2);
});
}