| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/widgets.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| void main() { |
| final MemoryAllocations ma = MemoryAllocations.instance; |
| |
| setUp(() { |
| assert(!ma.hasListeners); |
| }); |
| |
| test('Publishers dispatch events in debug mode', () async { |
| int eventCount = 0; |
| void listener(ObjectEvent event) => eventCount++; |
| ma.addListener(listener); |
| |
| final int expectedEventCount = await _activateFlutterObjectsAndReturnCountOfEvents(); |
| expect(eventCount, expectedEventCount); |
| |
| ma.removeListener(listener); |
| expect(ma.hasListeners, isFalse); |
| }); |
| |
| testWidgets('State dispatches events in debug mode', (WidgetTester tester) async { |
| bool stateCreated = false; |
| bool stateDisposed = false; |
| |
| void listener(ObjectEvent event) { |
| if (event is ObjectCreated && event.object is State) { |
| stateCreated = true; |
| } |
| if (event is ObjectDisposed && event.object is State) { |
| stateDisposed = true; |
| } |
| } |
| ma.addListener(listener); |
| |
| await tester.pumpWidget(const _TestStatefulWidget()); |
| expect(stateCreated, isTrue); |
| expect(stateDisposed, isFalse); |
| await tester.pumpWidget(const SizedBox.shrink()); |
| |
| expect(stateCreated, isTrue); |
| expect(stateDisposed, isTrue); |
| ma.removeListener(listener); |
| expect(ma.hasListeners, isFalse); |
| }); |
| } |
| |
| class _TestLeafRenderObjectWidget extends LeafRenderObjectWidget { |
| @override |
| RenderObject createRenderObject(BuildContext context) { |
| return _TestRenderObject(); |
| } |
| } |
| |
| class _TestElement extends RootRenderObjectElement{ |
| _TestElement(): super(_TestLeafRenderObjectWidget()); |
| |
| void makeInactive() { |
| assignOwner(BuildOwner(focusManager: FocusManager())); |
| mount(null, null); |
| deactivate(); |
| } |
| } |
| |
| class _TestRenderObject extends RenderObject { |
| @override |
| void debugAssertDoesMeetConstraints() {} |
| |
| @override |
| Rect get paintBounds => throw UnimplementedError(); |
| |
| @override |
| void performLayout() {} |
| |
| @override |
| void performResize() {} |
| |
| @override |
| Rect get semanticBounds => throw UnimplementedError(); |
| } |
| |
| |
| class _TestStatefulWidget extends StatefulWidget { |
| const _TestStatefulWidget(); |
| |
| @override |
| State<_TestStatefulWidget> createState() => _TestStatefulWidgetState(); |
| } |
| |
| class _TestStatefulWidgetState extends State<_TestStatefulWidget> { |
| @override |
| Widget build(BuildContext context) { |
| return Container(); |
| } |
| } |
| |
| /// Create and dispose Flutter objects to fire memory allocation events. |
| Future<int> _activateFlutterObjectsAndReturnCountOfEvents() async { |
| int count = 0; |
| |
| final _TestElement element = _TestElement(); count++; |
| final RenderObject renderObject = _TestRenderObject(); count++; |
| |
| element.makeInactive(); element.unmount(); count += 3; |
| renderObject.dispose(); count++; |
| |
| return count; |
| } |