Mercurial
comparison third_party/libuv/test/test-tty-escape-sequence-processing.c @ 160:948de3f54cea
[ThirdParty] Added libuv
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 14 Jan 2026 19:39:52 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 159:05cf9467a1c3 | 160:948de3f54cea |
|---|---|
| 1 /* Copyright libuv project contributors. All rights reserved. | |
| 2 * | |
| 3 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 4 * of this software and associated documentation files (the "Software"), to | |
| 5 * deal in the Software without restriction, including without limitation the | |
| 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
| 7 * sell copies of the Software, and to permit persons to whom the Software is | |
| 8 * furnished to do so, subject to the following conditions: | |
| 9 * | |
| 10 * The above copyright notice and this permission notice shall be included in | |
| 11 * all copies or substantial portions of the Software. | |
| 12 * | |
| 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 19 * IN THE SOFTWARE. | |
| 20 */ | |
| 21 | |
| 22 #ifdef _WIN32 | |
| 23 | |
| 24 #include "task.h" | |
| 25 #include "uv.h" | |
| 26 | |
| 27 #include <io.h> | |
| 28 #include <windows.h> | |
| 29 | |
| 30 #include <errno.h> | |
| 31 #include <string.h> | |
| 32 | |
| 33 #define ESC "\033" | |
| 34 #define CSI ESC "[" | |
| 35 #define ST ESC "\\" | |
| 36 #define BEL "\x07" | |
| 37 #define HELLO "Hello" | |
| 38 | |
| 39 #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) | |
| 40 #define FOREGROUND_BLACK 0 | |
| 41 #define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN) | |
| 42 #define FOREGROUND_CYAN (FOREGROUND_GREEN | FOREGROUND_BLUE) | |
| 43 #define FOREGROUND_MAGENTA (FOREGROUND_RED | FOREGROUND_BLUE) | |
| 44 #define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE) | |
| 45 #define BACKGROUND_BLACK 0 | |
| 46 #define BACKGROUND_YELLOW (BACKGROUND_RED | BACKGROUND_GREEN) | |
| 47 #define BACKGROUND_CYAN (BACKGROUND_GREEN | BACKGROUND_BLUE) | |
| 48 #define BACKGROUND_MAGENTA (BACKGROUND_RED | BACKGROUND_BLUE) | |
| 49 | |
| 50 #define F_INTENSITY 1 | |
| 51 #define FB_INTENSITY 2 | |
| 52 #define B_INTENSITY 5 | |
| 53 #define INVERSE 7 | |
| 54 #define F_INTENSITY_OFF1 21 | |
| 55 #define F_INTENSITY_OFF2 22 | |
| 56 #define B_INTENSITY_OFF 25 | |
| 57 #define INVERSE_OFF 27 | |
| 58 #define F_BLACK 30 | |
| 59 #define F_RED 31 | |
| 60 #define F_GREEN 32 | |
| 61 #define F_YELLOW 33 | |
| 62 #define F_BLUE 34 | |
| 63 #define F_MAGENTA 35 | |
| 64 #define F_CYAN 36 | |
| 65 #define F_WHITE 37 | |
| 66 #define F_DEFAULT 39 | |
| 67 #define B_BLACK 40 | |
| 68 #define B_RED 41 | |
| 69 #define B_GREEN 42 | |
| 70 #define B_YELLOW 43 | |
| 71 #define B_BLUE 44 | |
| 72 #define B_MAGENTA 45 | |
| 73 #define B_CYAN 46 | |
| 74 #define B_WHITE 47 | |
| 75 #define B_DEFAULT 49 | |
| 76 | |
| 77 #define CURSOR_SIZE_SMALL 25 | |
| 78 #define CURSOR_SIZE_MIDDLE 50 | |
| 79 #define CURSOR_SIZE_LARGE 100 | |
| 80 | |
| 81 struct screen_info { | |
| 82 CONSOLE_SCREEN_BUFFER_INFO csbi; | |
| 83 int top; | |
| 84 int width; | |
| 85 int height; | |
| 86 int length; | |
| 87 WORD default_attr; | |
| 88 }; | |
| 89 | |
| 90 struct captured_screen { | |
| 91 char* text; | |
| 92 WORD* attributes; | |
| 93 struct screen_info si; | |
| 94 }; | |
| 95 | |
| 96 static void get_screen_info(uv_tty_t* tty_out, struct screen_info* si) { | |
| 97 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &(si->csbi))); | |
| 98 si->width = si->csbi.dwSize.X; | |
| 99 si->height = si->csbi.srWindow.Bottom - si->csbi.srWindow.Top + 1; | |
| 100 si->length = si->width * si->height; | |
| 101 si->default_attr = si->csbi.wAttributes; | |
| 102 si->top = si->csbi.srWindow.Top; | |
| 103 } | |
| 104 | |
| 105 static void set_cursor_position(uv_tty_t* tty_out, COORD pos) { | |
| 106 HANDLE handle = tty_out->handle; | |
| 107 CONSOLE_SCREEN_BUFFER_INFO info; | |
| 108 ASSERT(GetConsoleScreenBufferInfo(handle, &info)); | |
| 109 pos.X -= 1; | |
| 110 pos.Y += info.srWindow.Top - 1; | |
| 111 ASSERT(SetConsoleCursorPosition(handle, pos)); | |
| 112 } | |
| 113 | |
| 114 static void get_cursor_position(uv_tty_t* tty_out, COORD* cursor_position) { | |
| 115 HANDLE handle = tty_out->handle; | |
| 116 CONSOLE_SCREEN_BUFFER_INFO info; | |
| 117 ASSERT(GetConsoleScreenBufferInfo(handle, &info)); | |
| 118 cursor_position->X = info.dwCursorPosition.X + 1; | |
| 119 cursor_position->Y = info.dwCursorPosition.Y - info.srWindow.Top + 1; | |
| 120 } | |
| 121 | |
| 122 static void set_cursor_to_home(uv_tty_t* tty_out) { | |
| 123 COORD origin = {1, 1}; | |
| 124 set_cursor_position(tty_out, origin); | |
| 125 } | |
| 126 | |
| 127 static CONSOLE_CURSOR_INFO get_cursor_info(uv_tty_t* tty_out) { | |
| 128 HANDLE handle = tty_out->handle; | |
| 129 CONSOLE_CURSOR_INFO info; | |
| 130 ASSERT(GetConsoleCursorInfo(handle, &info)); | |
| 131 return info; | |
| 132 } | |
| 133 | |
| 134 static void set_cursor_size(uv_tty_t* tty_out, DWORD size) { | |
| 135 CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out); | |
| 136 info.dwSize = size; | |
| 137 ASSERT(SetConsoleCursorInfo(tty_out->handle, &info)); | |
| 138 } | |
| 139 | |
| 140 static DWORD get_cursor_size(uv_tty_t* tty_out) { | |
| 141 return get_cursor_info(tty_out).dwSize; | |
| 142 } | |
| 143 | |
| 144 static void set_cursor_visibility(uv_tty_t* tty_out, BOOL visible) { | |
| 145 CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out); | |
| 146 info.bVisible = visible; | |
| 147 ASSERT(SetConsoleCursorInfo(tty_out->handle, &info)); | |
| 148 } | |
| 149 | |
| 150 static BOOL get_cursor_visibility(uv_tty_t* tty_out) { | |
| 151 return get_cursor_info(tty_out).bVisible; | |
| 152 } | |
| 153 | |
| 154 static BOOL is_scrolling(uv_tty_t* tty_out, struct screen_info si) { | |
| 155 CONSOLE_SCREEN_BUFFER_INFO info; | |
| 156 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); | |
| 157 return info.srWindow.Top != si.top; | |
| 158 } | |
| 159 | |
| 160 static void write_console(uv_tty_t* tty_out, char* src) { | |
| 161 int r; | |
| 162 uv_buf_t buf; | |
| 163 | |
| 164 buf.base = src; | |
| 165 buf.len = strlen(buf.base); | |
| 166 | |
| 167 r = uv_try_write((uv_stream_t*) tty_out, &buf, 1); | |
| 168 ASSERT_GE(r, 0); | |
| 169 ASSERT_EQ((unsigned int) r, buf.len); | |
| 170 } | |
| 171 | |
| 172 static void setup_screen(uv_tty_t* tty_out) { | |
| 173 DWORD length, number_of_written; | |
| 174 COORD origin; | |
| 175 CONSOLE_SCREEN_BUFFER_INFO info; | |
| 176 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); | |
| 177 length = info.dwSize.X * (info.srWindow.Bottom - info.srWindow.Top + 1); | |
| 178 origin.X = 0; | |
| 179 origin.Y = info.srWindow.Top; | |
| 180 ASSERT(FillConsoleOutputCharacter( | |
| 181 tty_out->handle, '.', length, origin, &number_of_written)); | |
| 182 ASSERT_EQ(length, number_of_written); | |
| 183 } | |
| 184 | |
| 185 static void clear_screen(uv_tty_t* tty_out, struct screen_info* si) { | |
| 186 DWORD length, number_of_written; | |
| 187 COORD origin; | |
| 188 CONSOLE_SCREEN_BUFFER_INFO info; | |
| 189 ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); | |
| 190 length = (info.srWindow.Bottom - info.srWindow.Top + 1) * info.dwSize.X - 1; | |
| 191 origin.X = 0; | |
| 192 origin.Y = info.srWindow.Top; | |
| 193 FillConsoleOutputCharacterA( | |
| 194 tty_out->handle, ' ', length, origin, &number_of_written); | |
| 195 ASSERT_EQ(length, number_of_written); | |
| 196 FillConsoleOutputAttribute( | |
| 197 tty_out->handle, si->default_attr, length, origin, &number_of_written); | |
| 198 ASSERT_EQ(length, number_of_written); | |
| 199 } | |
| 200 | |
| 201 static void free_screen(struct captured_screen* cs) { | |
| 202 free(cs->text); | |
| 203 cs->text = NULL; | |
| 204 free(cs->attributes); | |
| 205 cs->attributes = NULL; | |
| 206 } | |
| 207 | |
| 208 static void capture_screen(uv_tty_t* tty_out, struct captured_screen* cs) { | |
| 209 DWORD length; | |
| 210 COORD origin; | |
| 211 get_screen_info(tty_out, &(cs->si)); | |
| 212 origin.X = 0; | |
| 213 origin.Y = cs->si.csbi.srWindow.Top; | |
| 214 cs->text = malloc(cs->si.length * sizeof(*cs->text)); | |
| 215 ASSERT_NOT_NULL(cs->text); | |
| 216 cs->attributes = (WORD*) malloc(cs->si.length * sizeof(*cs->attributes)); | |
| 217 ASSERT_NOT_NULL(cs->attributes); | |
| 218 ASSERT(ReadConsoleOutputCharacter( | |
| 219 tty_out->handle, cs->text, cs->si.length, origin, &length)); | |
| 220 ASSERT_EQ((unsigned int) cs->si.length, length); | |
| 221 ASSERT(ReadConsoleOutputAttribute( | |
| 222 tty_out->handle, cs->attributes, cs->si.length, origin, &length)); | |
| 223 ASSERT_EQ((unsigned int) cs->si.length, length); | |
| 224 } | |
| 225 | |
| 226 static void make_expect_screen_erase(struct captured_screen* cs, | |
| 227 COORD cursor_position, | |
| 228 int dir, | |
| 229 BOOL entire_screen) { | |
| 230 /* beginning of line */ | |
| 231 char* start; | |
| 232 char* end; | |
| 233 start = cs->text + cs->si.width * (cursor_position.Y - 1); | |
| 234 if (dir == 0) { | |
| 235 if (entire_screen) { | |
| 236 /* erase to end of screen */ | |
| 237 end = cs->text + cs->si.length; | |
| 238 } else { | |
| 239 /* erase to end of line */ | |
| 240 end = start + cs->si.width; | |
| 241 } | |
| 242 /* erase from postition of cursor */ | |
| 243 start += cursor_position.X - 1; | |
| 244 } else if (dir == 1) { | |
| 245 /* erase to position of cursor */ | |
| 246 end = start + cursor_position.X; | |
| 247 if (entire_screen) { | |
| 248 /* erase form beginning of screen */ | |
| 249 start = cs->text; | |
| 250 } | |
| 251 } else if (dir == 2) { | |
| 252 if (entire_screen) { | |
| 253 /* erase form beginning of screen */ | |
| 254 start = cs->text; | |
| 255 /* erase to end of screen */ | |
| 256 end = cs->text + cs->si.length; | |
| 257 } else { | |
| 258 /* erase to end of line */ | |
| 259 end = start + cs->si.width; | |
| 260 } | |
| 261 } else { | |
| 262 ASSERT(FALSE); | |
| 263 } | |
| 264 ASSERT_PTR_LT(start, end); | |
| 265 ASSERT_LE(end - cs->text, cs->si.length); | |
| 266 for (; start < end; start++) { | |
| 267 *start = ' '; | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 static void make_expect_screen_write(struct captured_screen* cs, | |
| 272 COORD cursor_position, | |
| 273 const char* text) { | |
| 274 /* position of cursor */ | |
| 275 char* start; | |
| 276 start = cs->text + cs->si.width * (cursor_position.Y - 1) + | |
| 277 cursor_position.X - 1; | |
| 278 size_t length = strlen(text); | |
| 279 size_t remain_length = cs->si.length - (cs->text - start); | |
| 280 length = length > remain_length ? remain_length : length; | |
| 281 memcpy(start, text, length); | |
| 282 } | |
| 283 | |
| 284 static void make_expect_screen_set_attr(struct captured_screen* cs, | |
| 285 COORD cursor_position, | |
| 286 size_t length, | |
| 287 WORD attr) { | |
| 288 WORD* start; | |
| 289 start = cs->attributes + cs->si.width * (cursor_position.Y - 1) + | |
| 290 cursor_position.X - 1; | |
| 291 size_t remain_length = cs->si.length - (cs->attributes - start); | |
| 292 length = length > remain_length ? remain_length : length; | |
| 293 while (length) { | |
| 294 *start = attr; | |
| 295 start++; | |
| 296 length--; | |
| 297 } | |
| 298 } | |
| 299 | |
| 300 static BOOL compare_screen(uv_tty_t* tty_out, | |
| 301 struct captured_screen* actual, | |
| 302 struct captured_screen* expect) { | |
| 303 int line, col; | |
| 304 BOOL result = TRUE; | |
| 305 int current = 0; | |
| 306 ASSERT(actual->text); | |
| 307 ASSERT(actual->attributes); | |
| 308 ASSERT(expect->text); | |
| 309 ASSERT(expect->attributes); | |
| 310 if (actual->si.length != expect->si.length) { | |
| 311 return FALSE; | |
| 312 } | |
| 313 if (actual->si.width != expect->si.width) { | |
| 314 return FALSE; | |
| 315 } | |
| 316 if (actual->si.height != expect->si.height) { | |
| 317 return FALSE; | |
| 318 } | |
| 319 while (current < actual->si.length) { | |
| 320 if (*(actual->text + current) != *(expect->text + current)) { | |
| 321 line = current / actual->si.width + 1; | |
| 322 col = current - actual->si.width * (line - 1) + 1; | |
| 323 fprintf(stderr, | |
| 324 "line:%d col:%d expected character '%c' but found '%c'\n", | |
| 325 line, | |
| 326 col, | |
| 327 *(expect->text + current), | |
| 328 *(actual->text + current)); | |
| 329 result = FALSE; | |
| 330 } | |
| 331 if (*(actual->attributes + current) != *(expect->attributes + current)) { | |
| 332 line = current / actual->si.width + 1; | |
| 333 col = current - actual->si.width * (line - 1) + 1; | |
| 334 fprintf(stderr, | |
| 335 "line:%d col:%d expected attributes '%u' but found '%u'\n", | |
| 336 line, | |
| 337 col, | |
| 338 *(expect->attributes + current), | |
| 339 *(actual->attributes + current)); | |
| 340 result = FALSE; | |
| 341 } | |
| 342 current++; | |
| 343 } | |
| 344 clear_screen(tty_out, &expect->si); | |
| 345 free_screen(expect); | |
| 346 free_screen(actual); | |
| 347 return result; | |
| 348 } | |
| 349 | |
| 350 static void initialize_tty(uv_tty_t* tty_out) { | |
| 351 int r; | |
| 352 int ttyout_fd; | |
| 353 /* Make sure we have an FD that refers to a tty */ | |
| 354 HANDLE handle; | |
| 355 | |
| 356 uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED); | |
| 357 | |
| 358 handle = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | |
| 359 FILE_SHARE_READ | FILE_SHARE_WRITE, | |
| 360 NULL, | |
| 361 CONSOLE_TEXTMODE_BUFFER, | |
| 362 NULL); | |
| 363 ASSERT_PTR_NE(handle, INVALID_HANDLE_VALUE); | |
| 364 | |
| 365 ttyout_fd = _open_osfhandle((intptr_t) handle, 0); | |
| 366 ASSERT_GE(ttyout_fd, 0); | |
| 367 ASSERT_EQ(UV_TTY, uv_guess_handle(ttyout_fd)); | |
| 368 r = uv_tty_init(uv_default_loop(), tty_out, ttyout_fd, 0); /* Writable. */ | |
| 369 ASSERT_OK(r); | |
| 370 } | |
| 371 | |
| 372 static void terminate_tty(uv_tty_t* tty_out) { | |
| 373 set_cursor_to_home(tty_out); | |
| 374 uv_close((uv_handle_t*) tty_out, NULL); | |
| 375 } | |
| 376 | |
| 377 TEST_IMPL(tty_cursor_up) { | |
| 378 uv_tty_t tty_out; | |
| 379 uv_loop_t* loop; | |
| 380 COORD cursor_pos, cursor_pos_old; | |
| 381 char buffer[1024]; | |
| 382 struct screen_info si; | |
| 383 | |
| 384 loop = uv_default_loop(); | |
| 385 | |
| 386 initialize_tty(&tty_out); | |
| 387 get_screen_info(&tty_out, &si); | |
| 388 | |
| 389 cursor_pos_old.X = si.width / 2; | |
| 390 cursor_pos_old.Y = si.height / 2; | |
| 391 set_cursor_position(&tty_out, cursor_pos_old); | |
| 392 | |
| 393 /* cursor up one times if omitted arguments */ | |
| 394 snprintf(buffer, sizeof(buffer), "%sA", CSI); | |
| 395 write_console(&tty_out, buffer); | |
| 396 get_cursor_position(&tty_out, &cursor_pos); | |
| 397 ASSERT_EQ(cursor_pos_old.Y - 1, cursor_pos.Y); | |
| 398 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 399 | |
| 400 /* cursor up nth times */ | |
| 401 cursor_pos_old = cursor_pos; | |
| 402 snprintf(buffer, sizeof(buffer), "%s%dA", CSI, si.height / 4); | |
| 403 write_console(&tty_out, buffer); | |
| 404 get_cursor_position(&tty_out, &cursor_pos); | |
| 405 ASSERT_EQ(cursor_pos_old.Y - si.height / 4, cursor_pos.Y); | |
| 406 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 407 | |
| 408 /* cursor up from Window top does nothing */ | |
| 409 cursor_pos_old.X = 1; | |
| 410 cursor_pos_old.Y = 1; | |
| 411 set_cursor_position(&tty_out, cursor_pos_old); | |
| 412 snprintf(buffer, sizeof(buffer), "%sA", CSI); | |
| 413 write_console(&tty_out, buffer); | |
| 414 get_cursor_position(&tty_out, &cursor_pos); | |
| 415 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 416 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 417 ASSERT(!is_scrolling(&tty_out, si)); | |
| 418 | |
| 419 terminate_tty(&tty_out); | |
| 420 | |
| 421 uv_run(loop, UV_RUN_DEFAULT); | |
| 422 | |
| 423 MAKE_VALGRIND_HAPPY(loop); | |
| 424 return 0; | |
| 425 } | |
| 426 | |
| 427 | |
| 428 TEST_IMPL(tty_cursor_down) { | |
| 429 uv_tty_t tty_out; | |
| 430 uv_loop_t* loop; | |
| 431 COORD cursor_pos, cursor_pos_old; | |
| 432 char buffer[1024]; | |
| 433 struct screen_info si; | |
| 434 | |
| 435 loop = uv_default_loop(); | |
| 436 | |
| 437 initialize_tty(&tty_out); | |
| 438 get_screen_info(&tty_out, &si); | |
| 439 | |
| 440 cursor_pos_old.X = si.width / 2; | |
| 441 cursor_pos_old.Y = si.height / 2; | |
| 442 set_cursor_position(&tty_out, cursor_pos_old); | |
| 443 | |
| 444 /* cursor down one times if omitted arguments */ | |
| 445 snprintf(buffer, sizeof(buffer), "%sB", CSI); | |
| 446 write_console(&tty_out, buffer); | |
| 447 get_cursor_position(&tty_out, &cursor_pos); | |
| 448 ASSERT_EQ(cursor_pos_old.Y + 1, cursor_pos.Y); | |
| 449 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 450 | |
| 451 /* cursor down nth times */ | |
| 452 cursor_pos_old = cursor_pos; | |
| 453 snprintf(buffer, sizeof(buffer), "%s%dB", CSI, si.height / 4); | |
| 454 write_console(&tty_out, buffer); | |
| 455 get_cursor_position(&tty_out, &cursor_pos); | |
| 456 ASSERT_EQ(cursor_pos_old.Y + si.height / 4, cursor_pos.Y); | |
| 457 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 458 | |
| 459 /* cursor down from bottom line does nothing */ | |
| 460 cursor_pos_old.X = si.width / 2; | |
| 461 cursor_pos_old.Y = si.height; | |
| 462 set_cursor_position(&tty_out, cursor_pos_old); | |
| 463 snprintf(buffer, sizeof(buffer), "%sB", CSI); | |
| 464 write_console(&tty_out, buffer); | |
| 465 get_cursor_position(&tty_out, &cursor_pos); | |
| 466 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 467 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 468 ASSERT(!is_scrolling(&tty_out, si)); | |
| 469 | |
| 470 terminate_tty(&tty_out); | |
| 471 | |
| 472 uv_run(loop, UV_RUN_DEFAULT); | |
| 473 | |
| 474 MAKE_VALGRIND_HAPPY(loop); | |
| 475 return 0; | |
| 476 } | |
| 477 | |
| 478 | |
| 479 TEST_IMPL(tty_cursor_forward) { | |
| 480 uv_tty_t tty_out; | |
| 481 uv_loop_t* loop; | |
| 482 COORD cursor_pos, cursor_pos_old; | |
| 483 char buffer[1024]; | |
| 484 struct screen_info si; | |
| 485 | |
| 486 loop = uv_default_loop(); | |
| 487 | |
| 488 initialize_tty(&tty_out); | |
| 489 get_screen_info(&tty_out, &si); | |
| 490 | |
| 491 cursor_pos_old.X = si.width / 2; | |
| 492 cursor_pos_old.Y = si.height / 2; | |
| 493 set_cursor_position(&tty_out, cursor_pos_old); | |
| 494 | |
| 495 /* cursor forward one times if omitted arguments */ | |
| 496 snprintf(buffer, sizeof(buffer), "%sC", CSI); | |
| 497 write_console(&tty_out, buffer); | |
| 498 get_cursor_position(&tty_out, &cursor_pos); | |
| 499 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 500 ASSERT_EQ(cursor_pos_old.X + 1, cursor_pos.X); | |
| 501 | |
| 502 /* cursor forward nth times */ | |
| 503 cursor_pos_old = cursor_pos; | |
| 504 snprintf(buffer, sizeof(buffer), "%s%dC", CSI, si.width / 4); | |
| 505 write_console(&tty_out, buffer); | |
| 506 get_cursor_position(&tty_out, &cursor_pos); | |
| 507 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 508 ASSERT_EQ(cursor_pos_old.X + si.width / 4, cursor_pos.X); | |
| 509 | |
| 510 /* cursor forward from end of line does nothing*/ | |
| 511 cursor_pos_old.X = si.width; | |
| 512 cursor_pos_old.Y = si.height / 2; | |
| 513 set_cursor_position(&tty_out, cursor_pos_old); | |
| 514 snprintf(buffer, sizeof(buffer), "%sC", CSI); | |
| 515 write_console(&tty_out, buffer); | |
| 516 get_cursor_position(&tty_out, &cursor_pos); | |
| 517 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 518 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 519 | |
| 520 /* cursor forward from end of screen does nothing */ | |
| 521 cursor_pos_old.X = si.width; | |
| 522 cursor_pos_old.Y = si.height; | |
| 523 set_cursor_position(&tty_out, cursor_pos_old); | |
| 524 snprintf(buffer, sizeof(buffer), "%sC", CSI); | |
| 525 write_console(&tty_out, buffer); | |
| 526 get_cursor_position(&tty_out, &cursor_pos); | |
| 527 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 528 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 529 ASSERT(!is_scrolling(&tty_out, si)); | |
| 530 | |
| 531 terminate_tty(&tty_out); | |
| 532 | |
| 533 uv_run(loop, UV_RUN_DEFAULT); | |
| 534 | |
| 535 MAKE_VALGRIND_HAPPY(loop); | |
| 536 return 0; | |
| 537 } | |
| 538 | |
| 539 | |
| 540 TEST_IMPL(tty_cursor_back) { | |
| 541 uv_tty_t tty_out; | |
| 542 uv_loop_t* loop; | |
| 543 COORD cursor_pos, cursor_pos_old; | |
| 544 char buffer[1024]; | |
| 545 struct screen_info si; | |
| 546 | |
| 547 loop = uv_default_loop(); | |
| 548 | |
| 549 initialize_tty(&tty_out); | |
| 550 get_screen_info(&tty_out, &si); | |
| 551 | |
| 552 cursor_pos_old.X = si.width / 2; | |
| 553 cursor_pos_old.Y = si.height / 2; | |
| 554 set_cursor_position(&tty_out, cursor_pos_old); | |
| 555 | |
| 556 /* cursor back one times if omitted arguments */ | |
| 557 snprintf(buffer, sizeof(buffer), "%sD", CSI); | |
| 558 write_console(&tty_out, buffer); | |
| 559 get_cursor_position(&tty_out, &cursor_pos); | |
| 560 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 561 ASSERT_EQ(cursor_pos_old.X - 1, cursor_pos.X); | |
| 562 | |
| 563 /* cursor back nth times */ | |
| 564 cursor_pos_old = cursor_pos; | |
| 565 snprintf(buffer, sizeof(buffer), "%s%dD", CSI, si.width / 4); | |
| 566 write_console(&tty_out, buffer); | |
| 567 get_cursor_position(&tty_out, &cursor_pos); | |
| 568 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 569 ASSERT_EQ(cursor_pos_old.X - si.width / 4, cursor_pos.X); | |
| 570 | |
| 571 /* cursor back from beginning of line does nothing */ | |
| 572 cursor_pos_old.X = 1; | |
| 573 cursor_pos_old.Y = si.height / 2; | |
| 574 set_cursor_position(&tty_out, cursor_pos_old); | |
| 575 snprintf(buffer, sizeof(buffer), "%sD", CSI); | |
| 576 write_console(&tty_out, buffer); | |
| 577 get_cursor_position(&tty_out, &cursor_pos); | |
| 578 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 579 ASSERT_EQ(cursor_pos_old.X, cursor_pos.X); | |
| 580 | |
| 581 /* cursor back from top of screen does nothing */ | |
| 582 cursor_pos_old.X = 1; | |
| 583 cursor_pos_old.Y = 1; | |
| 584 set_cursor_position(&tty_out, cursor_pos_old); | |
| 585 snprintf(buffer, sizeof(buffer), "%sD", CSI); | |
| 586 write_console(&tty_out, buffer); | |
| 587 get_cursor_position(&tty_out, &cursor_pos); | |
| 588 ASSERT_EQ(1, cursor_pos.Y); | |
| 589 ASSERT_EQ(1, cursor_pos.X); | |
| 590 ASSERT(!is_scrolling(&tty_out, si)); | |
| 591 | |
| 592 terminate_tty(&tty_out); | |
| 593 | |
| 594 uv_run(loop, UV_RUN_DEFAULT); | |
| 595 | |
| 596 MAKE_VALGRIND_HAPPY(loop); | |
| 597 return 0; | |
| 598 } | |
| 599 | |
| 600 | |
| 601 TEST_IMPL(tty_cursor_next_line) { | |
| 602 uv_tty_t tty_out; | |
| 603 uv_loop_t* loop; | |
| 604 COORD cursor_pos, cursor_pos_old; | |
| 605 char buffer[1024]; | |
| 606 struct screen_info si; | |
| 607 | |
| 608 loop = uv_default_loop(); | |
| 609 | |
| 610 initialize_tty(&tty_out); | |
| 611 get_screen_info(&tty_out, &si); | |
| 612 | |
| 613 cursor_pos_old.X = si.width / 2; | |
| 614 cursor_pos_old.Y = si.height / 2; | |
| 615 set_cursor_position(&tty_out, cursor_pos_old); | |
| 616 | |
| 617 /* cursor next line one times if omitted arguments */ | |
| 618 snprintf(buffer, sizeof(buffer), "%sE", CSI); | |
| 619 write_console(&tty_out, buffer); | |
| 620 get_cursor_position(&tty_out, &cursor_pos); | |
| 621 ASSERT_EQ(cursor_pos_old.Y + 1, cursor_pos.Y); | |
| 622 ASSERT_EQ(1, cursor_pos.X); | |
| 623 | |
| 624 /* cursor next line nth times */ | |
| 625 cursor_pos_old = cursor_pos; | |
| 626 snprintf(buffer, sizeof(buffer), "%s%dE", CSI, si.height / 4); | |
| 627 write_console(&tty_out, buffer); | |
| 628 get_cursor_position(&tty_out, &cursor_pos); | |
| 629 ASSERT_EQ(cursor_pos_old.Y + si.height / 4, cursor_pos.Y); | |
| 630 ASSERT_EQ(1, cursor_pos.X); | |
| 631 | |
| 632 /* cursor next line from buttom row moves beginning of line */ | |
| 633 cursor_pos_old.X = si.width / 2; | |
| 634 cursor_pos_old.Y = si.height; | |
| 635 set_cursor_position(&tty_out, cursor_pos_old); | |
| 636 snprintf(buffer, sizeof(buffer), "%sE", CSI); | |
| 637 write_console(&tty_out, buffer); | |
| 638 get_cursor_position(&tty_out, &cursor_pos); | |
| 639 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 640 ASSERT_EQ(1, cursor_pos.X); | |
| 641 ASSERT(!is_scrolling(&tty_out, si)); | |
| 642 | |
| 643 terminate_tty(&tty_out); | |
| 644 | |
| 645 uv_run(loop, UV_RUN_DEFAULT); | |
| 646 | |
| 647 MAKE_VALGRIND_HAPPY(loop); | |
| 648 return 0; | |
| 649 } | |
| 650 | |
| 651 | |
| 652 TEST_IMPL(tty_cursor_previous_line) { | |
| 653 uv_tty_t tty_out; | |
| 654 uv_loop_t* loop; | |
| 655 COORD cursor_pos, cursor_pos_old; | |
| 656 char buffer[1024]; | |
| 657 struct screen_info si; | |
| 658 | |
| 659 loop = uv_default_loop(); | |
| 660 | |
| 661 initialize_tty(&tty_out); | |
| 662 get_screen_info(&tty_out, &si); | |
| 663 | |
| 664 cursor_pos_old.X = si.width / 2; | |
| 665 cursor_pos_old.Y = si.height / 2; | |
| 666 set_cursor_position(&tty_out, cursor_pos_old); | |
| 667 | |
| 668 /* cursor previous line one times if omitted arguments */ | |
| 669 snprintf(buffer, sizeof(buffer), "%sF", CSI); | |
| 670 write_console(&tty_out, buffer); | |
| 671 get_cursor_position(&tty_out, &cursor_pos); | |
| 672 ASSERT_EQ(cursor_pos_old.Y - 1, cursor_pos.Y); | |
| 673 ASSERT_EQ(1, cursor_pos.X); | |
| 674 | |
| 675 /* cursor previous line nth times */ | |
| 676 cursor_pos_old = cursor_pos; | |
| 677 snprintf(buffer, sizeof(buffer), "%s%dF", CSI, si.height / 4); | |
| 678 write_console(&tty_out, buffer); | |
| 679 get_cursor_position(&tty_out, &cursor_pos); | |
| 680 ASSERT_EQ(cursor_pos_old.Y - si.height / 4, cursor_pos.Y); | |
| 681 ASSERT_EQ(1, cursor_pos.X); | |
| 682 | |
| 683 /* cursor previous line from top of screen does nothing */ | |
| 684 cursor_pos_old.X = 1; | |
| 685 cursor_pos_old.Y = 1; | |
| 686 set_cursor_position(&tty_out, cursor_pos_old); | |
| 687 snprintf(buffer, sizeof(buffer), "%sD", CSI); | |
| 688 write_console(&tty_out, buffer); | |
| 689 get_cursor_position(&tty_out, &cursor_pos); | |
| 690 ASSERT_EQ(1, cursor_pos.Y); | |
| 691 ASSERT_EQ(1, cursor_pos.X); | |
| 692 ASSERT(!is_scrolling(&tty_out, si)); | |
| 693 | |
| 694 terminate_tty(&tty_out); | |
| 695 | |
| 696 uv_run(loop, UV_RUN_DEFAULT); | |
| 697 | |
| 698 MAKE_VALGRIND_HAPPY(loop); | |
| 699 return 0; | |
| 700 } | |
| 701 | |
| 702 | |
| 703 TEST_IMPL(tty_cursor_horizontal_move_absolute) { | |
| 704 uv_tty_t tty_out; | |
| 705 uv_loop_t* loop; | |
| 706 COORD cursor_pos, cursor_pos_old; | |
| 707 char buffer[1024]; | |
| 708 struct screen_info si; | |
| 709 | |
| 710 loop = uv_default_loop(); | |
| 711 | |
| 712 initialize_tty(&tty_out); | |
| 713 get_screen_info(&tty_out, &si); | |
| 714 | |
| 715 cursor_pos_old.X = si.width / 2; | |
| 716 cursor_pos_old.Y = si.height / 2; | |
| 717 set_cursor_position(&tty_out, cursor_pos_old); | |
| 718 | |
| 719 /* Move to beginning of line if omitted argument */ | |
| 720 snprintf(buffer, sizeof(buffer), "%sG", CSI); | |
| 721 write_console(&tty_out, buffer); | |
| 722 get_cursor_position(&tty_out, &cursor_pos); | |
| 723 ASSERT_EQ(1, cursor_pos.X); | |
| 724 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 725 | |
| 726 /* Move cursor to nth character */ | |
| 727 snprintf(buffer, sizeof(buffer), "%s%dG", CSI, si.width / 4); | |
| 728 write_console(&tty_out, buffer); | |
| 729 get_cursor_position(&tty_out, &cursor_pos); | |
| 730 ASSERT_EQ(si.width / 4, cursor_pos.X); | |
| 731 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 732 | |
| 733 /* Moving out of screen will fit within screen */ | |
| 734 snprintf(buffer, sizeof(buffer), "%s%dG", CSI, si.width + 1); | |
| 735 write_console(&tty_out, buffer); | |
| 736 get_cursor_position(&tty_out, &cursor_pos); | |
| 737 ASSERT_EQ(si.width, cursor_pos.X); | |
| 738 ASSERT_EQ(cursor_pos_old.Y, cursor_pos.Y); | |
| 739 | |
| 740 terminate_tty(&tty_out); | |
| 741 | |
| 742 uv_run(loop, UV_RUN_DEFAULT); | |
| 743 | |
| 744 MAKE_VALGRIND_HAPPY(loop); | |
| 745 return 0; | |
| 746 } | |
| 747 | |
| 748 | |
| 749 TEST_IMPL(tty_cursor_move_absolute) { | |
| 750 uv_tty_t tty_out; | |
| 751 uv_loop_t* loop; | |
| 752 COORD cursor_pos; | |
| 753 char buffer[1024]; | |
| 754 struct screen_info si; | |
| 755 | |
| 756 loop = uv_default_loop(); | |
| 757 | |
| 758 initialize_tty(&tty_out); | |
| 759 get_screen_info(&tty_out, &si); | |
| 760 | |
| 761 cursor_pos.X = si.width / 2; | |
| 762 cursor_pos.Y = si.height / 2; | |
| 763 set_cursor_position(&tty_out, cursor_pos); | |
| 764 | |
| 765 /* Move the cursor to home if omitted arguments */ | |
| 766 snprintf(buffer, sizeof(buffer), "%sH", CSI); | |
| 767 write_console(&tty_out, buffer); | |
| 768 get_cursor_position(&tty_out, &cursor_pos); | |
| 769 ASSERT_EQ(1, cursor_pos.X); | |
| 770 ASSERT_EQ(1, cursor_pos.Y); | |
| 771 | |
| 772 /* Move the cursor to the middle of the screen */ | |
| 773 snprintf( | |
| 774 buffer, sizeof(buffer), "%s%d;%df", CSI, si.height / 2, si.width / 2); | |
| 775 write_console(&tty_out, buffer); | |
| 776 get_cursor_position(&tty_out, &cursor_pos); | |
| 777 ASSERT_EQ(si.width / 2, cursor_pos.X); | |
| 778 ASSERT_EQ(si.height / 2, cursor_pos.Y); | |
| 779 | |
| 780 /* Moving out of screen will fit within screen */ | |
| 781 snprintf( | |
| 782 buffer, sizeof(buffer), "%s%d;%df", CSI, si.height / 2, si.width + 1); | |
| 783 write_console(&tty_out, buffer); | |
| 784 get_cursor_position(&tty_out, &cursor_pos); | |
| 785 ASSERT_EQ(si.width, cursor_pos.X); | |
| 786 ASSERT_EQ(si.height / 2, cursor_pos.Y); | |
| 787 | |
| 788 snprintf( | |
| 789 buffer, sizeof(buffer), "%s%d;%df", CSI, si.height + 1, si.width / 2); | |
| 790 write_console(&tty_out, buffer); | |
| 791 get_cursor_position(&tty_out, &cursor_pos); | |
| 792 ASSERT_EQ(si.width / 2, cursor_pos.X); | |
| 793 ASSERT_EQ(si.height, cursor_pos.Y); | |
| 794 ASSERT(!is_scrolling(&tty_out, si)); | |
| 795 | |
| 796 terminate_tty(&tty_out); | |
| 797 | |
| 798 uv_run(loop, UV_RUN_DEFAULT); | |
| 799 | |
| 800 MAKE_VALGRIND_HAPPY(loop); | |
| 801 return 0; | |
| 802 } | |
| 803 | |
| 804 | |
| 805 TEST_IMPL(tty_hide_show_cursor) { | |
| 806 uv_tty_t tty_out; | |
| 807 uv_loop_t* loop; | |
| 808 char buffer[1024]; | |
| 809 BOOL saved_cursor_visibility; | |
| 810 | |
| 811 loop = uv_default_loop(); | |
| 812 | |
| 813 initialize_tty(&tty_out); | |
| 814 | |
| 815 saved_cursor_visibility = get_cursor_visibility(&tty_out); | |
| 816 | |
| 817 /* Hide the cursor */ | |
| 818 set_cursor_visibility(&tty_out, TRUE); | |
| 819 snprintf(buffer, sizeof(buffer), "%s?25l", CSI); | |
| 820 write_console(&tty_out, buffer); | |
| 821 ASSERT(!get_cursor_visibility(&tty_out)); | |
| 822 | |
| 823 /* Show the cursor */ | |
| 824 set_cursor_visibility(&tty_out, FALSE); | |
| 825 snprintf(buffer, sizeof(buffer), "%s?25h", CSI); | |
| 826 write_console(&tty_out, buffer); | |
| 827 ASSERT(get_cursor_visibility(&tty_out)); | |
| 828 | |
| 829 set_cursor_visibility(&tty_out, saved_cursor_visibility); | |
| 830 terminate_tty(&tty_out); | |
| 831 | |
| 832 uv_run(loop, UV_RUN_DEFAULT); | |
| 833 | |
| 834 MAKE_VALGRIND_HAPPY(loop); | |
| 835 return 0; | |
| 836 } | |
| 837 | |
| 838 | |
| 839 TEST_IMPL(tty_erase) { | |
| 840 int dir; | |
| 841 uv_tty_t tty_out; | |
| 842 uv_loop_t* loop; | |
| 843 COORD cursor_pos; | |
| 844 char buffer[1024]; | |
| 845 struct captured_screen actual = {0}, expect = {0}; | |
| 846 | |
| 847 loop = uv_default_loop(); | |
| 848 | |
| 849 initialize_tty(&tty_out); | |
| 850 | |
| 851 /* Erase to below if omitted argument */ | |
| 852 dir = 0; | |
| 853 setup_screen(&tty_out); | |
| 854 capture_screen(&tty_out, &expect); | |
| 855 cursor_pos.X = expect.si.width / 2; | |
| 856 cursor_pos.Y = expect.si.height / 2; | |
| 857 make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); | |
| 858 | |
| 859 set_cursor_position(&tty_out, cursor_pos); | |
| 860 snprintf(buffer, sizeof(buffer), "%sJ", CSI); | |
| 861 write_console(&tty_out, buffer); | |
| 862 capture_screen(&tty_out, &actual); | |
| 863 | |
| 864 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 865 | |
| 866 /* Erase to below(dir = 0) */ | |
| 867 setup_screen(&tty_out); | |
| 868 capture_screen(&tty_out, &expect); | |
| 869 make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); | |
| 870 | |
| 871 set_cursor_position(&tty_out, cursor_pos); | |
| 872 snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); | |
| 873 write_console(&tty_out, buffer); | |
| 874 capture_screen(&tty_out, &actual); | |
| 875 | |
| 876 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 877 | |
| 878 /* Erase to above */ | |
| 879 dir = 1; | |
| 880 setup_screen(&tty_out); | |
| 881 capture_screen(&tty_out, &expect); | |
| 882 make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); | |
| 883 | |
| 884 set_cursor_position(&tty_out, cursor_pos); | |
| 885 snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); | |
| 886 write_console(&tty_out, buffer); | |
| 887 capture_screen(&tty_out, &actual); | |
| 888 | |
| 889 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 890 | |
| 891 /* Erase All */ | |
| 892 dir = 2; | |
| 893 setup_screen(&tty_out); | |
| 894 capture_screen(&tty_out, &expect); | |
| 895 make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); | |
| 896 | |
| 897 set_cursor_position(&tty_out, cursor_pos); | |
| 898 snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); | |
| 899 write_console(&tty_out, buffer); | |
| 900 capture_screen(&tty_out, &actual); | |
| 901 | |
| 902 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 903 | |
| 904 terminate_tty(&tty_out); | |
| 905 | |
| 906 uv_run(loop, UV_RUN_DEFAULT); | |
| 907 | |
| 908 MAKE_VALGRIND_HAPPY(loop); | |
| 909 return 0; | |
| 910 } | |
| 911 | |
| 912 | |
| 913 TEST_IMPL(tty_erase_line) { | |
| 914 int dir; | |
| 915 uv_tty_t tty_out; | |
| 916 uv_loop_t* loop; | |
| 917 COORD cursor_pos; | |
| 918 char buffer[1024]; | |
| 919 struct captured_screen actual = {0}, expect = {0}; | |
| 920 | |
| 921 loop = uv_default_loop(); | |
| 922 | |
| 923 initialize_tty(&tty_out); | |
| 924 | |
| 925 /* Erase to right if omitted arguments */ | |
| 926 dir = 0; | |
| 927 setup_screen(&tty_out); | |
| 928 capture_screen(&tty_out, &expect); | |
| 929 cursor_pos.X = expect.si.width / 2; | |
| 930 cursor_pos.Y = expect.si.height / 2; | |
| 931 make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); | |
| 932 | |
| 933 set_cursor_position(&tty_out, cursor_pos); | |
| 934 snprintf(buffer, sizeof(buffer), "%sK", CSI); | |
| 935 write_console(&tty_out, buffer); | |
| 936 capture_screen(&tty_out, &actual); | |
| 937 | |
| 938 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 939 | |
| 940 /* Erase to right(dir = 0) */ | |
| 941 setup_screen(&tty_out); | |
| 942 capture_screen(&tty_out, &expect); | |
| 943 make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); | |
| 944 | |
| 945 set_cursor_position(&tty_out, cursor_pos); | |
| 946 snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); | |
| 947 write_console(&tty_out, buffer); | |
| 948 capture_screen(&tty_out, &actual); | |
| 949 | |
| 950 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 951 | |
| 952 /* Erase to Left */ | |
| 953 dir = 1; | |
| 954 setup_screen(&tty_out); | |
| 955 capture_screen(&tty_out, &expect); | |
| 956 make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); | |
| 957 | |
| 958 set_cursor_position(&tty_out, cursor_pos); | |
| 959 snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); | |
| 960 write_console(&tty_out, buffer); | |
| 961 capture_screen(&tty_out, &actual); | |
| 962 | |
| 963 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 964 | |
| 965 /* Erase All */ | |
| 966 dir = 2; | |
| 967 setup_screen(&tty_out); | |
| 968 capture_screen(&tty_out, &expect); | |
| 969 make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); | |
| 970 | |
| 971 set_cursor_position(&tty_out, cursor_pos); | |
| 972 snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); | |
| 973 write_console(&tty_out, buffer); | |
| 974 capture_screen(&tty_out, &actual); | |
| 975 | |
| 976 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 977 | |
| 978 terminate_tty(&tty_out); | |
| 979 | |
| 980 uv_run(loop, UV_RUN_DEFAULT); | |
| 981 | |
| 982 MAKE_VALGRIND_HAPPY(loop); | |
| 983 return 0; | |
| 984 } | |
| 985 | |
| 986 | |
| 987 TEST_IMPL(tty_set_cursor_shape) { | |
| 988 uv_tty_t tty_out; | |
| 989 uv_loop_t* loop; | |
| 990 DWORD saved_cursor_size; | |
| 991 char buffer[1024]; | |
| 992 | |
| 993 loop = uv_default_loop(); | |
| 994 | |
| 995 initialize_tty(&tty_out); | |
| 996 | |
| 997 saved_cursor_size = get_cursor_size(&tty_out); | |
| 998 | |
| 999 /* cursor size large if omitted arguments */ | |
| 1000 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1001 snprintf(buffer, sizeof(buffer), "%s q", CSI); | |
| 1002 write_console(&tty_out, buffer); | |
| 1003 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_LARGE); | |
| 1004 | |
| 1005 /* cursor size large */ | |
| 1006 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1007 snprintf(buffer, sizeof(buffer), "%s1 q", CSI); | |
| 1008 write_console(&tty_out, buffer); | |
| 1009 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_LARGE); | |
| 1010 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1011 snprintf(buffer, sizeof(buffer), "%s2 q", CSI); | |
| 1012 write_console(&tty_out, buffer); | |
| 1013 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_LARGE); | |
| 1014 | |
| 1015 /* cursor size small */ | |
| 1016 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1017 snprintf(buffer, sizeof(buffer), "%s3 q", CSI); | |
| 1018 write_console(&tty_out, buffer); | |
| 1019 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_SMALL); | |
| 1020 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1021 snprintf(buffer, sizeof(buffer), "%s6 q", CSI); | |
| 1022 write_console(&tty_out, buffer); | |
| 1023 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_SMALL); | |
| 1024 | |
| 1025 /* Nothing occurs with arguments outside valid range */ | |
| 1026 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1027 snprintf(buffer, sizeof(buffer), "%s7 q", CSI); | |
| 1028 write_console(&tty_out, buffer); | |
| 1029 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_MIDDLE); | |
| 1030 | |
| 1031 /* restore cursor size if arguments is zero */ | |
| 1032 snprintf(buffer, sizeof(buffer), "%s0 q", CSI); | |
| 1033 write_console(&tty_out, buffer); | |
| 1034 ASSERT_EQ(get_cursor_size(&tty_out), saved_cursor_size); | |
| 1035 | |
| 1036 terminate_tty(&tty_out); | |
| 1037 | |
| 1038 uv_run(loop, UV_RUN_DEFAULT); | |
| 1039 | |
| 1040 MAKE_VALGRIND_HAPPY(loop); | |
| 1041 return 0; | |
| 1042 } | |
| 1043 | |
| 1044 | |
| 1045 TEST_IMPL(tty_set_style) { | |
| 1046 #if _MSC_VER >= 1920 && _MSC_VER <= 1929 | |
| 1047 RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " | |
| 1048 "See: https://github.com/libuv/libuv/issues/3304"); | |
| 1049 #else | |
| 1050 | |
| 1051 uv_tty_t tty_out; | |
| 1052 uv_loop_t* loop; | |
| 1053 COORD cursor_pos; | |
| 1054 char buffer[1024]; | |
| 1055 struct captured_screen actual = {0}, expect = {0}; | |
| 1056 WORD fg, bg; | |
| 1057 WORD fg_attrs[9][2] = {{F_BLACK, FOREGROUND_BLACK}, | |
| 1058 {F_RED, FOREGROUND_RED}, | |
| 1059 {F_GREEN, FOREGROUND_GREEN}, | |
| 1060 {F_YELLOW, FOREGROUND_YELLOW}, | |
| 1061 {F_BLUE, FOREGROUND_BLUE}, | |
| 1062 {F_MAGENTA, FOREGROUND_MAGENTA}, | |
| 1063 {F_CYAN, FOREGROUND_CYAN}, | |
| 1064 {F_WHITE, FOREGROUND_WHITE}, | |
| 1065 {F_DEFAULT, 0}}; | |
| 1066 WORD bg_attrs[9][2] = {{B_DEFAULT, 0}, | |
| 1067 {B_BLACK, BACKGROUND_BLACK}, | |
| 1068 {B_RED, BACKGROUND_RED}, | |
| 1069 {B_GREEN, BACKGROUND_GREEN}, | |
| 1070 {B_YELLOW, BACKGROUND_YELLOW}, | |
| 1071 {B_BLUE, BACKGROUND_BLUE}, | |
| 1072 {B_MAGENTA, BACKGROUND_MAGENTA}, | |
| 1073 {B_CYAN, BACKGROUND_CYAN}, | |
| 1074 {B_WHITE, BACKGROUND_WHITE}}; | |
| 1075 WORD attr; | |
| 1076 int i, length; | |
| 1077 | |
| 1078 loop = uv_default_loop(); | |
| 1079 | |
| 1080 initialize_tty(&tty_out); | |
| 1081 | |
| 1082 capture_screen(&tty_out, &expect); | |
| 1083 fg_attrs[8][1] = expect.si.default_attr & FOREGROUND_WHITE; | |
| 1084 bg_attrs[0][1] = expect.si.default_attr & BACKGROUND_WHITE; | |
| 1085 | |
| 1086 /* Set foreground color */ | |
| 1087 length = ARRAY_SIZE(fg_attrs); | |
| 1088 for (i = 0; i < length; i++) { | |
| 1089 capture_screen(&tty_out, &expect); | |
| 1090 cursor_pos.X = expect.si.width / 2; | |
| 1091 cursor_pos.Y = expect.si.height / 2; | |
| 1092 attr = (expect.si.default_attr & ~FOREGROUND_WHITE) | fg_attrs[i][1]; | |
| 1093 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1094 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1095 | |
| 1096 set_cursor_position(&tty_out, cursor_pos); | |
| 1097 snprintf( | |
| 1098 buffer, sizeof(buffer), "%s%dm%s%sm", CSI, fg_attrs[i][0], HELLO, CSI); | |
| 1099 write_console(&tty_out, buffer); | |
| 1100 capture_screen(&tty_out, &actual); | |
| 1101 | |
| 1102 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1103 } | |
| 1104 | |
| 1105 /* Set background color */ | |
| 1106 length = ARRAY_SIZE(bg_attrs); | |
| 1107 for (i = 0; i < length; i++) { | |
| 1108 capture_screen(&tty_out, &expect); | |
| 1109 cursor_pos.X = expect.si.width / 2; | |
| 1110 cursor_pos.Y = expect.si.height / 2; | |
| 1111 attr = (expect.si.default_attr & ~BACKGROUND_WHITE) | bg_attrs[i][1]; | |
| 1112 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1113 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1114 | |
| 1115 set_cursor_position(&tty_out, cursor_pos); | |
| 1116 snprintf( | |
| 1117 buffer, sizeof(buffer), "%s%dm%s%sm", CSI, bg_attrs[i][0], HELLO, CSI); | |
| 1118 write_console(&tty_out, buffer); | |
| 1119 capture_screen(&tty_out, &actual); | |
| 1120 | |
| 1121 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1122 } | |
| 1123 | |
| 1124 /* Set foreground and background color */ | |
| 1125 ASSERT_EQ(ARRAY_SIZE(fg_attrs), ARRAY_SIZE(bg_attrs)); | |
| 1126 length = ARRAY_SIZE(bg_attrs); | |
| 1127 for (i = 0; i < length; i++) { | |
| 1128 capture_screen(&tty_out, &expect); | |
| 1129 cursor_pos.X = expect.si.width / 2; | |
| 1130 cursor_pos.Y = expect.si.height / 2; | |
| 1131 attr = expect.si.default_attr & ~FOREGROUND_WHITE & ~BACKGROUND_WHITE; | |
| 1132 attr |= fg_attrs[i][1] | bg_attrs[i][1]; | |
| 1133 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1134 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1135 | |
| 1136 set_cursor_position(&tty_out, cursor_pos); | |
| 1137 snprintf(buffer, | |
| 1138 sizeof(buffer), | |
| 1139 "%s%d;%dm%s%sm", | |
| 1140 CSI, | |
| 1141 bg_attrs[i][0], | |
| 1142 fg_attrs[i][0], | |
| 1143 HELLO, | |
| 1144 CSI); | |
| 1145 write_console(&tty_out, buffer); | |
| 1146 capture_screen(&tty_out, &actual); | |
| 1147 | |
| 1148 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1149 } | |
| 1150 | |
| 1151 /* Set foreground bright on */ | |
| 1152 capture_screen(&tty_out, &expect); | |
| 1153 cursor_pos.X = expect.si.width / 2; | |
| 1154 cursor_pos.Y = expect.si.height / 2; | |
| 1155 set_cursor_position(&tty_out, cursor_pos); | |
| 1156 attr = expect.si.default_attr; | |
| 1157 attr |= FOREGROUND_INTENSITY; | |
| 1158 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1159 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1160 cursor_pos.X += strlen(HELLO); | |
| 1161 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1162 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1163 | |
| 1164 snprintf(buffer, | |
| 1165 sizeof(buffer), | |
| 1166 "%s%dm%s%s%dm%s%dm%s%s%dm", | |
| 1167 CSI, | |
| 1168 F_INTENSITY, | |
| 1169 HELLO, | |
| 1170 CSI, | |
| 1171 F_INTENSITY_OFF1, | |
| 1172 CSI, | |
| 1173 F_INTENSITY, | |
| 1174 HELLO, | |
| 1175 CSI, | |
| 1176 F_INTENSITY_OFF2); | |
| 1177 write_console(&tty_out, buffer); | |
| 1178 capture_screen(&tty_out, &actual); | |
| 1179 | |
| 1180 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1181 | |
| 1182 /* Set background bright on */ | |
| 1183 capture_screen(&tty_out, &expect); | |
| 1184 cursor_pos.X = expect.si.width / 2; | |
| 1185 cursor_pos.Y = expect.si.height / 2; | |
| 1186 set_cursor_position(&tty_out, cursor_pos); | |
| 1187 attr = expect.si.default_attr; | |
| 1188 attr |= BACKGROUND_INTENSITY; | |
| 1189 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1190 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1191 | |
| 1192 snprintf(buffer, | |
| 1193 sizeof(buffer), | |
| 1194 "%s%dm%s%s%dm", | |
| 1195 CSI, | |
| 1196 B_INTENSITY, | |
| 1197 HELLO, | |
| 1198 CSI, | |
| 1199 B_INTENSITY_OFF); | |
| 1200 write_console(&tty_out, buffer); | |
| 1201 capture_screen(&tty_out, &actual); | |
| 1202 | |
| 1203 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1204 | |
| 1205 /* Inverse */ | |
| 1206 capture_screen(&tty_out, &expect); | |
| 1207 cursor_pos.X = expect.si.width / 2; | |
| 1208 cursor_pos.Y = expect.si.height / 2; | |
| 1209 set_cursor_position(&tty_out, cursor_pos); | |
| 1210 attr = expect.si.default_attr; | |
| 1211 fg = attr & FOREGROUND_WHITE; | |
| 1212 bg = attr & BACKGROUND_WHITE; | |
| 1213 attr &= (~FOREGROUND_WHITE & ~BACKGROUND_WHITE); | |
| 1214 attr |= COMMON_LVB_REVERSE_VIDEO; | |
| 1215 attr |= fg << 4; | |
| 1216 attr |= bg >> 4; | |
| 1217 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1218 make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); | |
| 1219 cursor_pos.X += strlen(HELLO); | |
| 1220 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1221 | |
| 1222 snprintf(buffer, | |
| 1223 sizeof(buffer), | |
| 1224 "%s%dm%s%s%dm%s", | |
| 1225 CSI, | |
| 1226 INVERSE, | |
| 1227 HELLO, | |
| 1228 CSI, | |
| 1229 INVERSE_OFF, | |
| 1230 HELLO); | |
| 1231 write_console(&tty_out, buffer); | |
| 1232 capture_screen(&tty_out, &actual); | |
| 1233 | |
| 1234 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1235 | |
| 1236 terminate_tty(&tty_out); | |
| 1237 | |
| 1238 uv_run(loop, UV_RUN_DEFAULT); | |
| 1239 | |
| 1240 MAKE_VALGRIND_HAPPY(loop); | |
| 1241 return 0; | |
| 1242 #endif | |
| 1243 } | |
| 1244 | |
| 1245 | |
| 1246 TEST_IMPL(tty_save_restore_cursor_position) { | |
| 1247 uv_tty_t tty_out; | |
| 1248 uv_loop_t* loop; | |
| 1249 COORD cursor_pos, cursor_pos_old; | |
| 1250 char buffer[1024]; | |
| 1251 struct screen_info si; | |
| 1252 | |
| 1253 loop = uv_default_loop(); | |
| 1254 | |
| 1255 initialize_tty(&tty_out); | |
| 1256 get_screen_info(&tty_out, &si); | |
| 1257 | |
| 1258 cursor_pos_old.X = si.width / 2; | |
| 1259 cursor_pos_old.Y = si.height / 2; | |
| 1260 set_cursor_position(&tty_out, cursor_pos_old); | |
| 1261 | |
| 1262 /* save the cursor position */ | |
| 1263 snprintf(buffer, sizeof(buffer), "%ss", CSI); | |
| 1264 write_console(&tty_out, buffer); | |
| 1265 | |
| 1266 cursor_pos.X = si.width / 4; | |
| 1267 cursor_pos.Y = si.height / 4; | |
| 1268 set_cursor_position(&tty_out, cursor_pos); | |
| 1269 | |
| 1270 /* restore the cursor position */ | |
| 1271 snprintf(buffer, sizeof(buffer), "%su", CSI); | |
| 1272 write_console(&tty_out, buffer); | |
| 1273 get_cursor_position(&tty_out, &cursor_pos); | |
| 1274 ASSERT_EQ(cursor_pos.X, cursor_pos_old.X); | |
| 1275 ASSERT_EQ(cursor_pos.Y, cursor_pos_old.Y); | |
| 1276 | |
| 1277 cursor_pos_old.X = si.width / 2; | |
| 1278 cursor_pos_old.Y = si.height / 2; | |
| 1279 set_cursor_position(&tty_out, cursor_pos_old); | |
| 1280 | |
| 1281 /* save the cursor position */ | |
| 1282 snprintf(buffer, sizeof(buffer), "%s7", ESC); | |
| 1283 write_console(&tty_out, buffer); | |
| 1284 | |
| 1285 cursor_pos.X = si.width / 4; | |
| 1286 cursor_pos.Y = si.height / 4; | |
| 1287 set_cursor_position(&tty_out, cursor_pos); | |
| 1288 | |
| 1289 /* restore the cursor position */ | |
| 1290 snprintf(buffer, sizeof(buffer), "%s8", ESC); | |
| 1291 write_console(&tty_out, buffer); | |
| 1292 get_cursor_position(&tty_out, &cursor_pos); | |
| 1293 ASSERT_EQ(cursor_pos.X, cursor_pos_old.X); | |
| 1294 ASSERT_EQ(cursor_pos.Y, cursor_pos_old.Y); | |
| 1295 | |
| 1296 terminate_tty(&tty_out); | |
| 1297 | |
| 1298 uv_run(loop, UV_RUN_DEFAULT); | |
| 1299 | |
| 1300 MAKE_VALGRIND_HAPPY(loop); | |
| 1301 return 0; | |
| 1302 } | |
| 1303 | |
| 1304 | |
| 1305 TEST_IMPL(tty_full_reset) { | |
| 1306 uv_tty_t tty_out; | |
| 1307 uv_loop_t* loop; | |
| 1308 char buffer[1024]; | |
| 1309 struct captured_screen actual = {0}, expect = {0}; | |
| 1310 COORD cursor_pos; | |
| 1311 DWORD saved_cursor_size; | |
| 1312 BOOL saved_cursor_visibility; | |
| 1313 | |
| 1314 loop = uv_default_loop(); | |
| 1315 | |
| 1316 initialize_tty(&tty_out); | |
| 1317 | |
| 1318 capture_screen(&tty_out, &expect); | |
| 1319 setup_screen(&tty_out); | |
| 1320 cursor_pos.X = expect.si.width; | |
| 1321 cursor_pos.Y = expect.si.height; | |
| 1322 set_cursor_position(&tty_out, cursor_pos); | |
| 1323 snprintf(buffer, sizeof(buffer), "%s%d;%dm%s", CSI, F_CYAN, B_YELLOW, HELLO); | |
| 1324 saved_cursor_size = get_cursor_size(&tty_out); | |
| 1325 set_cursor_size(&tty_out, | |
| 1326 saved_cursor_size == CURSOR_SIZE_LARGE ? CURSOR_SIZE_SMALL | |
| 1327 : CURSOR_SIZE_LARGE); | |
| 1328 saved_cursor_visibility = get_cursor_visibility(&tty_out); | |
| 1329 set_cursor_visibility(&tty_out, saved_cursor_visibility ? FALSE : TRUE); | |
| 1330 write_console(&tty_out, buffer); | |
| 1331 snprintf(buffer, sizeof(buffer), "%sc", ESC); | |
| 1332 write_console(&tty_out, buffer); | |
| 1333 capture_screen(&tty_out, &actual); | |
| 1334 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1335 ASSERT_EQ(get_cursor_size(&tty_out), saved_cursor_size); | |
| 1336 ASSERT_EQ(get_cursor_visibility(&tty_out), saved_cursor_visibility); | |
| 1337 ASSERT_OK(actual.si.csbi.srWindow.Top); | |
| 1338 | |
| 1339 terminate_tty(&tty_out); | |
| 1340 | |
| 1341 uv_run(loop, UV_RUN_DEFAULT); | |
| 1342 | |
| 1343 MAKE_VALGRIND_HAPPY(loop); | |
| 1344 return 0; | |
| 1345 } | |
| 1346 | |
| 1347 | |
| 1348 TEST_IMPL(tty_escape_sequence_processing) { | |
| 1349 #if _MSC_VER >= 1920 && _MSC_VER <= 1929 | |
| 1350 RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " | |
| 1351 "See: https://github.com/libuv/libuv/issues/3304"); | |
| 1352 #else | |
| 1353 uv_tty_t tty_out; | |
| 1354 uv_loop_t* loop; | |
| 1355 COORD cursor_pos, cursor_pos_old; | |
| 1356 DWORD saved_cursor_size; | |
| 1357 char buffer[1024]; | |
| 1358 struct captured_screen actual = {0}, expect = {0}; | |
| 1359 int dir; | |
| 1360 | |
| 1361 loop = uv_default_loop(); | |
| 1362 | |
| 1363 initialize_tty(&tty_out); | |
| 1364 | |
| 1365 /* CSI + finally byte does not output anything */ | |
| 1366 cursor_pos.X = 1; | |
| 1367 cursor_pos.Y = 1; | |
| 1368 set_cursor_position(&tty_out, cursor_pos); | |
| 1369 capture_screen(&tty_out, &expect); | |
| 1370 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1371 cursor_pos.X += strlen(HELLO); | |
| 1372 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1373 snprintf(buffer, sizeof(buffer), "%s@%s%s~%s", CSI, HELLO, CSI, HELLO); | |
| 1374 write_console(&tty_out, buffer); | |
| 1375 capture_screen(&tty_out, &actual); | |
| 1376 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1377 | |
| 1378 /* CSI(C1) + finally byte does not output anything */ | |
| 1379 cursor_pos.X = 1; | |
| 1380 cursor_pos.Y = 1; | |
| 1381 set_cursor_position(&tty_out, cursor_pos); | |
| 1382 capture_screen(&tty_out, &expect); | |
| 1383 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1384 cursor_pos.X += strlen(HELLO); | |
| 1385 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1386 snprintf(buffer, sizeof(buffer), "\xC2\x9B@%s\xC2\x9B~%s", HELLO, HELLO); | |
| 1387 write_console(&tty_out, buffer); | |
| 1388 capture_screen(&tty_out, &actual); | |
| 1389 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1390 | |
| 1391 /* CSI + intermediate byte + finally byte does not output anything */ | |
| 1392 cursor_pos.X = 1; | |
| 1393 cursor_pos.Y = 1; | |
| 1394 set_cursor_position(&tty_out, cursor_pos); | |
| 1395 capture_screen(&tty_out, &expect); | |
| 1396 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1397 cursor_pos.X += strlen(HELLO); | |
| 1398 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1399 snprintf(buffer, sizeof(buffer), "%s @%s%s/~%s", CSI, HELLO, CSI, HELLO); | |
| 1400 write_console(&tty_out, buffer); | |
| 1401 capture_screen(&tty_out, &actual); | |
| 1402 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1403 | |
| 1404 /* CSI + parameter byte + finally byte does not output anything */ | |
| 1405 cursor_pos.X = 1; | |
| 1406 cursor_pos.Y = 1; | |
| 1407 set_cursor_position(&tty_out, cursor_pos); | |
| 1408 capture_screen(&tty_out, &expect); | |
| 1409 snprintf(buffer, | |
| 1410 sizeof(buffer), | |
| 1411 "%s0@%s%s>~%s%s?~%s", | |
| 1412 CSI, | |
| 1413 HELLO, | |
| 1414 CSI, | |
| 1415 HELLO, | |
| 1416 CSI, | |
| 1417 HELLO); | |
| 1418 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1419 cursor_pos.X += strlen(HELLO); | |
| 1420 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1421 cursor_pos.X += strlen(HELLO); | |
| 1422 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1423 write_console(&tty_out, buffer); | |
| 1424 capture_screen(&tty_out, &actual); | |
| 1425 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1426 | |
| 1427 /* ESC Single-char control does not output anyghing */ | |
| 1428 cursor_pos.X = 1; | |
| 1429 cursor_pos.Y = 1; | |
| 1430 set_cursor_position(&tty_out, cursor_pos); | |
| 1431 capture_screen(&tty_out, &expect); | |
| 1432 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1433 cursor_pos.X += strlen(HELLO); | |
| 1434 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1435 snprintf(buffer, sizeof(buffer), "%s @%s%s/~%s", CSI, HELLO, CSI, HELLO); | |
| 1436 write_console(&tty_out, buffer); | |
| 1437 capture_screen(&tty_out, &actual); | |
| 1438 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1439 | |
| 1440 /* Nothing is output from ESC + ^, _, P, ] to BEL or ESC \ */ | |
| 1441 /* Operaging System Command */ | |
| 1442 cursor_pos.X = 1; | |
| 1443 cursor_pos.Y = 1; | |
| 1444 set_cursor_position(&tty_out, cursor_pos); | |
| 1445 capture_screen(&tty_out, &expect); | |
| 1446 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1447 snprintf(buffer, sizeof(buffer), "%s]0;%s%s%s", ESC, HELLO, BEL, HELLO); | |
| 1448 write_console(&tty_out, buffer); | |
| 1449 capture_screen(&tty_out, &actual); | |
| 1450 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1451 /* Device Control Sequence */ | |
| 1452 cursor_pos.X = 1; | |
| 1453 cursor_pos.Y = 1; | |
| 1454 set_cursor_position(&tty_out, cursor_pos); | |
| 1455 capture_screen(&tty_out, &expect); | |
| 1456 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1457 snprintf(buffer, sizeof(buffer), "%sP$m%s%s", ESC, ST, HELLO); | |
| 1458 write_console(&tty_out, buffer); | |
| 1459 capture_screen(&tty_out, &actual); | |
| 1460 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1461 /* Privacy Message */ | |
| 1462 cursor_pos.X = 1; | |
| 1463 cursor_pos.Y = 1; | |
| 1464 set_cursor_position(&tty_out, cursor_pos); | |
| 1465 capture_screen(&tty_out, &expect); | |
| 1466 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1467 snprintf(buffer, | |
| 1468 sizeof(buffer), | |
| 1469 "%s^\"%s\\\"%s\"%s%s", | |
| 1470 ESC, | |
| 1471 HELLO, | |
| 1472 HELLO, | |
| 1473 ST, | |
| 1474 HELLO); | |
| 1475 write_console(&tty_out, buffer); | |
| 1476 capture_screen(&tty_out, &actual); | |
| 1477 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1478 /* Application Program Command */ | |
| 1479 cursor_pos.X = 1; | |
| 1480 cursor_pos.Y = 1; | |
| 1481 set_cursor_position(&tty_out, cursor_pos); | |
| 1482 capture_screen(&tty_out, &expect); | |
| 1483 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1484 snprintf(buffer, | |
| 1485 sizeof(buffer), | |
| 1486 "%s_\"%s%s%s\"%s%s", | |
| 1487 ESC, | |
| 1488 HELLO, | |
| 1489 ST, | |
| 1490 HELLO, | |
| 1491 BEL, | |
| 1492 HELLO); | |
| 1493 write_console(&tty_out, buffer); | |
| 1494 capture_screen(&tty_out, &actual); | |
| 1495 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1496 | |
| 1497 /* Ignore double escape */ | |
| 1498 cursor_pos.X = 1; | |
| 1499 cursor_pos.Y = 1; | |
| 1500 set_cursor_position(&tty_out, cursor_pos); | |
| 1501 capture_screen(&tty_out, &expect); | |
| 1502 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1503 cursor_pos.X += strlen(HELLO); | |
| 1504 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1505 snprintf(buffer, | |
| 1506 sizeof(buffer), | |
| 1507 "%s%s@%s%s%s~%s", | |
| 1508 ESC, | |
| 1509 CSI, | |
| 1510 HELLO, | |
| 1511 ESC, | |
| 1512 CSI, | |
| 1513 HELLO); | |
| 1514 write_console(&tty_out, buffer); | |
| 1515 capture_screen(&tty_out, &actual); | |
| 1516 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1517 | |
| 1518 /* Ignored if argument overflow */ | |
| 1519 set_cursor_to_home(&tty_out); | |
| 1520 snprintf(buffer, sizeof(buffer), "%s1;%dH", CSI, UINT16_MAX + 1); | |
| 1521 write_console(&tty_out, buffer); | |
| 1522 get_cursor_position(&tty_out, &cursor_pos); | |
| 1523 ASSERT_EQ(1, cursor_pos.X); | |
| 1524 ASSERT_EQ(1, cursor_pos.Y); | |
| 1525 | |
| 1526 /* Too many argument are ignored */ | |
| 1527 cursor_pos.X = 1; | |
| 1528 cursor_pos.Y = 1; | |
| 1529 set_cursor_position(&tty_out, cursor_pos); | |
| 1530 capture_screen(&tty_out, &expect); | |
| 1531 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1532 snprintf(buffer, | |
| 1533 sizeof(buffer), | |
| 1534 "%s%d;%d;%d;%d;%dm%s%sm", | |
| 1535 CSI, | |
| 1536 F_RED, | |
| 1537 F_INTENSITY, | |
| 1538 INVERSE, | |
| 1539 B_CYAN, | |
| 1540 B_INTENSITY_OFF, | |
| 1541 HELLO, | |
| 1542 CSI); | |
| 1543 write_console(&tty_out, buffer); | |
| 1544 capture_screen(&tty_out, &actual); | |
| 1545 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1546 | |
| 1547 /* In the case of DECSCUSR, the others are ignored */ | |
| 1548 set_cursor_to_home(&tty_out); | |
| 1549 snprintf(buffer, | |
| 1550 sizeof(buffer), | |
| 1551 "%s%d;%d H", | |
| 1552 CSI, | |
| 1553 expect.si.height / 2, | |
| 1554 expect.si.width / 2); | |
| 1555 write_console(&tty_out, buffer); | |
| 1556 get_cursor_position(&tty_out, &cursor_pos); | |
| 1557 ASSERT_EQ(1, cursor_pos.X); | |
| 1558 ASSERT_EQ(1, cursor_pos.Y); | |
| 1559 | |
| 1560 /* Invalid sequence are ignored */ | |
| 1561 saved_cursor_size = get_cursor_size(&tty_out); | |
| 1562 set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); | |
| 1563 snprintf(buffer, sizeof(buffer), "%s 1q", CSI); | |
| 1564 write_console(&tty_out, buffer); | |
| 1565 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_MIDDLE); | |
| 1566 snprintf(buffer, sizeof(buffer), "%s 1 q", CSI); | |
| 1567 write_console(&tty_out, buffer); | |
| 1568 ASSERT_EQ(get_cursor_size(&tty_out), CURSOR_SIZE_MIDDLE); | |
| 1569 set_cursor_size(&tty_out, saved_cursor_size); | |
| 1570 | |
| 1571 /* #1874 2. */ | |
| 1572 snprintf(buffer, sizeof(buffer), "%s??25l", CSI); | |
| 1573 write_console(&tty_out, buffer); | |
| 1574 ASSERT(get_cursor_visibility(&tty_out)); | |
| 1575 snprintf(buffer, sizeof(buffer), "%s25?l", CSI); | |
| 1576 write_console(&tty_out, buffer); | |
| 1577 ASSERT(get_cursor_visibility(&tty_out)); | |
| 1578 cursor_pos_old.X = expect.si.width / 2; | |
| 1579 cursor_pos_old.Y = expect.si.height / 2; | |
| 1580 set_cursor_position(&tty_out, cursor_pos_old); | |
| 1581 snprintf(buffer, | |
| 1582 sizeof(buffer), | |
| 1583 "%s??%d;%df", | |
| 1584 CSI, | |
| 1585 expect.si.height / 4, | |
| 1586 expect.si.width / 4); | |
| 1587 write_console(&tty_out, buffer); | |
| 1588 get_cursor_position(&tty_out, &cursor_pos); | |
| 1589 ASSERT(cursor_pos.X = cursor_pos_old.X); | |
| 1590 ASSERT(cursor_pos.Y = cursor_pos_old.Y); | |
| 1591 set_cursor_to_home(&tty_out); | |
| 1592 | |
| 1593 /* CSI 25 l does nothing (#1874 4.) */ | |
| 1594 snprintf(buffer, sizeof(buffer), "%s25l", CSI); | |
| 1595 write_console(&tty_out, buffer); | |
| 1596 ASSERT(get_cursor_visibility(&tty_out)); | |
| 1597 | |
| 1598 /* Unsupported sequences are ignored(#1874 5.) */ | |
| 1599 dir = 2; | |
| 1600 setup_screen(&tty_out); | |
| 1601 capture_screen(&tty_out, &expect); | |
| 1602 set_cursor_position(&tty_out, cursor_pos); | |
| 1603 snprintf(buffer, sizeof(buffer), "%s?%dJ", CSI, dir); | |
| 1604 write_console(&tty_out, buffer); | |
| 1605 capture_screen(&tty_out, &actual); | |
| 1606 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1607 | |
| 1608 /* Finally byte immedately after CSI [ are also output(#1874 1.) */ | |
| 1609 cursor_pos.X = expect.si.width / 2; | |
| 1610 cursor_pos.Y = expect.si.height / 2; | |
| 1611 set_cursor_position(&tty_out, cursor_pos); | |
| 1612 capture_screen(&tty_out, &expect); | |
| 1613 make_expect_screen_write(&expect, cursor_pos, HELLO); | |
| 1614 snprintf(buffer, sizeof(buffer), "%s[%s", CSI, HELLO); | |
| 1615 write_console(&tty_out, buffer); | |
| 1616 capture_screen(&tty_out, &actual); | |
| 1617 ASSERT(compare_screen(&tty_out, &actual, &expect)); | |
| 1618 | |
| 1619 terminate_tty(&tty_out); | |
| 1620 | |
| 1621 uv_run(loop, UV_RUN_DEFAULT); | |
| 1622 | |
| 1623 MAKE_VALGRIND_HAPPY(loop); | |
| 1624 return 0; | |
| 1625 #endif | |
| 1626 } | |
| 1627 | |
| 1628 #else | |
| 1629 | |
| 1630 typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ | |
| 1631 | |
| 1632 #endif /* ifdef _WIN32 */ |