platform/packages/support/test/support_tappable_test.dart

158 lines
3.9 KiB
Dart

import 'package:test/test.dart';
import 'package:platform_support/platform_support.dart';
import 'package:platform_reflection/reflection.dart';
@reflectable
class TappableTest with Tappable {
String value = '';
TappableTest setValue(String newValue) {
value = newValue;
return this;
}
String getValue() => value;
@override
dynamic noSuchMethod(Invocation invocation) {
if (invocation.memberName == #setValue &&
invocation.positionalArguments.length == 1) {
return setValue(invocation.positionalArguments[0] as String);
}
if (invocation.memberName == #getValue &&
invocation.positionalArguments.isEmpty) {
return getValue();
}
return super.noSuchMethod(invocation);
}
}
void main() {
late TappableTest instance;
setUp(() {
instance = TappableTest();
// Register class and methods for reflection
Reflector.reset();
Reflector.register(TappableTest);
// Register setValue method
Reflector.registerMethod(
TappableTest,
'setValue',
[String],
false, // not void
parameterNames: ['newValue'],
isRequired: [true],
);
// Register getValue method
Reflector.registerMethod(
TappableTest,
'getValue',
[],
false, // not void
);
// Register tap method
Reflector.registerMethod(
TappableTest,
'tap',
[Function],
false, // not void
parameterNames: ['callback'],
isRequired: [false],
);
});
group('Tappable', () {
test('tap executes callback and returns instance', () {
var callbackExecuted = false;
final result = instance.tap((obj) {
callbackExecuted = true;
expect(obj, equals(instance));
});
expect(callbackExecuted, isTrue);
expect(result, equals(instance));
});
test('tap can be used in method chains', () {
var beforeValue = '';
var afterValue = '';
instance
.tap((obj) => beforeValue = obj.getValue())
.setValue('test')
.tap((obj) => afterValue = obj.getValue());
expect(beforeValue, equals(''));
expect(afterValue, equals('test'));
expect(instance.value, equals('test'));
});
test('tap returns HigherOrderTapProxy when no callback provided', () {
final proxy = instance.tap();
expect(proxy, isA<HigherOrderTapProxy>());
});
test('tap proxy forwards method calls to target', () {
instance.tap().setValue('via proxy');
expect(instance.value, equals('via proxy'));
});
test('tap proxy can be chained', () {
instance
.tap() // Returns proxy
.setValue('first')
.setValue('second');
expect(instance.value, equals('second'));
});
test('tap proxy maintains instance state', () {
instance
.tap() // Returns proxy
.setValue('test'); // Called on instance via proxy
final result = instance.getValue(); // Called directly
expect(result, equals('test'));
});
test('tap callback can modify instance state', () {
instance.tap((obj) {
(obj as TappableTest).setValue('modified');
});
expect(instance.value, equals('modified'));
});
test('tap callback receives correct instance', () {
instance.setValue('initial');
instance.tap((obj) {
expect(obj, equals(instance));
expect((obj as TappableTest).value, equals('initial'));
});
});
test('tap proxy forwards multiple method calls', () {
instance.tap().setValue('first').setValue('second').setValue('third');
expect(instance.value, equals('third'));
});
test('tap can mix callbacks and proxies', () {
var middleValue = '';
instance
.setValue('first')
.tap((obj) => middleValue = obj.getValue())
.setValue('last');
expect(middleValue, equals('first'));
expect(instance.value, equals('last'));
});
});
}