Skip to content

Commit 4700d6f

Browse files
committed
fix(hydrated_bloc)!: HydratedCubit storage override should be a named parameter (#4537)
1 parent 425cf0f commit 4700d6f

File tree

2 files changed

+90
-4
lines changed

2 files changed

+90
-4
lines changed

packages/hydrated_bloc/lib/src/hydrated_bloc.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ HydrationErrorBehavior defaultOnHydrationError(
6161
abstract class HydratedBloc<Event, State> extends Bloc<Event, State>
6262
with HydratedMixin {
6363
/// {@macro hydrated_bloc}
64-
HydratedBloc(State state, {Storage? storage}) : super(state) {
65-
hydrate(storage: storage);
64+
HydratedBloc(
65+
State state, {
66+
Storage? storage,
67+
OnHydrationError onHydrationError = defaultOnHydrationError,
68+
}) : super(state) {
69+
hydrate(storage: storage, onError: onHydrationError);
6670
}
6771

6872
static Storage? _storage;
@@ -103,8 +107,12 @@ abstract class HydratedBloc<Event, State> extends Bloc<Event, State>
103107
abstract class HydratedCubit<State> extends Cubit<State>
104108
with HydratedMixin<State> {
105109
/// {@macro hydrated_cubit}
106-
HydratedCubit(State state, [Storage? storage]) : super(state) {
107-
hydrate(storage: storage);
110+
HydratedCubit(
111+
State state, {
112+
Storage? storage,
113+
OnHydrationError onHydrationError = defaultOnHydrationError,
114+
}) : super(state) {
115+
hydrate(storage: storage, onError: onHydrationError);
108116
}
109117
}
110118

packages/hydrated_bloc/test/hydrated_cubit_test.dart

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ class MyMultiHydratedCubit extends HydratedCubit<int> {
8888
int? fromJson(dynamic json) => json['value'] as int?;
8989
}
9090

91+
class MyHydratedCubitWithCustomStorage extends HydratedCubit<int> {
92+
MyHydratedCubitWithCustomStorage(Storage storage)
93+
: super(0, storage: storage);
94+
95+
@override
96+
Map<String, int>? toJson(int state) {
97+
return {'value': state};
98+
}
99+
100+
@override
101+
int? fromJson(Map<String, dynamic> json) => json['value'] as int?;
102+
}
103+
91104
void main() {
92105
group('HydratedCubit', () {
93106
late Storage storage;
@@ -379,5 +392,70 @@ void main() {
379392
expect(initialStateB, cachedState);
380393
});
381394
});
395+
396+
group('MyHydratedCubitWithCustomStorage', () {
397+
setUp(() {
398+
HydratedBloc.storage = null;
399+
});
400+
401+
test('should call storage.write when onChange is called', () {
402+
const expected = <String, int>{'value': 0};
403+
const change = Change(currentState: 0, nextState: 0);
404+
MyHydratedCubitWithCustomStorage(storage).onChange(change);
405+
verify(
406+
() => storage.write('MyHydratedCubitWithCustomStorage', expected),
407+
).called(2);
408+
});
409+
410+
test('should call onError when storage.write throws', () {
411+
runZonedGuarded(() async {
412+
final expectedError = Exception('oops');
413+
const change = Change(currentState: 0, nextState: 0);
414+
final cubit = MyHydratedCubitWithCustomStorage(storage);
415+
when(
416+
() => storage.write(any(), any<dynamic>()),
417+
).thenThrow(expectedError);
418+
cubit.onChange(change);
419+
await Future<void>.delayed(const Duration(milliseconds: 300));
420+
// ignore: invalid_use_of_protected_member
421+
verify(() => cubit.onError(expectedError, any())).called(2);
422+
}, (error, stackTrace) {
423+
expect(error.toString(), 'Exception: oops');
424+
expect(stackTrace, isNotNull);
425+
});
426+
});
427+
428+
test('stores initial state when instantiated', () {
429+
MyHydratedCubitWithCustomStorage(storage);
430+
verify(
431+
() => storage.write('MyHydratedCubitWithCustomStorage', {'value': 0}),
432+
).called(1);
433+
});
434+
435+
test('initial state should return 0 when fromJson returns null', () {
436+
when<dynamic>(() => storage.read(any())).thenReturn(null);
437+
expect(MyHydratedCubitWithCustomStorage(storage).state, 0);
438+
verify<dynamic>(
439+
() => storage.read('MyHydratedCubitWithCustomStorage'),
440+
).called(1);
441+
});
442+
443+
test('initial state should return 101 when fromJson returns 101', () {
444+
when<dynamic>(() => storage.read(any())).thenReturn({'value': 101});
445+
expect(MyHydratedCubitWithCustomStorage(storage).state, 101);
446+
verify<dynamic>(
447+
() => storage.read('MyHydratedCubitWithCustomStorage'),
448+
).called(1);
449+
});
450+
451+
group('clear', () {
452+
test('calls delete on custom storage', () async {
453+
await MyHydratedCubitWithCustomStorage(storage).clear();
454+
verify(
455+
() => storage.delete('MyHydratedCubitWithCustomStorage'),
456+
).called(1);
457+
});
458+
});
459+
});
382460
});
383461
}

0 commit comments

Comments
 (0)