Unverified Commit 32144161 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[null-safety] remove some usages of mockito (#62809)

parent 5b3dc525
...@@ -11,6 +11,7 @@ import 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignor ...@@ -11,6 +11,7 @@ import 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignor
import 'package:test_api/test_api.dart' as test_package show TypeMatcher; // ignore: deprecated_member_use import 'package:test_api/test_api.dart' as test_package show TypeMatcher; // ignore: deprecated_member_use
export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignore: deprecated_member_use export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignore: deprecated_member_use
export 'package:test_api/fake.dart'; // ignore: deprecated_member_use
/// A matcher that compares the type of the actual value to the type argument T. /// A matcher that compares the type of the actual value to the type argument T.
test_package.TypeMatcher<T> isInstanceOf<T>() => isA<T>(); test_package.TypeMatcher<T> isInstanceOf<T>() => isA<T>();
......
...@@ -11,43 +11,24 @@ import 'dart:io'; ...@@ -11,43 +11,24 @@ import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:mockito/mockito.dart';
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
final Uint8List chunkOne = Uint8List.fromList(<int>[0, 1, 2, 3, 4, 5]);
final Uint8List chunkTwo = Uint8List.fromList(<int>[6, 7, 8, 9, 10]);
void main() { void main() {
group(consolidateHttpClientResponseBytes, () { group(consolidateHttpClientResponseBytes, () {
final Uint8List chunkOne = Uint8List.fromList(<int>[0, 1, 2, 3, 4, 5]);
final Uint8List chunkTwo = Uint8List.fromList(<int>[6, 7, 8, 9, 10]);
MockHttpClientResponse response; MockHttpClientResponse response;
setUp(() { setUp(() {
response = MockHttpClientResponse(); response = MockHttpClientResponse(
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.notCompressed); chunkOne: chunkOne,
when(response.listen( chunkTwo: chunkTwo,
any, );
onDone: anyNamed('onDone'),
onError: anyNamed('onError'),
cancelOnError: anyNamed('cancelOnError'),
)).thenAnswer((Invocation invocation) {
final void Function(List<int>) onData = invocation.positionalArguments[0] as void Function(List<int>);
final void Function(Object) onError = invocation.namedArguments[#onError] as void Function(Object);
final VoidCallback onDone = invocation.namedArguments[#onDone] as VoidCallback;
final bool cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
return Stream<Uint8List>.fromIterable(
<Uint8List>[chunkOne, chunkTwo]).listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError,
);
});
}); });
test('Converts an HttpClientResponse with contentLength to bytes', () async { test('Converts an HttpClientResponse with contentLength to bytes', () async {
when(response.contentLength) response.contentLength = chunkOne.length + chunkTwo.length;
.thenReturn(chunkOne.length + chunkTwo.length);
final List<int> bytes = final List<int> bytes =
await consolidateHttpClientResponseBytes(response); await consolidateHttpClientResponseBytes(response);
...@@ -55,7 +36,7 @@ void main() { ...@@ -55,7 +36,7 @@ void main() {
}); });
test('Converts a compressed HttpClientResponse with contentLength to bytes', () async { test('Converts a compressed HttpClientResponse with contentLength to bytes', () async {
when(response.contentLength).thenReturn(chunkOne.length); response.contentLength = chunkOne.length;
final List<int> bytes = final List<int> bytes =
await consolidateHttpClientResponseBytes(response); await consolidateHttpClientResponseBytes(response);
...@@ -63,7 +44,7 @@ void main() { ...@@ -63,7 +44,7 @@ void main() {
}); });
test('Converts an HttpClientResponse without contentLength to bytes', () async { test('Converts an HttpClientResponse without contentLength to bytes', () async {
when(response.contentLength).thenReturn(-1); response.contentLength = -1;
final List<int> bytes = final List<int> bytes =
await consolidateHttpClientResponseBytes(response); await consolidateHttpClientResponseBytes(response);
...@@ -72,7 +53,7 @@ void main() { ...@@ -72,7 +53,7 @@ void main() {
test('Notifies onBytesReceived for every chunk of bytes', () async { test('Notifies onBytesReceived for every chunk of bytes', () async {
final int syntheticTotal = (chunkOne.length + chunkTwo.length) * 2; final int syntheticTotal = (chunkOne.length + chunkTwo.length) * 2;
when(response.contentLength).thenReturn(syntheticTotal); response.contentLength = syntheticTotal;
final List<int> records = <int>[]; final List<int> records = <int>[];
await consolidateHttpClientResponseBytes( await consolidateHttpClientResponseBytes(
response, response,
...@@ -90,33 +71,14 @@ void main() { ...@@ -90,33 +71,14 @@ void main() {
}); });
test('forwards errors from HttpClientResponse', () async { test('forwards errors from HttpClientResponse', () async {
when(response.listen( response = MockHttpClientResponse(error: Exception('Test Error'));
any, response.contentLength = -1;
onDone: anyNamed('onDone'),
onError: anyNamed('onError'),
cancelOnError: anyNamed('cancelOnError'),
)).thenAnswer((Invocation invocation) {
final void Function(List<int>) onData = invocation.positionalArguments[0] as void Function(List<int>);
final void Function(Object) onError = invocation.namedArguments[#onError] as void Function(Object);
final VoidCallback onDone = invocation.namedArguments[#onDone] as VoidCallback;
final bool cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
return Stream<Uint8List>.fromFuture(
Future<Uint8List>.error(Exception('Test Error')))
.listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError,
);
});
when(response.contentLength).thenReturn(-1);
expect(consolidateHttpClientResponseBytes(response), throwsException); expect(consolidateHttpClientResponseBytes(response), throwsException);
}); });
test('Propagates error to Future return value if onBytesReceived throws', () async { test('Propagates error to Future return value if onBytesReceived throws', () async {
when(response.contentLength).thenReturn(-1); response.contentLength = -1;
final Future<List<int>> result = consolidateHttpClientResponseBytes( final Future<List<int>> result = consolidateHttpClientResponseBytes(
response, response,
onBytesReceived: (int cumulative, int total) { onBytesReceived: (int cumulative, int total) {
...@@ -133,45 +95,24 @@ void main() { ...@@ -133,45 +95,24 @@ void main() {
final List<int> gzippedChunkTwo = gzipped.sublist(gzipped.length ~/ 2); final List<int> gzippedChunkTwo = gzipped.sublist(gzipped.length ~/ 2);
setUp(() { setUp(() {
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed); response = MockHttpClientResponse(chunkOne: gzippedChunkOne, chunkTwo: gzippedChunkTwo);
when(response.listen( response.compressionState = HttpClientResponseCompressionState.compressed;
any,
onDone: anyNamed('onDone'),
onError: anyNamed('onError'),
cancelOnError: anyNamed('cancelOnError'),
)).thenAnswer((Invocation invocation) {
final void Function(List<int>) onData = invocation.positionalArguments[0] as void Function(List<int>);
final void Function(Object) onError = invocation.namedArguments[#onError] as void Function(Object);
final VoidCallback onDone = invocation.namedArguments[#onDone] as VoidCallback;
final bool cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
return Stream<List<int>>.fromIterable(
<List<int>>[gzippedChunkOne, gzippedChunkTwo]).listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError,
);
});
}); });
test('Uncompresses GZIP bytes if autoUncompress is true and response.compressionState is compressed', () async { test('Uncompresses GZIP bytes if autoUncompress is true and response.compressionState is compressed', () async {
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed); response.contentLength = gzipped.length;
when(response.contentLength).thenReturn(gzipped.length);
final List<int> bytes = await consolidateHttpClientResponseBytes(response); final List<int> bytes = await consolidateHttpClientResponseBytes(response);
expect(bytes, <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); expect(bytes, <int>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
}); });
test('returns gzipped bytes if autoUncompress is false and response.compressionState is compressed', () async { test('returns gzipped bytes if autoUncompress is false and response.compressionState is compressed', () async {
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed); response.contentLength = gzipped.length;
when(response.contentLength).thenReturn(gzipped.length);
final List<int> bytes = await consolidateHttpClientResponseBytes(response, autoUncompress: false); final List<int> bytes = await consolidateHttpClientResponseBytes(response, autoUncompress: false);
expect(bytes, gzipped); expect(bytes, gzipped);
}); });
test('Notifies onBytesReceived with gzipped numbers', () async { test('Notifies onBytesReceived with gzipped numbers', () async {
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.compressed); response.contentLength = gzipped.length;
when(response.contentLength).thenReturn(gzipped.length);
final List<int> records = <int>[]; final List<int> records = <int>[];
await consolidateHttpClientResponseBytes( await consolidateHttpClientResponseBytes(
response, response,
...@@ -190,8 +131,8 @@ void main() { ...@@ -190,8 +131,8 @@ void main() {
test('Notifies onBytesReceived with expectedContentLength of -1 if response.compressionState is decompressed', () async { test('Notifies onBytesReceived with expectedContentLength of -1 if response.compressionState is decompressed', () async {
final int syntheticTotal = (chunkOne.length + chunkTwo.length) * 2; final int syntheticTotal = (chunkOne.length + chunkTwo.length) * 2;
when(response.compressionState).thenReturn(HttpClientResponseCompressionState.decompressed); response.compressionState = HttpClientResponseCompressionState.decompressed;
when(response.contentLength).thenReturn(syntheticTotal); response.contentLength = syntheticTotal;
final List<int> records = <int>[]; final List<int> records = <int>[];
await consolidateHttpClientResponseBytes( await consolidateHttpClientResponseBytes(
response, response,
...@@ -211,4 +152,36 @@ void main() { ...@@ -211,4 +152,36 @@ void main() {
}); });
} }
class MockHttpClientResponse extends Mock implements HttpClientResponse {} class MockHttpClientResponse extends Fake implements HttpClientResponse {
MockHttpClientResponse({this.error, this.chunkOne, this.chunkTwo});
final dynamic error;
final List<int> chunkOne;
final List<int> chunkTwo;
@override
int contentLength = 0;
@override
HttpClientResponseCompressionState compressionState = HttpClientResponseCompressionState.notCompressed;
@override
StreamSubscription<List<int>> listen(void Function(List<int> event) onData, {Function onError, void Function() onDone, bool cancelOnError}) {
if (error != null) {
return Stream<List<int>>.fromFuture(
Future<List<int>>.error(error)).listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError,
);
}
return Stream<List<int>>.fromIterable(
<List<int>>[chunkOne, chunkTwo]).listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError,
);
}
}
...@@ -9,7 +9,6 @@ import 'package:flutter/material.dart'; ...@@ -9,7 +9,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
void main() { void main() {
setUp(() => _GestureBindingSpy()); setUp(() => _GestureBindingSpy());
...@@ -58,7 +57,7 @@ class _GestureBindingSpy extends AutomatedTestWidgetsFlutterBinding { ...@@ -58,7 +57,7 @@ class _GestureBindingSpy extends AutomatedTestWidgetsFlutterBinding {
PointerRouter get pointerRouter => _testPointerRouter; PointerRouter get pointerRouter => _testPointerRouter;
} }
class FakeEditableTextState extends TextSelectionDelegate with Mock { } class FakeEditableTextState extends TextSelectionDelegate with Fake { }
class _PointerRouterSpy extends PointerRouter { class _PointerRouterSpy extends PointerRouter {
int routeCount = 0; int routeCount = 0;
......
...@@ -10,7 +10,6 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -10,7 +10,6 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:mockito/mockito.dart';
void main() { void main() {
group('PhysicalShape', () { group('PhysicalShape', () {
...@@ -353,8 +352,7 @@ void main() { ...@@ -353,8 +352,7 @@ void main() {
setUp(() { setUp(() {
mockContext = _MockPaintingContext(); mockContext = _MockPaintingContext();
mockCanvas = _MockCanvas(); mockCanvas = mockContext.canvas;
when(mockContext.canvas).thenReturn(mockCanvas);
}); });
testWidgets('ColoredBox - no size, no child', (WidgetTester tester) async { testWidgets('ColoredBox - no size, no child', (WidgetTester tester) async {
...@@ -372,8 +370,10 @@ void main() { ...@@ -372,8 +370,10 @@ void main() {
renderColoredBox.paint(mockContext, Offset.zero); renderColoredBox.paint(mockContext, Offset.zero);
verifyNever(mockCanvas.drawRect(any, any)); expect(mockCanvas.rects, isEmpty);
verifyNever(mockContext.paintChild(any, any)); expect(mockCanvas.paints, isEmpty);
expect(mockContext.children, isEmpty);
expect(mockContext.offets, isEmpty);
}); });
testWidgets('ColoredBox - no size, child', (WidgetTester tester) async { testWidgets('ColoredBox - no size, child', (WidgetTester tester) async {
...@@ -394,8 +394,10 @@ void main() { ...@@ -394,8 +394,10 @@ void main() {
renderColoredBox.paint(mockContext, Offset.zero); renderColoredBox.paint(mockContext, Offset.zero);
verifyNever(mockCanvas.drawRect(any, any)); expect(mockCanvas.rects, isEmpty);
verify(mockContext.paintChild(renderSizedBox, Offset.zero)).called(1); expect(mockCanvas.paints, isEmpty);
expect(mockContext.children.single, renderSizedBox);
expect(mockContext.offets.single, Offset.zero);
}); });
testWidgets('ColoredBox - size, no child', (WidgetTester tester) async { testWidgets('ColoredBox - size, no child', (WidgetTester tester) async {
...@@ -405,11 +407,10 @@ void main() { ...@@ -405,11 +407,10 @@ void main() {
renderColoredBox.paint(mockContext, Offset.zero); renderColoredBox.paint(mockContext, Offset.zero);
final List<dynamic> drawRect = verify(mockCanvas.drawRect(captureAny, captureAny)).captured; expect(mockCanvas.rects.single, const Rect.fromLTWH(0, 0, 800, 600));
expect(drawRect.length, 2); expect(mockCanvas.paints.single.color, colorToPaint);
expect(drawRect[0], const Rect.fromLTWH(0, 0, 800, 600)); expect(mockContext.children, isEmpty);
expect(drawRect[1].color, colorToPaint); expect(mockContext.offets, isEmpty);
verifyNever(mockContext.paintChild(any, any));
}); });
testWidgets('ColoredBox - size, child', (WidgetTester tester) async { testWidgets('ColoredBox - size, child', (WidgetTester tester) async {
...@@ -422,11 +423,10 @@ void main() { ...@@ -422,11 +423,10 @@ void main() {
renderColoredBox.paint(mockContext, Offset.zero); renderColoredBox.paint(mockContext, Offset.zero);
final List<dynamic> drawRect = verify(mockCanvas.drawRect(captureAny, captureAny)).captured; expect(mockCanvas.rects.single, const Rect.fromLTWH(0, 0, 800, 600));
expect(drawRect.length, 2); expect(mockCanvas.paints.single.color, colorToPaint);
expect(drawRect[0], const Rect.fromLTWH(0, 0, 800, 600)); expect(mockContext.children.single, renderSizedBox);
expect(drawRect[1].color, colorToPaint); expect(mockContext.offets.single, Offset.zero);
verify(mockContext.paintChild(renderSizedBox, Offset.zero)).called(1);
}); });
testWidgets('ColoredBox - properties', (WidgetTester tester) async { testWidgets('ColoredBox - properties', (WidgetTester tester) async {
...@@ -650,5 +650,28 @@ class DoesNotHitRenderBox extends Matcher { ...@@ -650,5 +650,28 @@ class DoesNotHitRenderBox extends Matcher {
} }
} }
class _MockPaintingContext extends Mock implements PaintingContext {} class _MockPaintingContext extends Fake implements PaintingContext {
class _MockCanvas extends Mock implements Canvas {} final List<RenderObject> children = <RenderObject>[];
final List<Offset> offets = <Offset>[];
@override
final _MockCanvas canvas = _MockCanvas();
@override
void paintChild(RenderObject child, Offset offset) {
children.add(child);
offets.add(offset);
}
}
class _MockCanvas extends Fake implements Canvas {
final List<Rect> rects = <Rect>[];
final List<Paint> paints = <Paint>[];
bool didPaint = false;
@override
void drawRect(Rect rect, Paint paint) {
rects.add(rect);
paints.add(paint);
}
}
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:mockito/mockito.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
...@@ -440,10 +439,6 @@ void main() { ...@@ -440,10 +439,6 @@ void main() {
final RenderBox decoratedBox = tester.renderObject(find.byType(DecoratedBox).last); final RenderBox decoratedBox = tester.renderObject(find.byType(DecoratedBox).last);
final PaintingContext context = _MockPaintingContext(); final PaintingContext context = _MockPaintingContext();
final Canvas canvas = _MockCanvas();
int saveCount = 0;
when(canvas.getSaveCount()).thenAnswer((_) => saveCount++);
when(context.canvas).thenReturn(canvas);
FlutterError error; FlutterError error;
try { try {
decoratedBox.paint(context, const Offset(0, 0)); decoratedBox.paint(context, const Offset(0, 0));
...@@ -561,5 +556,19 @@ void main() { ...@@ -561,5 +556,19 @@ void main() {
}); });
} }
class _MockPaintingContext extends Mock implements PaintingContext {} class _MockPaintingContext extends Fake implements PaintingContext {
class _MockCanvas extends Mock implements Canvas {} @override
final Canvas canvas = _MockCanvas();
}
class _MockCanvas extends Fake implements Canvas {
int saveCount = 0;
@override
int getSaveCount() {
return saveCount++;
}
@override
void drawRect(Rect rect, Paint paint) { }
}
...@@ -9,15 +9,11 @@ import 'dart:io'; ...@@ -9,15 +9,11 @@ import 'dart:io';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import '../painting/image_data.dart'; import '../painting/image_data.dart';
void main() { void main() {
final MockHttpClient client = MockHttpClient(); final MockHttpClient client = MockHttpClient();
final MockHttpClientRequest request = MockHttpClientRequest();
final MockHttpClientResponse response = MockHttpClientResponse();
final MockHttpHeaders headers = MockHttpHeaders();
testWidgets('Headers', (WidgetTester tester) async { testWidgets('Headers', (WidgetTester tester) async {
HttpOverrides.runZoned<Future<void>>(() async { HttpOverrides.runZoned<Future<void>>(() async {
...@@ -26,30 +22,61 @@ void main() { ...@@ -26,30 +22,61 @@ void main() {
headers: const <String, String>{'flutter': 'flutter'}, headers: const <String, String>{'flutter': 'flutter'},
)); ));
verify(headers.add('flutter', 'flutter')).called(1); expect(MockHttpHeaders.headers['flutter'], <String>['flutter']);
}, createHttpClient: (SecurityContext _) { }, createHttpClient: (SecurityContext _) {
when(client.getUrl(any)).thenAnswer((_) => Future<HttpClientRequest>.value(request));
when(request.headers).thenReturn(headers);
when(request.close()).thenAnswer((_) => Future<HttpClientResponse>.value(response));
when(response.contentLength).thenReturn(kTransparentImage.length);
when(response.statusCode).thenReturn(HttpStatus.ok);
when(response.listen(any)).thenAnswer((Invocation invocation) {
final void Function(List<int>) onData = invocation.positionalArguments[0] as void Function(List<int>);
final void Function() onDone = invocation.namedArguments[#onDone] as void Function();
final void Function(Object, [ StackTrace ]) onError = invocation.namedArguments[#onError] as void Function(Object, [ StackTrace ]);
final bool cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
return Stream<List<int>>.fromIterable(<List<int>>[kTransparentImage]).listen(onData, onDone: onDone, onError: onError, cancelOnError: cancelOnError);
});
return client; return client;
}); });
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/57187 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/57187
} }
class MockHttpClient extends Mock implements HttpClient {} class MockHttpClient extends Fake implements HttpClient {
@override
Future<HttpClientRequest> getUrl(Uri url) async {
return MockHttpClientRequest();
}
@override
bool autoUncompress = false;
}
class MockHttpClientRequest extends Fake implements HttpClientRequest {
@override
final MockHttpHeaders headers = MockHttpHeaders();
@override
Future<HttpClientResponse> close() async {
return MockHttpClientResponse();
}
}
class MockHttpClientResponse extends Fake implements HttpClientResponse {
@override
int get contentLength => kTransparentImage.length;
@override
int get statusCode => HttpStatus.ok;
class MockHttpClientRequest extends Mock implements HttpClientRequest {} @override
HttpClientResponseCompressionState get compressionState => HttpClientResponseCompressionState.decompressed;
class MockHttpClientResponse extends Mock implements HttpClientResponse {} @override
StreamSubscription<List<int>> listen(void Function(List<int> event) onData, {Function onError, void Function() onDone, bool cancelOnError}) {
return Stream<List<int>>.fromIterable(<List<int>>[kTransparentImage]).listen(
onData,
onDone: onDone,
onError: onError,
cancelOnError: cancelOnError,
);
}
}
class MockHttpHeaders extends Fake implements HttpHeaders {
static final Map<String, List<String>> headers = <String, List<String>>{};
class MockHttpHeaders extends Mock implements HttpHeaders {} @override
void add(String key, Object value, { bool preserveHeaderCase = false }) {
headers[key] ??= <String>[];
headers[key].add(value.toString());
}
}
...@@ -21,6 +21,9 @@ import 'package:test_api/src/backend/state.dart'; // ignore: implementation_impo ...@@ -21,6 +21,9 @@ import 'package:test_api/src/backend/state.dart'; // ignore: implementation_impo
// ignore: deprecated_member_use // ignore: deprecated_member_use
import 'package:test_api/test_api.dart'; import 'package:test_api/test_api.dart';
// ignore: deprecated_member_use
export 'package:test_api/fake.dart' show Fake;
Declarer _localDeclarer; Declarer _localDeclarer;
Declarer get _declarer { Declarer get _declarer {
final Declarer declarer = Zone.current[#test.declarer] as Declarer; final Declarer declarer = Zone.current[#test.declarer] as Declarer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment