1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'package:flutter/foundation.dart'; |
6 | import 'package:flutter/material.dart'; |
7 | import 'package:flutter_api_samples/material/tab_controller/tab_controller.1.dart' as example; |
8 | import 'package:flutter_test/flutter_test.dart'; |
9 | |
10 | void main() { |
11 | testWidgets('Verify first tab is selected by default' , (WidgetTester tester) async { |
12 | await tester.pumpWidget(const example.TabControllerExampleApp()); |
13 | |
14 | final Tab firstTab = example.TabControllerExampleApp.tabs.first; |
15 | |
16 | expect( |
17 | find.descendant(of: find.byType(TabBarView), matching: find.text(' ${firstTab.text} Tab' )), |
18 | findsOneWidget, |
19 | ); |
20 | }); |
21 | |
22 | testWidgets('Verify tabs can be changed' , (WidgetTester tester) async { |
23 | final List<String?> log = <String?>[]; |
24 | |
25 | final DebugPrintCallback originalDebugPrint = debugPrint; |
26 | debugPrint = (String? message, {int? wrapWidth}) { |
27 | log.add(message); |
28 | }; |
29 | |
30 | await tester.pumpWidget(const example.TabControllerExampleApp()); |
31 | |
32 | const List<Tab> tabs = example.TabControllerExampleApp.tabs; |
33 | final List<Tab> tabsTraversalOrder = <Tab>[]; |
34 | |
35 | // The traverse order is from the second tab from the start to the last, |
36 | // and then from the second tab from the end to the first. |
37 | tabsTraversalOrder.addAll(tabs.skip(1)); |
38 | tabsTraversalOrder.addAll(tabs.reversed.skip(1)); |
39 | |
40 | for (final Tab tab in tabsTraversalOrder) { |
41 | // Tap on the TabBar's tab to select it. |
42 | await tester.tap(find.descendant(of: find.byType(TabBar), matching: find.text(tab.text!))); |
43 | await tester.pumpAndSettle(); |
44 | |
45 | expect( |
46 | find.descendant(of: find.byType(TabBarView), matching: find.text(' ${tab.text} Tab' )), |
47 | findsOneWidget, |
48 | ); |
49 | |
50 | expect(log.length, equals(1)); |
51 | expect(log.last, equals('tab changed: ${tabs.indexOf(tab)}' )); |
52 | |
53 | log.clear(); |
54 | } |
55 | |
56 | debugPrint = originalDebugPrint; |
57 | }); |
58 | |
59 | testWidgets('DefaultTabControllerListener throws when no DefaultTabController above' , ( |
60 | WidgetTester tester, |
61 | ) async { |
62 | await tester.pumpWidget( |
63 | example.DefaultTabControllerListener(onTabChanged: (_) {}, child: const SizedBox.shrink()), |
64 | ); |
65 | |
66 | final dynamic exception = tester.takeException(); |
67 | expect(exception, isFlutterError); |
68 | |
69 | final FlutterError error = exception as FlutterError; |
70 | expect( |
71 | error.toStringDeep(), |
72 | equalsIgnoringHashCodes( |
73 | 'FlutterError\n' |
74 | ' No DefaultTabController for DefaultTabControllerListener.\n' |
75 | ' When creating a DefaultTabControllerListener, you must ensure\n' |
76 | ' that there is a DefaultTabController above the\n' |
77 | ' DefaultTabControllerListener.\n' , |
78 | ), |
79 | ); |
80 | }); |
81 | } |
82 | |