Skip to content

Commit 49a27bd

Browse files
committed
test: Cover Log.progress with synchronous (FutureOr) runners
These fail to compile if the runner is narrowed to Future<T> Function()
1 parent 91902ff commit 49a27bd

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import 'package:serverpod_logging/serverpod_logging.dart';
2+
import 'package:test/test.dart';
3+
4+
/// [Log.progress] accepts a `FutureOr<T> Function()` runner, so a plain
5+
/// synchronous callback (`() => value`, not `() async => value`) is a
6+
/// supported call shape. These tests pin that contract.
7+
void main() {
8+
group('Given Log.progress with a synchronous runner', () {
9+
late TestLogWriter writer;
10+
late Log log;
11+
12+
setUp(() {
13+
writer = TestLogWriter();
14+
log = Log(writer);
15+
});
16+
17+
test(
18+
'when the runner returns true synchronously, '
19+
'then the scope closes with success true', () async {
20+
final result = await log.progress('op', () => true);
21+
22+
expect(result, isTrue);
23+
expect(writer.closedScopes.single.success, isTrue);
24+
});
25+
26+
test(
27+
'when the runner returns false synchronously, '
28+
'then the scope closes with success false', () async {
29+
final result = await log.progress('op', () => false);
30+
31+
expect(result, isFalse);
32+
expect(writer.closedScopes.single.success, isFalse);
33+
});
34+
35+
test(
36+
'when a synchronous runner returns a non-bool value, '
37+
'then the value is returned and the scope closes successfully',
38+
() async {
39+
final result = await log.progress<String>('op', () => 'ok');
40+
41+
expect(result, 'ok');
42+
expect(writer.closedScopes.single.success, isTrue);
43+
},
44+
);
45+
46+
test(
47+
'when a synchronous runner emits a log entry, '
48+
'then that entry is scoped to the progress scope', () async {
49+
await log.progress('op', () {
50+
log.info('inside');
51+
return true;
52+
});
53+
await log.flush();
54+
55+
final opened = writer.openedScopes.single;
56+
final inside = writer.entries.singleWhere((e) => e.message == 'inside');
57+
expect(inside.scope.id, opened.id);
58+
});
59+
60+
test(
61+
'when a synchronous runner throws, '
62+
'then the scope closes with success false and rethrows', () async {
63+
await expectLater(
64+
log.progress<bool>('op', () => throw StateError('boom')),
65+
throwsA(isA<StateError>()),
66+
);
67+
68+
expect(writer.closedScopes.single.success, isFalse);
69+
expect(writer.closedScopes.single.error, isA<StateError>());
70+
});
71+
});
72+
}

0 commit comments

Comments
 (0)