import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'package:provider/src/provider.dart'; import 'matchers.dart'; void main() { late PostEventSpy spy; setUp(() { spy = spyPostEvent(); }); tearDown(() => spy.dispose()); testWidgets('calls postEvent whenever a provider is updated', (tester) async { final notifier = ValueNotifier(42); addTearDown(notifier.dispose); await tester.pumpWidget( MultiProvider( providers: [ ChangeNotifierProvider.value(value: notifier), ], child: Consumer>( builder: (context, value, child) { return Container(); }, ), ), ); final notifierId = ProviderBinding.debugInstance.providerDetails.keys.single; spy.logs.clear(); notifier.notifyListeners(); expect(spy.logs, isEmpty); await tester.pump(); expect( spy.logs, [ isPostEventCall( 'provider:provider_changed', {'id': notifierId}, ), ], ); spy.logs.clear(); }); testWidgets('calls postEvent whenever a provider is mounted/unmounted', (tester) async { Provider.value(value: 42); expect(spy.logs, isEmpty); expect(ProviderBinding.debugInstance.providerDetails, isEmpty); await tester.pumpWidget( MultiProvider( providers: [ Provider.value(value: 42), ], child: Container(), ), ); final intProviderId = ProviderBinding.debugInstance.providerDetails.keys.first; expect(ProviderBinding.debugInstance.providerDetails, { intProviderId: isA() .having((e) => e.id, 'id', intProviderId) .having((e) => e.type, 'type', 'Provider') .having((e) => e.value, 'value', 42), }); expect( spy.logs, [isPostEventCall('provider:provider_list_changed', isEmpty)], ); spy.logs.clear(); await tester.pumpWidget( MultiProvider( providers: [ Provider.value(value: 42), Provider.value(value: '42'), ], child: Container(), ), ); final stringProviderId = ProviderBinding.debugInstance.providerDetails.keys.last; expect(intProviderId, isNot(stringProviderId)); expect(ProviderBinding.debugInstance.providerDetails, { intProviderId: isA() .having((e) => e.id, 'id', intProviderId) .having((e) => e.type, 'type', 'Provider') .having((e) => e.value, 'value', 42), stringProviderId: isA() .having((e) => e.id, 'id', stringProviderId) .having((e) => e.type, 'type', 'Provider') .having((e) => e.value, 'value', '42'), }); expect( spy.logs, [isPostEventCall('provider:provider_list_changed', isEmpty)], ); spy.logs.clear(); await tester.pumpWidget( MultiProvider( providers: [ Provider.value(value: 42), ], child: Container(), ), ); expect(ProviderBinding.debugInstance.providerDetails, { intProviderId: isA() .having((e) => e.id, 'id', intProviderId) .having((e) => e.type, 'type', 'Provider') .having((e) => e.value, 'value', 42), }); expect( spy.logs, [isPostEventCall('provider:provider_list_changed', isEmpty)], ); spy.logs.clear(); }); }