Line data Source code
1 : /**
2 : * @file test_tui_resize.c
3 : * @brief PTY-04 — tg-tui SIGWINCH resize repaints screen.
4 : *
5 : * Verifies that tg-tui:
6 : * a) Starts at 80×24, shows "[dialogs]" hint.
7 : * b) After PTY resize to 60×20 + SIGWINCH, repaints and still shows
8 : * "[dialogs]".
9 : * c) After resize back to 80×24, repaints again.
10 : * d) Exits cleanly (exit code 0) when 'q' is pressed.
11 : *
12 : * Approach:
13 : * - Same stub-server setup as PTY-02 (pty_tel_stub seeds session.bin).
14 : * - pty_resize() issues TIOCSWINSZ on the master fd and delivers SIGWINCH
15 : * to the child, then pty_settle() waits for the repaint to settle.
16 : */
17 :
18 : #include "ptytest.h"
19 : #include "pty_assert.h"
20 : #include "pty_tel_stub.h"
21 :
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <unistd.h>
26 : #include <sys/stat.h>
27 :
28 : /* ── Test infrastructure ─────────────────────────────────────────────── */
29 :
30 : static int g_tests_run = 0;
31 : static int g_tests_failed = 0;
32 :
33 : #define RUN_TEST(fn) do { \
34 : printf(" running %s ...\n", #fn); \
35 : fn(); \
36 : } while(0)
37 :
38 : /** Absolute path to the binary under test (injected by CMake). */
39 : #ifndef TG_TUI_BINARY
40 : #define TG_TUI_BINARY "bin/tg-tui"
41 : #endif
42 :
43 : /** Common setup: tmp HOME, session seeded, stub running, env vars set. */
44 2 : static int setup_stub(PtyTelStub *stub) {
45 : char tmp[256];
46 2 : snprintf(tmp, sizeof(tmp), "/tmp/tg-cli-pty-resize-%d", (int)getpid());
47 :
48 : char cfg_dir[512];
49 2 : snprintf(cfg_dir, sizeof(cfg_dir), "%s/.config/tg-cli", tmp);
50 2 : mkdir(tmp, 0700);
51 : {
52 : char mid[512];
53 2 : snprintf(mid, sizeof(mid), "%s/.config", tmp);
54 2 : mkdir(mid, 0700);
55 : }
56 2 : mkdir(cfg_dir, 0700);
57 :
58 : char ini_path[640];
59 2 : snprintf(ini_path, sizeof(ini_path), "%s/config.ini", cfg_dir);
60 2 : FILE *f = fopen(ini_path, "w");
61 2 : if (!f) return 0;
62 2 : fprintf(f, "api_id=12345\napi_hash=deadbeefcafebabef00dbaadfeedc0de\n");
63 2 : fclose(f);
64 :
65 2 : setenv("HOME", tmp, 1);
66 :
67 2 : if (pty_tel_stub_start(stub) != 0) return 0;
68 :
69 2 : setenv("TG_CLI_DC_HOST", "127.0.0.1", 1);
70 : char port_str[16];
71 2 : snprintf(port_str, sizeof(port_str), "%d", stub->port);
72 2 : setenv("TG_CLI_DC_PORT", port_str, 1);
73 :
74 2 : setenv("TG_CLI_API_ID", "12345", 1);
75 2 : setenv("TG_CLI_API_HASH", "deadbeefcafebabef00dbaadfeedc0de", 1);
76 :
77 2 : return 1;
78 : }
79 :
80 : /* ── Tests ───────────────────────────────────────────────────────────── */
81 :
82 : /**
83 : * @brief PTY-04-a: resize 80×24 → 60×20 → 80×24; screen repaints each time.
84 : *
85 : * After each resize the test asserts:
86 : * - pty_get_size() reports the new dimensions.
87 : * - The screen still contains "[dialogs]" (TUI repainted without artefacts).
88 : */
89 2 : static void test_tui_resize_sigwinch(void) {
90 : PtyTelStub stub;
91 2 : g_tests_run++;
92 2 : if (!setup_stub(&stub)) {
93 0 : printf(" [FAIL] %s:%d: setup_stub failed\n", __FILE__, __LINE__);
94 0 : g_tests_failed++;
95 0 : return;
96 : }
97 :
98 2 : PtySession *s = pty_open(80, 24);
99 2 : g_tests_run++;
100 2 : if (!s) {
101 0 : printf(" [FAIL] %s:%d: pty_open failed\n", __FILE__, __LINE__);
102 0 : g_tests_failed++;
103 0 : pty_tel_stub_stop(&stub);
104 0 : return;
105 : }
106 :
107 2 : const char *argv[] = { TG_TUI_BINARY, "--tui", NULL };
108 2 : g_tests_run++;
109 2 : if (pty_run(s, argv) != 0) {
110 0 : printf(" [FAIL] %s:%d: pty_run failed\n", __FILE__, __LINE__);
111 0 : g_tests_failed++;
112 0 : pty_close(s);
113 0 : pty_tel_stub_stop(&stub);
114 0 : return;
115 : }
116 :
117 : /* Wait for the TUI to paint the initial layout. */
118 1 : ASSERT_WAIT_FOR(s, "[dialogs]", 5000);
119 :
120 : /* ── Resize to 60×20 ──────────────────────────────────────────────── */
121 1 : g_tests_run++;
122 1 : if (pty_resize(s, 60, 20) != 0) {
123 0 : printf(" [FAIL] %s:%d: pty_resize(60,20) failed\n",
124 : __FILE__, __LINE__);
125 0 : g_tests_failed++;
126 0 : pty_send_str(s, "q");
127 0 : pty_wait_exit(s, 3000);
128 0 : pty_close(s);
129 0 : pty_tel_stub_stop(&stub);
130 0 : return;
131 : }
132 :
133 : /* Wait for the repaint to settle. */
134 1 : pty_settle(s, 200);
135 :
136 : /* Assert new PTY dimensions. */
137 : {
138 1 : int cols = 0, rows = 0;
139 1 : pty_get_size(s, &cols, &rows);
140 1 : g_tests_run++;
141 1 : if (cols != 60 || rows != 20) {
142 0 : printf(" [FAIL] %s:%d: expected 60×20, got %d×%d\n",
143 : __FILE__, __LINE__, cols, rows);
144 0 : g_tests_failed++;
145 : }
146 : }
147 :
148 : /* Screen must still contain "[dialogs]" after repaint. */
149 1 : ASSERT_WAIT_FOR(s, "[dialogs]", 3000);
150 :
151 : /* ── Resize back to 80×24 ─────────────────────────────────────────── */
152 1 : g_tests_run++;
153 1 : if (pty_resize(s, 80, 24) != 0) {
154 0 : printf(" [FAIL] %s:%d: pty_resize(80,24) failed\n",
155 : __FILE__, __LINE__);
156 0 : g_tests_failed++;
157 0 : pty_send_str(s, "q");
158 0 : pty_wait_exit(s, 3000);
159 0 : pty_close(s);
160 0 : pty_tel_stub_stop(&stub);
161 0 : return;
162 : }
163 :
164 1 : pty_settle(s, 200);
165 :
166 : {
167 1 : int cols = 0, rows = 0;
168 1 : pty_get_size(s, &cols, &rows);
169 1 : g_tests_run++;
170 1 : if (cols != 80 || rows != 24) {
171 0 : printf(" [FAIL] %s:%d: expected 80×24 after second resize, got %d×%d\n",
172 : __FILE__, __LINE__, cols, rows);
173 0 : g_tests_failed++;
174 : }
175 : }
176 :
177 1 : ASSERT_WAIT_FOR(s, "[dialogs]", 3000);
178 :
179 : /* ── Clean exit ───────────────────────────────────────────────────── */
180 1 : pty_send_str(s, "q");
181 :
182 1 : int exit_code = pty_wait_exit(s, 5000);
183 1 : g_tests_run++;
184 1 : if (exit_code != 0) {
185 0 : printf(" [FAIL] %s:%d: expected exit code 0, got %d\n",
186 : __FILE__, __LINE__, exit_code);
187 0 : g_tests_failed++;
188 : }
189 :
190 1 : pty_close(s);
191 1 : pty_tel_stub_stop(&stub);
192 : }
193 :
194 : /* ── Entry point ─────────────────────────────────────────────────────── */
195 :
196 2 : int main(void) {
197 2 : printf("PTY-04 TUI SIGWINCH resize tests\n");
198 :
199 2 : RUN_TEST(test_tui_resize_sigwinch);
200 :
201 1 : printf("\n%d tests run, %d failed\n", g_tests_run, g_tests_failed);
202 1 : return g_tests_failed > 0 ? 1 : 0;
203 : }
|