Skip to content

Commit 0a2b459

Browse files
committed
test: Add TestZulipApp; replace uses of ZulipApp
Greg noticed an instance where using ZulipApp directly was causing tests to slow down by some 75%: #805 (comment) Specifically, that was when we converted the emoji-reaction widget tests over to use ZulipApp instead of mimicking it with a MaterialApp, etc. It's helpful to use something approaching the real ZulipApp. But we'd like to avoid that slowdown, especially if it's happening in code that most tests don't need to exercise. So, here's a stripped-down version that does that. It takes roughly the same time as the MaterialApp approach in those emoji-reaction tests. (11s on my machine, vs. 16s with ZulipApp.) This commit just converts the tests that were using ZulipApp. Next, we'll sweep through and treat the ones using the ad hoc MaterialApp approach.
1 parent f32fa86 commit 0a2b459

File tree

6 files changed

+59
-28
lines changed

6 files changed

+59
-28
lines changed

test/notifications/display_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ void main() {
340340
pushedRoutes = [];
341341
final testNavObserver = TestNavigatorObserver()
342342
..onPushed = (route, prevRoute) => pushedRoutes.add(route);
343+
// This uses [ZulipApp] instead of [TestZulipApp] because notification
344+
// logic uses `await ZulipApp.navigator`.
343345
await tester.pumpWidget(ZulipApp(navigatorObservers: [testNavObserver]));
344346
if (early) {
345347
check(pushedRoutes).isEmpty();

test/widgets/code_block_test.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import 'package:checks/checks.dart';
22
import 'package:flutter/material.dart';
33
import 'package:flutter_test/flutter_test.dart';
4-
import 'package:zulip/widgets/app.dart';
54
import 'package:zulip/widgets/code_block.dart';
6-
import 'package:zulip/widgets/page.dart';
75

86
import '../model/binding.dart';
7+
import 'test_app.dart';
98

109
void main() {
1110
TestZulipBinding.ensureInitialized();
@@ -14,12 +13,8 @@ void main() {
1413
group('lerp', () {
1514
Future<BuildContext> contextWithZulipTheme(WidgetTester tester) async {
1615
addTearDown(testBinding.reset);
17-
await tester.pumpWidget(const ZulipApp());
16+
await tester.pumpWidget(const TestZulipApp());
1817
await tester.pump();
19-
final navigator = await ZulipApp.navigator;
20-
navigator.push(MaterialWidgetRoute(page: Builder(
21-
builder: (context) => const Placeholder())));
22-
await tester.pumpAndSettle();
2318
return tester.element(find.byType(Placeholder));
2419
}
2520

test/widgets/inbox_test.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import 'package:flutter_test/flutter_test.dart';
44
import 'package:zulip/api/model/events.dart';
55
import 'package:zulip/api/model/model.dart';
66
import 'package:zulip/model/store.dart';
7-
import 'package:zulip/widgets/app.dart';
87
import 'package:zulip/widgets/icons.dart';
98
import 'package:zulip/widgets/inbox.dart';
109
import 'package:zulip/widgets/stream_colors.dart';
@@ -13,6 +12,7 @@ import '../example_data.dart' as eg;
1312
import '../flutter_checks.dart';
1413
import '../model/binding.dart';
1514
import '../model/test_store.dart';
15+
import 'test_app.dart';
1616

1717
/// Repeatedly drags `view` by `moveStep` until `finder` is invisible.
1818
///
@@ -71,11 +71,12 @@ void main() {
7171
await store.handleEvent(MessageEvent(id: 1, message: message));
7272
}
7373

74-
await tester.pumpWidget(
75-
ZulipApp(navigatorObservers: [if (navigatorObserver != null) navigatorObserver]));
74+
await tester.pumpWidget(TestZulipApp(
75+
accountId: eg.selfAccount.id,
76+
navigatorObservers: [if (navigatorObserver != null) navigatorObserver],
77+
child: const InboxPage(),
78+
));
7679
await tester.pump();
77-
final navigator = await ZulipApp.navigator;
78-
navigator.push(InboxPage.buildRoute(accountId: eg.selfAccount.id));
7980

8081
// global store and per-account store get loaded
8182
await tester.pumpAndSettle();

test/widgets/test_app.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
3+
4+
import 'package:zulip/widgets/store.dart';
5+
import 'package:zulip/widgets/theme.dart';
6+
7+
/// A lightweight mock of [ZulipApp], suitable for most widget tests.
8+
class TestZulipApp extends StatelessWidget {
9+
const TestZulipApp({
10+
super.key,
11+
this.accountId,
12+
this.child = const Placeholder(),
13+
this.navigatorObservers,
14+
});
15+
16+
final int? accountId;
17+
18+
/// A [Widget] to render on the home page.
19+
///
20+
/// If [accountId] is provided, this is wrapped in a [PerAccountStoreWidget].
21+
///
22+
/// Defaults to `Placeholder()`.
23+
final Widget child;
24+
25+
/// A list to pass through to [MaterialApp.navigatorObservers].
26+
final List<NavigatorObserver>? navigatorObservers;
27+
28+
@override
29+
Widget build(BuildContext context) {
30+
return GlobalStoreWidget(
31+
child: MaterialApp(
32+
title: 'Zulip',
33+
localizationsDelegates: ZulipLocalizations.localizationsDelegates,
34+
supportedLocales: ZulipLocalizations.supportedLocales,
35+
theme: zulipThemeData(context),
36+
37+
navigatorObservers: navigatorObservers ?? const [],
38+
39+
home: accountId != null
40+
? PerAccountStoreWidget(accountId: accountId!, child: child)
41+
: child,
42+
));
43+
}
44+
}

test/widgets/text_test.dart

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ import 'package:checks/checks.dart';
22
import 'package:collection/collection.dart';
33
import 'package:flutter/material.dart';
44
import 'package:flutter_test/flutter_test.dart';
5-
import 'package:zulip/widgets/app.dart';
6-
import 'package:zulip/widgets/page.dart';
75
import 'package:zulip/widgets/text.dart';
86

97
import '../flutter_checks.dart';
108
import '../model/binding.dart';
9+
import 'test_app.dart';
1110

1211
// From trying the options on an iPhone 13 Pro running iOS 16.6.1:
1312
const kTextScaleFactors = <double>[
@@ -397,13 +396,9 @@ void main() {
397396
addTearDown(tester.platformDispatcher.clearLocaleTestValue);
398397
addTearDown(tester.platformDispatcher.clearLocalesTestValue);
399398

400-
await tester.pumpWidget(const ZulipApp());
401-
await tester.pump();
402-
403-
final navigator = await ZulipApp.navigator;
404-
navigator.push(MaterialWidgetRoute(page: Builder(builder: (context) =>
399+
await tester.pumpWidget(TestZulipApp(child: Builder(builder: (context) =>
405400
Text('123', style: TextStyle(textBaseline: localizedTextBaseline(context))))));
406-
await tester.pumpAndSettle();
401+
await tester.pump();
407402

408403
final TextStyle? style = tester.widget<Text>(find.text('123')).style;
409404
final actualTextBaseline = style!.textBaseline!;

test/widgets/theme_test.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import 'package:checks/checks.dart';
22
import 'package:flutter/material.dart';
33
import 'package:flutter/rendering.dart';
44
import 'package:flutter_test/flutter_test.dart';
5-
import 'package:zulip/widgets/app.dart';
6-
import 'package:zulip/widgets/page.dart';
75
import 'package:zulip/widgets/stream_colors.dart';
86
import 'package:zulip/widgets/text.dart';
97
import 'package:zulip/widgets/theme.dart';
108

119
import '../example_data.dart' as eg;
1210
import '../flutter_checks.dart';
1311
import '../model/binding.dart';
12+
import 'test_app.dart';
1413

1514
void main() {
1615
TestZulipBinding.ensureInitialized();
@@ -118,14 +117,9 @@ void main() {
118117
tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;
119118
addTearDown(tester.platformDispatcher.clearPlatformBrightnessTestValue);
120119

121-
await tester.pumpWidget(const ZulipApp());
120+
await tester.pumpWidget(const TestZulipApp());
122121
await tester.pump();
123122

124-
final navigator = await ZulipApp.navigator;
125-
navigator.push(MaterialWidgetRoute(page: Builder(builder: (context) =>
126-
const Placeholder())));
127-
await tester.pumpAndSettle();
128-
129123
final element = tester.element(find.byType(Placeholder));
130124
// Compares all the swatch's members; see [ColorSwatch]'s `operator ==`.
131125
check(colorSwatchFor(element, subscription))

0 commit comments

Comments
 (0)