nandi/frqpublic Fork 0
463098d16892952fa740dea5029203611ddab1db
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 · 141 lines · 4.7 KBDart Blame HistoryRaw
Lay every screen out in a test, and fix what that found 36bdfc5 nandi 17h ago1/// 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 17h ago14library;
15
Lay every screen out in a test, and fix what that found 36bdfc5 nandi 17h ago16import 'package:flutter/material.dart';
17import 'package:flutter_test/flutter_test.dart';
18import 'package:frq_core/frq_core.dart' as core;
19import 'package:cljd_flutter/nim_renderer.dart';
20
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
102 testWidgets('lays out when scrolled off the present', (tester) async {
103 core.demoUi();
104 core.dispatch('jump.present');
105 await layOut(tester, sizes['phone']!);
106 expectLaidOut(tester, 'chat jumping');
107 });
108 });
109
110 group('the chats list', () {
111 for (final entry in sizes.entries) {
112 testWidgets('lays out at ${entry.key}', (tester) async {
113 core.demoUi();
114 core.dispatch('screen.chats');
115 await layOut(tester, entry.value);
116 expectLaidOut(tester, 'chats at ${entry.key}');
117 });
118 }
119
120 testWidgets('lays out with a search term in the box', (tester) async {
121 core.demoUi();
122 core.dispatch('screen.chats');
123 core.dispatch('search.change', 'te');
124 await layOut(tester, sizes['phone']!);
125 expectLaidOut(tester, 'chats searching');
126 });
127 });
128
129 group('discover and settings', () {
130 for (final screen in ['discover', 'settings']) {
131 for (final entry in sizes.entries) {
132 testWidgets('$screen lays out at ${entry.key}', (tester) async {
133 core.demoUi();
134 core.dispatch('screen.$screen');
135 await layOut(tester, entry.value);
136 expectLaidOut(tester, '$screen at ${entry.key}');
137 });
138 }
139 }
140 });
141}