import "package:arcane_framework/arcane_framework.dart"; import "package:flutter/material.dart"; import "package:flutter_test/flutter_test.dart"; void main() { group("ArcaneServiceProvider", () { late List testServices; setUp(() { testServices = [ MockArcaneService(), AnotherMockService(), ]; }); testWidgets("provides services to widget tree", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { final provider = ArcaneServiceProvider.of(context); expect(provider.registeredServices, equals(testServices)); return const SizedBox(); }, ), ), ); }); testWidgets("static serviceOfType method returns correct service", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { final service = ArcaneServiceProvider.serviceOfType( context, ); expect(service, isNotNull); expect(service, isA()); return const SizedBox(); }, ), ), ); }); testWidgets( "static serviceOfType method returns correct service and returns null when not found", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { // Should find this service final service = ArcaneServiceProvider.serviceOfType( context, ); expect(service, isA()); // Returns null for unregistered services expect( ArcaneServiceProvider.serviceOfType( context, ), isNull, ); return const SizedBox(); }, ), ), ); }); testWidgets("service extension returns correct service", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { final service = context.service(); expect(service, isNotNull); expect(service, isA()); return const SizedBox(); }, ), ), ); }); testWidgets( "requiredService extension returns correct service and throws when not found", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { // Should find this service final service = context.requiredService(); expect(service, isA()); // Should throw for missing service expect( () => context.requiredService(), throwsA(isA()), ); return const SizedBox(); }, ), ), ); }); testWidgets("service returns null for unregistered service", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { final service = context.service(); expect(service, isNull); return const SizedBox(); }, ), ), ); }); testWidgets("legacy serviceOfType method still works but is deprecated", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { // ignore: deprecated_member_use_from_same_package final service = context.serviceOfType(); expect(service, isNotNull); expect(service, isA()); return const SizedBox(); }, ), ), ); }); testWidgets("service updates trigger rebuilds", (tester) async { late ArcaneServiceProvider provider; int buildCount = 0; await tester.pumpWidget( MaterialApp( home: ArcaneServiceProvider( serviceInstances: testServices, child: Builder( builder: (context) { provider = ArcaneServiceProvider.of(context); buildCount++; // Access a service to create dependency context.service(); return const Text("Test"); }, ), ), ), ); expect(buildCount, 1); // Update services and verify rebuild provider.setServices([MockArcaneService(), AnotherMockService()]); await tester.pump(); expect(buildCount, 2); // Add a service and verify rebuild provider.addService(UnregisteredService()); await tester.pump(); expect(buildCount, 3); }); testWidgets("ArcaneService.of static helper works", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { final service = ArcaneService.of(context); expect(service, isNotNull); expect(service, isA()); return const SizedBox(); }, ), ), ); }); testWidgets("ArcaneService.requiredOf static helper works", (tester) async { await tester.pumpWidget( ArcaneApp( services: testServices, child: Builder( builder: (context) { final service = ArcaneService.requiredOf(context); expect(service, isA()); expect( () => ArcaneService.requiredOf(context), throwsA(isA()), ); return const SizedBox(); }, ), ), ); }); }); } // Mock classes for testing class MockArcaneService extends ArcaneService {} class AnotherMockService extends ArcaneService {} class UnregisteredService extends ArcaneService {} class MockBuildContext extends Fake implements BuildContext {}