실시간 구독 공유 스트림 — 여러 화면이 원본 구독 하나를 나눠 쓴다 · 서버 시험을 저장소 안 에뮬레이터 도구로 실행
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fancake/core/data/shared_stream.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
/// 실시간 구독 공유 — 같은 문서를 여러 화면이 볼 때 원본 구독은 하나만 연다.
|
||||
void main() {
|
||||
group('구독 공유 — 여러 화면이 원본 하나를 나눠 본다', () {
|
||||
test('여러 화면이 같은 원본 하나를 나눠 쓴다', () async {
|
||||
// 화면마다 snapshots() 를 열면 한 팬덤에 리스너가 화면 수만큼 붙는다.
|
||||
var opened = 0;
|
||||
final controller = StreamController<int>.broadcast();
|
||||
addTearDown(controller.close);
|
||||
final shared = SharedStream<int>(() {
|
||||
opened += 1;
|
||||
return controller.stream;
|
||||
});
|
||||
|
||||
final a = <int>[];
|
||||
final b = <int>[];
|
||||
final subA = shared.stream.listen(a.add);
|
||||
final subB = shared.stream.listen(b.add);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
controller.add(7);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
// 원본은 한 번만 열렸는데 두 화면 모두 값을 받았다.
|
||||
expect(opened, 1);
|
||||
expect(a, [7]);
|
||||
expect(b, [7]);
|
||||
|
||||
await subA.cancel();
|
||||
await subB.cancel();
|
||||
});
|
||||
|
||||
test('늦게 붙은 화면이 현재 값을 곧바로 받는다', () async {
|
||||
final controller = StreamController<int>.broadcast();
|
||||
addTearDown(controller.close);
|
||||
final shared = SharedStream<int>(() => controller.stream);
|
||||
|
||||
final first = <int>[];
|
||||
final subA = shared.stream.listen(first.add);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
controller.add(42);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
// 뒤늦게 열린 화면이 다음 갱신까지 빈 상태로 남으면 안 된다.
|
||||
final late = <int>[];
|
||||
final subB = shared.stream.listen(late.add);
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
expect(late, [42]);
|
||||
|
||||
await subA.cancel();
|
||||
await subB.cancel();
|
||||
});
|
||||
|
||||
test('마지막 화면이 떠나면 원본을 닫는다', () async {
|
||||
var cancelled = false;
|
||||
final controller = StreamController<int>(
|
||||
onCancel: () => cancelled = true,
|
||||
);
|
||||
addTearDown(controller.close);
|
||||
final shared = SharedStream<int>(() => controller.stream);
|
||||
|
||||
final sub = shared.stream.listen((_) {});
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
expect(cancelled, isFalse);
|
||||
|
||||
await sub.cancel();
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
// 남겨 두면 화면이 없는 동안에도 읽기 비용이 계속 든다.
|
||||
expect(cancelled, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user