platform/incubation/ioc_container/test/bound_method_test.dart

164 lines
5.7 KiB
Dart
Raw Normal View History

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:ioc_container/container.dart';
import 'package:platform_contracts/contracts.dart';
class MockContainer extends Mock implements Container {}
class TestClass {
String testMethod(String param) => 'Test: $param';
static String staticMethod(String param) => 'Static: $param';
String __invoke(String param) => 'Invoke: $param';
}
class DependencyClass {
final String value;
DependencyClass(this.value);
}
class ClassWithDependency {
String methodWithDependency(DependencyClass dep, String param) =>
'${dep.value}: $param';
}
class NestedDependency {
final DependencyClass dep;
NestedDependency(this.dep);
String nestedMethod(String param) => '${dep.value} nested: $param';
}
class ClassWithOptionalParam {
String methodWithOptional(String required, [String optional = 'default']) =>
'$required - $optional';
}
void main() {
group('Container.call', () {
late MockContainer container;
setUp(() {
container = MockContainer();
});
test('call with Function', () {
var result = container.call((String s) => 'Hello $s', ['World']);
expect(result, equals('Hello World'));
});
test('call with class@method string', () {
when(container.make('TestClass')).thenReturn(TestClass());
var result = container.call('TestClass@testMethod', ['World']);
expect(result, equals('Test: World'));
});
test('call with List callback', () {
when(container.make('TestClass')).thenReturn(TestClass());
var result = container.call(['TestClass', 'testMethod'], ['World']);
expect(result, equals('Test: World'));
});
test('call with static method', () {
when(container.make('TestClass')).thenReturn(TestClass);
var result = container.call(['TestClass', 'staticMethod'], ['World']);
expect(result, equals('Static: World'));
});
test('call with Map instance and method key', () {
var mapInstance = {'testMethod': (String s) => 'Map: $s'};
when(container.make('TestMap')).thenReturn(mapInstance);
var result = container.call(['TestMap', 'testMethod'], ['World']);
expect(result, equals('Map: World'));
});
test('call with global function', () {
when(container.make('globalFunction')).thenReturn(globalFunction);
var result = container.call('globalFunction', ['World']);
expect(result, equals('Global: World'));
});
test('call with default method', () {
when(container.make('TestClass')).thenReturn(TestClass());
var result = container.call('TestClass', ['World'], '__invoke');
expect(result, equals('Invoke: World'));
});
test('call with __invoke method', () {
when(container.make('TestClass')).thenReturn(TestClass());
var result = container.call('TestClass', ['World']);
expect(result, equals('Invoke: World'));
});
test('call with non-existent method throws BindingResolutionException', () {
when(container.make('TestClass')).thenReturn(TestClass());
expect(() => container.call('TestClass@nonExistentMethod', ['World']),
throwsA(isA<BindingResolutionException>()));
});
test('call with invalid callback type throws ArgumentError', () {
expect(
() => container.call(123, ['World']), throwsA(isA<ArgumentError>()));
});
test('call method with dependencies', () {
when(container.make('ClassWithDependency'))
.thenReturn(ClassWithDependency());
when(container.make('DependencyClass'))
.thenReturn(DependencyClass('Dependency'));
var result = container
.call(['ClassWithDependency', 'methodWithDependency'], ['World']);
expect(result, equals('Dependency: World'));
});
test('call method with overridden dependency', () {
when(container.make('ClassWithDependency'))
.thenReturn(ClassWithDependency());
when(container.make('DependencyClass'))
.thenReturn(DependencyClass('Dependency'));
var result = container.call(
['ClassWithDependency', 'methodWithDependency'],
[DependencyClass('Override'), 'World']);
expect(result, equals('Override: World'));
});
test('call method with nested dependency', () {
when(container.make('NestedDependency'))
.thenReturn(NestedDependency(DependencyClass('NestedDep')));
var result =
container.call(['NestedDependency', 'nestedMethod'], ['World']);
expect(result, equals('NestedDep nested: World'));
});
test('call method with optional parameter - provided', () {
when(container.make('ClassWithOptionalParam'))
.thenReturn(ClassWithOptionalParam());
var result = container.call(
['ClassWithOptionalParam', 'methodWithOptional'],
['Required', 'Provided']);
expect(result, equals('Required - Provided'));
});
test('call method with optional parameter - default', () {
when(container.make('ClassWithOptionalParam'))
.thenReturn(ClassWithOptionalParam());
var result = container
.call(['ClassWithOptionalParam', 'methodWithOptional'], ['Required']);
expect(result, equals('Required - default'));
});
test(
'call method with missing required dependency throws BindingResolutionException',
() {
when(container.make('ClassWithDependency'))
.thenReturn(ClassWithDependency());
when(container.make('DependencyClass'))
.thenThrow(BindingResolutionException('DependencyClass not found'));
expect(
() => container
.call(['ClassWithDependency', 'methodWithDependency'], ['World']),
throwsA(isA<BindingResolutionException>()));
});
});
}
String globalFunction(String param) => 'Global: $param';