// 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/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; typedef TestCallback = void Function(BuildContext context); class TestWidget extends StatefulWidget { const TestWidget(this.callback, { Key? key }) : super(key: key); final TestCallback callback; @override TestWidgetState createState() => TestWidgetState(); } class TestWidgetState extends State<TestWidget> { @override void dispose() { widget.callback(context); super.dispose(); } @override Widget build(BuildContext context) => const Text('test', textDirection: TextDirection.ltr); } void main() { testWidgets('dependOnInheritedWidgetOfExactType() called from dispose() throws error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; context.dependOnInheritedWidgetOfExactType<InheritedWidget>(); }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); expect(tester.takeException(), isFlutterError); }); testWidgets('getElementForInheritedWidgetOfExactType() called from dispose() throws error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; context.getElementForInheritedWidgetOfExactType<InheritedWidget>(); }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); expect(tester.takeException(), isFlutterError); }); testWidgets('findAncestorWidgetOfExactType() called from dispose() throws error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; context.findAncestorWidgetOfExactType<Container>(); }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); expect(tester.takeException(), isFlutterError); }); testWidgets('findAncestorStateOfType() called from dispose() throws error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; context.findAncestorStateOfType<State>(); }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); expect(tester.takeException(), isFlutterError); }); testWidgets('findAncestorRenderObjectOfType() called from dispose() throws error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; context.findAncestorRenderObjectOfType<RenderObject>(); }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); expect(tester.takeException(), isFlutterError); }); testWidgets('visitAncestorElements() called from dispose() throws error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; context.visitAncestorElements((Element element) => true); }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); expect(tester.takeException(), isFlutterError); }); testWidgets('dispose() method does not unconditionally throw an error', (WidgetTester tester) async { bool disposeCalled = false; await tester.pumpWidget( TestWidget((BuildContext context) { disposeCalled = true; }), ); await tester.pumpWidget(Container()); expect(disposeCalled, isTrue); }); }