Unverified Commit c3db0209 authored by Kostia Sokolovskyi's avatar Kostia Sokolovskyi Committed by GitHub

Cover more test/widgets tests with leak tracking #9 (#135054)

parent d0004c95
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
...@@ -20,9 +21,11 @@ void main() { ...@@ -20,9 +21,11 @@ void main() {
); );
} }
testWidgets('updates its registrar and delegate based on the number of selectables', (WidgetTester tester) async { testWidgetsWithLeakTracking('updates its registrar and delegate based on the number of selectables', (WidgetTester tester) async {
final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestSelectionRegistrar registrar = TestSelectionRegistrar();
final TestContainerDelegate delegate = TestContainerDelegate(); final TestContainerDelegate delegate = TestContainerDelegate();
addTearDown(delegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
SelectionContainer( SelectionContainer(
...@@ -42,9 +45,11 @@ void main() { ...@@ -42,9 +45,11 @@ void main() {
expect(delegate.selectables.length, 3); expect(delegate.selectables.length, 3);
}); });
testWidgets('disabled container', (WidgetTester tester) async { testWidgetsWithLeakTracking('disabled container', (WidgetTester tester) async {
final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestSelectionRegistrar registrar = TestSelectionRegistrar();
final TestContainerDelegate delegate = TestContainerDelegate(); final TestContainerDelegate delegate = TestContainerDelegate();
addTearDown(delegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
SelectionContainer( SelectionContainer(
...@@ -65,10 +70,13 @@ void main() { ...@@ -65,10 +70,13 @@ void main() {
expect(delegate.selectables.length, 0); expect(delegate.selectables.length, 0);
}); });
testWidgets('Swapping out container delegate does not crash', (WidgetTester tester) async { testWidgetsWithLeakTracking('Swapping out container delegate does not crash', (WidgetTester tester) async {
final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestSelectionRegistrar registrar = TestSelectionRegistrar();
final TestContainerDelegate delegate = TestContainerDelegate(); final TestContainerDelegate delegate = TestContainerDelegate();
addTearDown(delegate.dispose);
final TestContainerDelegate childDelegate = TestContainerDelegate(); final TestContainerDelegate childDelegate = TestContainerDelegate();
addTearDown(childDelegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
SelectionContainer( SelectionContainer(
...@@ -90,6 +98,8 @@ void main() { ...@@ -90,6 +98,8 @@ void main() {
expect(delegate.value.hasContent, isTrue); expect(delegate.value.hasContent, isTrue);
final TestContainerDelegate newDelegate = TestContainerDelegate(); final TestContainerDelegate newDelegate = TestContainerDelegate();
addTearDown(newDelegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
SelectionContainer( SelectionContainer(
...@@ -112,10 +122,13 @@ void main() { ...@@ -112,10 +122,13 @@ void main() {
expect(tester.takeException(), isNull); expect(tester.takeException(), isNull);
}); });
testWidgets('Can update within one frame', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can update within one frame', (WidgetTester tester) async {
final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestSelectionRegistrar registrar = TestSelectionRegistrar();
final TestContainerDelegate delegate = TestContainerDelegate(); final TestContainerDelegate delegate = TestContainerDelegate();
addTearDown(delegate.dispose);
final TestContainerDelegate childDelegate = TestContainerDelegate(); final TestContainerDelegate childDelegate = TestContainerDelegate();
addTearDown(childDelegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
SelectionContainer( SelectionContainer(
...@@ -139,9 +152,11 @@ void main() { ...@@ -139,9 +152,11 @@ void main() {
expect(delegate.value.hasContent, isTrue); expect(delegate.value.hasContent, isTrue);
}); });
testWidgets('selection container registers itself if there is a selectable child', (WidgetTester tester) async { testWidgetsWithLeakTracking('selection container registers itself if there is a selectable child', (WidgetTester tester) async {
final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestSelectionRegistrar registrar = TestSelectionRegistrar();
final TestContainerDelegate delegate = TestContainerDelegate(); final TestContainerDelegate delegate = TestContainerDelegate();
addTearDown(delegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
SelectionContainer( SelectionContainer(
...@@ -181,9 +196,10 @@ void main() { ...@@ -181,9 +196,10 @@ void main() {
expect(registrar.selectables.length, 0); expect(registrar.selectables.length, 0);
}); });
testWidgets('selection container gets registrar from context if not provided', (WidgetTester tester) async { testWidgetsWithLeakTracking('selection container gets registrar from context if not provided', (WidgetTester tester) async {
final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestSelectionRegistrar registrar = TestSelectionRegistrar();
final TestContainerDelegate delegate = TestContainerDelegate(); final TestContainerDelegate delegate = TestContainerDelegate();
addTearDown(delegate.dispose);
await pumpContainer( await pumpContainer(
tester, tester,
......
...@@ -6,11 +6,12 @@ import 'package:flutter/material.dart'; ...@@ -6,11 +6,12 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('can cease to be semantics boundary after markNeedsSemanticsUpdate() has already been called once', (WidgetTester tester) async { testWidgetsWithLeakTracking('can cease to be semantics boundary after markNeedsSemanticsUpdate() has already been called once', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -6,11 +6,12 @@ import 'package:flutter/material.dart'; ...@@ -6,11 +6,12 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('markNeedsSemanticsUpdate() called on non-boundary with non-boundary parent', (WidgetTester tester) async { testWidgetsWithLeakTracking('markNeedsSemanticsUpdate() called on non-boundary with non-boundary parent', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 1', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 1', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// smoketest // smoketest
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 2', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 2', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// this test is the same as the test in Semantics 1, but // this test is the same as the test in Semantics 1, but
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 3', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 3', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// implicit annotators // implicit annotators
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 4', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 4', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// O // O
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 5', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 5', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('can change semantics in a branch blocked by BlockSemantics', (WidgetTester tester) async { testWidgetsWithLeakTracking('can change semantics in a branch blocked by BlockSemantics', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final TestSemantics expectedSemantics = TestSemantics.root( final TestSemantics expectedSemantics = TestSemantics.root(
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 7 - Merging', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 7 - Merging', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
String label; String label;
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics 8 - Merging with reset', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics 8 - Merging with reset', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -6,12 +6,13 @@ import 'package:flutter/material.dart'; ...@@ -6,12 +6,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
group('BlockSemantics', () { group('BlockSemantics', () {
testWidgets('hides semantic nodes of siblings', (WidgetTester tester) async { testWidgetsWithLeakTracking('hides semantic nodes of siblings', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(Stack( await tester.pumpWidget(Stack(
...@@ -49,7 +50,7 @@ void main() { ...@@ -49,7 +50,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('does not hides semantic nodes of siblings outside the current semantic boundary', (WidgetTester tester) async { testWidgetsWithLeakTracking('does not hides semantic nodes of siblings outside the current semantic boundary', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: Stack( await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: Stack(
...@@ -103,7 +104,7 @@ void main() { ...@@ -103,7 +104,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('node is semantic boundary and blocking previously painted nodes', (WidgetTester tester) async { testWidgetsWithLeakTracking('node is semantic boundary and blocking previously painted nodes', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final GlobalKey stackKey = GlobalKey(); final GlobalKey stackKey = GlobalKey();
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics can merge sibling group', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics can merge sibling group', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
const SemanticsTag first = SemanticsTag('1'); const SemanticsTag first = SemanticsTag('1');
const SemanticsTag second = SemanticsTag('2'); const SemanticsTag second = SemanticsTag('2');
...@@ -74,7 +75,7 @@ void main() { ...@@ -74,7 +75,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics can drop semantics config', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics can drop semantics config', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
const SemanticsTag first = SemanticsTag('1'); const SemanticsTag first = SemanticsTag('1');
const SemanticsTag second = SemanticsTag('2'); const SemanticsTag second = SemanticsTag('2');
...@@ -132,7 +133,7 @@ void main() { ...@@ -132,7 +133,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics throws when mark the same config twice case 1', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics throws when mark the same config twice case 1', (WidgetTester tester) async {
const SemanticsTag first = SemanticsTag('1'); const SemanticsTag first = SemanticsTag('1');
const SemanticsTag second = SemanticsTag('2'); const SemanticsTag second = SemanticsTag('2');
const SemanticsTag third = SemanticsTag('3'); const SemanticsTag third = SemanticsTag('3');
...@@ -178,7 +179,7 @@ void main() { ...@@ -178,7 +179,7 @@ void main() {
expect(tester.takeException(), isAssertionError); expect(tester.takeException(), isAssertionError);
}); });
testWidgets('Semantics throws when mark the same config twice case 2', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics throws when mark the same config twice case 2', (WidgetTester tester) async {
const SemanticsTag first = SemanticsTag('1'); const SemanticsTag first = SemanticsTag('1');
const SemanticsTag second = SemanticsTag('2'); const SemanticsTag second = SemanticsTag('2');
const SemanticsTag third = SemanticsTag('3'); const SemanticsTag third = SemanticsTag('3');
...@@ -224,7 +225,7 @@ void main() { ...@@ -224,7 +225,7 @@ void main() {
expect(tester.takeException(), isAssertionError); expect(tester.takeException(), isAssertionError);
}); });
testWidgets('RenderObject with semantics child delegate will mark correct boundary dirty', (WidgetTester tester) async { testWidgetsWithLeakTracking('RenderObject with semantics child delegate will mark correct boundary dirty', (WidgetTester tester) async {
final UniqueKey inner = UniqueKey(); final UniqueKey inner = UniqueKey();
final UniqueKey boundaryParent = UniqueKey(); final UniqueKey boundaryParent = UniqueKey();
final UniqueKey grandBoundaryParent = UniqueKey(); final UniqueKey grandBoundaryParent = UniqueKey();
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('SemanticNode.rect is clipped', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticNode.rect is clipped', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(const Directionality( await tester.pumpWidget(const Directionality(
...@@ -67,7 +68,7 @@ void main() { ...@@ -67,7 +68,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('SemanticsNode is not removed if out of bounds and merged into something within bounds', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsNode is not removed if out of bounds and merged into something within bounds', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(const Directionality( await tester.pumpWidget(const Directionality(
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('SemanticsDebugger will schedule a frame', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger will schedule a frame', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
SemanticsDebugger( SemanticsDebugger(
child: Container(), child: Container(),
...@@ -17,7 +18,7 @@ void main() { ...@@ -17,7 +18,7 @@ void main() {
expect(tester.binding.hasScheduledFrame, isTrue); expect(tester.binding.hasScheduledFrame, isTrue);
}); });
testWidgets('SemanticsDebugger smoke test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger smoke test', (WidgetTester tester) async {
// This is a smoketest to verify that adding a debugger doesn't crash. // This is a smoketest to verify that adding a debugger doesn't crash.
await tester.pumpWidget( await tester.pumpWidget(
...@@ -61,7 +62,7 @@ void main() { ...@@ -61,7 +62,7 @@ void main() {
expect(true, isTrue); // expect that we reach here without crashing expect(true, isTrue); // expect that we reach here without crashing
}); });
testWidgets('SemanticsDebugger reparents subtree', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger reparents subtree', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -147,7 +148,7 @@ void main() { ...@@ -147,7 +148,7 @@ void main() {
expect(tester.takeException(), isNull); expect(tester.takeException(), isNull);
}); });
testWidgets('SemanticsDebugger interaction test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger interaction test', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -185,7 +186,7 @@ void main() { ...@@ -185,7 +186,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('SemanticsDebugger interaction test - negative', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger interaction test - negative', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -225,7 +226,7 @@ void main() { ...@@ -225,7 +226,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('SemanticsDebugger scroll test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger scroll test', (WidgetTester tester) async {
final Key childKey = UniqueKey(); final Key childKey = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -268,7 +269,7 @@ void main() { ...@@ -268,7 +269,7 @@ void main() {
expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0)); expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0));
}); });
testWidgets('SemanticsDebugger long press', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger long press', (WidgetTester tester) async {
bool didLongPress = false; bool didLongPress = false;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -290,7 +291,7 @@ void main() { ...@@ -290,7 +291,7 @@ void main() {
expect(didLongPress, isTrue); expect(didLongPress, isTrue);
}); });
testWidgets('SemanticsDebugger slider', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger slider', (WidgetTester tester) async {
double value = 0.75; double value = 0.75;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -337,7 +338,7 @@ void main() { ...@@ -337,7 +338,7 @@ void main() {
} }
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
testWidgets('SemanticsDebugger checkbox', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger checkbox', (WidgetTester tester) async {
final Key keyTop = UniqueKey(); final Key keyTop = UniqueKey();
final Key keyBottom = UniqueKey(); final Key keyBottom = UniqueKey();
...@@ -378,7 +379,7 @@ void main() { ...@@ -378,7 +379,7 @@ void main() {
expect(valueTop, isFalse); expect(valueTop, isFalse);
}); });
testWidgets('SemanticsDebugger checkbox message', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger checkbox message', (WidgetTester tester) async {
final Key checkbox = UniqueKey(); final Key checkbox = UniqueKey();
final Key checkboxUnchecked = UniqueKey(); final Key checkboxUnchecked = UniqueKey();
final Key checkboxDisabled = UniqueKey(); final Key checkboxDisabled = UniqueKey();
...@@ -450,7 +451,7 @@ void main() { ...@@ -450,7 +451,7 @@ void main() {
); );
}); });
testWidgets('SemanticsDebugger ignores duplicated label and tooltip for Android', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger ignores duplicated label and tooltip for Android', (WidgetTester tester) async {
final Key child = UniqueKey(); final Key child = UniqueKey();
final Key debugger = UniqueKey(); final Key debugger = UniqueKey();
final bool isPlatformAndroid = defaultTargetPlatform == TargetPlatform.android; final bool isPlatformAndroid = defaultTargetPlatform == TargetPlatform.android;
...@@ -477,7 +478,7 @@ void main() { ...@@ -477,7 +478,7 @@ void main() {
); );
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
testWidgets('SemanticsDebugger textfield', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger textfield', (WidgetTester tester) async {
final UniqueKey textField = UniqueKey(); final UniqueKey textField = UniqueKey();
final UniqueKey debugger = UniqueKey(); final UniqueKey debugger = UniqueKey();
...@@ -504,7 +505,7 @@ void main() { ...@@ -504,7 +505,7 @@ void main() {
); );
}); });
testWidgets('SemanticsDebugger label style is used in the painter.', (WidgetTester tester) async { testWidgetsWithLeakTracking('SemanticsDebugger label style is used in the painter.', (WidgetTester tester) async {
final UniqueKey debugger = UniqueKey(); final UniqueKey debugger = UniqueKey();
const TextStyle labelStyle = TextStyle(color: Colors.amber); const TextStyle labelStyle = TextStyle(color: Colors.amber);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Un-layouted RenderObject in keep alive offstage area do not crash semantics compiler', (WidgetTester tester) async { testWidgetsWithLeakTracking('Un-layouted RenderObject in keep alive offstage area do not crash semantics compiler', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/20313. // Regression test for https://github.com/flutter/flutter/issues/20313.
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
...@@ -18,6 +19,7 @@ void main() { ...@@ -18,6 +19,7 @@ void main() {
const double bottomScrollOffset = 3000.0; const double bottomScrollOffset = 3000.0;
final ScrollController controller = ScrollController(initialScrollOffset: bottomScrollOffset); final ScrollController controller = ScrollController(initialScrollOffset: bottomScrollOffset);
addTearDown(controller.dispose);
await tester.pumpWidget(_buildTestWidget( await tester.pumpWidget(_buildTestWidget(
extraPadding: false, extraPadding: false,
......
...@@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; ...@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
...@@ -14,7 +15,7 @@ void main() { ...@@ -14,7 +15,7 @@ void main() {
debugResetSemanticsIdCounter(); debugResetSemanticsIdCounter();
}); });
testWidgets('MergeSemantics', (WidgetTester tester) async { testWidgetsWithLeakTracking('MergeSemantics', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// not merged // not merged
...@@ -120,7 +121,7 @@ void main() { ...@@ -120,7 +121,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('MergeSemantics works if other nodes are implicitly merged into its node', (WidgetTester tester) async { testWidgetsWithLeakTracking('MergeSemantics works if other nodes are implicitly merged into its node', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -7,6 +7,7 @@ import 'dart:math'; ...@@ -7,6 +7,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
...@@ -15,7 +16,7 @@ void main() { ...@@ -15,7 +16,7 @@ void main() {
debugResetSemanticsIdCounter(); debugResetSemanticsIdCounter();
}); });
testWidgets('Semantics shutdown and restart', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics shutdown and restart', (WidgetTester tester) async {
SemanticsTester? semantics = SemanticsTester(tester); SemanticsTester? semantics = SemanticsTester(tester);
final TestSemantics expectedSemantics = TestSemantics.root( final TestSemantics expectedSemantics = TestSemantics.root(
...@@ -59,7 +60,7 @@ void main() { ...@@ -59,7 +60,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}, semanticsEnabled: false); }, semanticsEnabled: false);
testWidgets('Semantics tag only applies to immediate child', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics tag only applies to immediate child', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -95,7 +96,7 @@ void main() { ...@@ -95,7 +96,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}, semanticsEnabled: false); }, semanticsEnabled: false);
testWidgets('Semantics tooltip', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics tooltip', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final TestSemantics expectedSemantics = TestSemantics.root( final TestSemantics expectedSemantics = TestSemantics.root(
...@@ -123,7 +124,7 @@ void main() { ...@@ -123,7 +124,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Detach and reattach assert', (WidgetTester tester) async { testWidgetsWithLeakTracking('Detach and reattach assert', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
...@@ -201,7 +202,7 @@ void main() { ...@@ -201,7 +202,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics and Directionality - RTL', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics and Directionality - RTL', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -218,7 +219,7 @@ void main() { ...@@ -218,7 +219,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics and Directionality - LTR', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics and Directionality - LTR', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -235,7 +236,7 @@ void main() { ...@@ -235,7 +236,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics and Directionality - cannot override RTL with LTR', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics and Directionality - cannot override RTL with LTR', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final TestSemantics expectedSemantics = TestSemantics.root( final TestSemantics expectedSemantics = TestSemantics.root(
...@@ -262,7 +263,7 @@ void main() { ...@@ -262,7 +263,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics and Directionality - cannot override LTR with RTL', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics and Directionality - cannot override LTR with RTL', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final TestSemantics expectedSemantics = TestSemantics.root( final TestSemantics expectedSemantics = TestSemantics.root(
...@@ -289,7 +290,7 @@ void main() { ...@@ -289,7 +290,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics label and hint', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics label and hint', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -319,7 +320,7 @@ void main() { ...@@ -319,7 +320,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics hints can merge', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics hints can merge', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -355,7 +356,7 @@ void main() { ...@@ -355,7 +356,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics values do not merge', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics values do not merge', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -406,7 +407,7 @@ void main() { ...@@ -406,7 +407,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics value and hint can merge', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics value and hint can merge', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -442,7 +443,7 @@ void main() { ...@@ -442,7 +443,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics tagForChildren works', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics tagForChildren works', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -490,7 +491,7 @@ void main() { ...@@ -490,7 +491,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widget supports all actions', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widget supports all actions', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final List<SemanticsAction> performedActions = <SemanticsAction>[]; final List<SemanticsAction> performedActions = <SemanticsAction>[];
...@@ -580,7 +581,7 @@ void main() { ...@@ -580,7 +581,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widget supports all flags', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widget supports all flags', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// Checked state and toggled state are mutually exclusive. // Checked state and toggled state are mutually exclusive.
await tester.pumpWidget( await tester.pumpWidget(
...@@ -710,7 +711,7 @@ void main() { ...@@ -710,7 +711,7 @@ void main() {
expect(semantics, hasSemantics(expectedSemantics, ignoreId: true)); expect(semantics, hasSemantics(expectedSemantics, ignoreId: true));
}); });
testWidgets('Actions can be replaced without triggering semantics update', (WidgetTester tester) async { testWidgetsWithLeakTracking('Actions can be replaced without triggering semantics update', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
int semanticsUpdateCount = 0; int semanticsUpdateCount = 0;
final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(
...@@ -807,7 +808,7 @@ void main() { ...@@ -807,7 +808,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('onTapHint and onLongPressHint create custom actions', (WidgetTester tester) async { testWidgetsWithLeakTracking('onTapHint and onLongPressHint create custom actions', (WidgetTester tester) async {
final SemanticsHandle semantics = tester.ensureSemantics(); final SemanticsHandle semantics = tester.ensureSemantics();
await tester.pumpWidget(Semantics( await tester.pumpWidget(Semantics(
container: true, container: true,
...@@ -833,7 +834,7 @@ void main() { ...@@ -833,7 +834,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('CustomSemanticsActions can be added to a Semantics widget', (WidgetTester tester) async { testWidgetsWithLeakTracking('CustomSemanticsActions can be added to a Semantics widget', (WidgetTester tester) async {
final SemanticsHandle semantics = tester.ensureSemantics(); final SemanticsHandle semantics = tester.ensureSemantics();
await tester.pumpWidget(Semantics( await tester.pumpWidget(Semantics(
container: true, container: true,
...@@ -852,7 +853,7 @@ void main() { ...@@ -852,7 +853,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Increased/decreased values are annotated', (WidgetTester tester) async { testWidgetsWithLeakTracking('Increased/decreased values are annotated', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -884,7 +885,7 @@ void main() { ...@@ -884,7 +885,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widgets built in a widget tree are sorted properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widgets built in a widget tree are sorted properly', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
int semanticsUpdateCount = 0; int semanticsUpdateCount = 0;
final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(
...@@ -967,7 +968,7 @@ void main() { ...@@ -967,7 +968,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widgets built with explicit sort orders are sorted properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widgets built with explicit sort orders are sorted properly', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
int semanticsUpdateCount = 0; int semanticsUpdateCount = 0;
final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(
...@@ -1025,7 +1026,7 @@ void main() { ...@@ -1025,7 +1026,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widgets without sort orders are sorted properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widgets without sort orders are sorted properly', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
int semanticsUpdateCount = 0; int semanticsUpdateCount = 0;
final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(
...@@ -1086,7 +1087,7 @@ void main() { ...@@ -1086,7 +1087,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widgets that are transformed are sorted properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widgets that are transformed are sorted properly', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
int semanticsUpdateCount = 0; int semanticsUpdateCount = 0;
final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(
...@@ -1150,7 +1151,7 @@ void main() { ...@@ -1150,7 +1151,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics widgets without sort orders are sorted properly when no Directionality is present', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics widgets without sort orders are sorted properly when no Directionality is present', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
int semanticsUpdateCount = 0; int semanticsUpdateCount = 0;
final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(listener: () { final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(listener: () {
...@@ -1251,7 +1252,7 @@ void main() { ...@@ -1251,7 +1252,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Semantics excludeSemantics ignores children', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics excludeSemantics ignores children', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(Semantics( await tester.pumpWidget(Semantics(
label: 'label', label: 'label',
...@@ -1279,7 +1280,7 @@ void main() { ...@@ -1279,7 +1280,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Can change handlers', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can change handlers', (WidgetTester tester) async {
await tester.pumpWidget(Semantics( await tester.pumpWidget(Semantics(
container: true, container: true,
label: 'foo', label: 'foo',
...@@ -1666,7 +1667,7 @@ void main() { ...@@ -1666,7 +1667,7 @@ void main() {
)); ));
}); });
testWidgets('Semantics with zero transform gets dropped', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics with zero transform gets dropped', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/110671. // Regression test for https://github.com/flutter/flutter/issues/110671.
// Construct a widget tree that will end up with a fitted box that applies // Construct a widget tree that will end up with a fitted box that applies
// a zero transform because it does not actually draw its children. // a zero transform because it does not actually draw its children.
...@@ -1693,7 +1694,7 @@ void main() { ...@@ -1693,7 +1694,7 @@ void main() {
expect(node.childrenCount, 0); expect(node.childrenCount, 0);
}); });
testWidgets('blocking user interaction works on explicit child node.', (WidgetTester tester) async { testWidgetsWithLeakTracking('blocking user interaction works on explicit child node.', (WidgetTester tester) async {
final UniqueKey key1 = UniqueKey(); final UniqueKey key1 = UniqueKey();
final UniqueKey key2 = UniqueKey(); final UniqueKey key2 = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1736,7 +1737,7 @@ void main() { ...@@ -1736,7 +1737,7 @@ void main() {
); );
}); });
testWidgets('blocking user interaction on a merged child', (WidgetTester tester) async { testWidgetsWithLeakTracking('blocking user interaction on a merged child', (WidgetTester tester) async {
final UniqueKey key = UniqueKey(); final UniqueKey key = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1771,7 +1772,7 @@ void main() { ...@@ -1771,7 +1772,7 @@ void main() {
); );
}); });
testWidgets('does not merge conflicting actions even if one of them is blocked', (WidgetTester tester) async { testWidgetsWithLeakTracking('does not merge conflicting actions even if one of them is blocked', (WidgetTester tester) async {
final UniqueKey key = UniqueKey(); final UniqueKey key = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
......
...@@ -10,6 +10,7 @@ import 'dart:io'; ...@@ -10,6 +10,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart'; import 'package:flutter/semantics.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
...@@ -52,7 +53,7 @@ void _tests() { ...@@ -52,7 +53,7 @@ void _tests() {
// also update this code to reflect the new output. // also update this code to reflect the new output.
// //
// This test is flexible w.r.t. leading and trailing whitespace. // This test is flexible w.r.t. leading and trailing whitespace.
testWidgets('generates code', (WidgetTester tester) async { testWidgetsWithLeakTracking('generates code', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await pumpTestWidget(tester); await pumpTestWidget(tester);
final String code = semantics final String code = semantics
...@@ -91,7 +92,7 @@ void _tests() { ...@@ -91,7 +92,7 @@ void _tests() {
expect('$code,', expectedCode); expect('$code,', expectedCode);
}); });
testWidgets('generated code is correct', (WidgetTester tester) async { testWidgetsWithLeakTracking('generated code is correct', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await pumpTestWidget(tester); await pumpTestWidget(tester);
expect( expect(
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Semantics tester visits last child', (WidgetTester tester) async { testWidgetsWithLeakTracking('Semantics tester visits last child', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
const TextStyle textStyle = TextStyle(); const TextStyle textStyle = TextStyle();
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
...@@ -21,7 +22,7 @@ void main() { ...@@ -21,7 +22,7 @@ void main() {
}); });
void testTraversal(String description, TraversalTestFunction testFunction) { void testTraversal(String description, TraversalTestFunction testFunction) {
testWidgets(description, (WidgetTester tester) async { testWidgetsWithLeakTracking(description, (WidgetTester tester) async {
final TraversalTester traversalTester = TraversalTester(tester); final TraversalTester traversalTester = TraversalTester(tester);
await testFunction(traversalTester); await testFunction(traversalTester);
traversalTester.dispose(); traversalTester.dispose();
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('has only root node if surface size is 0x0', (WidgetTester tester) async { testWidgetsWithLeakTracking('has only root node if surface size is 0x0', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(Semantics( await tester.pumpWidget(Semantics(
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class Inside extends StatefulWidget { class Inside extends StatefulWidget {
const Inside({ super.key }); const Inside({ super.key });
...@@ -65,7 +66,7 @@ class OutsideState extends State<Outside> { ...@@ -65,7 +66,7 @@ class OutsideState extends State<Outside> {
} }
void main() { void main() {
testWidgets('setState() smoke test', (WidgetTester tester) async { testWidgetsWithLeakTracking('setState() smoke test', (WidgetTester tester) async {
await tester.pumpWidget(const Outside()); await tester.pumpWidget(const Outside());
final Offset location = tester.getCenter(find.text('INSIDE')); final Offset location = tester.getCenter(find.text('INSIDE'));
final TestGesture gesture = await tester.startGesture(location); final TestGesture gesture = await tester.startGesture(location);
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('setState() overbuild test', (WidgetTester tester) async { testWidgetsWithLeakTracking('setState() overbuild test', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
final Builder inner = Builder( final Builder inner = Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
late ChangerState changer; late ChangerState changer;
...@@ -52,7 +53,7 @@ class LeafState extends State<Leaf> { ...@@ -52,7 +53,7 @@ class LeafState extends State<Leaf> {
} }
void main() { void main() {
testWidgets('three-way setState() smoke test', (WidgetTester tester) async { testWidgetsWithLeakTracking('three-way setState() smoke test', (WidgetTester tester) async {
await tester.pumpWidget(const Changer(Wrapper(Leaf()))); await tester.pumpWidget(const Changer(Wrapper(Leaf())));
await tester.pumpWidget(const Changer(Wrapper(Leaf()))); await tester.pumpWidget(const Changer(Wrapper(Leaf())));
changer.test(); changer.test();
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class Changer extends StatefulWidget { class Changer extends StatefulWidget {
const Changer({ super.key }); const Changer({ super.key });
...@@ -21,7 +22,7 @@ class ChangerState extends State<Changer> { ...@@ -21,7 +22,7 @@ class ChangerState extends State<Changer> {
} }
void main() { void main() {
testWidgets('setState() catches being used with an async callback', (WidgetTester tester) async { testWidgetsWithLeakTracking('setState() catches being used with an async callback', (WidgetTester tester) async {
await tester.pumpWidget(const Changer()); await tester.pumpWidget(const Changer());
final ChangerState s = tester.state(find.byType(Changer)); final ChangerState s = tester.state(find.byType(Changer));
expect(s.test0, isNot(throwsFlutterError)); expect(s.test0, isNot(throwsFlutterError));
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class BadWidget extends StatefulWidget { class BadWidget extends StatefulWidget {
const BadWidget({ super.key }); const BadWidget({ super.key });
...@@ -27,7 +28,7 @@ class BadWidgetState extends State<BadWidget> { ...@@ -27,7 +28,7 @@ class BadWidgetState extends State<BadWidget> {
} }
void main() { void main() {
testWidgets('setState() catches being used inside a constructor', (WidgetTester tester) async { testWidgetsWithLeakTracking('setState() catches being used inside a constructor', (WidgetTester tester) async {
await tester.pumpWidget(const BadWidget()); await tester.pumpWidget(const BadWidget());
expect(tester.takeException(), isFlutterError); expect(tester.takeException(), isFlutterError);
}); });
......
...@@ -9,6 +9,7 @@ library; ...@@ -9,6 +9,7 @@ library;
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
Shader createShader(Rect bounds) { Shader createShader(Rect bounds) {
return const LinearGradient( return const LinearGradient(
...@@ -21,12 +22,12 @@ Shader createShader(Rect bounds) { ...@@ -21,12 +22,12 @@ Shader createShader(Rect bounds) {
void main() { void main() {
testWidgets('Can be constructed', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can be constructed', (WidgetTester tester) async {
const Widget child = SizedBox(width: 100.0, height: 100.0); const Widget child = SizedBox(width: 100.0, height: 100.0);
await tester.pumpWidget(const ShaderMask(shaderCallback: createShader, child: child)); await tester.pumpWidget(const ShaderMask(shaderCallback: createShader, child: child));
}); });
testWidgets('Bounds rect includes offset', (WidgetTester tester) async { testWidgetsWithLeakTracking('Bounds rect includes offset', (WidgetTester tester) async {
late Rect shaderBounds; late Rect shaderBounds;
Shader recordShaderBounds(Rect bounds) { Shader recordShaderBounds(Rect bounds) {
shaderBounds = bounds; shaderBounds = bounds;
...@@ -50,7 +51,7 @@ void main() { ...@@ -50,7 +51,7 @@ void main() {
}); });
testWidgets('Bounds rect includes offset visual inspection', (WidgetTester tester) async { testWidgetsWithLeakTracking('Bounds rect includes offset visual inspection', (WidgetTester tester) async {
final Widget widgetBottomRight = Container( final Widget widgetBottomRight = Container(
width: 400, width: 400,
height: 400, height: 400,
......
...@@ -9,13 +9,14 @@ library; ...@@ -9,13 +9,14 @@ library;
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
tearDown(() { tearDown(() {
debugDisableShadows = true; debugDisableShadows = true;
}); });
testWidgets('Shadows on BoxDecoration', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shadows on BoxDecoration', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Center( Center(
child: RepaintBoundary( child: RepaintBoundary(
...@@ -61,7 +62,7 @@ void main() { ...@@ -61,7 +62,7 @@ void main() {
); );
} }
for (final int elevation in kElevationToShadow.keys) { for (final int elevation in kElevationToShadow.keys) {
testWidgets('elevation $elevation', (WidgetTester tester) async { testWidgetsWithLeakTracking('elevation $elevation', (WidgetTester tester) async {
debugDisableShadows = false; debugDisableShadows = false;
await tester.pumpWidget(build(elevation)); await tester.pumpWidget(build(elevation));
await expectLater( await expectLater(
...@@ -73,7 +74,7 @@ void main() { ...@@ -73,7 +74,7 @@ void main() {
} }
}); });
testWidgets('Shadows with PhysicalLayer', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shadows with PhysicalLayer', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Center( Center(
child: RepaintBoundary( child: RepaintBoundary(
...@@ -132,7 +133,7 @@ void main() { ...@@ -132,7 +133,7 @@ void main() {
} }
for (final int elevation in kElevationToShadow.keys) { for (final int elevation in kElevationToShadow.keys) {
testWidgets('elevation $elevation', (WidgetTester tester) async { testWidgetsWithLeakTracking('elevation $elevation', (WidgetTester tester) async {
debugDisableShadows = false; debugDisableShadows = false;
await tester.pumpWidget(build(elevation.toDouble())); await tester.pumpWidget(build(elevation.toDouble()));
await expectLater( await expectLater(
......
...@@ -7,6 +7,7 @@ import 'dart:ui' as ui show Image; ...@@ -7,6 +7,7 @@ import 'dart:ui' as ui show Image;
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../image_data.dart'; import '../image_data.dart';
import '../painting/mocks_for_image_cache.dart'; import '../painting/mocks_for_image_cache.dart';
...@@ -16,7 +17,7 @@ Future<void> main() async { ...@@ -16,7 +17,7 @@ Future<void> main() async {
AutomatedTestWidgetsFlutterBinding(); AutomatedTestWidgetsFlutterBinding();
final ui.Image rawImage = await decodeImageFromList(Uint8List.fromList(kTransparentImage)); final ui.Image rawImage = await decodeImageFromList(Uint8List.fromList(kTransparentImage));
final ImageProvider image = TestImageProvider(0, 0, image: rawImage); final ImageProvider image = TestImageProvider(0, 0, image: rawImage);
testWidgets('ShapeDecoration.image', (WidgetTester tester) async { testWidgetsWithLeakTracking('ShapeDecoration.image', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: DecoratedBox( home: DecoratedBox(
...@@ -39,7 +40,7 @@ Future<void> main() async { ...@@ -39,7 +40,7 @@ Future<void> main() async {
); );
}); });
testWidgets('ShapeDecoration.color', (WidgetTester tester) async { testWidgetsWithLeakTracking('ShapeDecoration.color', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: DecoratedBox( home: DecoratedBox(
...@@ -68,7 +69,7 @@ Future<void> main() async { ...@@ -68,7 +69,7 @@ Future<void> main() async {
expect(decoration.padding, isA<EdgeInsetsDirectional>()); expect(decoration.padding, isA<EdgeInsetsDirectional>());
}); });
testWidgets('TestBorder and Directionality - 1', (WidgetTester tester) async { testWidgetsWithLeakTracking('TestBorder and Directionality - 1', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -89,7 +90,7 @@ Future<void> main() async { ...@@ -89,7 +90,7 @@ Future<void> main() async {
); );
}); });
testWidgets('TestBorder and Directionality - 2', (WidgetTester tester) async { testWidgetsWithLeakTracking('TestBorder and Directionality - 2', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -113,7 +114,7 @@ Future<void> main() async { ...@@ -113,7 +114,7 @@ Future<void> main() async {
); );
}); });
testWidgets('Does not crash with directional gradient', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does not crash with directional gradient', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/76967. // Regression test for https://github.com/flutter/flutter/issues/76967.
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('SharedAppData basics', (WidgetTester tester) async { testWidgetsWithLeakTracking('SharedAppData basics', (WidgetTester tester) async {
int columnBuildCount = 0; int columnBuildCount = 0;
int child1BuildCount = 0; int child1BuildCount = 0;
int child2BuildCount = 0; int child2BuildCount = 0;
...@@ -116,7 +117,7 @@ void main() { ...@@ -116,7 +117,7 @@ void main() {
expect(find.text('null').evaluate().length, 2); expect(find.text('null').evaluate().length, 2);
}); });
testWidgets('WidgetsApp SharedAppData ', (WidgetTester tester) async { testWidgetsWithLeakTracking('WidgetsApp SharedAppData ', (WidgetTester tester) async {
int parentBuildCount = 0; int parentBuildCount = 0;
int childBuildCount = 0; int childBuildCount = 0;
...@@ -154,7 +155,7 @@ void main() { ...@@ -154,7 +155,7 @@ void main() {
expect(find.text('child'), findsOneWidget); expect(find.text('child'), findsOneWidget);
}); });
testWidgets('WidgetsApp SharedAppData Shadowing', (WidgetTester tester) async { testWidgetsWithLeakTracking('WidgetsApp SharedAppData Shadowing', (WidgetTester tester) async {
int innerTapCount = 0; int innerTapCount = 0;
int outerTapCount = 0; int outerTapCount = 0;
......
...@@ -112,7 +112,7 @@ void main() { ...@@ -112,7 +112,7 @@ void main() {
); );
}); });
testWidgets('handles two keys', (WidgetTester tester) async { testWidgetsWithLeakTracking('handles two keys', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
LogicalKeySet( LogicalKeySet(
...@@ -211,7 +211,7 @@ void main() { ...@@ -211,7 +211,7 @@ void main() {
); );
}); });
testWidgets('isActivatedBy works as expected', (WidgetTester tester) async { testWidgetsWithLeakTracking('isActivatedBy works as expected', (WidgetTester tester) async {
// Collect some key events to use for testing. // Collect some key events to use for testing.
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -253,7 +253,7 @@ void main() { ...@@ -253,7 +253,7 @@ void main() {
}); });
group(SingleActivator, () { group(SingleActivator, () {
testWidgets('handles Ctrl-C', (WidgetTester tester) async { testWidgetsWithLeakTracking('handles Ctrl-C', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const SingleActivator( const SingleActivator(
...@@ -352,7 +352,7 @@ void main() { ...@@ -352,7 +352,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('handles repeated events', (WidgetTester tester) async { testWidgetsWithLeakTracking('handles repeated events', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const SingleActivator( const SingleActivator(
...@@ -378,7 +378,7 @@ void main() { ...@@ -378,7 +378,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('rejects repeated events if requested', (WidgetTester tester) async { testWidgetsWithLeakTracking('rejects repeated events if requested', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const SingleActivator( const SingleActivator(
...@@ -405,7 +405,7 @@ void main() { ...@@ -405,7 +405,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('handles Shift-Ctrl-C', (WidgetTester tester) async { testWidgetsWithLeakTracking('handles Shift-Ctrl-C', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const SingleActivator( const SingleActivator(
...@@ -455,7 +455,7 @@ void main() { ...@@ -455,7 +455,7 @@ void main() {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
}); });
testWidgets('isActivatedBy works as expected', (WidgetTester tester) async { testWidgetsWithLeakTracking('isActivatedBy works as expected', (WidgetTester tester) async {
// Collect some key events to use for testing. // Collect some key events to use for testing.
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -534,15 +534,16 @@ void main() { ...@@ -534,15 +534,16 @@ void main() {
}); });
group(Shortcuts, () { group(Shortcuts, () {
testWidgets('Default constructed Shortcuts has empty shortcuts', (WidgetTester tester) async { testWidgetsWithLeakTracking('Default constructed Shortcuts has empty shortcuts', (WidgetTester tester) async {
const Shortcuts shortcuts = Shortcuts(shortcuts: <LogicalKeySet, Intent>{}, child: SizedBox()); const Shortcuts shortcuts = Shortcuts(shortcuts: <LogicalKeySet, Intent>{}, child: SizedBox());
await tester.pumpWidget(shortcuts); await tester.pumpWidget(shortcuts);
expect(shortcuts.shortcuts, isNotNull); expect(shortcuts.shortcuts, isNotNull);
expect(shortcuts.shortcuts, isEmpty); expect(shortcuts.shortcuts, isEmpty);
}); });
testWidgets('Default constructed Shortcuts.manager has empty shortcuts', (WidgetTester tester) async { testWidgetsWithLeakTracking('Default constructed Shortcuts.manager has empty shortcuts', (WidgetTester tester) async {
final ShortcutManager manager = ShortcutManager(); final ShortcutManager manager = ShortcutManager();
addTearDown(manager.dispose);
expect(manager.shortcuts, isNotNull); expect(manager.shortcuts, isNotNull);
expect(manager.shortcuts, isEmpty); expect(manager.shortcuts, isEmpty);
final Shortcuts shortcuts = Shortcuts.manager(manager: manager, child: const SizedBox()); final Shortcuts shortcuts = Shortcuts.manager(manager: manager, child: const SizedBox());
...@@ -551,11 +552,12 @@ void main() { ...@@ -551,11 +552,12 @@ void main() {
expect(shortcuts.shortcuts, isEmpty); expect(shortcuts.shortcuts, isEmpty);
}); });
testWidgets('Shortcuts.manager passes on shortcuts', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts.manager passes on shortcuts', (WidgetTester tester) async {
final Map<LogicalKeySet, Intent> testShortcuts = <LogicalKeySet, Intent>{ final Map<LogicalKeySet, Intent> testShortcuts = <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
}; };
final ShortcutManager manager = ShortcutManager(shortcuts: testShortcuts); final ShortcutManager manager = ShortcutManager(shortcuts: testShortcuts);
addTearDown(manager.dispose);
expect(manager.shortcuts, isNotNull); expect(manager.shortcuts, isNotNull);
expect(manager.shortcuts, equals(testShortcuts)); expect(manager.shortcuts, equals(testShortcuts));
final Shortcuts shortcuts = Shortcuts.manager(manager: manager, child: const SizedBox()); final Shortcuts shortcuts = Shortcuts.manager(manager: manager, child: const SizedBox());
...@@ -564,7 +566,7 @@ void main() { ...@@ -564,7 +566,7 @@ void main() {
expect(shortcuts.shortcuts, equals(testShortcuts)); expect(shortcuts.shortcuts, equals(testShortcuts));
}); });
testWidgets('ShortcutManager handles shortcuts', (WidgetTester tester) async { testWidgetsWithLeakTracking('ShortcutManager handles shortcuts', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -573,6 +575,7 @@ void main() { ...@@ -573,6 +575,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
Actions( Actions(
...@@ -599,7 +602,7 @@ void main() { ...@@ -599,7 +602,7 @@ void main() {
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
}); });
testWidgets('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -608,6 +611,7 @@ void main() { ...@@ -608,6 +611,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
Actions( Actions(
...@@ -634,7 +638,7 @@ void main() { ...@@ -634,7 +638,7 @@ void main() {
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
}); });
testWidgets('ShortcutManager ignores key presses with no primary focus', (WidgetTester tester) async { testWidgetsWithLeakTracking('ShortcutManager ignores key presses with no primary focus', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -643,6 +647,7 @@ void main() { ...@@ -643,6 +647,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
Actions( Actions(
...@@ -671,7 +676,7 @@ void main() { ...@@ -671,7 +676,7 @@ void main() {
expect(()=> ShortcutManager().dispose(), dispatchesMemoryEvents(ShortcutManager)); expect(()=> ShortcutManager().dispose(), dispatchesMemoryEvents(ShortcutManager));
}); });
testWidgets("Shortcuts passes to the next Shortcuts widget if it doesn't map the key", (WidgetTester tester) async { testWidgetsWithLeakTracking("Shortcuts passes to the next Shortcuts widget if it doesn't map the key", (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -680,6 +685,7 @@ void main() { ...@@ -680,6 +685,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
Shortcuts.manager( Shortcuts.manager(
...@@ -711,7 +717,7 @@ void main() { ...@@ -711,7 +717,7 @@ void main() {
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
}); });
testWidgets('Shortcuts can disable a shortcut with Intent.doNothing', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts can disable a shortcut with Intent.doNothing', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -720,6 +726,7 @@ void main() { ...@@ -720,6 +726,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -753,7 +760,7 @@ void main() { ...@@ -753,7 +760,7 @@ void main() {
expect(pressedKeys, isEmpty); expect(pressedKeys, isEmpty);
}); });
testWidgets("Shortcuts that aren't bound to an action don't absorb keys meant for text fields", (WidgetTester tester) async { testWidgetsWithLeakTracking("Shortcuts that aren't bound to an action don't absorb keys meant for text fields", (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -762,6 +769,7 @@ void main() { ...@@ -762,6 +769,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
...@@ -778,7 +786,7 @@ void main() { ...@@ -778,7 +786,7 @@ void main() {
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.keyA])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.keyA]));
}); });
testWidgets('Shortcuts that are bound to an action do override text fields', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts that are bound to an action do override text fields', (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -787,6 +795,7 @@ void main() { ...@@ -787,6 +795,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -815,7 +824,7 @@ void main() { ...@@ -815,7 +824,7 @@ void main() {
expect(invoked, isTrue); expect(invoked, isTrue);
}); });
testWidgets('Shortcuts can override intents that apply to text fields', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts can override intents that apply to text fields', (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -824,6 +833,7 @@ void main() { ...@@ -824,6 +833,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -856,7 +866,7 @@ void main() { ...@@ -856,7 +866,7 @@ void main() {
expect(invoked, isFalse); expect(invoked, isFalse);
}); });
testWidgets('Shortcuts can override intents that apply to text fields with DoNothingAndStopPropagationIntent', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts can override intents that apply to text fields with DoNothingAndStopPropagationIntent', (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
final TestShortcutManager testManager = TestShortcutManager( final TestShortcutManager testManager = TestShortcutManager(
...@@ -865,6 +875,7 @@ void main() { ...@@ -865,6 +875,7 @@ void main() {
LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(),
}, },
); );
addTearDown(testManager.dispose);
bool invoked = false; bool invoked = false;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -982,6 +993,7 @@ void main() { ...@@ -982,6 +993,7 @@ void main() {
): const ActivateIntent(), ): const ActivateIntent(),
}, },
); );
addTearDown(testManager.dispose);
Shortcuts.manager( Shortcuts.manager(
manager: testManager, manager: testManager,
...@@ -997,7 +1009,7 @@ void main() { ...@@ -997,7 +1009,7 @@ void main() {
expect(description[1], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}')); expect(description[1], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}'));
}); });
testWidgets('Shortcuts support multiple intents', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts support multiple intents', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true; bool? value = true;
Widget buildApp() { Widget buildApp() {
...@@ -1078,7 +1090,7 @@ void main() { ...@@ -1078,7 +1090,7 @@ void main() {
expect(controller.position.pixels, 0.0); expect(controller.position.pixels, 0.0);
}); });
testWidgets('Shortcuts support activators that returns null in triggers', (WidgetTester tester) async { testWidgetsWithLeakTracking('Shortcuts support activators that returns null in triggers', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const DumbLogicalActivator(LogicalKeyboardKey.keyC), const DumbLogicalActivator(LogicalKeyboardKey.keyC),
...@@ -1120,7 +1132,7 @@ void main() { ...@@ -1120,7 +1132,7 @@ void main() {
}); });
group('CharacterActivator', () { group('CharacterActivator', () {
testWidgets('is triggered on events with correct character', (WidgetTester tester) async { testWidgetsWithLeakTracking('is triggered on events with correct character', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const CharacterActivator('?'), const CharacterActivator('?'),
...@@ -1138,7 +1150,7 @@ void main() { ...@@ -1138,7 +1150,7 @@ void main() {
invoked = 0; invoked = 0;
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('handles repeated events', (WidgetTester tester) async { testWidgetsWithLeakTracking('handles repeated events', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const CharacterActivator('?'), const CharacterActivator('?'),
...@@ -1158,7 +1170,7 @@ void main() { ...@@ -1158,7 +1170,7 @@ void main() {
invoked = 0; invoked = 0;
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('rejects repeated events if requested', (WidgetTester tester) async { testWidgetsWithLeakTracking('rejects repeated events if requested', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const CharacterActivator('?', includeRepeats: false), const CharacterActivator('?', includeRepeats: false),
...@@ -1178,7 +1190,7 @@ void main() { ...@@ -1178,7 +1190,7 @@ void main() {
invoked = 0; invoked = 0;
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('handles Alt, Ctrl and Meta', (WidgetTester tester) async { testWidgetsWithLeakTracking('handles Alt, Ctrl and Meta', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
const CharacterActivator('?', alt: true, meta: true, control: true), const CharacterActivator('?', alt: true, meta: true, control: true),
...@@ -1224,7 +1236,7 @@ void main() { ...@@ -1224,7 +1236,7 @@ void main() {
invoked = 0; invoked = 0;
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
testWidgets('isActivatedBy works as expected', (WidgetTester tester) async { testWidgetsWithLeakTracking('isActivatedBy works as expected', (WidgetTester tester) async {
// Collect some key events to use for testing. // Collect some key events to use for testing.
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1293,7 +1305,7 @@ void main() { ...@@ -1293,7 +1305,7 @@ void main() {
}); });
group('CallbackShortcuts', () { group('CallbackShortcuts', () {
testWidgets('trigger on key events', (WidgetTester tester) async { testWidgetsWithLeakTracking('trigger on key events', (WidgetTester tester) async {
int invokedA = 0; int invokedA = 0;
int invokedB = 0; int invokedB = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1331,7 +1343,7 @@ void main() { ...@@ -1331,7 +1343,7 @@ void main() {
expect(invokedB, equals(1)); expect(invokedB, equals(1));
}); });
testWidgets('nested CallbackShortcuts stop propagation', (WidgetTester tester) async { testWidgetsWithLeakTracking('nested CallbackShortcuts stop propagation', (WidgetTester tester) async {
int invokedOuter = 0; int invokedOuter = 0;
int invokedInner = 0; int invokedInner = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1364,7 +1376,7 @@ void main() { ...@@ -1364,7 +1376,7 @@ void main() {
expect(invokedInner, equals(1)); expect(invokedInner, equals(1));
}); });
testWidgets('non-overlapping nested CallbackShortcuts fire appropriately', (WidgetTester tester) async { testWidgetsWithLeakTracking('non-overlapping nested CallbackShortcuts fire appropriately', (WidgetTester tester) async {
int invokedOuter = 0; int invokedOuter = 0;
int invokedInner = 0; int invokedInner = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1401,7 +1413,7 @@ void main() { ...@@ -1401,7 +1413,7 @@ void main() {
expect(invokedInner, equals(1)); expect(invokedInner, equals(1));
}); });
testWidgets('Works correctly with Shortcuts too', (WidgetTester tester) async { testWidgetsWithLeakTracking('Works correctly with Shortcuts too', (WidgetTester tester) async {
int invokedCallbackA = 0; int invokedCallbackA = 0;
int invokedCallbackB = 0; int invokedCallbackB = 0;
int invokedActionA = 0; int invokedActionA = 0;
...@@ -1475,7 +1487,7 @@ void main() { ...@@ -1475,7 +1487,7 @@ void main() {
}); });
group('ShortcutRegistrar', () { group('ShortcutRegistrar', () {
testWidgets('trigger ShortcutRegistrar on key events', (WidgetTester tester) async { testWidgetsWithLeakTracking('trigger ShortcutRegistrar on key events', (WidgetTester tester) async {
int invokedA = 0; int invokedA = 0;
int invokedB = 0; int invokedB = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1520,7 +1532,7 @@ void main() { ...@@ -1520,7 +1532,7 @@ void main() {
expect(invokedB, equals(1)); expect(invokedB, equals(1));
}); });
testWidgets('MaterialApp has a ShortcutRegistrar listening', (WidgetTester tester) async { testWidgetsWithLeakTracking('MaterialApp has a ShortcutRegistrar listening', (WidgetTester tester) async {
int invokedA = 0; int invokedA = 0;
int invokedB = 0; int invokedB = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1565,7 +1577,7 @@ void main() { ...@@ -1565,7 +1577,7 @@ void main() {
expect(invokedB, equals(1)); expect(invokedB, equals(1));
}); });
testWidgets("doesn't override text field shortcuts", (WidgetTester tester) async { testWidgetsWithLeakTracking("doesn't override text field shortcuts", (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(); final TextEditingController controller = TextEditingController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1597,7 +1609,7 @@ void main() { ...@@ -1597,7 +1609,7 @@ void main() {
expect(controller.selection.extentOffset, equals(7)); expect(controller.selection.extentOffset, equals(7));
}); });
testWidgets('nested ShortcutRegistrars stop propagation', (WidgetTester tester) async { testWidgetsWithLeakTracking('nested ShortcutRegistrars stop propagation', (WidgetTester tester) async {
int invokedOuter = 0; int invokedOuter = 0;
int invokedInner = 0; int invokedInner = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1638,7 +1650,7 @@ void main() { ...@@ -1638,7 +1650,7 @@ void main() {
expect(invokedInner, equals(1)); expect(invokedInner, equals(1));
}); });
testWidgets('non-overlapping nested ShortcutRegistrars fire appropriately', (WidgetTester tester) async { testWidgetsWithLeakTracking('non-overlapping nested ShortcutRegistrars fire appropriately', (WidgetTester tester) async {
int invokedOuter = 0; int invokedOuter = 0;
int invokedInner = 0; int invokedInner = 0;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1684,7 +1696,7 @@ void main() { ...@@ -1684,7 +1696,7 @@ void main() {
expect(invokedInner, equals(1)); expect(invokedInner, equals(1));
}); });
testWidgets('Works correctly with Shortcuts too', (WidgetTester tester) async { testWidgetsWithLeakTracking('Works correctly with Shortcuts too', (WidgetTester tester) async {
int invokedCallbackA = 0; int invokedCallbackA = 0;
int invokedCallbackB = 0; int invokedCallbackB = 0;
int invokedActionA = 0; int invokedActionA = 0;
...@@ -1761,7 +1773,7 @@ void main() { ...@@ -1761,7 +1773,7 @@ void main() {
await tester.sendKeyUpEvent(LogicalKeyboardKey.keyB); await tester.sendKeyUpEvent(LogicalKeyboardKey.keyB);
}); });
testWidgets('Updating shortcuts triggers dependency rebuild', (WidgetTester tester) async { testWidgetsWithLeakTracking('Updating shortcuts triggers dependency rebuild', (WidgetTester tester) async {
final List<Map<ShortcutActivator, Intent>> shortcutsChanged = <Map<ShortcutActivator, Intent>>[]; final List<Map<ShortcutActivator, Intent>> shortcutsChanged = <Map<ShortcutActivator, Intent>>[];
void dependenciesUpdated(Map<ShortcutActivator, Intent> shortcuts) { void dependenciesUpdated(Map<ShortcutActivator, Intent> shortcuts) {
shortcutsChanged.add(shortcuts); shortcutsChanged.add(shortcuts);
...@@ -1835,8 +1847,9 @@ void main() { ...@@ -1835,8 +1847,9 @@ void main() {
})); }));
}); });
testWidgets('using a disposed token asserts', (WidgetTester tester) async { testWidgetsWithLeakTracking('using a disposed token asserts', (WidgetTester tester) async {
final ShortcutRegistry registry = ShortcutRegistry(); final ShortcutRegistry registry = ShortcutRegistry();
addTearDown(registry.dispose);
final ShortcutRegistryEntry token = registry.addAll(const <ShortcutActivator, Intent>{ final ShortcutRegistryEntry token = registry.addAll(const <ShortcutActivator, Intent>{
SingleActivator(LogicalKeyboardKey.keyA): DoNothingIntent(), SingleActivator(LogicalKeyboardKey.keyA): DoNothingIntent(),
}); });
...@@ -1844,8 +1857,9 @@ void main() { ...@@ -1844,8 +1857,9 @@ void main() {
expect(() {token.replaceAll(<ShortcutActivator, Intent>{}); }, throwsFlutterError); expect(() {token.replaceAll(<ShortcutActivator, Intent>{}); }, throwsFlutterError);
}); });
testWidgets('setting duplicate bindings asserts', (WidgetTester tester) async { testWidgetsWithLeakTracking('setting duplicate bindings asserts', (WidgetTester tester) async {
final ShortcutRegistry registry = ShortcutRegistry(); final ShortcutRegistry registry = ShortcutRegistry();
addTearDown(registry.dispose);
final ShortcutRegistryEntry token = registry.addAll(const <ShortcutActivator, Intent>{ final ShortcutRegistryEntry token = registry.addAll(const <ShortcutActivator, Intent>{
SingleActivator(LogicalKeyboardKey.keyA): DoNothingIntent(), SingleActivator(LogicalKeyboardKey.keyA): DoNothingIntent(),
}); });
......
...@@ -6,11 +6,12 @@ import 'dart:ui'; ...@@ -6,11 +6,12 @@ import 'dart:ui';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Simple tree is simple', (WidgetTester tester) async { testWidgetsWithLeakTracking('Simple tree is simple', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -34,7 +35,7 @@ void main() { ...@@ -34,7 +35,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Simple tree is simple - material', (WidgetTester tester) async { testWidgetsWithLeakTracking('Simple tree is simple - material', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
// Not using Text widget because of https://github.com/flutter/flutter/issues/12357. // Not using Text widget because of https://github.com/flutter/flutter/issues/12357.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../rendering/rendering_tester.dart' show TestClipPaintingContext; import '../rendering/rendering_tester.dart' show TestClipPaintingContext;
import 'semantics_tester.dart'; import 'semantics_tester.dart';
...@@ -144,7 +145,7 @@ void main() { ...@@ -144,7 +145,7 @@ void main() {
); );
}); });
testWidgets('SingleChildScrollView control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView control test', (WidgetTester tester) async {
await tester.pumpWidget(SingleChildScrollView( await tester.pumpWidget(SingleChildScrollView(
child: Container( child: Container(
height: 2000.0, height: 2000.0,
...@@ -160,8 +161,9 @@ void main() { ...@@ -160,8 +161,9 @@ void main() {
expect(box.localToGlobal(Offset.zero), equals(const Offset(0.0, -200.0))); expect(box.localToGlobal(Offset.zero), equals(const Offset(0.0, -200.0)));
}); });
testWidgets('Changing controllers changes scroll position', (WidgetTester tester) async { testWidgetsWithLeakTracking('Changing controllers changes scroll position', (WidgetTester tester) async {
final TestScrollController controller = TestScrollController(); final TestScrollController controller = TestScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(SingleChildScrollView( await tester.pumpWidget(SingleChildScrollView(
child: Container( child: Container(
...@@ -182,8 +184,9 @@ void main() { ...@@ -182,8 +184,9 @@ void main() {
expect(scrollable.position, isA<TestScrollPosition>()); expect(scrollable.position, isA<TestScrollPosition>());
}); });
testWidgets('Sets PrimaryScrollController when primary', (WidgetTester tester) async { testWidgetsWithLeakTracking('Sets PrimaryScrollController when primary', (WidgetTester tester) async {
final ScrollController primaryScrollController = ScrollController(); final ScrollController primaryScrollController = ScrollController();
addTearDown(primaryScrollController.dispose);
await tester.pumpWidget(PrimaryScrollController( await tester.pumpWidget(PrimaryScrollController(
controller: primaryScrollController, controller: primaryScrollController,
child: SingleChildScrollView( child: SingleChildScrollView(
...@@ -200,8 +203,9 @@ void main() { ...@@ -200,8 +203,9 @@ void main() {
}); });
testWidgets('Changing scroll controller inside dirty layout builder does not assert', (WidgetTester tester) async { testWidgetsWithLeakTracking('Changing scroll controller inside dirty layout builder does not assert', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(Center( await tester.pumpWidget(Center(
child: SizedBox( child: SizedBox(
...@@ -237,25 +241,28 @@ void main() { ...@@ -237,25 +241,28 @@ void main() {
)); ));
}); });
testWidgets('Vertical SingleChildScrollViews are not primary by default', (WidgetTester tester) async { testWidgetsWithLeakTracking('Vertical SingleChildScrollViews are not primary by default', (WidgetTester tester) async {
const SingleChildScrollView view = SingleChildScrollView(); const SingleChildScrollView view = SingleChildScrollView();
expect(view.primary, isNull); expect(view.primary, isNull);
}); });
testWidgets('Horizontal SingleChildScrollViews are not primary by default', (WidgetTester tester) async { testWidgetsWithLeakTracking('Horizontal SingleChildScrollViews are not primary by default', (WidgetTester tester) async {
const SingleChildScrollView view = SingleChildScrollView(scrollDirection: Axis.horizontal); const SingleChildScrollView view = SingleChildScrollView(scrollDirection: Axis.horizontal);
expect(view.primary, isNull); expect(view.primary, isNull);
}); });
testWidgets('SingleChildScrollViews with controllers are not primary by default', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollViews with controllers are not primary by default', (WidgetTester tester) async {
final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final SingleChildScrollView view = SingleChildScrollView( final SingleChildScrollView view = SingleChildScrollView(
controller: ScrollController(), controller: controller,
); );
expect(view.primary, isNull); expect(view.primary, isNull);
}); });
testWidgets('Vertical SingleChildScrollViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async { testWidgetsWithLeakTracking('Vertical SingleChildScrollViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(primaryScrollControllerBoilerplate( await tester.pumpWidget(primaryScrollControllerBoilerplate(
child: const SingleChildScrollView(), child: const SingleChildScrollView(),
controller: controller, controller: controller,
...@@ -263,8 +270,9 @@ void main() { ...@@ -263,8 +270,9 @@ void main() {
expect(controller.hasClients, isTrue); expect(controller.hasClients, isTrue);
}, variant: TargetPlatformVariant.mobile()); }, variant: TargetPlatformVariant.mobile());
testWidgets("Vertical SingleChildScrollViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async { testWidgetsWithLeakTracking("Vertical SingleChildScrollViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(primaryScrollControllerBoilerplate( await tester.pumpWidget(primaryScrollControllerBoilerplate(
child: const SingleChildScrollView(), child: const SingleChildScrollView(),
controller: controller, controller: controller,
...@@ -272,9 +280,10 @@ void main() { ...@@ -272,9 +280,10 @@ void main() {
expect(controller.hasClients, isFalse); expect(controller.hasClients, isFalse);
}, variant: TargetPlatformVariant.desktop()); }, variant: TargetPlatformVariant.desktop());
testWidgets('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async { testWidgetsWithLeakTracking('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async {
const Key innerKey = Key('inner'); const Key innerKey = Key('inner');
final ScrollController primaryScrollController = ScrollController(); final ScrollController primaryScrollController = ScrollController();
addTearDown(primaryScrollController.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -300,9 +309,10 @@ void main() { ...@@ -300,9 +309,10 @@ void main() {
expect(innerScrollable.controller, isNull); expect(innerScrollable.controller, isNull);
}); });
testWidgets('SingleChildScrollView semantics', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView semantics', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -395,8 +405,9 @@ void main() { ...@@ -395,8 +405,9 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('SingleChildScrollView semantics clips cover entire child vertical', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView semantics clips cover entire child vertical', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final UniqueKey scrollView = UniqueKey(); final UniqueKey scrollView = UniqueKey();
final UniqueKey childBox = UniqueKey(); final UniqueKey childBox = UniqueKey();
const double length = 10000; const double length = 10000;
...@@ -434,8 +445,9 @@ void main() { ...@@ -434,8 +445,9 @@ void main() {
expect(semanticsClip.size.height, length); expect(semanticsClip.size.height, length);
}); });
testWidgets('SingleChildScrollView semantics clips cover entire child', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView semantics clips cover entire child', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final UniqueKey scrollView = UniqueKey(); final UniqueKey scrollView = UniqueKey();
final UniqueKey childBox = UniqueKey(); final UniqueKey childBox = UniqueKey();
const double length = 10000; const double length = 10000;
...@@ -474,7 +486,9 @@ void main() { ...@@ -474,7 +486,9 @@ void main() {
expect(semanticsClip.size.width, length); expect(semanticsClip.size.width, length);
}); });
testWidgets('SingleChildScrollView getOffsetToReveal - down', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - down', (WidgetTester tester) async {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
List<Widget> children; List<Widget> children;
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -484,7 +498,7 @@ void main() { ...@@ -484,7 +498,7 @@ void main() {
height: 200.0, height: 200.0,
width: 300.0, width: 300.0,
child: SingleChildScrollView( child: SingleChildScrollView(
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
child: Column( child: Column(
children: children = List<Widget>.generate(20, (int i) { children: children = List<Widget>.generate(20, (int i) {
return SizedBox( return SizedBox(
...@@ -520,7 +534,9 @@ void main() { ...@@ -520,7 +534,9 @@ void main() {
expect(revealed.rect, const Rect.fromLTWH(40.0, 190.0, 10.0, 10.0)); expect(revealed.rect, const Rect.fromLTWH(40.0, 190.0, 10.0, 10.0));
}); });
testWidgets('SingleChildScrollView getOffsetToReveal - up', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - up', (WidgetTester tester) async {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
final List<Widget> children = List<Widget>.generate(20, (int i) { final List<Widget> children = List<Widget>.generate(20, (int i) {
return SizedBox( return SizedBox(
height: 100.0, height: 100.0,
...@@ -536,7 +552,7 @@ void main() { ...@@ -536,7 +552,7 @@ void main() {
height: 200.0, height: 200.0,
width: 300.0, width: 300.0,
child: SingleChildScrollView( child: SingleChildScrollView(
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
reverse: true, reverse: true,
child: Column( child: Column(
children: children.reversed.toList(), children: children.reversed.toList(),
...@@ -567,7 +583,9 @@ void main() { ...@@ -567,7 +583,9 @@ void main() {
expect(revealed.rect, const Rect.fromLTWH(40.0, 0.0, 10.0, 10.0)); expect(revealed.rect, const Rect.fromLTWH(40.0, 0.0, 10.0, 10.0));
}); });
testWidgets('SingleChildScrollView getOffsetToReveal - right', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - right', (WidgetTester tester) async {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
List<Widget> children; List<Widget> children;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -579,7 +597,7 @@ void main() { ...@@ -579,7 +597,7 @@ void main() {
width: 200.0, width: 200.0,
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
child: Row( child: Row(
children: children = List<Widget>.generate(20, (int i) { children: children = List<Widget>.generate(20, (int i) {
return SizedBox( return SizedBox(
...@@ -615,7 +633,9 @@ void main() { ...@@ -615,7 +633,9 @@ void main() {
expect(revealed.rect, const Rect.fromLTWH(190.0, 40.0, 10.0, 10.0)); expect(revealed.rect, const Rect.fromLTWH(190.0, 40.0, 10.0, 10.0));
}); });
testWidgets('SingleChildScrollView getOffsetToReveal - left', (WidgetTester tester) async { testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - left', (WidgetTester tester) async {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
final List<Widget> children = List<Widget>.generate(20, (int i) { final List<Widget> children = List<Widget>.generate(20, (int i) {
return SizedBox( return SizedBox(
height: 300.0, height: 300.0,
...@@ -634,7 +654,7 @@ void main() { ...@@ -634,7 +654,7 @@ void main() {
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
reverse: true, reverse: true,
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
child: Row( child: Row(
children: children.reversed.toList(), children: children.reversed.toList(),
), ),
...@@ -664,7 +684,7 @@ void main() { ...@@ -664,7 +684,7 @@ void main() {
expect(revealed.rect, const Rect.fromLTWH(0.0, 40.0, 10.0, 10.0)); expect(revealed.rect, const Rect.fromLTWH(0.0, 40.0, 10.0, 10.0));
}); });
testWidgets('Nested SingleChildScrollView showOnScreen', (WidgetTester tester) async { testWidgetsWithLeakTracking('Nested SingleChildScrollView showOnScreen', (WidgetTester tester) async {
final List<List<Widget>> children = List<List<Widget>>.generate(10, (int x) { final List<List<Widget>> children = List<List<Widget>>.generate(10, (int x) {
return List<Widget>.generate(10, (int y) { return List<Widget>.generate(10, (int y) {
return SizedBox( return SizedBox(
...@@ -674,8 +694,10 @@ void main() { ...@@ -674,8 +694,10 @@ void main() {
); );
}); });
}); });
ScrollController controllerX; late ScrollController controllerX;
ScrollController controllerY; addTearDown(() => controllerX.dispose());
late ScrollController controllerY;
addTearDown(() => controllerY.dispose());
/// Builds a gird: /// Builds a gird:
/// ///
...@@ -874,9 +896,11 @@ void main() { ...@@ -874,9 +896,11 @@ void main() {
); );
} }
testWidgets('in view in inner, but not in outer', (WidgetTester tester) async { testWidgetsWithLeakTracking('in view in inner, but not in outer', (WidgetTester tester) async {
final ScrollController inner = ScrollController(); final ScrollController inner = ScrollController();
addTearDown(inner.dispose);
final ScrollController outer = ScrollController(); final ScrollController outer = ScrollController();
addTearDown(outer.dispose);
await buildNestedScroller( await buildNestedScroller(
tester: tester, tester: tester,
inner: inner, inner: inner,
...@@ -891,9 +915,11 @@ void main() { ...@@ -891,9 +915,11 @@ void main() {
expect(outer.offset, 100.0); expect(outer.offset, 100.0);
}); });
testWidgets('not in view of neither inner nor outer', (WidgetTester tester) async { testWidgetsWithLeakTracking('not in view of neither inner nor outer', (WidgetTester tester) async {
final ScrollController inner = ScrollController(); final ScrollController inner = ScrollController();
addTearDown(inner.dispose);
final ScrollController outer = ScrollController(); final ScrollController outer = ScrollController();
addTearDown(outer.dispose);
await buildNestedScroller( await buildNestedScroller(
tester: tester, tester: tester,
inner: inner, inner: inner,
...@@ -908,9 +934,11 @@ void main() { ...@@ -908,9 +934,11 @@ void main() {
expect(outer.offset, 200.0); expect(outer.offset, 200.0);
}); });
testWidgets('in view in inner and outer', (WidgetTester tester) async { testWidgetsWithLeakTracking('in view in inner and outer', (WidgetTester tester) async {
final ScrollController inner = ScrollController(initialScrollOffset: 200.0); final ScrollController inner = ScrollController(initialScrollOffset: 200.0);
addTearDown(inner.dispose);
final ScrollController outer = ScrollController(initialScrollOffset: 200.0); final ScrollController outer = ScrollController(initialScrollOffset: 200.0);
addTearDown(outer.dispose);
await buildNestedScroller( await buildNestedScroller(
tester: tester, tester: tester,
inner: inner, inner: inner,
...@@ -925,9 +953,11 @@ void main() { ...@@ -925,9 +953,11 @@ void main() {
expect(inner.offset, 200.0); expect(inner.offset, 200.0);
}); });
testWidgets('inner shown in outer, but item not visible', (WidgetTester tester) async { testWidgetsWithLeakTracking('inner shown in outer, but item not visible', (WidgetTester tester) async {
final ScrollController inner = ScrollController(initialScrollOffset: 200.0); final ScrollController inner = ScrollController(initialScrollOffset: 200.0);
addTearDown(inner.dispose);
final ScrollController outer = ScrollController(initialScrollOffset: 200.0); final ScrollController outer = ScrollController(initialScrollOffset: 200.0);
addTearDown(outer.dispose);
await buildNestedScroller( await buildNestedScroller(
tester: tester, tester: tester,
inner: inner, inner: inner,
...@@ -942,9 +972,11 @@ void main() { ...@@ -942,9 +972,11 @@ void main() {
expect(inner.offset, 400.0); expect(inner.offset, 400.0);
}); });
testWidgets('inner half shown in outer, item only visible in inner', (WidgetTester tester) async { testWidgetsWithLeakTracking('inner half shown in outer, item only visible in inner', (WidgetTester tester) async {
final ScrollController inner = ScrollController(); final ScrollController inner = ScrollController();
addTearDown(inner.dispose);
final ScrollController outer = ScrollController(initialScrollOffset: 100.0); final ScrollController outer = ScrollController(initialScrollOffset: 100.0);
addTearDown(outer.dispose);
await buildNestedScroller( await buildNestedScroller(
tester: tester, tester: tester,
inner: inner, inner: inner,
...@@ -960,8 +992,13 @@ void main() { ...@@ -960,8 +992,13 @@ void main() {
}); });
}); });
testWidgets('keyboardDismissBehavior tests', (WidgetTester tester) async { testWidgetsWithLeakTracking('keyboardDismissBehavior tests', (WidgetTester tester) async {
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode()); final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
addTearDown(() {
for (final FocusNode node in focusNodes) {
node.dispose();
}
});
Future<void> boilerplate(ScrollViewKeyboardDismissBehavior behavior) { Future<void> boilerplate(ScrollViewKeyboardDismissBehavior behavior) {
return tester.pumpWidget( return tester.pumpWidget(
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('SizeChangedLayoutNotification test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SizeChangedLayoutNotification test', (WidgetTester tester) async {
bool notified = false; bool notified = false;
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('SizedBox constructors', (WidgetTester tester) async { testWidgetsWithLeakTracking('SizedBox constructors', (WidgetTester tester) async {
const SizedBox a = SizedBox(); const SizedBox a = SizedBox();
expect(a.width, isNull); expect(a.width, isNull);
expect(a.height, isNull); expect(a.height, isNull);
...@@ -37,7 +38,7 @@ void main() { ...@@ -37,7 +38,7 @@ void main() {
expect(g.height, 0.0); expect(g.height, 0.0);
}); });
testWidgets('SizedBox - no child', (WidgetTester tester) async { testWidgetsWithLeakTracking('SizedBox - no child', (WidgetTester tester) async {
final GlobalKey patient = GlobalKey(); final GlobalKey patient = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -109,7 +110,7 @@ void main() { ...@@ -109,7 +110,7 @@ void main() {
expect(patient.currentContext!.size, equals(Size.zero)); expect(patient.currentContext!.size, equals(Size.zero));
}); });
testWidgets('SizedBox - container child', (WidgetTester tester) async { testWidgetsWithLeakTracking('SizedBox - container child', (WidgetTester tester) async {
final GlobalKey patient = GlobalKey(); final GlobalKey patient = GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -188,7 +189,7 @@ void main() { ...@@ -188,7 +189,7 @@ void main() {
expect(patient.currentContext!.size, equals(Size.zero)); expect(patient.currentContext!.size, equals(Size.zero));
}); });
testWidgets('SizedBox.square tests', (WidgetTester tester) async { testWidgetsWithLeakTracking('SizedBox.square tests', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const SizedBox.square( const SizedBox.square(
dimension: 100, dimension: 100,
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('!pinned && !floating && !bottom ==> fade opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('!pinned && !floating && !bottom ==> fade opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: false, pinned: false,
...@@ -26,8 +28,9 @@ void main() { ...@@ -26,8 +28,9 @@ void main() {
expect(render.text.style!.color!.opacity, 0.0); expect(render.text.style!.color!.opacity, 0.0);
}); });
testWidgets('!pinned && !floating && bottom ==> fade opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('!pinned && !floating && bottom ==> fade opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: false, pinned: false,
...@@ -45,8 +48,9 @@ void main() { ...@@ -45,8 +48,9 @@ void main() {
expect(render.text.style!.color!.opacity, 0.0); expect(render.text.style!.color!.opacity, 0.0);
}); });
testWidgets('!pinned && floating && !bottom ==> fade opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('!pinned && floating && !bottom ==> fade opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: false, pinned: false,
...@@ -64,8 +68,9 @@ void main() { ...@@ -64,8 +68,9 @@ void main() {
expect(render.text.style!.color!.opacity, 0.0); expect(render.text.style!.color!.opacity, 0.0);
}); });
testWidgets('!pinned && floating && bottom ==> fade opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('!pinned && floating && bottom ==> fade opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: false, pinned: false,
...@@ -83,8 +88,9 @@ void main() { ...@@ -83,8 +88,9 @@ void main() {
expect(render.text.style!.color!.opacity, 0.0); expect(render.text.style!.color!.opacity, 0.0);
}); });
testWidgets('pinned && !floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('pinned && !floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: true, pinned: true,
...@@ -102,8 +108,9 @@ void main() { ...@@ -102,8 +108,9 @@ void main() {
expect(render.text.style!.color!.opacity, 1.0); expect(render.text.style!.color!.opacity, 1.0);
}); });
testWidgets('pinned && !floating && bottom ==> 1.0 opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('pinned && !floating && bottom ==> 1.0 opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: true, pinned: true,
...@@ -121,10 +128,11 @@ void main() { ...@@ -121,10 +128,11 @@ void main() {
expect(render.text.style!.color!.opacity, 1.0); expect(render.text.style!.color!.opacity, 1.0);
}); });
testWidgets('pinned && floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('pinned && floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/25000. // Regression test for https://github.com/flutter/flutter/issues/25000.
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: true, pinned: true,
...@@ -142,10 +150,11 @@ void main() { ...@@ -142,10 +150,11 @@ void main() {
expect(render.text.style!.color!.opacity, 1.0); expect(render.text.style!.color!.opacity, 1.0);
}); });
testWidgets('pinned && floating && bottom && extraToolbarHeight == 0.0 ==> fade opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('pinned && floating && bottom && extraToolbarHeight == 0.0 ==> fade opacity', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/25993. // Regression test for https://github.com/flutter/flutter/issues/25993.
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: true, pinned: true,
...@@ -163,8 +172,9 @@ void main() { ...@@ -163,8 +172,9 @@ void main() {
expect(render.text.style!.color!.opacity, 0.0); expect(render.text.style!.color!.opacity, 0.0);
}); });
testWidgets('pinned && floating && bottom && extraToolbarHeight != 0.0 ==> 1.0 opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('pinned && floating && bottom && extraToolbarHeight != 0.0 ==> 1.0 opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
pinned: true, pinned: true,
...@@ -183,8 +193,9 @@ void main() { ...@@ -183,8 +193,9 @@ void main() {
expect(render.text.style!.color!.opacity, 1.0); expect(render.text.style!.color!.opacity, 1.0);
}); });
testWidgets('!pinned && !floating && !bottom && extraToolbarHeight != 0.0 ==> fade opacity', (WidgetTester tester) async { testWidgetsWithLeakTracking('!pinned && !floating && !bottom && extraToolbarHeight != 0.0 ==> fade opacity', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
const double collapsedHeight = 100.0; const double collapsedHeight = 100.0;
await tester.pumpWidget( await tester.pumpWidget(
_TestWidget( _TestWidget(
......
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
const double VIEWPORT_HEIGHT = 500; const double VIEWPORT_HEIGHT = 500;
const double VIEWPORT_WIDTH = 300; const double VIEWPORT_WIDTH = 300;
void main() { void main() {
testWidgets('SliverConstrainedCrossAxis basic test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverConstrainedCrossAxis basic test', (WidgetTester tester) async {
await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 50)); await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 50));
final RenderBox box = tester.renderObject(find.byType(Container)); final RenderBox box = tester.renderObject(find.byType(Container));
...@@ -21,7 +22,7 @@ void main() { ...@@ -21,7 +22,7 @@ void main() {
expect(sliver.geometry!.paintExtent, equals(100)); expect(sliver.geometry!.paintExtent, equals(100));
}); });
testWidgets('SliverConstrainedCrossAxis updates correctly', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverConstrainedCrossAxis updates correctly', (WidgetTester tester) async {
await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 50)); await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 50));
final RenderBox box1 = tester.renderObject(find.byType(Container)); final RenderBox box1 = tester.renderObject(find.byType(Container));
...@@ -35,7 +36,7 @@ void main() { ...@@ -35,7 +36,7 @@ void main() {
expect(box2.size.width, 80); expect(box2.size.width, 80);
}); });
testWidgets('SliverConstrainedCrossAxis uses parent extent if maxExtent is greater', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverConstrainedCrossAxis uses parent extent if maxExtent is greater', (WidgetTester tester) async {
await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 400)); await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 400));
final RenderBox box = tester.renderObject(find.byType(Container)); final RenderBox box = tester.renderObject(find.byType(Container));
...@@ -43,7 +44,7 @@ void main() { ...@@ -43,7 +44,7 @@ void main() {
expect(box.size.width, VIEWPORT_WIDTH); expect(box.size.width, VIEWPORT_WIDTH);
}); });
testWidgets('SliverConstrainedCrossAxis constrains the height when direction is horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverConstrainedCrossAxis constrains the height when direction is horizontal', (WidgetTester tester) async {
await tester.pumpWidget(_buildSliverConstrainedCrossAxis( await tester.pumpWidget(_buildSliverConstrainedCrossAxis(
maxExtent: 50, maxExtent: 50,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -53,7 +54,7 @@ void main() { ...@@ -53,7 +54,7 @@ void main() {
expect(box.size.height, 50); expect(box.size.height, 50);
}); });
testWidgets('SliverConstrainedCrossAxis sets its own flex to 0', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverConstrainedCrossAxis sets its own flex to 0', (WidgetTester tester) async {
await tester.pumpWidget(_buildSliverConstrainedCrossAxis( await tester.pumpWidget(_buildSliverConstrainedCrossAxis(
maxExtent: 50, maxExtent: 50,
)); ));
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('precedingScrollExtent is reported as infinity for Sliver of unknown size', (WidgetTester tester) async { testWidgetsWithLeakTracking('precedingScrollExtent is reported as infinity for Sliver of unknown size', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: CustomScrollView( home: CustomScrollView(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../rendering/sliver_utils.dart'; import '../rendering/sliver_utils.dart';
...@@ -13,9 +14,10 @@ const double VIEWPORT_HEIGHT = 600; ...@@ -13,9 +14,10 @@ const double VIEWPORT_HEIGHT = 600;
const double VIEWPORT_WIDTH = 300; const double VIEWPORT_WIDTH = 300;
void main() { void main() {
testWidgets('SliverCrossAxisGroup is laid out properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverCrossAxisGroup is laid out properly', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
...@@ -60,7 +62,7 @@ void main() { ...@@ -60,7 +62,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('SliverExpanded is laid out properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverExpanded is laid out properly', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
slivers: <Widget>[ slivers: <Widget>[
...@@ -98,7 +100,7 @@ void main() { ...@@ -98,7 +100,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('SliverConstrainedCrossAxis is laid out properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverConstrainedCrossAxis is laid out properly', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
slivers: <Widget>[ slivers: <Widget>[
...@@ -127,7 +129,7 @@ void main() { ...@@ -127,7 +129,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('Mix of slivers is laid out properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('Mix of slivers is laid out properly', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
slivers: <Widget>[ slivers: <Widget>[
...@@ -160,7 +162,7 @@ void main() { ...@@ -160,7 +162,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('Mix of slivers is laid out properly when horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('Mix of slivers is laid out properly when horizontal', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -215,7 +217,7 @@ void main() { ...@@ -215,7 +217,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('Mix of slivers is laid out properly when reversed horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('Mix of slivers is laid out properly when reversed horizontal', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -271,7 +273,7 @@ void main() { ...@@ -271,7 +273,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('Mix of slivers is laid out properly when reversed vertical', (WidgetTester tester) async { testWidgetsWithLeakTracking('Mix of slivers is laid out properly when reversed vertical', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
reverse: true, reverse: true,
...@@ -354,9 +356,10 @@ void main() { ...@@ -354,9 +356,10 @@ void main() {
); );
}); });
testWidgets('Hit test works properly on various parts of SliverCrossAxisGroup', (WidgetTester tester) async { testWidgetsWithLeakTracking('Hit test works properly on various parts of SliverCrossAxisGroup', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
String? clickedTile; String? clickedTile;
...@@ -425,7 +428,7 @@ void main() { ...@@ -425,7 +428,7 @@ void main() {
expect(clickedTile, equals('Group 1 Tile 2')); expect(clickedTile, equals('Group 1 Tile 2'));
}); });
testWidgets('Constrained sliver takes up remaining space', (WidgetTester tester) async { testWidgetsWithLeakTracking('Constrained sliver takes up remaining space', (WidgetTester tester) async {
final List<int> items = List<int>.generate(20, (int i) => i); final List<int> items = List<int>.generate(20, (int i) => i);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
slivers: <Widget>[ slivers: <Widget>[
...@@ -454,7 +457,7 @@ void main() { ...@@ -454,7 +457,7 @@ void main() {
expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); expect(renderGroup.geometry!.scrollExtent, equals(300 * 20));
}); });
testWidgets('Assertion error when constrained widget runs out of cross axis extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('Assertion error when constrained widget runs out of cross axis extent', (WidgetTester tester) async {
final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[]; final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
final Function(FlutterErrorDetails)? oldHandler = FlutterError.onError; final Function(FlutterErrorDetails)? oldHandler = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
...@@ -476,7 +479,7 @@ void main() { ...@@ -476,7 +479,7 @@ void main() {
); );
}); });
testWidgets('Assertion error when expanded widget runs out of cross axis extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('Assertion error when expanded widget runs out of cross axis extent', (WidgetTester tester) async {
final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[]; final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
final Function(FlutterErrorDetails)? oldHandler = FlutterError.onError; final Function(FlutterErrorDetails)? oldHandler = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
...@@ -499,7 +502,7 @@ void main() { ...@@ -499,7 +502,7 @@ void main() {
); );
}); });
testWidgets('applyPaintTransform is implemented properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('applyPaintTransform is implemented properly', (WidgetTester tester) async {
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
slivers: <Widget>[ slivers: <Widget>[
const SliverToBoxAdapter(child: Text('first box')), const SliverToBoxAdapter(child: Text('first box')),
...@@ -515,8 +518,9 @@ void main() { ...@@ -515,8 +518,9 @@ void main() {
expect(second.localToGlobal(Offset.zero), const Offset(VIEWPORT_WIDTH / 2, 0)); expect(second.localToGlobal(Offset.zero), const Offset(VIEWPORT_WIDTH / 2, 0));
}); });
testWidgets('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -540,8 +544,9 @@ void main() { ...@@ -540,8 +544,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-20.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-20.0));
}); });
testWidgets('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -569,8 +574,9 @@ void main() { ...@@ -569,8 +574,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0));
}); });
testWidgets('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -599,8 +605,9 @@ void main() { ...@@ -599,8 +605,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0));
}); });
testWidgets('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -635,8 +642,9 @@ void main() { ...@@ -635,8 +642,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0));
}); });
testWidgets('SliverPinnedFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverPinnedFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -672,8 +680,9 @@ void main() { ...@@ -672,8 +680,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0));
}); });
testWidgets('SliverAppBar with floating: false, pinned: false, snap: false is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverAppBar with floating: false, pinned: false, snap: false is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -701,8 +710,9 @@ void main() { ...@@ -701,8 +710,9 @@ void main() {
expect(renderHeader.geometry!.paintExtent, equals(0.0)); expect(renderHeader.geometry!.paintExtent, equals(0.0));
}); });
testWidgets('SliverAppBar with floating: true, pinned: false, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverAppBar with floating: true, pinned: false, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -741,8 +751,9 @@ void main() { ...@@ -741,8 +751,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-50.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-50.0));
}); });
testWidgets('SliverAppBar with floating: true, pinned: true, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverAppBar with floating: true, pinned: true, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -781,8 +792,9 @@ void main() { ...@@ -781,8 +792,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-50.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-50.0));
}); });
testWidgets('SliverFloatingPersistentHeader scroll direction is not affected by controller.jumpTo', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverFloatingPersistentHeader scroll direction is not affected by controller.jumpTo', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget(_buildSliverCrossAxisGroup( await tester.pumpWidget(_buildSliverCrossAxisGroup(
controller: controller, controller: controller,
slivers: <Widget>[ slivers: <Widget>[
...@@ -810,8 +822,9 @@ void main() { ...@@ -810,8 +822,9 @@ void main() {
expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0));
}); });
testWidgets('SliverCrossAxisGroup skips painting invisible children', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverCrossAxisGroup skips painting invisible children', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
int counter = 0; int counter = 0;
void incrementCounter() { void incrementCounter() {
......
...@@ -6,6 +6,7 @@ import 'dart:math' as math; ...@@ -6,6 +6,7 @@ import 'dart:math' as math;
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:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
...@@ -39,8 +40,9 @@ void main() { ...@@ -39,8 +40,9 @@ void main() {
group('SliverFillRemaining', () { group('SliverFillRemaining', () {
group('hasScrollBody: true, default', () { group('hasScrollBody: true, default', () {
testWidgets('no siblings', (WidgetTester tester) async { testWidgetsWithLeakTracking('no siblings', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -79,8 +81,9 @@ void main() { ...@@ -79,8 +81,9 @@ void main() {
); );
}); });
testWidgets('one sibling', (WidgetTester tester) async { testWidgetsWithLeakTracking('one sibling', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -120,8 +123,9 @@ void main() { ...@@ -120,8 +123,9 @@ void main() {
); );
}); });
testWidgets('scrolls beyond viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('scrolls beyond viewportMainAxisExtent', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
SliverFillRemaining( SliverFillRemaining(
...@@ -139,8 +143,9 @@ void main() { ...@@ -139,8 +143,9 @@ void main() {
}); });
group('hasScrollBody: false', () { group('hasScrollBody: false', () {
testWidgets('does not extend past viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('does not extend past viewportMainAxisExtent', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
SliverFillRemaining( SliverFillRemaining(
...@@ -158,7 +163,7 @@ void main() { ...@@ -158,7 +163,7 @@ void main() {
expect(find.byType(Container), findsNWidgets(2)); expect(find.byType(Container), findsNWidgets(2));
}); });
testWidgets('child without size is sized by extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('child without size is sized by extent', (WidgetTester tester) async {
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
SliverFillRemaining( SliverFillRemaining(
...@@ -179,7 +184,7 @@ void main() { ...@@ -179,7 +184,7 @@ void main() {
expect(box.size.width, equals(650)); expect(box.size.width, equals(650));
}); });
testWidgets('child with smaller size is sized by extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('child with smaller size is sized by extent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
...@@ -220,7 +225,7 @@ void main() { ...@@ -220,7 +225,7 @@ void main() {
); );
}); });
testWidgets('extent is overridden by child with larger size', (WidgetTester tester) async { testWidgetsWithLeakTracking('extent is overridden by child with larger size', (WidgetTester tester) async {
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
SliverFillRemaining( SliverFillRemaining(
...@@ -244,7 +249,7 @@ void main() { ...@@ -244,7 +249,7 @@ void main() {
expect(box.size.width, equals(1000)); expect(box.size.width, equals(1000));
}); });
testWidgets('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
SliverFixedExtentList( SliverFixedExtentList(
...@@ -285,7 +290,7 @@ void main() { ...@@ -285,7 +290,7 @@ void main() {
expect(tester.getCenter(button).dx, equals(400.0)); expect(tester.getCenter(button).dx, equals(400.0));
}); });
testWidgets('alignment with a flexible works', (WidgetTester tester) async { testWidgetsWithLeakTracking('alignment with a flexible works', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
...@@ -354,7 +359,7 @@ void main() { ...@@ -354,7 +359,7 @@ void main() {
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
group('fillOverscroll: true, relevant platforms', () { group('fillOverscroll: true, relevant platforms', () {
testWidgets('child without size is sized by extent and overscroll', (WidgetTester tester) async { testWidgetsWithLeakTracking('child without size is sized by extent and overscroll', (WidgetTester tester) async {
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
SliverFillRemaining( SliverFillRemaining(
...@@ -381,7 +386,7 @@ void main() { ...@@ -381,7 +386,7 @@ void main() {
expect(box3.size.height, equals(450)); expect(box3.size.height, equals(450));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('child with smaller size is overridden and sized by extent and overscroll', (WidgetTester tester) async { testWidgetsWithLeakTracking('child with smaller size is overridden and sized by extent and overscroll', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
...@@ -428,9 +433,10 @@ void main() { ...@@ -428,9 +433,10 @@ void main() {
); );
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('extent is overridden by child size and overscroll if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('extent is overridden by child size and overscroll if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
SliverFixedExtentList( SliverFixedExtentList(
itemExtent: 150, itemExtent: 150,
...@@ -492,9 +498,10 @@ void main() { ...@@ -492,9 +498,10 @@ void main() {
); );
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('fillOverscroll works when child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('fillOverscroll works when child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
SliverFixedExtentList( SliverFixedExtentList(
itemExtent: 150, itemExtent: 150,
...@@ -554,7 +561,7 @@ void main() { ...@@ -554,7 +561,7 @@ void main() {
); );
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('alignment with a flexible works with fillOverscroll', (WidgetTester tester) async { testWidgetsWithLeakTracking('alignment with a flexible works with fillOverscroll', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
...@@ -648,7 +655,7 @@ void main() { ...@@ -648,7 +655,7 @@ void main() {
group('fillOverscroll: true, is ignored on irrelevant platforms', () { group('fillOverscroll: true, is ignored on irrelevant platforms', () {
// Android/Other scroll physics when hasScrollBody: false, ignores fillOverscroll: true // Android/Other scroll physics when hasScrollBody: false, ignores fillOverscroll: true
testWidgets('child without size is sized by extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('child without size is sized by extent', (WidgetTester tester) async {
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
SliverFillRemaining( SliverFillRemaining(
...@@ -667,7 +674,7 @@ void main() { ...@@ -667,7 +674,7 @@ void main() {
expect(box2.size.height, equals(450)); expect(box2.size.height, equals(450));
}); });
testWidgets('child with size is overridden and sized by extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('child with size is overridden and sized by extent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
sliverBox, sliverBox,
...@@ -706,9 +713,10 @@ void main() { ...@@ -706,9 +713,10 @@ void main() {
expect(tester.getCenter(button).dx, equals(400.0)); expect(tester.getCenter(button).dx, equals(400.0));
}); });
testWidgets('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
SliverFixedExtentList( SliverFixedExtentList(
itemExtent: 150, itemExtent: 150,
...@@ -763,9 +771,10 @@ void main() { ...@@ -763,9 +771,10 @@ void main() {
expect(tester.getCenter(button).dx, equals(400.0)); expect(tester.getCenter(button).dx, equals(400.0));
}); });
testWidgets('child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<Widget> slivers = <Widget>[ final List<Widget> slivers = <Widget>[
SliverFixedExtentList( SliverFixedExtentList(
itemExtent: 150, itemExtent: 150,
......
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