Skip to content

Commit 4a762e2

Browse files
committed
Add text callback and test
1 parent a7ac05b commit 4a762e2

File tree

4 files changed

+330
-57
lines changed

4 files changed

+330
-57
lines changed

example/lib/pages/components/dialpad_example.dart

+81-13
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,94 @@ import 'package:flutter/material.dart';
22
import 'package:zeta_example/widgets.dart';
33
import 'package:zeta_flutter/zeta_flutter.dart';
44

5-
class DialPadExample extends StatelessWidget {
5+
const double _paddingSize = 40;
6+
7+
class DialPadExample extends StatefulWidget {
68
static const String name = 'DialPad';
79

810
const DialPadExample({super.key});
911

12+
@override
13+
State<DialPadExample> createState() => _DialPadExampleState();
14+
}
15+
16+
class _DialPadExampleState extends State<DialPadExample> {
17+
String number = '', text = '';
18+
1019
@override
1120
Widget build(BuildContext context) {
1221
return ExampleScaffold(
13-
name: name,
14-
child: Row(
15-
mainAxisAlignment: MainAxisAlignment.center,
16-
children: [
17-
Column(
18-
mainAxisAlignment: MainAxisAlignment.center,
19-
children: [
20-
ZetaDialPad(),
21-
],
22-
),
23-
],
24-
),
22+
name: DialPadExample.name,
23+
child: LayoutBuilder(builder: (context, constraints) {
24+
return Row(
25+
mainAxisAlignment: MainAxisAlignment.center,
26+
children: [
27+
SizedBox(
28+
width: constraints.maxWidth,
29+
child: Column(
30+
mainAxisAlignment: MainAxisAlignment.center,
31+
crossAxisAlignment: CrossAxisAlignment.center,
32+
children: [
33+
Row(
34+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
35+
children: [
36+
const SizedBox(width: _paddingSize),
37+
SizedBox(
38+
width: constraints.maxWidth - (_paddingSize * 2),
39+
child: Text(
40+
number,
41+
style: ZetaTextStyles.heading3,
42+
maxLines: 1,
43+
overflow: TextOverflow.ellipsis,
44+
textAlign: TextAlign.center,
45+
),
46+
),
47+
IconButton(
48+
icon: Icon(Icons.backspace),
49+
onPressed: () => number.length == 0
50+
? null
51+
: setState(
52+
() => number = number.substring(0, (number.length - 1)),
53+
),
54+
)
55+
],
56+
),
57+
Row(
58+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
59+
children: [
60+
const SizedBox(),
61+
Text(
62+
text,
63+
style: ZetaTextStyles.heading3,
64+
maxLines: 1,
65+
overflow: TextOverflow.ellipsis,
66+
textAlign: TextAlign.center,
67+
),
68+
IconButton(
69+
icon: Icon(Icons.backspace),
70+
onPressed: () => text.length == 0
71+
? null
72+
: setState(
73+
() => text = text.substring(0, text.length - 1),
74+
),
75+
)
76+
],
77+
),
78+
ZetaDialPad(
79+
onNumber: (value) => setState(() => number += value),
80+
onText: (value) => setState(() => text += value),
81+
),
82+
ZetaButton.primary(
83+
label: 'Clear',
84+
borderType: ZetaWidgetBorder.full,
85+
onPressed: () => setState(() => number = text = ''),
86+
)
87+
].divide(const SizedBox(height: ZetaSpacing.m)).toList(),
88+
),
89+
),
90+
],
91+
);
92+
}),
2593
);
2694
}
2795
}

example/test/dialpad_test.dart

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:zeta_flutter/zeta_flutter.dart';
4+
5+
import 'test_components.dart';
6+
7+
void main() {
8+
group('ZetaDialPad Tests', () {
9+
testWidgets('Initializes with correct parameters', (WidgetTester tester) async {
10+
String number = '', text = '';
11+
12+
Future<void> debounceWait() => tester.binding.delayed(const Duration(milliseconds: 500));
13+
14+
await tester.pumpWidget(
15+
TestWidget(
16+
screenSize: Size(1000, 1000),
17+
widget: ZetaDialPad(
18+
onNumber: (value) => number += value,
19+
onText: (value) => text += value,
20+
),
21+
),
22+
);
23+
final dialPadFinder = find.byType(ZetaDialPad);
24+
final buttonFinder = find.byType(ZetaDialPadButton);
25+
26+
final oneFinder = find.byWidgetPredicate((widget) => widget is ZetaDialPadButton && widget.primary == '1');
27+
final twoFinder = find.byWidgetPredicate((widget) => widget is ZetaDialPadButton && widget.primary == '2');
28+
final threeFinder = find.byWidgetPredicate((widget) => widget is ZetaDialPadButton && widget.primary == '3');
29+
final starFinder = find.byWidgetPredicate((widget) => widget is ZetaDialPadButton && widget.primary == '*');
30+
final hashFinder = find.byWidgetPredicate((widget) => widget is ZetaDialPadButton && widget.primary == '#');
31+
32+
final ZetaDialPad dialPad = tester.firstWidget(dialPadFinder);
33+
final List<Widget> dialPadButtons = tester.widgetList(buttonFinder).toList();
34+
35+
final ZetaDialPadButton one = tester.firstWidget(oneFinder);
36+
final ZetaDialPadButton two = tester.firstWidget(twoFinder);
37+
final ZetaDialPadButton three = tester.firstWidget(threeFinder);
38+
39+
/// Dial Pad built correctly.
40+
expect(dialPad.buttonsPerRow, 3);
41+
expect(dialPadButtons.length, 12);
42+
43+
/// Dial Pad buttons built correctly.
44+
expect(one.primary, '1');
45+
expect(one.secondary, '');
46+
expect(two.primary, '2');
47+
expect(two.secondary, 'ABC');
48+
expect(three.primary, '3');
49+
expect(three.secondary, 'DEF');
50+
51+
/// Tap button with only number.
52+
await tester.tap(oneFinder);
53+
await tester.pump();
54+
expect(number, '1');
55+
56+
/// Tap button with number and text.
57+
await tester.tap(twoFinder);
58+
await tester.pump();
59+
await debounceWait();
60+
expect(number, '12');
61+
expect(text, 'A');
62+
63+
/// Tap different button.
64+
await tester.tap(threeFinder);
65+
await tester.pump();
66+
await debounceWait();
67+
expect(number, '123');
68+
expect(text, 'AD');
69+
70+
/// Tap text button twice.
71+
await tester.tap(twoFinder);
72+
await tester.tap(twoFinder);
73+
await tester.pump();
74+
await debounceWait();
75+
expect(text, 'ADB');
76+
77+
/// Tap text button thrice.
78+
await tester.tap(twoFinder);
79+
await tester.tap(twoFinder);
80+
await tester.tap(twoFinder);
81+
await tester.pump();
82+
await debounceWait();
83+
expect(text, 'ADBC');
84+
85+
/// Tap different text buttons to ensure debounce is cancelled.
86+
await tester.tap(twoFinder);
87+
await tester.tap(threeFinder);
88+
await tester.tap(twoFinder);
89+
await tester.pump();
90+
await debounceWait();
91+
expect(text, 'ADBCADA');
92+
93+
/// Tap text button more times than there is options to ensure it loops around correctly.
94+
await tester.tap(threeFinder);
95+
await tester.tap(threeFinder);
96+
await tester.tap(threeFinder);
97+
await tester.tap(threeFinder);
98+
await tester.tap(threeFinder);
99+
await tester.tap(threeFinder);
100+
await tester.tap(oneFinder);
101+
await tester.pump();
102+
expect(text, 'ADBCADAF');
103+
number = '';
104+
105+
/// Tap buttons with symbols
106+
await tester.ensureVisible(starFinder);
107+
await tester.tap(starFinder);
108+
await tester.tap(hashFinder);
109+
await tester.pump();
110+
expect(number, '*#');
111+
112+
/// Allow all timers to end in text debounce
113+
await debounceWait();
114+
});
115+
});
116+
}

0 commit comments

Comments
 (0)