nandi/frqpublic Fork 0
98d613511f9664af4d9779a07baf26ecb2feaeea
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

nim_layout_test.dart · 172 lines · 5.8 KBDart Blame HistoryRaw
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday1/// Every screen, laid out for real, at sizes that squeeze.
2///
3/// This is the test that was missing. `Cannot hit test a render box that has
4/// never been laid out` is what a failed layout looks like from the outside,
5/// and nothing automated ever laid the chat screen out — a GUI on Wayland
6/// cannot be clicked, so every check stopped at the room list while the
7/// biggest screen in the app went out unverified.
8///
9/// `tester.takeException()` is the whole point: a layout error is reported to
10/// FlutterError rather than thrown at the caller, so a test that only pumps
11/// and asserts on widgets passes while the screen is broken. These fail.
12///
13/// just test layout
Quality pass: reuse, dead weight, and two real costs 4dfc719 nandi yesterday14library;
15
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday16import 'package:flutter/material.dart';
17import 'package:flutter_test/flutter_test.dart';
18import 'package:frq_core/frq_core.dart' as core;
The last of the Clojure 284b59c nandi yesterday19import 'package:frq/nim_renderer.dart';
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday20
21/// Phone, small desktop, and a deliberately cramped one. The head row of the
22/// chat screen asks for more than 360 points has, which is why it wraps.
23const sizes = <String, Size>{
24 'phone': Size(360, 690),
25 'desktop': Size(1280, 800),
26 'cramped': Size(300, 500),
27};
28
29Future<void> layOut(WidgetTester tester, Size size) async {
30 await tester.binding.setSurfaceSize(size);
31 addTearDown(() => tester.binding.setSurfaceSize(null));
32 await tester.pumpWidget(const NimApp());
33 await tester.pump();
34}
35
36/// Nothing went to FlutterError while that frame was built.
37void expectLaidOut(WidgetTester tester, String what) {
38 final e = tester.takeException();
39 expect(e, isNull, reason: '$what reported: $e');
40}
41
42void main() {
43 // No offline guard needed: `demoUi` sets the state directly and none of
44 // these dispatch `connect`, so nothing here opens a socket.
45
46 group('the connect screen', () {
47 for (final entry in sizes.entries) {
48 testWidgets('lays out at ${entry.key}', (tester) async {
49 core.resetUi();
50 await layOut(tester, entry.value);
51 expectLaidOut(tester, 'connect at ${entry.key}');
52 });
53 }
54
55 testWidgets('lays out in every auth mode', (tester) async {
56 for (final mode in ['guest', 'bluesky', 'app-password']) {
57 core.resetUi();
58 core.dispatch('mode.$mode');
59 await layOut(tester, sizes['phone']!);
60 expectLaidOut(tester, 'connect in $mode');
61 }
62 });
63 });
64
65 group('the chat screen', () {
66 // The one that was never laid out by anything automated.
67 for (final entry in sizes.entries) {
68 testWidgets('lays out at ${entry.key}', (tester) async {
69 core.demoUi();
70 await layOut(tester, entry.value);
71 expectLaidOut(tester, 'chat at ${entry.key}');
72 });
73 }
74
75 testWidgets('renders the conversation it was given', (tester) async {
76 core.demoUi();
77 await layOut(tester, sizes['desktop']!);
78 expect(find.text('hello there'), findsOneWidget);
79 expect(find.text('#test'), findsWidgets);
80 expectLaidOut(tester, 'chat content');
81 });
82
83 testWidgets('lays out with the people panel up', (tester) async {
84 core.demoUi();
85 core.dispatch('users.toggle');
86 await layOut(tester, sizes['desktop']!);
87 expectLaidOut(tester, 'chat with people');
88 });
89
90 testWidgets('lays out with every compose banner showing', (tester) async {
91 core.demoUi();
92 core.dispatch('reply.to:2');
93 await layOut(tester, sizes['phone']!);
94 expectLaidOut(tester, 'chat replying');
95
96 core.demoUi();
97 core.dispatch('edit.start:7');
98 await layOut(tester, sizes['phone']!);
99 expectLaidOut(tester, 'chat editing');
100 });
101
Three buttons that did nothing now do what they say 98d6135 nandi yesterday102 testWidgets('lays out with the emoji picker open', (tester) async {
103 // 120 emoji in a grid under a message, on a phone.
104 core.demoUi();
105 core.dispatch('react.open:2');
106 await layOut(tester, sizes['phone']!);
107 expectLaidOut(tester, 'chat with the picker');
108 });
109
110 testWidgets('lays out with the picker showing a whole group',
111 (tester) async {
112 core.demoUi();
113 core.dispatch('react.open:2');
114 core.dispatch('emoji.group:Smileys & Emotion');
115 await layOut(tester, sizes['cramped']!);
116 expectLaidOut(tester, 'chat with a full picker');
117 });
118
119 testWidgets('lays out with the overview open', (tester) async {
120 core.demoUi();
121 core.dispatch('overview.toggle');
122 await layOut(tester, sizes['phone']!);
123 expectLaidOut(tester, 'chat with the overview');
124 });
125
126 testWidgets('lays out with the lightbox open', (tester) async {
127 core.demoUi();
128 core.dispatch('lightbox:https://example.com/a.png');
129 await layOut(tester, sizes['phone']!);
130 expectLaidOut(tester, 'chat with the lightbox');
131 });
132
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday133 testWidgets('lays out when scrolled off the present', (tester) async {
134 core.demoUi();
135 core.dispatch('jump.present');
136 await layOut(tester, sizes['phone']!);
137 expectLaidOut(tester, 'chat jumping');
138 });
139 });
140
141 group('the chats list', () {
142 for (final entry in sizes.entries) {
143 testWidgets('lays out at ${entry.key}', (tester) async {
144 core.demoUi();
145 core.dispatch('screen.chats');
146 await layOut(tester, entry.value);
147 expectLaidOut(tester, 'chats at ${entry.key}');
148 });
149 }
150
151 testWidgets('lays out with a search term in the box', (tester) async {
152 core.demoUi();
153 core.dispatch('screen.chats');
154 core.dispatch('search.change', 'te');
155 await layOut(tester, sizes['phone']!);
156 expectLaidOut(tester, 'chats searching');
157 });
158 });
159
160 group('discover and settings', () {
161 for (final screen in ['discover', 'settings']) {
162 for (final entry in sizes.entries) {
163 testWidgets('$screen lays out at ${entry.key}', (tester) async {
164 core.demoUi();
165 core.dispatch('screen.$screen');
166 await layOut(tester, entry.value);
167 expectLaidOut(tester, '$screen at ${entry.key}');
168 });
169 }
170 }
171 });
172}