Unverified Commit 7f17cf45 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Cheaper debug string for widget-provided tickers (#81247)

parent d1f02ae0
......@@ -126,7 +126,7 @@ mixin SingleTickerProviderStateMixin<T extends StatefulWidget> on State<T> imple
),
]);
}());
_ticker = Ticker(onTick, debugLabel: kDebugMode ? 'created by $this' : null);
_ticker = Ticker(onTick, debugLabel: kDebugMode ? 'created by ${describeIdentity(this)}' : null);
// We assume that this is called from initState, build, or some sort of
// event handler, and that thus TickerMode.of(context) would return true. We
// can't actually check that here because if we're in initState then we're
......@@ -199,7 +199,7 @@ mixin TickerProviderStateMixin<T extends StatefulWidget> on State<T> implements
@override
Ticker createTicker(TickerCallback onTick) {
_tickers ??= <_WidgetTicker>{};
final _WidgetTicker result = _WidgetTicker(onTick, this, debugLabel: 'created by $this');
final _WidgetTicker result = _WidgetTicker(onTick, this, debugLabel: kDebugMode ? 'created by ${describeIdentity(this)}' : null);
_tickers!.add(result);
return result;
}
......
......@@ -117,7 +117,7 @@ void main() {
'the ticker will leak.\n'
);
expect(error.diagnostics[3], isA<DiagnosticsProperty<Ticker>>());
expect(error.toStringDeep().split('\n').take(14).join('\n'), equalsIgnoringHashCodes(
expect(error.toStringDeep().split('\n').take(13).join('\n'), equalsIgnoringHashCodes(
'FlutterError\n'
' _SingleTickerTestState#00000(ticker active) was disposed with an\n'
' active Ticker.\n'
......@@ -129,8 +129,7 @@ void main() {
' calling dispose() on the AnimationController itself. Otherwise,\n'
' the ticker will leak.\n'
' The offending ticker was:\n'
' Ticker(created by _SingleTickerTestState#00000(lifecycle state:\n'
' created))\n'
' Ticker(created by _SingleTickerTestState#00000)\n'
' The stack trace when the Ticker was actually created was:'
));
key.currentState!.controller.stop();
......@@ -158,7 +157,7 @@ void main() {
'the ticker will leak.\n'
);
expect(error.diagnostics[3], isA<DiagnosticsProperty<Ticker>>());
expect(error.toStringDeep().split('\n').take(14).join('\n'), equalsIgnoringHashCodes(
expect(error.toStringDeep().split('\n').take(13).join('\n'), equalsIgnoringHashCodes(
'FlutterError\n'
' _SingleTickerTestState#00000(ticker active) was disposed with an\n'
' active Ticker.\n'
......@@ -170,15 +169,14 @@ void main() {
' calling dispose() on the AnimationController itself. Otherwise,\n'
' the ticker will leak.\n'
' The offending ticker was:\n'
' Ticker(created by _SingleTickerTestState#00000(lifecycle state:\n'
' created))\n'
' Ticker(created by _SingleTickerTestState#00000)\n'
' The stack trace when the Ticker was actually created was:'
));
key.currentState!.controller.stop();
}
});
testWidgets('ProviderStateMixin dispose while any ticker is active', (WidgetTester tester) async {
testWidgets('TickerProviderStateMixin dispose while any ticker is active', (WidgetTester tester) async {
final GlobalKey<_MultipleTickerTestState> key = GlobalKey<_MultipleTickerTestState>();
final Widget widget = _MultipleTickerTest(key: key);
await tester.pumpWidget(widget);
......@@ -199,7 +197,7 @@ void main() {
'the ticker will leak.\n'
);
expect(error.diagnostics[3], isA<DiagnosticsProperty<Ticker>>());
expect(error.toStringDeep().split('\n').take(14).join('\n'), equalsIgnoringHashCodes(
expect(error.toStringDeep().split('\n').take(12).join('\n'), equalsIgnoringHashCodes(
'FlutterError\n'
' _MultipleTickerTestState#00000(tickers: tracking 2 tickers) was\n'
' disposed with an active Ticker.\n'
......@@ -211,14 +209,22 @@ void main() {
' calling dispose() on the AnimationController itself. Otherwise,\n'
' the ticker will leak.\n'
' The offending ticker was:\n'
' _WidgetTicker(created by\n'
' _MultipleTickerTestState#00000(lifecycle state: created,\n'
' tickers: tracking 0 tickers))'
' _WidgetTicker(created by _MultipleTickerTestState#00000)'
));
key.currentState!.controllers.first.stop();
}
});
});
testWidgets('SingleTickerProviderStateMixin does not call State.toString', (WidgetTester tester) async {
await tester.pumpWidget(const _SingleTickerTest());
expect(tester.state<_SingleTickerTestState>(find.byType(_SingleTickerTest)).toStringCount, 0);
});
testWidgets('TickerProviderStateMixin does not call State.toString', (WidgetTester tester) async {
await tester.pumpWidget(const _MultipleTickerTest());
expect(tester.state<_MultipleTickerTestState>(find.byType(_MultipleTickerTest)).toStringCount, 0);
});
}
class BoringTickerTest extends StatefulWidget {
......@@ -255,6 +261,14 @@ class _SingleTickerTestState extends State<_SingleTickerTest> with SingleTickerP
Widget build(BuildContext context) {
return Container();
}
int toStringCount = 0;
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
toStringCount += 1;
return super.toString(minLevel: minLevel);
}
}
class _MultipleTickerTest extends StatefulWidget {
......@@ -279,6 +293,14 @@ class _MultipleTickerTestState extends State<_MultipleTickerTest> with TickerPro
Widget build(BuildContext context) {
return Container();
}
int toStringCount = 0;
@override
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
toStringCount += 1;
return super.toString(minLevel: minLevel);
}
}
class _SingleTickerCreateMultipleTicker extends StatefulWidget {
......
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