[READ-ONLY] Mirror of https://github.com/bombshell-dev/clack. Effortlessly build beautiful command-line apps bomb.sh/docs/clack/basics/getting-started/
cli command-line command-line-app node prompt prompts
5

Configure Feed

Select the types of activity you want to include in your feed.

test: split up tests into individual files (#295)

authored by

James Garbutt and committed by
GitHub
(Apr 17, 2025, 8:37 AM +0100) a4eb491b c185e5c6

+6870 -6672
+299
packages/prompts/src/__snapshots__/confirm.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`confirm (isCI = false) > can cancel 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ◆ foo 8 + │ ● Yes / ○ No 9 + └ 10 + ", 11 + "", 12 + "", 13 + "", 14 + "■ foo 15 + │ No 16 + │", 17 + " 18 + ", 19 + "[?25h", 20 + ] 21 + `; 22 + 23 + exports[`confirm (isCI = false) > can set initialValue 1`] = ` 24 + [ 25 + "[?25l", 26 + "│ 27 + ◆ foo 28 + │ ○ Yes / ● No 29 + └ 30 + ", 31 + "", 32 + "", 33 + "", 34 + "◇ foo 35 + │ No", 36 + " 37 + ", 38 + "[?25h", 39 + ] 40 + `; 41 + 42 + exports[`confirm (isCI = false) > left arrow moves to previous choice 1`] = ` 43 + [ 44 + "[?25l", 45 + "│ 46 + ◆ foo 47 + │ ● Yes / ○ No 48 + └ 49 + ", 50 + "", 51 + "", 52 + "", 53 + "│ ○ Yes / ● No", 54 + "", 55 + "", 56 + "", 57 + "", 58 + "│ ● Yes / ○ No", 59 + "", 60 + "", 61 + "", 62 + "", 63 + "◇ foo 64 + │ Yes", 65 + " 66 + ", 67 + "[?25h", 68 + ] 69 + `; 70 + 71 + exports[`confirm (isCI = false) > renders custom active choice 1`] = ` 72 + [ 73 + "[?25l", 74 + "│ 75 + ◆ foo 76 + │ ● bleep / ○ No 77 + └ 78 + ", 79 + "", 80 + "", 81 + "", 82 + "◇ foo 83 + │ bleep", 84 + " 85 + ", 86 + "[?25h", 87 + ] 88 + `; 89 + 90 + exports[`confirm (isCI = false) > renders custom inactive choice 1`] = ` 91 + [ 92 + "[?25l", 93 + "│ 94 + ◆ foo 95 + │ ● Yes / ○ bleep 96 + └ 97 + ", 98 + "", 99 + "", 100 + "", 101 + "◇ foo 102 + │ Yes", 103 + " 104 + ", 105 + "[?25h", 106 + ] 107 + `; 108 + 109 + exports[`confirm (isCI = false) > renders message with choices 1`] = ` 110 + [ 111 + "[?25l", 112 + "│ 113 + ◆ foo 114 + │ ● Yes / ○ No 115 + └ 116 + ", 117 + "", 118 + "", 119 + "", 120 + "◇ foo 121 + │ Yes", 122 + " 123 + ", 124 + "[?25h", 125 + ] 126 + `; 127 + 128 + exports[`confirm (isCI = false) > right arrow moves to next choice 1`] = ` 129 + [ 130 + "[?25l", 131 + "│ 132 + ◆ foo 133 + │ ● Yes / ○ No 134 + └ 135 + ", 136 + "", 137 + "", 138 + "", 139 + "│ ○ Yes / ● No", 140 + "", 141 + "", 142 + "", 143 + "", 144 + "◇ foo 145 + │ No", 146 + " 147 + ", 148 + "[?25h", 149 + ] 150 + `; 151 + 152 + exports[`confirm (isCI = true) > can cancel 1`] = ` 153 + [ 154 + "[?25l", 155 + "│ 156 + ◆ foo 157 + │ ● Yes / ○ No 158 + └ 159 + ", 160 + "", 161 + "", 162 + "", 163 + "■ foo 164 + │ No 165 + │", 166 + " 167 + ", 168 + "[?25h", 169 + ] 170 + `; 171 + 172 + exports[`confirm (isCI = true) > can set initialValue 1`] = ` 173 + [ 174 + "[?25l", 175 + "│ 176 + ◆ foo 177 + │ ○ Yes / ● No 178 + └ 179 + ", 180 + "", 181 + "", 182 + "", 183 + "◇ foo 184 + │ No", 185 + " 186 + ", 187 + "[?25h", 188 + ] 189 + `; 190 + 191 + exports[`confirm (isCI = true) > left arrow moves to previous choice 1`] = ` 192 + [ 193 + "[?25l", 194 + "│ 195 + ◆ foo 196 + │ ● Yes / ○ No 197 + └ 198 + ", 199 + "", 200 + "", 201 + "", 202 + "│ ○ Yes / ● No", 203 + "", 204 + "", 205 + "", 206 + "", 207 + "│ ● Yes / ○ No", 208 + "", 209 + "", 210 + "", 211 + "", 212 + "◇ foo 213 + │ Yes", 214 + " 215 + ", 216 + "[?25h", 217 + ] 218 + `; 219 + 220 + exports[`confirm (isCI = true) > renders custom active choice 1`] = ` 221 + [ 222 + "[?25l", 223 + "│ 224 + ◆ foo 225 + │ ● bleep / ○ No 226 + └ 227 + ", 228 + "", 229 + "", 230 + "", 231 + "◇ foo 232 + │ bleep", 233 + " 234 + ", 235 + "[?25h", 236 + ] 237 + `; 238 + 239 + exports[`confirm (isCI = true) > renders custom inactive choice 1`] = ` 240 + [ 241 + "[?25l", 242 + "│ 243 + ◆ foo 244 + │ ● Yes / ○ bleep 245 + └ 246 + ", 247 + "", 248 + "", 249 + "", 250 + "◇ foo 251 + │ Yes", 252 + " 253 + ", 254 + "[?25h", 255 + ] 256 + `; 257 + 258 + exports[`confirm (isCI = true) > renders message with choices 1`] = ` 259 + [ 260 + "[?25l", 261 + "│ 262 + ◆ foo 263 + │ ● Yes / ○ No 264 + └ 265 + ", 266 + "", 267 + "", 268 + "", 269 + "◇ foo 270 + │ Yes", 271 + " 272 + ", 273 + "[?25h", 274 + ] 275 + `; 276 + 277 + exports[`confirm (isCI = true) > right arrow moves to next choice 1`] = ` 278 + [ 279 + "[?25l", 280 + "│ 281 + ◆ foo 282 + │ ● Yes / ○ No 283 + └ 284 + ", 285 + "", 286 + "", 287 + "", 288 + "│ ○ Yes / ● No", 289 + "", 290 + "", 291 + "", 292 + "", 293 + "◇ foo 294 + │ No", 295 + " 296 + ", 297 + "[?25h", 298 + ] 299 + `;
+1043
packages/prompts/src/__snapshots__/group-multi-select.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`groupMultiselect (isCI = false) > can deselect an option 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ◆ foo 8 + │ ◻ group1 9 + │ │ ◻ group1value0 10 + │ └ ◻ group1value1 11 + └ 12 + ", 13 + "", 14 + "", 15 + "", 16 + "│ ◻ group1 17 + │ │ ◻ group1value0 18 + │ └ ◻ group1value1 19 + └ 20 + ", 21 + "", 22 + "", 23 + "", 24 + "│ │ ◼ group1value0", 25 + "", 26 + "", 27 + "", 28 + "", 29 + "│ │ ◼ group1value0 30 + │ └ ◻ group1value1 31 + └ 32 + ", 33 + "", 34 + "", 35 + "", 36 + "│ ◼ group1 37 + │ │ ◼ group1value0 38 + │ └ ◼ group1value1 39 + └ 40 + ", 41 + "", 42 + "", 43 + "", 44 + "│ ◻ group1 45 + │ │ ◼ group1value0 46 + │ └ ◻ group1value1 47 + └ 48 + ", 49 + "", 50 + "", 51 + "", 52 + "◇ foo 53 + │ group1value0", 54 + " 55 + ", 56 + "[?25h", 57 + ] 58 + `; 59 + 60 + exports[`groupMultiselect (isCI = false) > can select a group 1`] = ` 61 + [ 62 + "[?25l", 63 + "│ 64 + ◆ foo 65 + │ ◻ group1 66 + │ │ ◻ group1value0 67 + │ └ ◻ group1value1 68 + └ 69 + ", 70 + "", 71 + "", 72 + "", 73 + "│ ◼ group1 74 + │ │ ◼ group1value0 75 + │ └ ◼ group1value1 76 + └ 77 + ", 78 + "", 79 + "", 80 + "", 81 + "◇ foo 82 + │ group1value0, group1value1", 83 + " 84 + ", 85 + "[?25h", 86 + ] 87 + `; 88 + 89 + exports[`groupMultiselect (isCI = false) > can select a group by selecting all members 1`] = ` 90 + [ 91 + "[?25l", 92 + "│ 93 + ◆ foo 94 + │ ◻ group1 95 + │ │ ◻ group1value0 96 + │ └ ◻ group1value1 97 + └ 98 + ", 99 + "", 100 + "", 101 + "", 102 + "│ ◻ group1 103 + │ │ ◻ group1value0 104 + │ └ ◻ group1value1 105 + └ 106 + ", 107 + "", 108 + "", 109 + "", 110 + "│ │ ◼ group1value0", 111 + "", 112 + "", 113 + "", 114 + "", 115 + "│ │ ◼ group1value0 116 + │ └ ◻ group1value1 117 + └ 118 + ", 119 + "", 120 + "", 121 + "", 122 + "│ ◼ group1 123 + │ │ ◼ group1value0 124 + │ └ ◼ group1value1 125 + └ 126 + ", 127 + "", 128 + "", 129 + "", 130 + "◇ foo 131 + │ group1value0, group1value1", 132 + " 133 + ", 134 + "[?25h", 135 + ] 136 + `; 137 + 138 + exports[`groupMultiselect (isCI = false) > can select multiple options 1`] = ` 139 + [ 140 + "[?25l", 141 + "│ 142 + ◆ foo 143 + │ ◻ group1 144 + │ │ ◻ group1value0 145 + │ │ ◻ group1value1 146 + │ └ ◻ group1value2 147 + └ 148 + ", 149 + "", 150 + "", 151 + "", 152 + "│ ◻ group1 153 + │ │ ◻ group1value0 154 + │ │ ◻ group1value1 155 + │ └ ◻ group1value2 156 + └ 157 + ", 158 + "", 159 + "", 160 + "", 161 + "│ │ ◼ group1value0", 162 + "", 163 + "", 164 + "", 165 + "", 166 + "│ │ ◼ group1value0 167 + │ │ ◻ group1value1 168 + │ └ ◻ group1value2 169 + └ 170 + ", 171 + "", 172 + "", 173 + "", 174 + "│ │ ◼ group1value1", 175 + "", 176 + "", 177 + "", 178 + "", 179 + "◇ foo 180 + │ group1value0, group1value1", 181 + " 182 + ", 183 + "[?25h", 184 + ] 185 + `; 186 + 187 + exports[`groupMultiselect (isCI = false) > can submit empty selection when require = false 1`] = ` 188 + [ 189 + "[?25l", 190 + "│ 191 + ◆ foo 192 + │ ◻ group1 193 + │ │ ◻ group1value0 194 + │ └ ◻ group1value1 195 + └ 196 + ", 197 + "", 198 + "", 199 + "", 200 + "◇ foo 201 + │", 202 + " 203 + ", 204 + "[?25h", 205 + ] 206 + `; 207 + 208 + exports[`groupMultiselect (isCI = false) > cursorAt sets initial selection 1`] = ` 209 + [ 210 + "[?25l", 211 + "│ 212 + ◆ foo 213 + │ ◻ group1 214 + │ │ ◻ group1value0 215 + │ └ ◻ group1value1 216 + └ 217 + ", 218 + "", 219 + "", 220 + "", 221 + "│ └ ◼ group1value1", 222 + "", 223 + "", 224 + "", 225 + "", 226 + "◇ foo 227 + │ group1value1", 228 + " 229 + ", 230 + "[?25h", 231 + ] 232 + `; 233 + 234 + exports[`groupMultiselect (isCI = false) > groupSpacing > negative spacing is ignored 1`] = ` 235 + [ 236 + "[?25l", 237 + "│ 238 + ◆ foo 239 + │ ◻ group1 240 + │ └ ◻ group1value0 241 + │ ◻ group2 242 + │ └ ◻ group2value0 243 + └ 244 + ", 245 + "", 246 + "", 247 + "", 248 + "│ ◻ group1 249 + │ └ ◻ group1value0 250 + │ ◻ group2 251 + │ └ ◻ group2value0 252 + └ 253 + ", 254 + "", 255 + "", 256 + "", 257 + "│ ◼ group1 258 + │ └ ◼ group1value0 259 + │ ◻ group2 260 + │ └ ◻ group2value0 261 + └ 262 + ", 263 + "", 264 + "", 265 + "", 266 + "◇ foo 267 + │ group1value0", 268 + " 269 + ", 270 + "[?25h", 271 + ] 272 + `; 273 + 274 + exports[`groupMultiselect (isCI = false) > groupSpacing > renders spaced groups 1`] = ` 275 + [ 276 + "[?25l", 277 + "│ 278 + ◆ foo 279 + │ 280 + │ 281 + │ ◻ group1 282 + │ └ ◻ group1value0 283 + │ 284 + │ 285 + │ ◻ group2 286 + │ └ ◻ group2value0 287 + └ 288 + ", 289 + "", 290 + "", 291 + "", 292 + "│ ◻ group1 293 + │ └ ◻ group1value0 294 + │ 295 + │ 296 + │ ◻ group2 297 + │ └ ◻ group2value0 298 + └ 299 + ", 300 + "", 301 + "", 302 + "", 303 + "│ ◼ group1 304 + │ └ ◼ group1value0 305 + │ 306 + │ 307 + │ ◻ group2 308 + │ └ ◻ group2value0 309 + └ 310 + ", 311 + "", 312 + "", 313 + "", 314 + "◇ foo 315 + │ group1value0", 316 + " 317 + ", 318 + "[?25h", 319 + ] 320 + `; 321 + 322 + exports[`groupMultiselect (isCI = false) > initial values can be set 1`] = ` 323 + [ 324 + "[?25l", 325 + "│ 326 + ◆ foo 327 + │ ◻ group1 328 + │ │ ◻ group1value0 329 + │ └ ◼ group1value1 330 + └ 331 + ", 332 + "", 333 + "", 334 + "", 335 + "◇ foo 336 + │ group1value1", 337 + " 338 + ", 339 + "[?25h", 340 + ] 341 + `; 342 + 343 + exports[`groupMultiselect (isCI = false) > renders error when nothing selected 1`] = ` 344 + [ 345 + "[?25l", 346 + "│ 347 + ◆ foo 348 + │ ◻ group1 349 + │ │ ◻ group1value0 350 + │ └ ◻ group1value1 351 + └ 352 + ", 353 + "", 354 + "", 355 + "", 356 + "▲ foo 357 + │ ◻ group1 358 + │ │ ◻ group1value0 359 + │ └ ◻ group1value1 360 + └ Please select at least one option. 361 + Press  space  to select,  enter  to submit 362 + ", 363 + "", 364 + "", 365 + "", 366 + "◆ foo 367 + │ ◻ group1 368 + │ │ ◻ group1value0 369 + │ └ ◻ group1value1 370 + └ 371 + ", 372 + "", 373 + "", 374 + "", 375 + "│ │ ◼ group1value0", 376 + "", 377 + "", 378 + "", 379 + "", 380 + "◇ foo 381 + │ group1value0", 382 + " 383 + ", 384 + "[?25h", 385 + ] 386 + `; 387 + 388 + exports[`groupMultiselect (isCI = false) > renders message with options 1`] = ` 389 + [ 390 + "[?25l", 391 + "│ 392 + ◆ foo 393 + │ ◻ group1 394 + │ │ ◻ group1value0 395 + │ └ ◻ group1value1 396 + │ ◻ group2 397 + │ └ ◻ group2value0 398 + └ 399 + ", 400 + "", 401 + "", 402 + "", 403 + "│ ◻ group1 404 + │ │ ◻ group1value0 405 + │ └ ◻ group1value1 406 + │ ◻ group2 407 + │ └ ◻ group2value0 408 + └ 409 + ", 410 + "", 411 + "", 412 + "", 413 + "│ │ ◼ group1value0", 414 + "", 415 + "", 416 + "", 417 + "", 418 + "◇ foo 419 + │ group1value0", 420 + " 421 + ", 422 + "[?25h", 423 + ] 424 + `; 425 + 426 + exports[`groupMultiselect (isCI = false) > selectableGroups = false > cannot select groups 1`] = ` 427 + [ 428 + "[?25l", 429 + "│ 430 + ◆ foo 431 + │  group1 432 + │  ◻ group1value0 433 + │  ◻ group1value1 434 + └ 435 + ", 436 + "", 437 + "", 438 + "", 439 + "│  ◼ group1value0", 440 + "", 441 + "", 442 + "", 443 + "", 444 + "◇ foo 445 + │ group1value0", 446 + " 447 + ", 448 + "[?25h", 449 + ] 450 + `; 451 + 452 + exports[`groupMultiselect (isCI = false) > selectableGroups = false > selecting all members of group does not select group 1`] = ` 453 + [ 454 + "[?25l", 455 + "│ 456 + ◆ foo 457 + │  group1 458 + │  ◻ group1value0 459 + │  ◻ group1value1 460 + └ 461 + ", 462 + "", 463 + "", 464 + "", 465 + "│  ◼ group1value0", 466 + "", 467 + "", 468 + "", 469 + "", 470 + "│  ◼ group1value0 471 + │  ◻ group1value1 472 + └ 473 + ", 474 + "", 475 + "", 476 + "", 477 + "│  ◼ group1value1", 478 + "", 479 + "", 480 + "", 481 + "", 482 + "◇ foo 483 + │ group1value0, group1value1", 484 + " 485 + ", 486 + "[?25h", 487 + ] 488 + `; 489 + 490 + exports[`groupMultiselect (isCI = false) > values can be non-primitive 1`] = ` 491 + [ 492 + "[?25l", 493 + "│ 494 + ◆ foo 495 + │ ◻ group1 496 + │ │ ◻ value0 497 + │ └ ◻ value1 498 + └ 499 + ", 500 + "", 501 + "", 502 + "", 503 + "│ ◻ group1 504 + │ │ ◻ value0 505 + │ └ ◻ value1 506 + └ 507 + ", 508 + "", 509 + "", 510 + "", 511 + "│ │ ◼ value0", 512 + "", 513 + "", 514 + "", 515 + "", 516 + "◇ foo 517 + │ value0", 518 + " 519 + ", 520 + "[?25h", 521 + ] 522 + `; 523 + 524 + exports[`groupMultiselect (isCI = true) > can deselect an option 1`] = ` 525 + [ 526 + "[?25l", 527 + "│ 528 + ◆ foo 529 + │ ◻ group1 530 + │ │ ◻ group1value0 531 + │ └ ◻ group1value1 532 + └ 533 + ", 534 + "", 535 + "", 536 + "", 537 + "│ ◻ group1 538 + │ │ ◻ group1value0 539 + │ └ ◻ group1value1 540 + └ 541 + ", 542 + "", 543 + "", 544 + "", 545 + "│ │ ◼ group1value0", 546 + "", 547 + "", 548 + "", 549 + "", 550 + "│ │ ◼ group1value0 551 + │ └ ◻ group1value1 552 + └ 553 + ", 554 + "", 555 + "", 556 + "", 557 + "│ ◼ group1 558 + │ │ ◼ group1value0 559 + │ └ ◼ group1value1 560 + └ 561 + ", 562 + "", 563 + "", 564 + "", 565 + "│ ◻ group1 566 + │ │ ◼ group1value0 567 + │ └ ◻ group1value1 568 + └ 569 + ", 570 + "", 571 + "", 572 + "", 573 + "◇ foo 574 + │ group1value0", 575 + " 576 + ", 577 + "[?25h", 578 + ] 579 + `; 580 + 581 + exports[`groupMultiselect (isCI = true) > can select a group 1`] = ` 582 + [ 583 + "[?25l", 584 + "│ 585 + ◆ foo 586 + │ ◻ group1 587 + │ │ ◻ group1value0 588 + │ └ ◻ group1value1 589 + └ 590 + ", 591 + "", 592 + "", 593 + "", 594 + "│ ◼ group1 595 + │ │ ◼ group1value0 596 + │ └ ◼ group1value1 597 + └ 598 + ", 599 + "", 600 + "", 601 + "", 602 + "◇ foo 603 + │ group1value0, group1value1", 604 + " 605 + ", 606 + "[?25h", 607 + ] 608 + `; 609 + 610 + exports[`groupMultiselect (isCI = true) > can select a group by selecting all members 1`] = ` 611 + [ 612 + "[?25l", 613 + "│ 614 + ◆ foo 615 + │ ◻ group1 616 + │ │ ◻ group1value0 617 + │ └ ◻ group1value1 618 + └ 619 + ", 620 + "", 621 + "", 622 + "", 623 + "│ ◻ group1 624 + │ │ ◻ group1value0 625 + │ └ ◻ group1value1 626 + └ 627 + ", 628 + "", 629 + "", 630 + "", 631 + "│ │ ◼ group1value0", 632 + "", 633 + "", 634 + "", 635 + "", 636 + "│ │ ◼ group1value0 637 + │ └ ◻ group1value1 638 + └ 639 + ", 640 + "", 641 + "", 642 + "", 643 + "│ ◼ group1 644 + │ │ ◼ group1value0 645 + │ └ ◼ group1value1 646 + └ 647 + ", 648 + "", 649 + "", 650 + "", 651 + "◇ foo 652 + │ group1value0, group1value1", 653 + " 654 + ", 655 + "[?25h", 656 + ] 657 + `; 658 + 659 + exports[`groupMultiselect (isCI = true) > can select multiple options 1`] = ` 660 + [ 661 + "[?25l", 662 + "│ 663 + ◆ foo 664 + │ ◻ group1 665 + │ │ ◻ group1value0 666 + │ │ ◻ group1value1 667 + │ └ ◻ group1value2 668 + └ 669 + ", 670 + "", 671 + "", 672 + "", 673 + "│ ◻ group1 674 + │ │ ◻ group1value0 675 + │ │ ◻ group1value1 676 + │ └ ◻ group1value2 677 + └ 678 + ", 679 + "", 680 + "", 681 + "", 682 + "│ │ ◼ group1value0", 683 + "", 684 + "", 685 + "", 686 + "", 687 + "│ │ ◼ group1value0 688 + │ │ ◻ group1value1 689 + │ └ ◻ group1value2 690 + └ 691 + ", 692 + "", 693 + "", 694 + "", 695 + "│ │ ◼ group1value1", 696 + "", 697 + "", 698 + "", 699 + "", 700 + "◇ foo 701 + │ group1value0, group1value1", 702 + " 703 + ", 704 + "[?25h", 705 + ] 706 + `; 707 + 708 + exports[`groupMultiselect (isCI = true) > can submit empty selection when require = false 1`] = ` 709 + [ 710 + "[?25l", 711 + "│ 712 + ◆ foo 713 + │ ◻ group1 714 + │ │ ◻ group1value0 715 + │ └ ◻ group1value1 716 + └ 717 + ", 718 + "", 719 + "", 720 + "", 721 + "◇ foo 722 + │", 723 + " 724 + ", 725 + "[?25h", 726 + ] 727 + `; 728 + 729 + exports[`groupMultiselect (isCI = true) > cursorAt sets initial selection 1`] = ` 730 + [ 731 + "[?25l", 732 + "│ 733 + ◆ foo 734 + │ ◻ group1 735 + │ │ ◻ group1value0 736 + │ └ ◻ group1value1 737 + └ 738 + ", 739 + "", 740 + "", 741 + "", 742 + "│ └ ◼ group1value1", 743 + "", 744 + "", 745 + "", 746 + "", 747 + "◇ foo 748 + │ group1value1", 749 + " 750 + ", 751 + "[?25h", 752 + ] 753 + `; 754 + 755 + exports[`groupMultiselect (isCI = true) > groupSpacing > negative spacing is ignored 1`] = ` 756 + [ 757 + "[?25l", 758 + "│ 759 + ◆ foo 760 + │ ◻ group1 761 + │ └ ◻ group1value0 762 + │ ◻ group2 763 + │ └ ◻ group2value0 764 + └ 765 + ", 766 + "", 767 + "", 768 + "", 769 + "│ ◻ group1 770 + │ └ ◻ group1value0 771 + │ ◻ group2 772 + │ └ ◻ group2value0 773 + └ 774 + ", 775 + "", 776 + "", 777 + "", 778 + "│ ◼ group1 779 + │ └ ◼ group1value0 780 + │ ◻ group2 781 + │ └ ◻ group2value0 782 + └ 783 + ", 784 + "", 785 + "", 786 + "", 787 + "◇ foo 788 + │ group1value0", 789 + " 790 + ", 791 + "[?25h", 792 + ] 793 + `; 794 + 795 + exports[`groupMultiselect (isCI = true) > groupSpacing > renders spaced groups 1`] = ` 796 + [ 797 + "[?25l", 798 + "│ 799 + ◆ foo 800 + │ 801 + │ 802 + │ ◻ group1 803 + │ └ ◻ group1value0 804 + │ 805 + │ 806 + │ ◻ group2 807 + │ └ ◻ group2value0 808 + └ 809 + ", 810 + "", 811 + "", 812 + "", 813 + "│ ◻ group1 814 + │ └ ◻ group1value0 815 + │ 816 + │ 817 + │ ◻ group2 818 + │ └ ◻ group2value0 819 + └ 820 + ", 821 + "", 822 + "", 823 + "", 824 + "│ ◼ group1 825 + │ └ ◼ group1value0 826 + │ 827 + │ 828 + │ ◻ group2 829 + │ └ ◻ group2value0 830 + └ 831 + ", 832 + "", 833 + "", 834 + "", 835 + "◇ foo 836 + │ group1value0", 837 + " 838 + ", 839 + "[?25h", 840 + ] 841 + `; 842 + 843 + exports[`groupMultiselect (isCI = true) > initial values can be set 1`] = ` 844 + [ 845 + "[?25l", 846 + "│ 847 + ◆ foo 848 + │ ◻ group1 849 + │ │ ◻ group1value0 850 + │ └ ◼ group1value1 851 + └ 852 + ", 853 + "", 854 + "", 855 + "", 856 + "◇ foo 857 + │ group1value1", 858 + " 859 + ", 860 + "[?25h", 861 + ] 862 + `; 863 + 864 + exports[`groupMultiselect (isCI = true) > renders error when nothing selected 1`] = ` 865 + [ 866 + "[?25l", 867 + "│ 868 + ◆ foo 869 + │ ◻ group1 870 + │ │ ◻ group1value0 871 + │ └ ◻ group1value1 872 + └ 873 + ", 874 + "", 875 + "", 876 + "", 877 + "▲ foo 878 + │ ◻ group1 879 + │ │ ◻ group1value0 880 + │ └ ◻ group1value1 881 + └ Please select at least one option. 882 + Press  space  to select,  enter  to submit 883 + ", 884 + "", 885 + "", 886 + "", 887 + "◆ foo 888 + │ ◻ group1 889 + │ │ ◻ group1value0 890 + │ └ ◻ group1value1 891 + └ 892 + ", 893 + "", 894 + "", 895 + "", 896 + "│ │ ◼ group1value0", 897 + "", 898 + "", 899 + "", 900 + "", 901 + "◇ foo 902 + │ group1value0", 903 + " 904 + ", 905 + "[?25h", 906 + ] 907 + `; 908 + 909 + exports[`groupMultiselect (isCI = true) > renders message with options 1`] = ` 910 + [ 911 + "[?25l", 912 + "│ 913 + ◆ foo 914 + │ ◻ group1 915 + │ │ ◻ group1value0 916 + │ └ ◻ group1value1 917 + │ ◻ group2 918 + │ └ ◻ group2value0 919 + └ 920 + ", 921 + "", 922 + "", 923 + "", 924 + "│ ◻ group1 925 + │ │ ◻ group1value0 926 + │ └ ◻ group1value1 927 + │ ◻ group2 928 + │ └ ◻ group2value0 929 + └ 930 + ", 931 + "", 932 + "", 933 + "", 934 + "│ │ ◼ group1value0", 935 + "", 936 + "", 937 + "", 938 + "", 939 + "◇ foo 940 + │ group1value0", 941 + " 942 + ", 943 + "[?25h", 944 + ] 945 + `; 946 + 947 + exports[`groupMultiselect (isCI = true) > selectableGroups = false > cannot select groups 1`] = ` 948 + [ 949 + "[?25l", 950 + "│ 951 + ◆ foo 952 + │  group1 953 + │  ◻ group1value0 954 + │  ◻ group1value1 955 + └ 956 + ", 957 + "", 958 + "", 959 + "", 960 + "│  ◼ group1value0", 961 + "", 962 + "", 963 + "", 964 + "", 965 + "◇ foo 966 + │ group1value0", 967 + " 968 + ", 969 + "[?25h", 970 + ] 971 + `; 972 + 973 + exports[`groupMultiselect (isCI = true) > selectableGroups = false > selecting all members of group does not select group 1`] = ` 974 + [ 975 + "[?25l", 976 + "│ 977 + ◆ foo 978 + │  group1 979 + │  ◻ group1value0 980 + │  ◻ group1value1 981 + └ 982 + ", 983 + "", 984 + "", 985 + "", 986 + "│  ◼ group1value0", 987 + "", 988 + "", 989 + "", 990 + "", 991 + "│  ◼ group1value0 992 + │  ◻ group1value1 993 + └ 994 + ", 995 + "", 996 + "", 997 + "", 998 + "│  ◼ group1value1", 999 + "", 1000 + "", 1001 + "", 1002 + "", 1003 + "◇ foo 1004 + │ group1value0, group1value1", 1005 + " 1006 + ", 1007 + "[?25h", 1008 + ] 1009 + `; 1010 + 1011 + exports[`groupMultiselect (isCI = true) > values can be non-primitive 1`] = ` 1012 + [ 1013 + "[?25l", 1014 + "│ 1015 + ◆ foo 1016 + │ ◻ group1 1017 + │ │ ◻ value0 1018 + │ └ ◻ value1 1019 + └ 1020 + ", 1021 + "", 1022 + "", 1023 + "", 1024 + "│ ◻ group1 1025 + │ │ ◻ value0 1026 + │ └ ◻ value1 1027 + └ 1028 + ", 1029 + "", 1030 + "", 1031 + "", 1032 + "│ │ ◼ value0", 1033 + "", 1034 + "", 1035 + "", 1036 + "", 1037 + "◇ foo 1038 + │ value0", 1039 + " 1040 + ", 1041 + "[?25h", 1042 + ] 1043 + `;
-5013
packages/prompts/src/__snapshots__/index.test.ts.snap
··· 1 - // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 - 3 - exports[`prompts (isCI = false) > confirm > can cancel 1`] = ` 4 - [ 5 - "[?25l", 6 - "│ 7 - ◆ foo 8 - │ ● Yes / ○ No 9 - └ 10 - ", 11 - "", 12 - "", 13 - "", 14 - "■ foo 15 - │ No 16 - │", 17 - " 18 - ", 19 - "[?25h", 20 - ] 21 - `; 22 - 23 - exports[`prompts (isCI = false) > confirm > can set initialValue 1`] = ` 24 - [ 25 - "[?25l", 26 - "│ 27 - ◆ foo 28 - │ ○ Yes / ● No 29 - └ 30 - ", 31 - "", 32 - "", 33 - "", 34 - "◇ foo 35 - │ No", 36 - " 37 - ", 38 - "[?25h", 39 - ] 40 - `; 41 - 42 - exports[`prompts (isCI = false) > confirm > left arrow moves to previous choice 1`] = ` 43 - [ 44 - "[?25l", 45 - "│ 46 - ◆ foo 47 - │ ● Yes / ○ No 48 - └ 49 - ", 50 - "", 51 - "", 52 - "", 53 - "│ ○ Yes / ● No", 54 - "", 55 - "", 56 - "", 57 - "", 58 - "│ ● Yes / ○ No", 59 - "", 60 - "", 61 - "", 62 - "", 63 - "◇ foo 64 - │ Yes", 65 - " 66 - ", 67 - "[?25h", 68 - ] 69 - `; 70 - 71 - exports[`prompts (isCI = false) > confirm > renders custom active choice 1`] = ` 72 - [ 73 - "[?25l", 74 - "│ 75 - ◆ foo 76 - │ ● bleep / ○ No 77 - └ 78 - ", 79 - "", 80 - "", 81 - "", 82 - "◇ foo 83 - │ bleep", 84 - " 85 - ", 86 - "[?25h", 87 - ] 88 - `; 89 - 90 - exports[`prompts (isCI = false) > confirm > renders custom inactive choice 1`] = ` 91 - [ 92 - "[?25l", 93 - "│ 94 - ◆ foo 95 - │ ● Yes / ○ bleep 96 - └ 97 - ", 98 - "", 99 - "", 100 - "", 101 - "◇ foo 102 - │ Yes", 103 - " 104 - ", 105 - "[?25h", 106 - ] 107 - `; 108 - 109 - exports[`prompts (isCI = false) > confirm > renders message with choices 1`] = ` 110 - [ 111 - "[?25l", 112 - "│ 113 - ◆ foo 114 - │ ● Yes / ○ No 115 - └ 116 - ", 117 - "", 118 - "", 119 - "", 120 - "◇ foo 121 - │ Yes", 122 - " 123 - ", 124 - "[?25h", 125 - ] 126 - `; 127 - 128 - exports[`prompts (isCI = false) > confirm > right arrow moves to next choice 1`] = ` 129 - [ 130 - "[?25l", 131 - "│ 132 - ◆ foo 133 - │ ● Yes / ○ No 134 - └ 135 - ", 136 - "", 137 - "", 138 - "", 139 - "│ ○ Yes / ● No", 140 - "", 141 - "", 142 - "", 143 - "", 144 - "◇ foo 145 - │ No", 146 - " 147 - ", 148 - "[?25h", 149 - ] 150 - `; 151 - 152 - exports[`prompts (isCI = false) > groupMultiselect > can deselect an option 1`] = ` 153 - [ 154 - "[?25l", 155 - "│ 156 - ◆ foo 157 - │ ◻ group1 158 - │ │ ◻ group1value0 159 - │ └ ◻ group1value1 160 - └ 161 - ", 162 - "", 163 - "", 164 - "", 165 - "│ ◻ group1 166 - │ │ ◻ group1value0 167 - │ └ ◻ group1value1 168 - └ 169 - ", 170 - "", 171 - "", 172 - "", 173 - "│ │ ◼ group1value0", 174 - "", 175 - "", 176 - "", 177 - "", 178 - "│ │ ◼ group1value0 179 - │ └ ◻ group1value1 180 - └ 181 - ", 182 - "", 183 - "", 184 - "", 185 - "│ ◼ group1 186 - │ │ ◼ group1value0 187 - │ └ ◼ group1value1 188 - └ 189 - ", 190 - "", 191 - "", 192 - "", 193 - "│ ◻ group1 194 - │ │ ◼ group1value0 195 - │ └ ◻ group1value1 196 - └ 197 - ", 198 - "", 199 - "", 200 - "", 201 - "◇ foo 202 - │ group1value0", 203 - " 204 - ", 205 - "[?25h", 206 - ] 207 - `; 208 - 209 - exports[`prompts (isCI = false) > groupMultiselect > can select a group 1`] = ` 210 - [ 211 - "[?25l", 212 - "│ 213 - ◆ foo 214 - │ ◻ group1 215 - │ │ ◻ group1value0 216 - │ └ ◻ group1value1 217 - └ 218 - ", 219 - "", 220 - "", 221 - "", 222 - "│ ◼ group1 223 - │ │ ◼ group1value0 224 - │ └ ◼ group1value1 225 - └ 226 - ", 227 - "", 228 - "", 229 - "", 230 - "◇ foo 231 - │ group1value0, group1value1", 232 - " 233 - ", 234 - "[?25h", 235 - ] 236 - `; 237 - 238 - exports[`prompts (isCI = false) > groupMultiselect > can select a group by selecting all members 1`] = ` 239 - [ 240 - "[?25l", 241 - "│ 242 - ◆ foo 243 - │ ◻ group1 244 - │ │ ◻ group1value0 245 - │ └ ◻ group1value1 246 - └ 247 - ", 248 - "", 249 - "", 250 - "", 251 - "│ ◻ group1 252 - │ │ ◻ group1value0 253 - │ └ ◻ group1value1 254 - └ 255 - ", 256 - "", 257 - "", 258 - "", 259 - "│ │ ◼ group1value0", 260 - "", 261 - "", 262 - "", 263 - "", 264 - "│ │ ◼ group1value0 265 - │ └ ◻ group1value1 266 - └ 267 - ", 268 - "", 269 - "", 270 - "", 271 - "│ ◼ group1 272 - │ │ ◼ group1value0 273 - │ └ ◼ group1value1 274 - └ 275 - ", 276 - "", 277 - "", 278 - "", 279 - "◇ foo 280 - │ group1value0, group1value1", 281 - " 282 - ", 283 - "[?25h", 284 - ] 285 - `; 286 - 287 - exports[`prompts (isCI = false) > groupMultiselect > can select multiple options 1`] = ` 288 - [ 289 - "[?25l", 290 - "│ 291 - ◆ foo 292 - │ ◻ group1 293 - │ │ ◻ group1value0 294 - │ │ ◻ group1value1 295 - │ └ ◻ group1value2 296 - └ 297 - ", 298 - "", 299 - "", 300 - "", 301 - "│ ◻ group1 302 - │ │ ◻ group1value0 303 - │ │ ◻ group1value1 304 - │ └ ◻ group1value2 305 - └ 306 - ", 307 - "", 308 - "", 309 - "", 310 - "│ │ ◼ group1value0", 311 - "", 312 - "", 313 - "", 314 - "", 315 - "│ │ ◼ group1value0 316 - │ │ ◻ group1value1 317 - │ └ ◻ group1value2 318 - └ 319 - ", 320 - "", 321 - "", 322 - "", 323 - "│ │ ◼ group1value1", 324 - "", 325 - "", 326 - "", 327 - "", 328 - "◇ foo 329 - │ group1value0, group1value1", 330 - " 331 - ", 332 - "[?25h", 333 - ] 334 - `; 335 - 336 - exports[`prompts (isCI = false) > groupMultiselect > can submit empty selection when require = false 1`] = ` 337 - [ 338 - "[?25l", 339 - "│ 340 - ◆ foo 341 - │ ◻ group1 342 - │ │ ◻ group1value0 343 - │ └ ◻ group1value1 344 - └ 345 - ", 346 - "", 347 - "", 348 - "", 349 - "◇ foo 350 - │", 351 - " 352 - ", 353 - "[?25h", 354 - ] 355 - `; 356 - 357 - exports[`prompts (isCI = false) > groupMultiselect > cursorAt sets initial selection 1`] = ` 358 - [ 359 - "[?25l", 360 - "│ 361 - ◆ foo 362 - │ ◻ group1 363 - │ │ ◻ group1value0 364 - │ └ ◻ group1value1 365 - └ 366 - ", 367 - "", 368 - "", 369 - "", 370 - "│ └ ◼ group1value1", 371 - "", 372 - "", 373 - "", 374 - "", 375 - "◇ foo 376 - │ group1value1", 377 - " 378 - ", 379 - "[?25h", 380 - ] 381 - `; 382 - 383 - exports[`prompts (isCI = false) > groupMultiselect > groupSpacing > negative spacing is ignored 1`] = ` 384 - [ 385 - "[?25l", 386 - "│ 387 - ◆ foo 388 - │ ◻ group1 389 - │ └ ◻ group1value0 390 - │ ◻ group2 391 - │ └ ◻ group2value0 392 - └ 393 - ", 394 - "", 395 - "", 396 - "", 397 - "│ ◻ group1 398 - │ └ ◻ group1value0 399 - │ ◻ group2 400 - │ └ ◻ group2value0 401 - └ 402 - ", 403 - "", 404 - "", 405 - "", 406 - "│ ◼ group1 407 - │ └ ◼ group1value0 408 - │ ◻ group2 409 - │ └ ◻ group2value0 410 - └ 411 - ", 412 - "", 413 - "", 414 - "", 415 - "◇ foo 416 - │ group1value0", 417 - " 418 - ", 419 - "[?25h", 420 - ] 421 - `; 422 - 423 - exports[`prompts (isCI = false) > groupMultiselect > groupSpacing > renders spaced groups 1`] = ` 424 - [ 425 - "[?25l", 426 - "│ 427 - ◆ foo 428 - │ 429 - │ 430 - │ ◻ group1 431 - │ └ ◻ group1value0 432 - │ 433 - │ 434 - │ ◻ group2 435 - │ └ ◻ group2value0 436 - └ 437 - ", 438 - "", 439 - "", 440 - "", 441 - "│ ◻ group1 442 - │ └ ◻ group1value0 443 - │ 444 - │ 445 - │ ◻ group2 446 - │ └ ◻ group2value0 447 - └ 448 - ", 449 - "", 450 - "", 451 - "", 452 - "│ ◼ group1 453 - │ └ ◼ group1value0 454 - │ 455 - │ 456 - │ ◻ group2 457 - │ └ ◻ group2value0 458 - └ 459 - ", 460 - "", 461 - "", 462 - "", 463 - "◇ foo 464 - │ group1value0", 465 - " 466 - ", 467 - "[?25h", 468 - ] 469 - `; 470 - 471 - exports[`prompts (isCI = false) > groupMultiselect > initial values can be set 1`] = ` 472 - [ 473 - "[?25l", 474 - "│ 475 - ◆ foo 476 - │ ◻ group1 477 - │ │ ◻ group1value0 478 - │ └ ◼ group1value1 479 - └ 480 - ", 481 - "", 482 - "", 483 - "", 484 - "◇ foo 485 - │ group1value1", 486 - " 487 - ", 488 - "[?25h", 489 - ] 490 - `; 491 - 492 - exports[`prompts (isCI = false) > groupMultiselect > renders error when nothing selected 1`] = ` 493 - [ 494 - "[?25l", 495 - "│ 496 - ◆ foo 497 - │ ◻ group1 498 - │ │ ◻ group1value0 499 - │ └ ◻ group1value1 500 - └ 501 - ", 502 - "", 503 - "", 504 - "", 505 - "▲ foo 506 - │ ◻ group1 507 - │ │ ◻ group1value0 508 - │ └ ◻ group1value1 509 - └ Please select at least one option. 510 - Press  space  to select,  enter  to submit 511 - ", 512 - "", 513 - "", 514 - "", 515 - "◆ foo 516 - │ ◻ group1 517 - │ │ ◻ group1value0 518 - │ └ ◻ group1value1 519 - └ 520 - ", 521 - "", 522 - "", 523 - "", 524 - "│ │ ◼ group1value0", 525 - "", 526 - "", 527 - "", 528 - "", 529 - "◇ foo 530 - │ group1value0", 531 - " 532 - ", 533 - "[?25h", 534 - ] 535 - `; 536 - 537 - exports[`prompts (isCI = false) > groupMultiselect > renders message with options 1`] = ` 538 - [ 539 - "[?25l", 540 - "│ 541 - ◆ foo 542 - │ ◻ group1 543 - │ │ ◻ group1value0 544 - │ └ ◻ group1value1 545 - │ ◻ group2 546 - │ └ ◻ group2value0 547 - └ 548 - ", 549 - "", 550 - "", 551 - "", 552 - "│ ◻ group1 553 - │ │ ◻ group1value0 554 - │ └ ◻ group1value1 555 - │ ◻ group2 556 - │ └ ◻ group2value0 557 - └ 558 - ", 559 - "", 560 - "", 561 - "", 562 - "│ │ ◼ group1value0", 563 - "", 564 - "", 565 - "", 566 - "", 567 - "◇ foo 568 - │ group1value0", 569 - " 570 - ", 571 - "[?25h", 572 - ] 573 - `; 574 - 575 - exports[`prompts (isCI = false) > groupMultiselect > selectableGroups = false > cannot select groups 1`] = ` 576 - [ 577 - "[?25l", 578 - "│ 579 - ◆ foo 580 - │  group1 581 - │  ◻ group1value0 582 - │  ◻ group1value1 583 - └ 584 - ", 585 - "", 586 - "", 587 - "", 588 - "│  ◼ group1value0", 589 - "", 590 - "", 591 - "", 592 - "", 593 - "◇ foo 594 - │ group1value0", 595 - " 596 - ", 597 - "[?25h", 598 - ] 599 - `; 600 - 601 - exports[`prompts (isCI = false) > groupMultiselect > selectableGroups = false > selecting all members of group does not select group 1`] = ` 602 - [ 603 - "[?25l", 604 - "│ 605 - ◆ foo 606 - │  group1 607 - │  ◻ group1value0 608 - │  ◻ group1value1 609 - └ 610 - ", 611 - "", 612 - "", 613 - "", 614 - "│  ◼ group1value0", 615 - "", 616 - "", 617 - "", 618 - "", 619 - "│  ◼ group1value0 620 - │  ◻ group1value1 621 - └ 622 - ", 623 - "", 624 - "", 625 - "", 626 - "│  ◼ group1value1", 627 - "", 628 - "", 629 - "", 630 - "", 631 - "◇ foo 632 - │ group1value0, group1value1", 633 - " 634 - ", 635 - "[?25h", 636 - ] 637 - `; 638 - 639 - exports[`prompts (isCI = false) > groupMultiselect > values can be non-primitive 1`] = ` 640 - [ 641 - "[?25l", 642 - "│ 643 - ◆ foo 644 - │ ◻ group1 645 - │ │ ◻ value0 646 - │ └ ◻ value1 647 - └ 648 - ", 649 - "", 650 - "", 651 - "", 652 - "│ ◻ group1 653 - │ │ ◻ value0 654 - │ └ ◻ value1 655 - └ 656 - ", 657 - "", 658 - "", 659 - "", 660 - "│ │ ◼ value0", 661 - "", 662 - "", 663 - "", 664 - "", 665 - "◇ foo 666 - │ value0", 667 - " 668 - ", 669 - "[?25h", 670 - ] 671 - `; 672 - 673 - exports[`prompts (isCI = false) > multiselect > can cancel 1`] = ` 674 - [ 675 - "[?25l", 676 - "│ 677 - ◆ foo 678 - │ ◻ opt0 679 - │ ◻ opt1 680 - └ 681 - ", 682 - "", 683 - "", 684 - "", 685 - "■ foo 686 - │", 687 - " 688 - ", 689 - "[?25h", 690 - ] 691 - `; 692 - 693 - exports[`prompts (isCI = false) > multiselect > can render option hints 1`] = ` 694 - [ 695 - "[?25l", 696 - "│ 697 - ◆ foo 698 - │ ◻ opt0 (Hint 0) 699 - │ ◻ opt1 700 - └ 701 - ", 702 - "", 703 - "", 704 - "", 705 - "│ ◼ opt0 (Hint 0)", 706 - "", 707 - "", 708 - "", 709 - "", 710 - "◇ foo 711 - │ opt0", 712 - " 713 - ", 714 - "[?25h", 715 - ] 716 - `; 717 - 718 - exports[`prompts (isCI = false) > multiselect > can set cursorAt to preselect an option 1`] = ` 719 - [ 720 - "[?25l", 721 - "│ 722 - ◆ foo 723 - │ ◻ opt0 724 - │ ◻ opt1 725 - └ 726 - ", 727 - "", 728 - "", 729 - "", 730 - "│ ◼ opt1", 731 - "", 732 - "", 733 - "", 734 - "", 735 - "◇ foo 736 - │ opt1", 737 - " 738 - ", 739 - "[?25h", 740 - ] 741 - `; 742 - 743 - exports[`prompts (isCI = false) > multiselect > can set custom labels 1`] = ` 744 - [ 745 - "[?25l", 746 - "│ 747 - ◆ foo 748 - │ ◻ Option 0 749 - │ ◻ Option 1 750 - └ 751 - ", 752 - "", 753 - "", 754 - "", 755 - "│ ◼ Option 0", 756 - "", 757 - "", 758 - "", 759 - "", 760 - "◇ foo 761 - │ Option 0", 762 - " 763 - ", 764 - "[?25h", 765 - ] 766 - `; 767 - 768 - exports[`prompts (isCI = false) > multiselect > can set initial values 1`] = ` 769 - [ 770 - "[?25l", 771 - "│ 772 - ◆ foo 773 - │ ◻ opt0 774 - │ ◼ opt1 775 - └ 776 - ", 777 - "", 778 - "", 779 - "", 780 - "◇ foo 781 - │ opt1", 782 - " 783 - ", 784 - "[?25h", 785 - ] 786 - `; 787 - 788 - exports[`prompts (isCI = false) > multiselect > can submit without selection when required = false 1`] = ` 789 - [ 790 - "[?25l", 791 - "│ 792 - ◆ foo 793 - │ ◻ opt0 794 - │ ◻ opt1 795 - └ 796 - ", 797 - "", 798 - "", 799 - "", 800 - "◇ foo 801 - │ none", 802 - " 803 - ", 804 - "[?25h", 805 - ] 806 - `; 807 - 808 - exports[`prompts (isCI = false) > multiselect > maxItems renders a sliding window 1`] = ` 809 - [ 810 - "[?25l", 811 - "│ 812 - ◆ foo 813 - │ ◻ opt0 814 - │ ◻ opt1 815 - │ ◻ opt2 816 - │ ◻ opt3 817 - │ ◻ opt4 818 - │ ... 819 - └ 820 - ", 821 - "", 822 - "", 823 - "", 824 - "│ ◻ opt0 825 - │ ◻ opt1 826 - │ ◻ opt2 827 - │ ◻ opt3 828 - │ ◻ opt4 829 - │ ... 830 - └ 831 - ", 832 - "", 833 - "", 834 - "", 835 - "│ ◻ opt1 836 - │ ◻ opt2 837 - │ ◻ opt3 838 - │ ◻ opt4 839 - │ ... 840 - └ 841 - ", 842 - "", 843 - "", 844 - "", 845 - "│ ◻ opt2 846 - │ ◻ opt3 847 - │ ◻ opt4 848 - │ ... 849 - └ 850 - ", 851 - "", 852 - "", 853 - "", 854 - "│ ... 855 - │ ◻ opt2 856 - │ ◻ opt3 857 - │ ◻ opt4 858 - │ ◻ opt5 859 - │ ... 860 - └ 861 - ", 862 - "", 863 - "", 864 - "", 865 - "│ ◻ opt3 866 - │ ◻ opt4 867 - │ ◻ opt5 868 - │ ◻ opt6 869 - │ ... 870 - └ 871 - ", 872 - "", 873 - "", 874 - "", 875 - "│ ◻ opt4 876 - │ ◻ opt5 877 - │ ◻ opt6 878 - │ ◻ opt7 879 - │ ... 880 - └ 881 - ", 882 - "", 883 - "", 884 - "", 885 - "│ ◼ opt6", 886 - "", 887 - "", 888 - "", 889 - "", 890 - "◇ foo 891 - │ opt6", 892 - " 893 - ", 894 - "[?25h", 895 - ] 896 - `; 897 - 898 - exports[`prompts (isCI = false) > multiselect > renders message 1`] = ` 899 - [ 900 - "[?25l", 901 - "│ 902 - ◆ foo 903 - │ ◻ opt0 904 - │ ◻ opt1 905 - └ 906 - ", 907 - "", 908 - "", 909 - "", 910 - "│ ◼ opt0", 911 - "", 912 - "", 913 - "", 914 - "", 915 - "◇ foo 916 - │ opt0", 917 - " 918 - ", 919 - "[?25h", 920 - ] 921 - `; 922 - 923 - exports[`prompts (isCI = false) > multiselect > renders multiple cancelled values 1`] = ` 924 - [ 925 - "[?25l", 926 - "│ 927 - ◆ foo 928 - │ ◻ opt0 929 - │ ◻ opt1 930 - │ ◻ opt2 931 - └ 932 - ", 933 - "", 934 - "", 935 - "", 936 - "│ ◼ opt0", 937 - "", 938 - "", 939 - "", 940 - "", 941 - "│ ◼ opt0 942 - │ ◻ opt1 943 - │ ◻ opt2 944 - └ 945 - ", 946 - "", 947 - "", 948 - "", 949 - "│ ◼ opt1", 950 - "", 951 - "", 952 - "", 953 - "", 954 - "■ foo 955 - │ opt0, opt1 956 - │", 957 - " 958 - ", 959 - "[?25h", 960 - ] 961 - `; 962 - 963 - exports[`prompts (isCI = false) > multiselect > renders multiple selected options 1`] = ` 964 - [ 965 - "[?25l", 966 - "│ 967 - ◆ foo 968 - │ ◻ opt0 969 - │ ◻ opt1 970 - │ ◻ opt2 971 - └ 972 - ", 973 - "", 974 - "", 975 - "", 976 - "│ ◼ opt0", 977 - "", 978 - "", 979 - "", 980 - "", 981 - "│ ◼ opt0 982 - │ ◻ opt1 983 - │ ◻ opt2 984 - └ 985 - ", 986 - "", 987 - "", 988 - "", 989 - "│ ◼ opt1", 990 - "", 991 - "", 992 - "", 993 - "", 994 - "│ ◼ opt1 995 - │ ◻ opt2 996 - └ 997 - ", 998 - "", 999 - "", 1000 - "", 1001 - "◇ foo 1002 - │ opt0, opt1", 1003 - " 1004 - ", 1005 - "[?25h", 1006 - ] 1007 - `; 1008 - 1009 - exports[`prompts (isCI = false) > multiselect > renders validation errors 1`] = ` 1010 - [ 1011 - "[?25l", 1012 - "│ 1013 - ◆ foo 1014 - │ ◻ opt0 1015 - │ ◻ opt1 1016 - └ 1017 - ", 1018 - "", 1019 - "", 1020 - "", 1021 - "▲ foo 1022 - │ ◻ opt0 1023 - │ ◻ opt1 1024 - └ Please select at least one option. 1025 - Press  space  to select,  enter  to submit 1026 - ", 1027 - "", 1028 - "", 1029 - "", 1030 - "◆ foo 1031 - │ ◼ opt0 1032 - │ ◻ opt1 1033 - └ 1034 - ", 1035 - "", 1036 - "", 1037 - "", 1038 - "◇ foo 1039 - │ opt0", 1040 - " 1041 - ", 1042 - "[?25h", 1043 - ] 1044 - `; 1045 - 1046 - exports[`prompts (isCI = false) > multiselect > shows hints for all selected options 1`] = ` 1047 - [ 1048 - "[?25l", 1049 - "│ 1050 - ◆ foo 1051 - │ ◼ opt0 (Hint 0) 1052 - │ ◼ opt1 (Hint 1) 1053 - │ ◻ opt2 1054 - └ 1055 - ", 1056 - "", 1057 - "", 1058 - "", 1059 - "│ ◼ opt0 (Hint 0) 1060 - │ ◼ opt1 (Hint 1) 1061 - │ ◻ opt2 1062 - └ 1063 - ", 1064 - "", 1065 - "", 1066 - "", 1067 - "│ ◼ opt1 (Hint 1) 1068 - │ ◻ opt2 (Hint 2) 1069 - └ 1070 - ", 1071 - "", 1072 - "", 1073 - "", 1074 - "◇ foo 1075 - │ opt0, opt1", 1076 - " 1077 - ", 1078 - "[?25h", 1079 - ] 1080 - `; 1081 - 1082 - exports[`prompts (isCI = false) > multiselect > sliding window loops downwards 1`] = ` 1083 - [ 1084 - "[?25l", 1085 - "│ 1086 - ◆ foo 1087 - │ ◻ opt0 1088 - │ ◻ opt1 1089 - │ ◻ opt2 1090 - │ ◻ opt3 1091 - │ ◻ opt4 1092 - │ ... 1093 - └ 1094 - ", 1095 - "", 1096 - "", 1097 - "", 1098 - "│ ◻ opt0 1099 - │ ◻ opt1 1100 - │ ◻ opt2 1101 - │ ◻ opt3 1102 - │ ◻ opt4 1103 - │ ... 1104 - └ 1105 - ", 1106 - "", 1107 - "", 1108 - "", 1109 - "│ ◻ opt1 1110 - │ ◻ opt2 1111 - │ ◻ opt3 1112 - │ ◻ opt4 1113 - │ ... 1114 - └ 1115 - ", 1116 - "", 1117 - "", 1118 - "", 1119 - "│ ◻ opt2 1120 - │ ◻ opt3 1121 - │ ◻ opt4 1122 - │ ... 1123 - └ 1124 - ", 1125 - "", 1126 - "", 1127 - "", 1128 - "│ ... 1129 - │ ◻ opt2 1130 - │ ◻ opt3 1131 - │ ◻ opt4 1132 - │ ◻ opt5 1133 - │ ... 1134 - └ 1135 - ", 1136 - "", 1137 - "", 1138 - "", 1139 - "│ ◻ opt3 1140 - │ ◻ opt4 1141 - │ ◻ opt5 1142 - │ ◻ opt6 1143 - │ ... 1144 - └ 1145 - ", 1146 - "", 1147 - "", 1148 - "", 1149 - "│ ◻ opt4 1150 - │ ◻ opt5 1151 - │ ◻ opt6 1152 - │ ◻ opt7 1153 - │ ... 1154 - └ 1155 - ", 1156 - "", 1157 - "", 1158 - "", 1159 - "│ ◻ opt5 1160 - │ ◻ opt6 1161 - │ ◻ opt7 1162 - │ ◻ opt8 1163 - │ ... 1164 - └ 1165 - ", 1166 - "", 1167 - "", 1168 - "", 1169 - "│ ◻ opt6 1170 - │ ◻ opt7 1171 - │ ◻ opt8 1172 - │ ◻ opt9 1173 - │ ... 1174 - └ 1175 - ", 1176 - "", 1177 - "", 1178 - "", 1179 - "│ ◻ opt7 1180 - │ ◻ opt8 1181 - │ ◻ opt9 1182 - │ ◻ opt10 1183 - │ ◻ opt11 1184 - └ 1185 - ", 1186 - "", 1187 - "", 1188 - "", 1189 - "│ ◻ opt9 1190 - │ ◻ opt10 1191 - │ ◻ opt11 1192 - └ 1193 - ", 1194 - "", 1195 - "", 1196 - "", 1197 - "│ ◻ opt10 1198 - │ ◻ opt11 1199 - └ 1200 - ", 1201 - "", 1202 - "", 1203 - "", 1204 - "│ ◻ opt0 1205 - │ ◻ opt1 1206 - │ ◻ opt2 1207 - │ ◻ opt3 1208 - │ ◻ opt4 1209 - │ ... 1210 - └ 1211 - ", 1212 - "", 1213 - "", 1214 - "", 1215 - "│ ◼ opt0", 1216 - "", 1217 - "", 1218 - "", 1219 - "", 1220 - "◇ foo 1221 - │ opt0", 1222 - " 1223 - ", 1224 - "[?25h", 1225 - ] 1226 - `; 1227 - 1228 - exports[`prompts (isCI = false) > multiselect > sliding window loops upwards 1`] = ` 1229 - [ 1230 - "[?25l", 1231 - "│ 1232 - ◆ foo 1233 - │ ◻ opt0 1234 - │ ◻ opt1 1235 - │ ◻ opt2 1236 - │ ◻ opt3 1237 - │ ◻ opt4 1238 - │ ... 1239 - └ 1240 - ", 1241 - "", 1242 - "", 1243 - "", 1244 - "│ ... 1245 - │ ◻ opt7 1246 - │ ◻ opt8 1247 - │ ◻ opt9 1248 - │ ◻ opt10 1249 - │ ◻ opt11 1250 - └ 1251 - ", 1252 - "", 1253 - "", 1254 - "", 1255 - "│ ◼ opt11", 1256 - "", 1257 - "", 1258 - "", 1259 - "", 1260 - "◇ foo 1261 - │ opt11", 1262 - " 1263 - ", 1264 - "[?25h", 1265 - ] 1266 - `; 1267 - 1268 - exports[`prompts (isCI = false) > note > formatter which adds colors works 1`] = ` 1269 - [ 1270 - "│ 1271 - ◇ title ──╮ 1272 - │ │ 1273 - │ line 0 │ 1274 - │ line 1 │ 1275 - │ line 2 │ 1276 - │ │ 1277 - ├──────────╯ 1278 - ", 1279 - ] 1280 - `; 1281 - 1282 - exports[`prompts (isCI = false) > note > formatter which adds length works 1`] = ` 1283 - [ 1284 - "│ 1285 - ◇ title ──────╮ 1286 - │ │ 1287 - │ * line 0 * │ 1288 - │ * line 1 * │ 1289 - │ * line 2 * │ 1290 - │ │ 1291 - ├──────────────╯ 1292 - ", 1293 - ] 1294 - `; 1295 - 1296 - exports[`prompts (isCI = false) > note > renders as wide as longest line 1`] = ` 1297 - [ 1298 - "│ 1299 - ◇ title ───────────────────────────╮ 1300 - │ │ 1301 - │ short │ 1302 - │ somewhat questionably long line │ 1303 - │ │ 1304 - ├───────────────────────────────────╯ 1305 - ", 1306 - ] 1307 - `; 1308 - 1309 - exports[`prompts (isCI = false) > note > renders message with title 1`] = ` 1310 - [ 1311 - "│ 1312 - ◇ title ───╮ 1313 - │ │ 1314 - │ message │ 1315 - │ │ 1316 - ├───────────╯ 1317 - ", 1318 - ] 1319 - `; 1320 - 1321 - exports[`prompts (isCI = false) > password > renders and clears validation errors 1`] = ` 1322 - [ 1323 - "[?25l", 1324 - "│ 1325 - ◆ foo 1326 - │ _ 1327 - └ 1328 - ", 1329 - "", 1330 - "", 1331 - "", 1332 - "│ ▪_", 1333 - "", 1334 - "", 1335 - "", 1336 - "", 1337 - "▲ foo 1338 - │ ▪ 1339 - └ Password must be at least 2 characters 1340 - ", 1341 - "", 1342 - "", 1343 - "", 1344 - "◆ foo 1345 - │ ▪▪_ 1346 - └ 1347 - ", 1348 - "", 1349 - "", 1350 - "", 1351 - "◇ foo 1352 - │ ▪▪", 1353 - " 1354 - ", 1355 - "[?25h", 1356 - ] 1357 - `; 1358 - 1359 - exports[`prompts (isCI = false) > password > renders cancelled value 1`] = ` 1360 - [ 1361 - "[?25l", 1362 - "│ 1363 - ◆ foo 1364 - │ _ 1365 - └ 1366 - ", 1367 - "", 1368 - "", 1369 - "", 1370 - "│ ▪_", 1371 - "", 1372 - "", 1373 - "", 1374 - "", 1375 - "■ foo 1376 - │ ▪ 1377 - │", 1378 - " 1379 - ", 1380 - "[?25h", 1381 - ] 1382 - `; 1383 - 1384 - exports[`prompts (isCI = false) > password > renders custom mask 1`] = ` 1385 - [ 1386 - "[?25l", 1387 - "│ 1388 - ◆ foo 1389 - │ _ 1390 - └ 1391 - ", 1392 - "", 1393 - "", 1394 - "", 1395 - "│ *_", 1396 - "", 1397 - "", 1398 - "", 1399 - "", 1400 - "│ **_", 1401 - "", 1402 - "", 1403 - "", 1404 - "", 1405 - "◇ foo 1406 - │ **", 1407 - " 1408 - ", 1409 - "[?25h", 1410 - ] 1411 - `; 1412 - 1413 - exports[`prompts (isCI = false) > password > renders masked value 1`] = ` 1414 - [ 1415 - "[?25l", 1416 - "│ 1417 - ◆ foo 1418 - │ _ 1419 - └ 1420 - ", 1421 - "", 1422 - "", 1423 - "", 1424 - "│ ▪_", 1425 - "", 1426 - "", 1427 - "", 1428 - "", 1429 - "│ ▪▪_", 1430 - "", 1431 - "", 1432 - "", 1433 - "", 1434 - "◇ foo 1435 - │ ▪▪", 1436 - " 1437 - ", 1438 - "[?25h", 1439 - ] 1440 - `; 1441 - 1442 - exports[`prompts (isCI = false) > password > renders message 1`] = ` 1443 - [ 1444 - "[?25l", 1445 - "│ 1446 - ◆ foo 1447 - │ _ 1448 - └ 1449 - ", 1450 - "", 1451 - "", 1452 - "", 1453 - "◇ foo 1454 - │", 1455 - " 1456 - ", 1457 - "[?25h", 1458 - ] 1459 - `; 1460 - 1461 - exports[`prompts (isCI = false) > select > can cancel 1`] = ` 1462 - [ 1463 - "[?25l", 1464 - "│ 1465 - ◆ foo 1466 - │ ● opt0 1467 - │ ○ opt1 1468 - └ 1469 - ", 1470 - "", 1471 - "", 1472 - "", 1473 - "■ foo 1474 - │ opt0 1475 - │", 1476 - " 1477 - ", 1478 - "[?25h", 1479 - ] 1480 - `; 1481 - 1482 - exports[`prompts (isCI = false) > select > down arrow selects next option 1`] = ` 1483 - [ 1484 - "[?25l", 1485 - "│ 1486 - ◆ foo 1487 - │ ● opt0 1488 - │ ○ opt1 1489 - └ 1490 - ", 1491 - "", 1492 - "", 1493 - "", 1494 - "│ ○ opt0 1495 - │ ● opt1 1496 - └ 1497 - ", 1498 - "", 1499 - "", 1500 - "", 1501 - "◇ foo 1502 - │ opt1", 1503 - " 1504 - ", 1505 - "[?25h", 1506 - ] 1507 - `; 1508 - 1509 - exports[`prompts (isCI = false) > select > renders option hints 1`] = ` 1510 - [ 1511 - "[?25l", 1512 - "│ 1513 - ◆ foo 1514 - │ ● opt0 (Hint 0) 1515 - │ ○ opt1 1516 - └ 1517 - ", 1518 - "", 1519 - "", 1520 - "", 1521 - "◇ foo 1522 - │ opt0", 1523 - " 1524 - ", 1525 - "[?25h", 1526 - ] 1527 - `; 1528 - 1529 - exports[`prompts (isCI = false) > select > renders option labels 1`] = ` 1530 - [ 1531 - "[?25l", 1532 - "│ 1533 - ◆ foo 1534 - │ ● Option 0 1535 - │ ○ Option 1 1536 - └ 1537 - ", 1538 - "", 1539 - "", 1540 - "", 1541 - "◇ foo 1542 - │ Option 0", 1543 - " 1544 - ", 1545 - "[?25h", 1546 - ] 1547 - `; 1548 - 1549 - exports[`prompts (isCI = false) > select > renders options and message 1`] = ` 1550 - [ 1551 - "[?25l", 1552 - "│ 1553 - ◆ foo 1554 - │ ● opt0 1555 - │ ○ opt1 1556 - └ 1557 - ", 1558 - "", 1559 - "", 1560 - "", 1561 - "◇ foo 1562 - │ opt0", 1563 - " 1564 - ", 1565 - "[?25h", 1566 - ] 1567 - `; 1568 - 1569 - exports[`prompts (isCI = false) > select > up arrow selects previous option 1`] = ` 1570 - [ 1571 - "[?25l", 1572 - "│ 1573 - ◆ foo 1574 - │ ● opt0 1575 - │ ○ opt1 1576 - └ 1577 - ", 1578 - "", 1579 - "", 1580 - "", 1581 - "│ ○ opt0 1582 - │ ● opt1 1583 - └ 1584 - ", 1585 - "", 1586 - "", 1587 - "", 1588 - "│ ● opt0 1589 - │ ○ opt1 1590 - └ 1591 - ", 1592 - "", 1593 - "", 1594 - "", 1595 - "◇ foo 1596 - │ opt0", 1597 - " 1598 - ", 1599 - "[?25h", 1600 - ] 1601 - `; 1602 - 1603 - exports[`prompts (isCI = false) > spinner > message > sets message for next frame 1`] = ` 1604 - [ 1605 - "[?25l", 1606 - "│ 1607 - ", 1608 - "◒ ", 1609 - "", 1610 - "", 1611 - "◐ foo", 1612 - ] 1613 - `; 1614 - 1615 - exports[`prompts (isCI = false) > spinner > process exit handling > prioritizes direct options over global settings 1`] = ` 1616 - [ 1617 - "[?25l", 1618 - "│ 1619 - ", 1620 - "■ Spinner cancel message 1621 - ", 1622 - "[?25h", 1623 - ] 1624 - `; 1625 - 1626 - exports[`prompts (isCI = false) > spinner > process exit handling > prioritizes direct options over global settings 2`] = ` 1627 - [ 1628 - "[?25l", 1629 - "│ 1630 - ", 1631 - "▲ Spinner error message 1632 - ", 1633 - "[?25h", 1634 - ] 1635 - `; 1636 - 1637 - exports[`prompts (isCI = false) > spinner > process exit handling > uses custom cancel message when provided directly 1`] = ` 1638 - [ 1639 - "[?25l", 1640 - "│ 1641 - ", 1642 - "■ Custom cancel message 1643 - ", 1644 - "[?25h", 1645 - ] 1646 - `; 1647 - 1648 - exports[`prompts (isCI = false) > spinner > process exit handling > uses custom error message when provided directly 1`] = ` 1649 - [ 1650 - "[?25l", 1651 - "│ 1652 - ", 1653 - "▲ Custom error message 1654 - ", 1655 - "[?25h", 1656 - ] 1657 - `; 1658 - 1659 - exports[`prompts (isCI = false) > spinner > process exit handling > uses default cancel message 1`] = ` 1660 - [ 1661 - "[?25l", 1662 - "│ 1663 - ", 1664 - "■ Canceled 1665 - ", 1666 - "[?25h", 1667 - ] 1668 - `; 1669 - 1670 - exports[`prompts (isCI = false) > spinner > process exit handling > uses global custom cancel message from settings 1`] = ` 1671 - [ 1672 - "[?25l", 1673 - "│ 1674 - ", 1675 - "■ Global cancel message 1676 - ", 1677 - "[?25h", 1678 - ] 1679 - `; 1680 - 1681 - exports[`prompts (isCI = false) > spinner > process exit handling > uses global custom error message from settings 1`] = ` 1682 - [ 1683 - "[?25l", 1684 - "│ 1685 - ", 1686 - "▲ Global error message 1687 - ", 1688 - "[?25h", 1689 - ] 1690 - `; 1691 - 1692 - exports[`prompts (isCI = false) > spinner > start > renders frames at interval 1`] = ` 1693 - [ 1694 - "[?25l", 1695 - "│ 1696 - ", 1697 - "◒ ", 1698 - "", 1699 - "", 1700 - "◐ ", 1701 - "", 1702 - "", 1703 - "◓ ", 1704 - "", 1705 - "", 1706 - "◑ ", 1707 - ] 1708 - `; 1709 - 1710 - exports[`prompts (isCI = false) > spinner > start > renders message 1`] = ` 1711 - [ 1712 - "[?25l", 1713 - "│ 1714 - ", 1715 - "◒ foo", 1716 - ] 1717 - `; 1718 - 1719 - exports[`prompts (isCI = false) > spinner > start > renders timer when indicator is "timer" 1`] = ` 1720 - [ 1721 - "[?25l", 1722 - "│ 1723 - ", 1724 - "◒ [0s]", 1725 - ] 1726 - `; 1727 - 1728 - exports[`prompts (isCI = false) > spinner > stop > renders cancel symbol if code = 1 1`] = ` 1729 - [ 1730 - "[?25l", 1731 - "│ 1732 - ", 1733 - "◒ ", 1734 - "", 1735 - "", 1736 - "■ 1737 - ", 1738 - "[?25h", 1739 - ] 1740 - `; 1741 - 1742 - exports[`prompts (isCI = false) > spinner > stop > renders error symbol if code > 1 1`] = ` 1743 - [ 1744 - "[?25l", 1745 - "│ 1746 - ", 1747 - "◒ ", 1748 - "", 1749 - "", 1750 - "▲ 1751 - ", 1752 - "[?25h", 1753 - ] 1754 - `; 1755 - 1756 - exports[`prompts (isCI = false) > spinner > stop > renders message 1`] = ` 1757 - [ 1758 - "[?25l", 1759 - "│ 1760 - ", 1761 - "◒ ", 1762 - "", 1763 - "", 1764 - "◇ foo 1765 - ", 1766 - "[?25h", 1767 - ] 1768 - `; 1769 - 1770 - exports[`prompts (isCI = false) > spinner > stop > renders message without removing dots 1`] = ` 1771 - [ 1772 - "[?25l", 1773 - "│ 1774 - ", 1775 - "◒ ", 1776 - "", 1777 - "", 1778 - "◇ foo. 1779 - ", 1780 - "[?25h", 1781 - ] 1782 - `; 1783 - 1784 - exports[`prompts (isCI = false) > spinner > stop > renders submit symbol and stops spinner 1`] = ` 1785 - [ 1786 - "[?25l", 1787 - "│ 1788 - ", 1789 - "◒ ", 1790 - "", 1791 - "", 1792 - "◇ 1793 - ", 1794 - "[?25h", 1795 - ] 1796 - `; 1797 - 1798 - exports[`prompts (isCI = false) > taskLog > error > clears output if showLog = false 1`] = ` 1799 - [ 1800 - "│ 1801 - ", 1802 - "◇ foo 1803 - ", 1804 - "│ 1805 - ", 1806 - "│ line 0 1807 - ", 1808 - "", 1809 - "│ line 0 1810 - │ line 1 1811 - ", 1812 - "", 1813 - "│ 1814 - ■ some error! 1815 - ", 1816 - ] 1817 - `; 1818 - 1819 - exports[`prompts (isCI = false) > taskLog > error > renders output with message 1`] = ` 1820 - [ 1821 - "│ 1822 - ", 1823 - "◇ foo 1824 - ", 1825 - "│ 1826 - ", 1827 - "│ line 0 1828 - ", 1829 - "", 1830 - "│ line 0 1831 - │ line 1 1832 - ", 1833 - "", 1834 - "│ 1835 - ■ some error! 1836 - ", 1837 - "│ 1838 - │ line 0 1839 - │ line 1 1840 - ", 1841 - ] 1842 - `; 1843 - 1844 - exports[`prompts (isCI = false) > taskLog > message > can write line by line 1`] = ` 1845 - [ 1846 - "│ 1847 - ", 1848 - "◇ foo 1849 - ", 1850 - "│ 1851 - ", 1852 - "│ line 0 1853 - ", 1854 - "", 1855 - "│ line 0 1856 - │ line 1 1857 - ", 1858 - ] 1859 - `; 1860 - 1861 - exports[`prompts (isCI = false) > taskLog > message > can write multiple lines 1`] = ` 1862 - [ 1863 - "│ 1864 - ", 1865 - "◇ foo 1866 - ", 1867 - "│ 1868 - ", 1869 - "│ line 0 1870 - │ line 1 1871 - ", 1872 - ] 1873 - `; 1874 - 1875 - exports[`prompts (isCI = false) > taskLog > message > enforces limit if set 1`] = ` 1876 - [ 1877 - "│ 1878 - ", 1879 - "◇ foo 1880 - ", 1881 - "│ 1882 - ", 1883 - "│ line 0 1884 - ", 1885 - "", 1886 - "│ line 0 1887 - │ line 1 1888 - ", 1889 - "", 1890 - "│ line 1 1891 - │ line 2 1892 - ", 1893 - ] 1894 - `; 1895 - 1896 - exports[`prompts (isCI = false) > taskLog > message > prints empty lines 1`] = ` 1897 - [ 1898 - "│ 1899 - ", 1900 - "◇ foo 1901 - ", 1902 - "│ 1903 - ", 1904 - "│  1905 - ", 1906 - "│ line 1 1907 - ", 1908 - "", 1909 - "│ line 1 1910 - │  1911 - ", 1912 - "", 1913 - "│ line 1 1914 - │  1915 - │ line 3 1916 - ", 1917 - ] 1918 - `; 1919 - 1920 - exports[`prompts (isCI = false) > taskLog > message > raw = true appends message text until newline 1`] = ` 1921 - [ 1922 - "│ 1923 - ", 1924 - "◇ foo 1925 - ", 1926 - "│ 1927 - ", 1928 - "│ line 0 1929 - ", 1930 - "", 1931 - "│ line 0still line 0 1932 - ", 1933 - "", 1934 - "│ line 0still line 0 1935 - │ line 1 1936 - ", 1937 - ] 1938 - `; 1939 - 1940 - exports[`prompts (isCI = false) > taskLog > message > raw = true works when mixed with non-raw messages 1`] = ` 1941 - [ 1942 - "│ 1943 - ", 1944 - "◇ foo 1945 - ", 1946 - "│ 1947 - ", 1948 - "│ line 0 1949 - ", 1950 - "", 1951 - "│ line 0still line 0 1952 - ", 1953 - "", 1954 - "│ line 0still line 0 1955 - │ line 1 1956 - ", 1957 - ] 1958 - `; 1959 - 1960 - exports[`prompts (isCI = false) > taskLog > message > raw = true works when started with non-raw messages 1`] = ` 1961 - [ 1962 - "│ 1963 - ", 1964 - "◇ foo 1965 - ", 1966 - "│ 1967 - ", 1968 - "│ line 0 1969 - ", 1970 - "", 1971 - "│ line 0 1972 - │ line 1 1973 - ", 1974 - "", 1975 - "│ line 0 1976 - │ line 1still line 1 1977 - ", 1978 - ] 1979 - `; 1980 - 1981 - exports[`prompts (isCI = false) > taskLog > retainLog > error > outputs limited log with limit by default 1`] = ` 1982 - [ 1983 - "│ 1984 - ", 1985 - "◇ foo 1986 - ", 1987 - "│ 1988 - ", 1989 - "│ line 0 1990 - ", 1991 - "", 1992 - "│ line 0 1993 - │ line 1 1994 - ", 1995 - "", 1996 - "│ line 1 1997 - │ line 2 1998 - ", 1999 - "", 2000 - "│ line 2 2001 - │ line 3 2002 - ", 2003 - "", 2004 - "│ 2005 - ■ woo! 2006 - ", 2007 - "│ 2008 - │ line 2 2009 - │ line 3 2010 - ", 2011 - ] 2012 - `; 2013 - 2014 - exports[`prompts (isCI = false) > taskLog > retainLog > error > retainLog = false outputs full log without limit 1`] = ` 2015 - [ 2016 - "│ 2017 - ", 2018 - "◇ foo 2019 - ", 2020 - "│ 2021 - ", 2022 - "│ line 0 2023 - ", 2024 - "", 2025 - "│ line 0 2026 - │ line 1 2027 - ", 2028 - "", 2029 - "│ line 0 2030 - │ line 1 2031 - │ line 2 2032 - ", 2033 - "", 2034 - "│ line 0 2035 - │ line 1 2036 - │ line 2 2037 - │ line 3 2038 - ", 2039 - "", 2040 - "│ 2041 - ■ woo! 2042 - ", 2043 - "│ 2044 - │ line 0 2045 - │ line 1 2046 - │ line 2 2047 - │ line 3 2048 - ", 2049 - ] 2050 - `; 2051 - 2052 - exports[`prompts (isCI = false) > taskLog > retainLog > error > retainLog = false outputs limited log with limit 1`] = ` 2053 - [ 2054 - "│ 2055 - ", 2056 - "◇ foo 2057 - ", 2058 - "│ 2059 - ", 2060 - "│ line 0 2061 - ", 2062 - "", 2063 - "│ line 0 2064 - │ line 1 2065 - ", 2066 - "", 2067 - "│ line 1 2068 - │ line 2 2069 - ", 2070 - "", 2071 - "│ line 2 2072 - │ line 3 2073 - ", 2074 - "", 2075 - "│ 2076 - ■ woo! 2077 - ", 2078 - "│ 2079 - │ line 2 2080 - │ line 3 2081 - ", 2082 - ] 2083 - `; 2084 - 2085 - exports[`prompts (isCI = false) > taskLog > retainLog > error > retainLog = true outputs full log 1`] = ` 2086 - [ 2087 - "│ 2088 - ", 2089 - "◇ foo 2090 - ", 2091 - "│ 2092 - ", 2093 - "│ line 0 2094 - ", 2095 - "", 2096 - "│ line 0 2097 - │ line 1 2098 - ", 2099 - "", 2100 - "│ line 0 2101 - │ line 1 2102 - │ line 2 2103 - ", 2104 - "", 2105 - "│ line 0 2106 - │ line 1 2107 - │ line 2 2108 - │ line 3 2109 - ", 2110 - "", 2111 - "│ 2112 - ■ woo! 2113 - ", 2114 - "│ 2115 - │ line 0 2116 - │ line 1 2117 - │ line 2 2118 - │ line 3 2119 - ", 2120 - ] 2121 - `; 2122 - 2123 - exports[`prompts (isCI = false) > taskLog > retainLog > error > retainLog = true outputs full log with limit 1`] = ` 2124 - [ 2125 - "│ 2126 - ", 2127 - "◇ foo 2128 - ", 2129 - "│ 2130 - ", 2131 - "│ line 0 2132 - ", 2133 - "", 2134 - "│ line 0 2135 - │ line 1 2136 - ", 2137 - "", 2138 - "│ line 1 2139 - │ line 2 2140 - ", 2141 - "", 2142 - "│ line 2 2143 - │ line 3 2144 - ", 2145 - "", 2146 - "│ 2147 - ■ woo! 2148 - ", 2149 - "│ 2150 - │ line 0 2151 - │ line 1 2152 - │ line 2 2153 - │ line 3 2154 - ", 2155 - ] 2156 - `; 2157 - 2158 - exports[`prompts (isCI = false) > taskLog > retainLog > success > outputs limited log with limit by default 1`] = ` 2159 - [ 2160 - "│ 2161 - ", 2162 - "◇ foo 2163 - ", 2164 - "│ 2165 - ", 2166 - "│ line 0 2167 - ", 2168 - "", 2169 - "│ line 0 2170 - │ line 1 2171 - ", 2172 - "", 2173 - "│ line 1 2174 - │ line 2 2175 - ", 2176 - "", 2177 - "│ line 2 2178 - │ line 3 2179 - ", 2180 - "", 2181 - "│ 2182 - ◆ woo! 2183 - ", 2184 - "│ 2185 - │ line 2 2186 - │ line 3 2187 - ", 2188 - ] 2189 - `; 2190 - 2191 - exports[`prompts (isCI = false) > taskLog > retainLog > success > retainLog = false outputs full log without limit 1`] = ` 2192 - [ 2193 - "│ 2194 - ", 2195 - "◇ foo 2196 - ", 2197 - "│ 2198 - ", 2199 - "│ line 0 2200 - ", 2201 - "", 2202 - "│ line 0 2203 - │ line 1 2204 - ", 2205 - "", 2206 - "│ line 0 2207 - │ line 1 2208 - │ line 2 2209 - ", 2210 - "", 2211 - "│ line 0 2212 - │ line 1 2213 - │ line 2 2214 - │ line 3 2215 - ", 2216 - "", 2217 - "│ 2218 - ◆ woo! 2219 - ", 2220 - "│ 2221 - │ line 0 2222 - │ line 1 2223 - │ line 2 2224 - │ line 3 2225 - ", 2226 - ] 2227 - `; 2228 - 2229 - exports[`prompts (isCI = false) > taskLog > retainLog > success > retainLog = false outputs limited log with limit 1`] = ` 2230 - [ 2231 - "│ 2232 - ", 2233 - "◇ foo 2234 - ", 2235 - "│ 2236 - ", 2237 - "│ line 0 2238 - ", 2239 - "", 2240 - "│ line 0 2241 - │ line 1 2242 - ", 2243 - "", 2244 - "│ line 1 2245 - │ line 2 2246 - ", 2247 - "", 2248 - "│ line 2 2249 - │ line 3 2250 - ", 2251 - "", 2252 - "│ 2253 - ◆ woo! 2254 - ", 2255 - "│ 2256 - │ line 2 2257 - │ line 3 2258 - ", 2259 - ] 2260 - `; 2261 - 2262 - exports[`prompts (isCI = false) > taskLog > retainLog > success > retainLog = true outputs full log 1`] = ` 2263 - [ 2264 - "│ 2265 - ", 2266 - "◇ foo 2267 - ", 2268 - "│ 2269 - ", 2270 - "│ line 0 2271 - ", 2272 - "", 2273 - "│ line 0 2274 - │ line 1 2275 - ", 2276 - "", 2277 - "│ line 0 2278 - │ line 1 2279 - │ line 2 2280 - ", 2281 - "", 2282 - "│ line 0 2283 - │ line 1 2284 - │ line 2 2285 - │ line 3 2286 - ", 2287 - "", 2288 - "│ 2289 - ◆ woo! 2290 - ", 2291 - "│ 2292 - │ line 0 2293 - │ line 1 2294 - │ line 2 2295 - │ line 3 2296 - ", 2297 - ] 2298 - `; 2299 - 2300 - exports[`prompts (isCI = false) > taskLog > retainLog > success > retainLog = true outputs full log with limit 1`] = ` 2301 - [ 2302 - "│ 2303 - ", 2304 - "◇ foo 2305 - ", 2306 - "│ 2307 - ", 2308 - "│ line 0 2309 - ", 2310 - "", 2311 - "│ line 0 2312 - │ line 1 2313 - ", 2314 - "", 2315 - "│ line 1 2316 - │ line 2 2317 - ", 2318 - "", 2319 - "│ line 2 2320 - │ line 3 2321 - ", 2322 - "", 2323 - "│ 2324 - ◆ woo! 2325 - ", 2326 - "│ 2327 - │ line 0 2328 - │ line 1 2329 - │ line 2 2330 - │ line 3 2331 - ", 2332 - ] 2333 - `; 2334 - 2335 - exports[`prompts (isCI = false) > taskLog > success > clears output and renders message 1`] = ` 2336 - [ 2337 - "│ 2338 - ", 2339 - "◇ foo 2340 - ", 2341 - "│ 2342 - ", 2343 - "│ line 0 2344 - ", 2345 - "", 2346 - "│ line 0 2347 - │ line 1 2348 - ", 2349 - "", 2350 - "│ 2351 - ◆ success! 2352 - ", 2353 - ] 2354 - `; 2355 - 2356 - exports[`prompts (isCI = false) > taskLog > success > renders output if showLog = true 1`] = ` 2357 - [ 2358 - "│ 2359 - ", 2360 - "◇ foo 2361 - ", 2362 - "│ 2363 - ", 2364 - "│ line 0 2365 - ", 2366 - "", 2367 - "│ line 0 2368 - │ line 1 2369 - ", 2370 - "", 2371 - "│ 2372 - ◆ success! 2373 - ", 2374 - "│ 2375 - │ line 0 2376 - │ line 1 2377 - ", 2378 - ] 2379 - `; 2380 - 2381 - exports[`prompts (isCI = false) > taskLog > writes message header 1`] = ` 2382 - [ 2383 - "│ 2384 - ", 2385 - "◇ foo 2386 - ", 2387 - "│ 2388 - ", 2389 - ] 2390 - `; 2391 - 2392 - exports[`prompts (isCI = false) > text > can cancel 1`] = ` 2393 - [ 2394 - "[?25l", 2395 - "│ 2396 - ◆ foo 2397 - │ _ 2398 - └ 2399 - ", 2400 - "", 2401 - "", 2402 - "", 2403 - "■ foo 2404 - │", 2405 - " 2406 - ", 2407 - "[?25h", 2408 - ] 2409 - `; 2410 - 2411 - exports[`prompts (isCI = false) > text > defaultValue sets the value but does not render 1`] = ` 2412 - [ 2413 - "[?25l", 2414 - "│ 2415 - ◆ foo 2416 - │ _ 2417 - └ 2418 - ", 2419 - "", 2420 - "", 2421 - "", 2422 - "◇ foo 2423 - │ bar", 2424 - " 2425 - ", 2426 - "[?25h", 2427 - ] 2428 - `; 2429 - 2430 - exports[`prompts (isCI = false) > text > renders cancelled value if one set 1`] = ` 2431 - [ 2432 - "[?25l", 2433 - "│ 2434 - ◆ foo 2435 - │ _ 2436 - └ 2437 - ", 2438 - "", 2439 - "", 2440 - "", 2441 - "│ x█", 2442 - "", 2443 - "", 2444 - "", 2445 - "", 2446 - "│ xy█", 2447 - "", 2448 - "", 2449 - "", 2450 - "", 2451 - "■ foo 2452 - │ xy 2453 - │", 2454 - " 2455 - ", 2456 - "[?25h", 2457 - ] 2458 - `; 2459 - 2460 - exports[`prompts (isCI = false) > text > renders message 1`] = ` 2461 - [ 2462 - "[?25l", 2463 - "│ 2464 - ◆ foo 2465 - │ _ 2466 - └ 2467 - ", 2468 - "", 2469 - "", 2470 - "", 2471 - "◇ foo 2472 - │ undefined", 2473 - " 2474 - ", 2475 - "[?25h", 2476 - ] 2477 - `; 2478 - 2479 - exports[`prompts (isCI = false) > text > renders placeholder if set 1`] = ` 2480 - [ 2481 - "[?25l", 2482 - "│ 2483 - ◆ foo 2484 - │ bar 2485 - └ 2486 - ", 2487 - "", 2488 - "", 2489 - "", 2490 - "◇ foo 2491 - │ bar", 2492 - " 2493 - ", 2494 - "[?25h", 2495 - ] 2496 - `; 2497 - 2498 - exports[`prompts (isCI = false) > text > renders submitted value 1`] = ` 2499 - [ 2500 - "[?25l", 2501 - "│ 2502 - ◆ foo 2503 - │ _ 2504 - └ 2505 - ", 2506 - "", 2507 - "", 2508 - "", 2509 - "│ x█", 2510 - "", 2511 - "", 2512 - "", 2513 - "", 2514 - "│ xy█", 2515 - "", 2516 - "", 2517 - "", 2518 - "", 2519 - "◇ foo 2520 - │ xy", 2521 - " 2522 - ", 2523 - "[?25h", 2524 - ] 2525 - `; 2526 - 2527 - exports[`prompts (isCI = false) > text > validation errors render and clear (using Error) 1`] = ` 2528 - [ 2529 - "[?25l", 2530 - "│ 2531 - ◆ foo 2532 - │ _ 2533 - └ 2534 - ", 2535 - "", 2536 - "", 2537 - "", 2538 - "│ x█", 2539 - "", 2540 - "", 2541 - "", 2542 - "", 2543 - "▲ foo 2544 - │ x█ 2545 - └ should be xy 2546 - ", 2547 - "", 2548 - "", 2549 - "", 2550 - "◆ foo 2551 - │ xy█ 2552 - └ 2553 - ", 2554 - "", 2555 - "", 2556 - "", 2557 - "◇ foo 2558 - │ xy", 2559 - " 2560 - ", 2561 - "[?25h", 2562 - ] 2563 - `; 2564 - 2565 - exports[`prompts (isCI = false) > text > validation errors render and clear 1`] = ` 2566 - [ 2567 - "[?25l", 2568 - "│ 2569 - ◆ foo 2570 - │ _ 2571 - └ 2572 - ", 2573 - "", 2574 - "", 2575 - "", 2576 - "│ x█", 2577 - "", 2578 - "", 2579 - "", 2580 - "", 2581 - "▲ foo 2582 - │ x█ 2583 - └ should be xy 2584 - ", 2585 - "", 2586 - "", 2587 - "", 2588 - "◆ foo 2589 - │ xy█ 2590 - └ 2591 - ", 2592 - "", 2593 - "", 2594 - "", 2595 - "◇ foo 2596 - │ xy", 2597 - " 2598 - ", 2599 - "[?25h", 2600 - ] 2601 - `; 2602 - 2603 - exports[`prompts (isCI = true) > confirm > can cancel 1`] = ` 2604 - [ 2605 - "[?25l", 2606 - "│ 2607 - ◆ foo 2608 - │ ● Yes / ○ No 2609 - └ 2610 - ", 2611 - "", 2612 - "", 2613 - "", 2614 - "■ foo 2615 - │ No 2616 - │", 2617 - " 2618 - ", 2619 - "[?25h", 2620 - ] 2621 - `; 2622 - 2623 - exports[`prompts (isCI = true) > confirm > can set initialValue 1`] = ` 2624 - [ 2625 - "[?25l", 2626 - "│ 2627 - ◆ foo 2628 - │ ○ Yes / ● No 2629 - └ 2630 - ", 2631 - "", 2632 - "", 2633 - "", 2634 - "◇ foo 2635 - │ No", 2636 - " 2637 - ", 2638 - "[?25h", 2639 - ] 2640 - `; 2641 - 2642 - exports[`prompts (isCI = true) > confirm > left arrow moves to previous choice 1`] = ` 2643 - [ 2644 - "[?25l", 2645 - "│ 2646 - ◆ foo 2647 - │ ● Yes / ○ No 2648 - └ 2649 - ", 2650 - "", 2651 - "", 2652 - "", 2653 - "│ ○ Yes / ● No", 2654 - "", 2655 - "", 2656 - "", 2657 - "", 2658 - "│ ● Yes / ○ No", 2659 - "", 2660 - "", 2661 - "", 2662 - "", 2663 - "◇ foo 2664 - │ Yes", 2665 - " 2666 - ", 2667 - "[?25h", 2668 - ] 2669 - `; 2670 - 2671 - exports[`prompts (isCI = true) > confirm > renders custom active choice 1`] = ` 2672 - [ 2673 - "[?25l", 2674 - "│ 2675 - ◆ foo 2676 - │ ● bleep / ○ No 2677 - └ 2678 - ", 2679 - "", 2680 - "", 2681 - "", 2682 - "◇ foo 2683 - │ bleep", 2684 - " 2685 - ", 2686 - "[?25h", 2687 - ] 2688 - `; 2689 - 2690 - exports[`prompts (isCI = true) > confirm > renders custom inactive choice 1`] = ` 2691 - [ 2692 - "[?25l", 2693 - "│ 2694 - ◆ foo 2695 - │ ● Yes / ○ bleep 2696 - └ 2697 - ", 2698 - "", 2699 - "", 2700 - "", 2701 - "◇ foo 2702 - │ Yes", 2703 - " 2704 - ", 2705 - "[?25h", 2706 - ] 2707 - `; 2708 - 2709 - exports[`prompts (isCI = true) > confirm > renders message with choices 1`] = ` 2710 - [ 2711 - "[?25l", 2712 - "│ 2713 - ◆ foo 2714 - │ ● Yes / ○ No 2715 - └ 2716 - ", 2717 - "", 2718 - "", 2719 - "", 2720 - "◇ foo 2721 - │ Yes", 2722 - " 2723 - ", 2724 - "[?25h", 2725 - ] 2726 - `; 2727 - 2728 - exports[`prompts (isCI = true) > confirm > right arrow moves to next choice 1`] = ` 2729 - [ 2730 - "[?25l", 2731 - "│ 2732 - ◆ foo 2733 - │ ● Yes / ○ No 2734 - └ 2735 - ", 2736 - "", 2737 - "", 2738 - "", 2739 - "│ ○ Yes / ● No", 2740 - "", 2741 - "", 2742 - "", 2743 - "", 2744 - "◇ foo 2745 - │ No", 2746 - " 2747 - ", 2748 - "[?25h", 2749 - ] 2750 - `; 2751 - 2752 - exports[`prompts (isCI = true) > groupMultiselect > can deselect an option 1`] = ` 2753 - [ 2754 - "[?25l", 2755 - "│ 2756 - ◆ foo 2757 - │ ◻ group1 2758 - │ │ ◻ group1value0 2759 - │ └ ◻ group1value1 2760 - └ 2761 - ", 2762 - "", 2763 - "", 2764 - "", 2765 - "│ ◻ group1 2766 - │ │ ◻ group1value0 2767 - │ └ ◻ group1value1 2768 - └ 2769 - ", 2770 - "", 2771 - "", 2772 - "", 2773 - "│ │ ◼ group1value0", 2774 - "", 2775 - "", 2776 - "", 2777 - "", 2778 - "│ │ ◼ group1value0 2779 - │ └ ◻ group1value1 2780 - └ 2781 - ", 2782 - "", 2783 - "", 2784 - "", 2785 - "│ ◼ group1 2786 - │ │ ◼ group1value0 2787 - │ └ ◼ group1value1 2788 - └ 2789 - ", 2790 - "", 2791 - "", 2792 - "", 2793 - "│ ◻ group1 2794 - │ │ ◼ group1value0 2795 - │ └ ◻ group1value1 2796 - └ 2797 - ", 2798 - "", 2799 - "", 2800 - "", 2801 - "◇ foo 2802 - │ group1value0", 2803 - " 2804 - ", 2805 - "[?25h", 2806 - ] 2807 - `; 2808 - 2809 - exports[`prompts (isCI = true) > groupMultiselect > can select a group 1`] = ` 2810 - [ 2811 - "[?25l", 2812 - "│ 2813 - ◆ foo 2814 - │ ◻ group1 2815 - │ │ ◻ group1value0 2816 - │ └ ◻ group1value1 2817 - └ 2818 - ", 2819 - "", 2820 - "", 2821 - "", 2822 - "│ ◼ group1 2823 - │ │ ◼ group1value0 2824 - │ └ ◼ group1value1 2825 - └ 2826 - ", 2827 - "", 2828 - "", 2829 - "", 2830 - "◇ foo 2831 - │ group1value0, group1value1", 2832 - " 2833 - ", 2834 - "[?25h", 2835 - ] 2836 - `; 2837 - 2838 - exports[`prompts (isCI = true) > groupMultiselect > can select a group by selecting all members 1`] = ` 2839 - [ 2840 - "[?25l", 2841 - "│ 2842 - ◆ foo 2843 - │ ◻ group1 2844 - │ │ ◻ group1value0 2845 - │ └ ◻ group1value1 2846 - └ 2847 - ", 2848 - "", 2849 - "", 2850 - "", 2851 - "│ ◻ group1 2852 - │ │ ◻ group1value0 2853 - │ └ ◻ group1value1 2854 - └ 2855 - ", 2856 - "", 2857 - "", 2858 - "", 2859 - "│ │ ◼ group1value0", 2860 - "", 2861 - "", 2862 - "", 2863 - "", 2864 - "│ │ ◼ group1value0 2865 - │ └ ◻ group1value1 2866 - └ 2867 - ", 2868 - "", 2869 - "", 2870 - "", 2871 - "│ ◼ group1 2872 - │ │ ◼ group1value0 2873 - │ └ ◼ group1value1 2874 - └ 2875 - ", 2876 - "", 2877 - "", 2878 - "", 2879 - "◇ foo 2880 - │ group1value0, group1value1", 2881 - " 2882 - ", 2883 - "[?25h", 2884 - ] 2885 - `; 2886 - 2887 - exports[`prompts (isCI = true) > groupMultiselect > can select multiple options 1`] = ` 2888 - [ 2889 - "[?25l", 2890 - "│ 2891 - ◆ foo 2892 - │ ◻ group1 2893 - │ │ ◻ group1value0 2894 - │ │ ◻ group1value1 2895 - │ └ ◻ group1value2 2896 - └ 2897 - ", 2898 - "", 2899 - "", 2900 - "", 2901 - "│ ◻ group1 2902 - │ │ ◻ group1value0 2903 - │ │ ◻ group1value1 2904 - │ └ ◻ group1value2 2905 - └ 2906 - ", 2907 - "", 2908 - "", 2909 - "", 2910 - "│ │ ◼ group1value0", 2911 - "", 2912 - "", 2913 - "", 2914 - "", 2915 - "│ │ ◼ group1value0 2916 - │ │ ◻ group1value1 2917 - │ └ ◻ group1value2 2918 - └ 2919 - ", 2920 - "", 2921 - "", 2922 - "", 2923 - "│ │ ◼ group1value1", 2924 - "", 2925 - "", 2926 - "", 2927 - "", 2928 - "◇ foo 2929 - │ group1value0, group1value1", 2930 - " 2931 - ", 2932 - "[?25h", 2933 - ] 2934 - `; 2935 - 2936 - exports[`prompts (isCI = true) > groupMultiselect > can submit empty selection when require = false 1`] = ` 2937 - [ 2938 - "[?25l", 2939 - "│ 2940 - ◆ foo 2941 - │ ◻ group1 2942 - │ │ ◻ group1value0 2943 - │ └ ◻ group1value1 2944 - └ 2945 - ", 2946 - "", 2947 - "", 2948 - "", 2949 - "◇ foo 2950 - │", 2951 - " 2952 - ", 2953 - "[?25h", 2954 - ] 2955 - `; 2956 - 2957 - exports[`prompts (isCI = true) > groupMultiselect > cursorAt sets initial selection 1`] = ` 2958 - [ 2959 - "[?25l", 2960 - "│ 2961 - ◆ foo 2962 - │ ◻ group1 2963 - │ │ ◻ group1value0 2964 - │ └ ◻ group1value1 2965 - └ 2966 - ", 2967 - "", 2968 - "", 2969 - "", 2970 - "│ └ ◼ group1value1", 2971 - "", 2972 - "", 2973 - "", 2974 - "", 2975 - "◇ foo 2976 - │ group1value1", 2977 - " 2978 - ", 2979 - "[?25h", 2980 - ] 2981 - `; 2982 - 2983 - exports[`prompts (isCI = true) > groupMultiselect > groupSpacing > negative spacing is ignored 1`] = ` 2984 - [ 2985 - "[?25l", 2986 - "│ 2987 - ◆ foo 2988 - │ ◻ group1 2989 - │ └ ◻ group1value0 2990 - │ ◻ group2 2991 - │ └ ◻ group2value0 2992 - └ 2993 - ", 2994 - "", 2995 - "", 2996 - "", 2997 - "│ ◻ group1 2998 - │ └ ◻ group1value0 2999 - │ ◻ group2 3000 - │ └ ◻ group2value0 3001 - └ 3002 - ", 3003 - "", 3004 - "", 3005 - "", 3006 - "│ ◼ group1 3007 - │ └ ◼ group1value0 3008 - │ ◻ group2 3009 - │ └ ◻ group2value0 3010 - └ 3011 - ", 3012 - "", 3013 - "", 3014 - "", 3015 - "◇ foo 3016 - │ group1value0", 3017 - " 3018 - ", 3019 - "[?25h", 3020 - ] 3021 - `; 3022 - 3023 - exports[`prompts (isCI = true) > groupMultiselect > groupSpacing > renders spaced groups 1`] = ` 3024 - [ 3025 - "[?25l", 3026 - "│ 3027 - ◆ foo 3028 - │ 3029 - │ 3030 - │ ◻ group1 3031 - │ └ ◻ group1value0 3032 - │ 3033 - │ 3034 - │ ◻ group2 3035 - │ └ ◻ group2value0 3036 - └ 3037 - ", 3038 - "", 3039 - "", 3040 - "", 3041 - "│ ◻ group1 3042 - │ └ ◻ group1value0 3043 - │ 3044 - │ 3045 - │ ◻ group2 3046 - │ └ ◻ group2value0 3047 - └ 3048 - ", 3049 - "", 3050 - "", 3051 - "", 3052 - "│ ◼ group1 3053 - │ └ ◼ group1value0 3054 - │ 3055 - │ 3056 - │ ◻ group2 3057 - │ └ ◻ group2value0 3058 - └ 3059 - ", 3060 - "", 3061 - "", 3062 - "", 3063 - "◇ foo 3064 - │ group1value0", 3065 - " 3066 - ", 3067 - "[?25h", 3068 - ] 3069 - `; 3070 - 3071 - exports[`prompts (isCI = true) > groupMultiselect > initial values can be set 1`] = ` 3072 - [ 3073 - "[?25l", 3074 - "│ 3075 - ◆ foo 3076 - │ ◻ group1 3077 - │ │ ◻ group1value0 3078 - │ └ ◼ group1value1 3079 - └ 3080 - ", 3081 - "", 3082 - "", 3083 - "", 3084 - "◇ foo 3085 - │ group1value1", 3086 - " 3087 - ", 3088 - "[?25h", 3089 - ] 3090 - `; 3091 - 3092 - exports[`prompts (isCI = true) > groupMultiselect > renders error when nothing selected 1`] = ` 3093 - [ 3094 - "[?25l", 3095 - "│ 3096 - ◆ foo 3097 - │ ◻ group1 3098 - │ │ ◻ group1value0 3099 - │ └ ◻ group1value1 3100 - └ 3101 - ", 3102 - "", 3103 - "", 3104 - "", 3105 - "▲ foo 3106 - │ ◻ group1 3107 - │ │ ◻ group1value0 3108 - │ └ ◻ group1value1 3109 - └ Please select at least one option. 3110 - Press  space  to select,  enter  to submit 3111 - ", 3112 - "", 3113 - "", 3114 - "", 3115 - "◆ foo 3116 - │ ◻ group1 3117 - │ │ ◻ group1value0 3118 - │ └ ◻ group1value1 3119 - └ 3120 - ", 3121 - "", 3122 - "", 3123 - "", 3124 - "│ │ ◼ group1value0", 3125 - "", 3126 - "", 3127 - "", 3128 - "", 3129 - "◇ foo 3130 - │ group1value0", 3131 - " 3132 - ", 3133 - "[?25h", 3134 - ] 3135 - `; 3136 - 3137 - exports[`prompts (isCI = true) > groupMultiselect > renders message with options 1`] = ` 3138 - [ 3139 - "[?25l", 3140 - "│ 3141 - ◆ foo 3142 - │ ◻ group1 3143 - │ │ ◻ group1value0 3144 - │ └ ◻ group1value1 3145 - │ ◻ group2 3146 - │ └ ◻ group2value0 3147 - └ 3148 - ", 3149 - "", 3150 - "", 3151 - "", 3152 - "│ ◻ group1 3153 - │ │ ◻ group1value0 3154 - │ └ ◻ group1value1 3155 - │ ◻ group2 3156 - │ └ ◻ group2value0 3157 - └ 3158 - ", 3159 - "", 3160 - "", 3161 - "", 3162 - "│ │ ◼ group1value0", 3163 - "", 3164 - "", 3165 - "", 3166 - "", 3167 - "◇ foo 3168 - │ group1value0", 3169 - " 3170 - ", 3171 - "[?25h", 3172 - ] 3173 - `; 3174 - 3175 - exports[`prompts (isCI = true) > groupMultiselect > selectableGroups = false > cannot select groups 1`] = ` 3176 - [ 3177 - "[?25l", 3178 - "│ 3179 - ◆ foo 3180 - │  group1 3181 - │  ◻ group1value0 3182 - │  ◻ group1value1 3183 - └ 3184 - ", 3185 - "", 3186 - "", 3187 - "", 3188 - "│  ◼ group1value0", 3189 - "", 3190 - "", 3191 - "", 3192 - "", 3193 - "◇ foo 3194 - │ group1value0", 3195 - " 3196 - ", 3197 - "[?25h", 3198 - ] 3199 - `; 3200 - 3201 - exports[`prompts (isCI = true) > groupMultiselect > selectableGroups = false > selecting all members of group does not select group 1`] = ` 3202 - [ 3203 - "[?25l", 3204 - "│ 3205 - ◆ foo 3206 - │  group1 3207 - │  ◻ group1value0 3208 - │  ◻ group1value1 3209 - └ 3210 - ", 3211 - "", 3212 - "", 3213 - "", 3214 - "│  ◼ group1value0", 3215 - "", 3216 - "", 3217 - "", 3218 - "", 3219 - "│  ◼ group1value0 3220 - │  ◻ group1value1 3221 - └ 3222 - ", 3223 - "", 3224 - "", 3225 - "", 3226 - "│  ◼ group1value1", 3227 - "", 3228 - "", 3229 - "", 3230 - "", 3231 - "◇ foo 3232 - │ group1value0, group1value1", 3233 - " 3234 - ", 3235 - "[?25h", 3236 - ] 3237 - `; 3238 - 3239 - exports[`prompts (isCI = true) > groupMultiselect > values can be non-primitive 1`] = ` 3240 - [ 3241 - "[?25l", 3242 - "│ 3243 - ◆ foo 3244 - │ ◻ group1 3245 - │ │ ◻ value0 3246 - │ └ ◻ value1 3247 - └ 3248 - ", 3249 - "", 3250 - "", 3251 - "", 3252 - "│ ◻ group1 3253 - │ │ ◻ value0 3254 - │ └ ◻ value1 3255 - └ 3256 - ", 3257 - "", 3258 - "", 3259 - "", 3260 - "│ │ ◼ value0", 3261 - "", 3262 - "", 3263 - "", 3264 - "", 3265 - "◇ foo 3266 - │ value0", 3267 - " 3268 - ", 3269 - "[?25h", 3270 - ] 3271 - `; 3272 - 3273 - exports[`prompts (isCI = true) > multiselect > can cancel 1`] = ` 3274 - [ 3275 - "[?25l", 3276 - "│ 3277 - ◆ foo 3278 - │ ◻ opt0 3279 - │ ◻ opt1 3280 - └ 3281 - ", 3282 - "", 3283 - "", 3284 - "", 3285 - "■ foo 3286 - │", 3287 - " 3288 - ", 3289 - "[?25h", 3290 - ] 3291 - `; 3292 - 3293 - exports[`prompts (isCI = true) > multiselect > can render option hints 1`] = ` 3294 - [ 3295 - "[?25l", 3296 - "│ 3297 - ◆ foo 3298 - │ ◻ opt0 (Hint 0) 3299 - │ ◻ opt1 3300 - └ 3301 - ", 3302 - "", 3303 - "", 3304 - "", 3305 - "│ ◼ opt0 (Hint 0)", 3306 - "", 3307 - "", 3308 - "", 3309 - "", 3310 - "◇ foo 3311 - │ opt0", 3312 - " 3313 - ", 3314 - "[?25h", 3315 - ] 3316 - `; 3317 - 3318 - exports[`prompts (isCI = true) > multiselect > can set cursorAt to preselect an option 1`] = ` 3319 - [ 3320 - "[?25l", 3321 - "│ 3322 - ◆ foo 3323 - │ ◻ opt0 3324 - │ ◻ opt1 3325 - └ 3326 - ", 3327 - "", 3328 - "", 3329 - "", 3330 - "│ ◼ opt1", 3331 - "", 3332 - "", 3333 - "", 3334 - "", 3335 - "◇ foo 3336 - │ opt1", 3337 - " 3338 - ", 3339 - "[?25h", 3340 - ] 3341 - `; 3342 - 3343 - exports[`prompts (isCI = true) > multiselect > can set custom labels 1`] = ` 3344 - [ 3345 - "[?25l", 3346 - "│ 3347 - ◆ foo 3348 - │ ◻ Option 0 3349 - │ ◻ Option 1 3350 - └ 3351 - ", 3352 - "", 3353 - "", 3354 - "", 3355 - "│ ◼ Option 0", 3356 - "", 3357 - "", 3358 - "", 3359 - "", 3360 - "◇ foo 3361 - │ Option 0", 3362 - " 3363 - ", 3364 - "[?25h", 3365 - ] 3366 - `; 3367 - 3368 - exports[`prompts (isCI = true) > multiselect > can set initial values 1`] = ` 3369 - [ 3370 - "[?25l", 3371 - "│ 3372 - ◆ foo 3373 - │ ◻ opt0 3374 - │ ◼ opt1 3375 - └ 3376 - ", 3377 - "", 3378 - "", 3379 - "", 3380 - "◇ foo 3381 - │ opt1", 3382 - " 3383 - ", 3384 - "[?25h", 3385 - ] 3386 - `; 3387 - 3388 - exports[`prompts (isCI = true) > multiselect > can submit without selection when required = false 1`] = ` 3389 - [ 3390 - "[?25l", 3391 - "│ 3392 - ◆ foo 3393 - │ ◻ opt0 3394 - │ ◻ opt1 3395 - └ 3396 - ", 3397 - "", 3398 - "", 3399 - "", 3400 - "◇ foo 3401 - │ none", 3402 - " 3403 - ", 3404 - "[?25h", 3405 - ] 3406 - `; 3407 - 3408 - exports[`prompts (isCI = true) > multiselect > maxItems renders a sliding window 1`] = ` 3409 - [ 3410 - "[?25l", 3411 - "│ 3412 - ◆ foo 3413 - │ ◻ opt0 3414 - │ ◻ opt1 3415 - │ ◻ opt2 3416 - │ ◻ opt3 3417 - │ ◻ opt4 3418 - │ ... 3419 - └ 3420 - ", 3421 - "", 3422 - "", 3423 - "", 3424 - "│ ◻ opt0 3425 - │ ◻ opt1 3426 - │ ◻ opt2 3427 - │ ◻ opt3 3428 - │ ◻ opt4 3429 - │ ... 3430 - └ 3431 - ", 3432 - "", 3433 - "", 3434 - "", 3435 - "│ ◻ opt1 3436 - │ ◻ opt2 3437 - │ ◻ opt3 3438 - │ ◻ opt4 3439 - │ ... 3440 - └ 3441 - ", 3442 - "", 3443 - "", 3444 - "", 3445 - "│ ◻ opt2 3446 - │ ◻ opt3 3447 - │ ◻ opt4 3448 - │ ... 3449 - └ 3450 - ", 3451 - "", 3452 - "", 3453 - "", 3454 - "│ ... 3455 - │ ◻ opt2 3456 - │ ◻ opt3 3457 - │ ◻ opt4 3458 - │ ◻ opt5 3459 - │ ... 3460 - └ 3461 - ", 3462 - "", 3463 - "", 3464 - "", 3465 - "│ ◻ opt3 3466 - │ ◻ opt4 3467 - │ ◻ opt5 3468 - │ ◻ opt6 3469 - │ ... 3470 - └ 3471 - ", 3472 - "", 3473 - "", 3474 - "", 3475 - "│ ◻ opt4 3476 - │ ◻ opt5 3477 - │ ◻ opt6 3478 - │ ◻ opt7 3479 - │ ... 3480 - └ 3481 - ", 3482 - "", 3483 - "", 3484 - "", 3485 - "│ ◼ opt6", 3486 - "", 3487 - "", 3488 - "", 3489 - "", 3490 - "◇ foo 3491 - │ opt6", 3492 - " 3493 - ", 3494 - "[?25h", 3495 - ] 3496 - `; 3497 - 3498 - exports[`prompts (isCI = true) > multiselect > renders message 1`] = ` 3499 - [ 3500 - "[?25l", 3501 - "│ 3502 - ◆ foo 3503 - │ ◻ opt0 3504 - │ ◻ opt1 3505 - └ 3506 - ", 3507 - "", 3508 - "", 3509 - "", 3510 - "│ ◼ opt0", 3511 - "", 3512 - "", 3513 - "", 3514 - "", 3515 - "◇ foo 3516 - │ opt0", 3517 - " 3518 - ", 3519 - "[?25h", 3520 - ] 3521 - `; 3522 - 3523 - exports[`prompts (isCI = true) > multiselect > renders multiple cancelled values 1`] = ` 3524 - [ 3525 - "[?25l", 3526 - "│ 3527 - ◆ foo 3528 - │ ◻ opt0 3529 - │ ◻ opt1 3530 - │ ◻ opt2 3531 - └ 3532 - ", 3533 - "", 3534 - "", 3535 - "", 3536 - "│ ◼ opt0", 3537 - "", 3538 - "", 3539 - "", 3540 - "", 3541 - "│ ◼ opt0 3542 - │ ◻ opt1 3543 - │ ◻ opt2 3544 - └ 3545 - ", 3546 - "", 3547 - "", 3548 - "", 3549 - "│ ◼ opt1", 3550 - "", 3551 - "", 3552 - "", 3553 - "", 3554 - "■ foo 3555 - │ opt0, opt1 3556 - │", 3557 - " 3558 - ", 3559 - "[?25h", 3560 - ] 3561 - `; 3562 - 3563 - exports[`prompts (isCI = true) > multiselect > renders multiple selected options 1`] = ` 3564 - [ 3565 - "[?25l", 3566 - "│ 3567 - ◆ foo 3568 - │ ◻ opt0 3569 - │ ◻ opt1 3570 - │ ◻ opt2 3571 - └ 3572 - ", 3573 - "", 3574 - "", 3575 - "", 3576 - "│ ◼ opt0", 3577 - "", 3578 - "", 3579 - "", 3580 - "", 3581 - "│ ◼ opt0 3582 - │ ◻ opt1 3583 - │ ◻ opt2 3584 - └ 3585 - ", 3586 - "", 3587 - "", 3588 - "", 3589 - "│ ◼ opt1", 3590 - "", 3591 - "", 3592 - "", 3593 - "", 3594 - "│ ◼ opt1 3595 - │ ◻ opt2 3596 - └ 3597 - ", 3598 - "", 3599 - "", 3600 - "", 3601 - "◇ foo 3602 - │ opt0, opt1", 3603 - " 3604 - ", 3605 - "[?25h", 3606 - ] 3607 - `; 3608 - 3609 - exports[`prompts (isCI = true) > multiselect > renders validation errors 1`] = ` 3610 - [ 3611 - "[?25l", 3612 - "│ 3613 - ◆ foo 3614 - │ ◻ opt0 3615 - │ ◻ opt1 3616 - └ 3617 - ", 3618 - "", 3619 - "", 3620 - "", 3621 - "▲ foo 3622 - │ ◻ opt0 3623 - │ ◻ opt1 3624 - └ Please select at least one option. 3625 - Press  space  to select,  enter  to submit 3626 - ", 3627 - "", 3628 - "", 3629 - "", 3630 - "◆ foo 3631 - │ ◼ opt0 3632 - │ ◻ opt1 3633 - └ 3634 - ", 3635 - "", 3636 - "", 3637 - "", 3638 - "◇ foo 3639 - │ opt0", 3640 - " 3641 - ", 3642 - "[?25h", 3643 - ] 3644 - `; 3645 - 3646 - exports[`prompts (isCI = true) > multiselect > shows hints for all selected options 1`] = ` 3647 - [ 3648 - "[?25l", 3649 - "│ 3650 - ◆ foo 3651 - │ ◼ opt0 (Hint 0) 3652 - │ ◼ opt1 (Hint 1) 3653 - │ ◻ opt2 3654 - └ 3655 - ", 3656 - "", 3657 - "", 3658 - "", 3659 - "│ ◼ opt0 (Hint 0) 3660 - │ ◼ opt1 (Hint 1) 3661 - │ ◻ opt2 3662 - └ 3663 - ", 3664 - "", 3665 - "", 3666 - "", 3667 - "│ ◼ opt1 (Hint 1) 3668 - │ ◻ opt2 (Hint 2) 3669 - └ 3670 - ", 3671 - "", 3672 - "", 3673 - "", 3674 - "◇ foo 3675 - │ opt0, opt1", 3676 - " 3677 - ", 3678 - "[?25h", 3679 - ] 3680 - `; 3681 - 3682 - exports[`prompts (isCI = true) > multiselect > sliding window loops downwards 1`] = ` 3683 - [ 3684 - "[?25l", 3685 - "│ 3686 - ◆ foo 3687 - │ ◻ opt0 3688 - │ ◻ opt1 3689 - │ ◻ opt2 3690 - │ ◻ opt3 3691 - │ ◻ opt4 3692 - │ ... 3693 - └ 3694 - ", 3695 - "", 3696 - "", 3697 - "", 3698 - "│ ◻ opt0 3699 - │ ◻ opt1 3700 - │ ◻ opt2 3701 - │ ◻ opt3 3702 - │ ◻ opt4 3703 - │ ... 3704 - └ 3705 - ", 3706 - "", 3707 - "", 3708 - "", 3709 - "│ ◻ opt1 3710 - │ ◻ opt2 3711 - │ ◻ opt3 3712 - │ ◻ opt4 3713 - │ ... 3714 - └ 3715 - ", 3716 - "", 3717 - "", 3718 - "", 3719 - "│ ◻ opt2 3720 - │ ◻ opt3 3721 - │ ◻ opt4 3722 - │ ... 3723 - └ 3724 - ", 3725 - "", 3726 - "", 3727 - "", 3728 - "│ ... 3729 - │ ◻ opt2 3730 - │ ◻ opt3 3731 - │ ◻ opt4 3732 - │ ◻ opt5 3733 - │ ... 3734 - └ 3735 - ", 3736 - "", 3737 - "", 3738 - "", 3739 - "│ ◻ opt3 3740 - │ ◻ opt4 3741 - │ ◻ opt5 3742 - │ ◻ opt6 3743 - │ ... 3744 - └ 3745 - ", 3746 - "", 3747 - "", 3748 - "", 3749 - "│ ◻ opt4 3750 - │ ◻ opt5 3751 - │ ◻ opt6 3752 - │ ◻ opt7 3753 - │ ... 3754 - └ 3755 - ", 3756 - "", 3757 - "", 3758 - "", 3759 - "│ ◻ opt5 3760 - │ ◻ opt6 3761 - │ ◻ opt7 3762 - │ ◻ opt8 3763 - │ ... 3764 - └ 3765 - ", 3766 - "", 3767 - "", 3768 - "", 3769 - "│ ◻ opt6 3770 - │ ◻ opt7 3771 - │ ◻ opt8 3772 - │ ◻ opt9 3773 - │ ... 3774 - └ 3775 - ", 3776 - "", 3777 - "", 3778 - "", 3779 - "│ ◻ opt7 3780 - │ ◻ opt8 3781 - │ ◻ opt9 3782 - │ ◻ opt10 3783 - │ ◻ opt11 3784 - └ 3785 - ", 3786 - "", 3787 - "", 3788 - "", 3789 - "│ ◻ opt9 3790 - │ ◻ opt10 3791 - │ ◻ opt11 3792 - └ 3793 - ", 3794 - "", 3795 - "", 3796 - "", 3797 - "│ ◻ opt10 3798 - │ ◻ opt11 3799 - └ 3800 - ", 3801 - "", 3802 - "", 3803 - "", 3804 - "│ ◻ opt0 3805 - │ ◻ opt1 3806 - │ ◻ opt2 3807 - │ ◻ opt3 3808 - │ ◻ opt4 3809 - │ ... 3810 - └ 3811 - ", 3812 - "", 3813 - "", 3814 - "", 3815 - "│ ◼ opt0", 3816 - "", 3817 - "", 3818 - "", 3819 - "", 3820 - "◇ foo 3821 - │ opt0", 3822 - " 3823 - ", 3824 - "[?25h", 3825 - ] 3826 - `; 3827 - 3828 - exports[`prompts (isCI = true) > multiselect > sliding window loops upwards 1`] = ` 3829 - [ 3830 - "[?25l", 3831 - "│ 3832 - ◆ foo 3833 - │ ◻ opt0 3834 - │ ◻ opt1 3835 - │ ◻ opt2 3836 - │ ◻ opt3 3837 - │ ◻ opt4 3838 - │ ... 3839 - └ 3840 - ", 3841 - "", 3842 - "", 3843 - "", 3844 - "│ ... 3845 - │ ◻ opt7 3846 - │ ◻ opt8 3847 - │ ◻ opt9 3848 - │ ◻ opt10 3849 - │ ◻ opt11 3850 - └ 3851 - ", 3852 - "", 3853 - "", 3854 - "", 3855 - "│ ◼ opt11", 3856 - "", 3857 - "", 3858 - "", 3859 - "", 3860 - "◇ foo 3861 - │ opt11", 3862 - " 3863 - ", 3864 - "[?25h", 3865 - ] 3866 - `; 3867 - 3868 - exports[`prompts (isCI = true) > note > formatter which adds colors works 1`] = ` 3869 - [ 3870 - "│ 3871 - ◇ title ──╮ 3872 - │ │ 3873 - │ line 0 │ 3874 - │ line 1 │ 3875 - │ line 2 │ 3876 - │ │ 3877 - ├──────────╯ 3878 - ", 3879 - ] 3880 - `; 3881 - 3882 - exports[`prompts (isCI = true) > note > formatter which adds length works 1`] = ` 3883 - [ 3884 - "│ 3885 - ◇ title ──────╮ 3886 - │ │ 3887 - │ * line 0 * │ 3888 - │ * line 1 * │ 3889 - │ * line 2 * │ 3890 - │ │ 3891 - ├──────────────╯ 3892 - ", 3893 - ] 3894 - `; 3895 - 3896 - exports[`prompts (isCI = true) > note > renders as wide as longest line 1`] = ` 3897 - [ 3898 - "│ 3899 - ◇ title ───────────────────────────╮ 3900 - │ │ 3901 - │ short │ 3902 - │ somewhat questionably long line │ 3903 - │ │ 3904 - ├───────────────────────────────────╯ 3905 - ", 3906 - ] 3907 - `; 3908 - 3909 - exports[`prompts (isCI = true) > note > renders message with title 1`] = ` 3910 - [ 3911 - "│ 3912 - ◇ title ───╮ 3913 - │ │ 3914 - │ message │ 3915 - │ │ 3916 - ├───────────╯ 3917 - ", 3918 - ] 3919 - `; 3920 - 3921 - exports[`prompts (isCI = true) > password > renders and clears validation errors 1`] = ` 3922 - [ 3923 - "[?25l", 3924 - "│ 3925 - ◆ foo 3926 - │ _ 3927 - └ 3928 - ", 3929 - "", 3930 - "", 3931 - "", 3932 - "│ ▪_", 3933 - "", 3934 - "", 3935 - "", 3936 - "", 3937 - "▲ foo 3938 - │ ▪ 3939 - └ Password must be at least 2 characters 3940 - ", 3941 - "", 3942 - "", 3943 - "", 3944 - "◆ foo 3945 - │ ▪▪_ 3946 - └ 3947 - ", 3948 - "", 3949 - "", 3950 - "", 3951 - "◇ foo 3952 - │ ▪▪", 3953 - " 3954 - ", 3955 - "[?25h", 3956 - ] 3957 - `; 3958 - 3959 - exports[`prompts (isCI = true) > password > renders cancelled value 1`] = ` 3960 - [ 3961 - "[?25l", 3962 - "│ 3963 - ◆ foo 3964 - │ _ 3965 - └ 3966 - ", 3967 - "", 3968 - "", 3969 - "", 3970 - "│ ▪_", 3971 - "", 3972 - "", 3973 - "", 3974 - "", 3975 - "■ foo 3976 - │ ▪ 3977 - │", 3978 - " 3979 - ", 3980 - "[?25h", 3981 - ] 3982 - `; 3983 - 3984 - exports[`prompts (isCI = true) > password > renders custom mask 1`] = ` 3985 - [ 3986 - "[?25l", 3987 - "│ 3988 - ◆ foo 3989 - │ _ 3990 - └ 3991 - ", 3992 - "", 3993 - "", 3994 - "", 3995 - "│ *_", 3996 - "", 3997 - "", 3998 - "", 3999 - "", 4000 - "│ **_", 4001 - "", 4002 - "", 4003 - "", 4004 - "", 4005 - "◇ foo 4006 - │ **", 4007 - " 4008 - ", 4009 - "[?25h", 4010 - ] 4011 - `; 4012 - 4013 - exports[`prompts (isCI = true) > password > renders masked value 1`] = ` 4014 - [ 4015 - "[?25l", 4016 - "│ 4017 - ◆ foo 4018 - │ _ 4019 - └ 4020 - ", 4021 - "", 4022 - "", 4023 - "", 4024 - "│ ▪_", 4025 - "", 4026 - "", 4027 - "", 4028 - "", 4029 - "│ ▪▪_", 4030 - "", 4031 - "", 4032 - "", 4033 - "", 4034 - "◇ foo 4035 - │ ▪▪", 4036 - " 4037 - ", 4038 - "[?25h", 4039 - ] 4040 - `; 4041 - 4042 - exports[`prompts (isCI = true) > password > renders message 1`] = ` 4043 - [ 4044 - "[?25l", 4045 - "│ 4046 - ◆ foo 4047 - │ _ 4048 - └ 4049 - ", 4050 - "", 4051 - "", 4052 - "", 4053 - "◇ foo 4054 - │", 4055 - " 4056 - ", 4057 - "[?25h", 4058 - ] 4059 - `; 4060 - 4061 - exports[`prompts (isCI = true) > select > can cancel 1`] = ` 4062 - [ 4063 - "[?25l", 4064 - "│ 4065 - ◆ foo 4066 - │ ● opt0 4067 - │ ○ opt1 4068 - └ 4069 - ", 4070 - "", 4071 - "", 4072 - "", 4073 - "■ foo 4074 - │ opt0 4075 - │", 4076 - " 4077 - ", 4078 - "[?25h", 4079 - ] 4080 - `; 4081 - 4082 - exports[`prompts (isCI = true) > select > down arrow selects next option 1`] = ` 4083 - [ 4084 - "[?25l", 4085 - "│ 4086 - ◆ foo 4087 - │ ● opt0 4088 - │ ○ opt1 4089 - └ 4090 - ", 4091 - "", 4092 - "", 4093 - "", 4094 - "│ ○ opt0 4095 - │ ● opt1 4096 - └ 4097 - ", 4098 - "", 4099 - "", 4100 - "", 4101 - "◇ foo 4102 - │ opt1", 4103 - " 4104 - ", 4105 - "[?25h", 4106 - ] 4107 - `; 4108 - 4109 - exports[`prompts (isCI = true) > select > renders option hints 1`] = ` 4110 - [ 4111 - "[?25l", 4112 - "│ 4113 - ◆ foo 4114 - │ ● opt0 (Hint 0) 4115 - │ ○ opt1 4116 - └ 4117 - ", 4118 - "", 4119 - "", 4120 - "", 4121 - "◇ foo 4122 - │ opt0", 4123 - " 4124 - ", 4125 - "[?25h", 4126 - ] 4127 - `; 4128 - 4129 - exports[`prompts (isCI = true) > select > renders option labels 1`] = ` 4130 - [ 4131 - "[?25l", 4132 - "│ 4133 - ◆ foo 4134 - │ ● Option 0 4135 - │ ○ Option 1 4136 - └ 4137 - ", 4138 - "", 4139 - "", 4140 - "", 4141 - "◇ foo 4142 - │ Option 0", 4143 - " 4144 - ", 4145 - "[?25h", 4146 - ] 4147 - `; 4148 - 4149 - exports[`prompts (isCI = true) > select > renders options and message 1`] = ` 4150 - [ 4151 - "[?25l", 4152 - "│ 4153 - ◆ foo 4154 - │ ● opt0 4155 - │ ○ opt1 4156 - └ 4157 - ", 4158 - "", 4159 - "", 4160 - "", 4161 - "◇ foo 4162 - │ opt0", 4163 - " 4164 - ", 4165 - "[?25h", 4166 - ] 4167 - `; 4168 - 4169 - exports[`prompts (isCI = true) > select > up arrow selects previous option 1`] = ` 4170 - [ 4171 - "[?25l", 4172 - "│ 4173 - ◆ foo 4174 - │ ● opt0 4175 - │ ○ opt1 4176 - └ 4177 - ", 4178 - "", 4179 - "", 4180 - "", 4181 - "│ ○ opt0 4182 - │ ● opt1 4183 - └ 4184 - ", 4185 - "", 4186 - "", 4187 - "", 4188 - "│ ● opt0 4189 - │ ○ opt1 4190 - └ 4191 - ", 4192 - "", 4193 - "", 4194 - "", 4195 - "◇ foo 4196 - │ opt0", 4197 - " 4198 - ", 4199 - "[?25h", 4200 - ] 4201 - `; 4202 - 4203 - exports[`prompts (isCI = true) > spinner > message > sets message for next frame 1`] = ` 4204 - [ 4205 - "[?25l", 4206 - "│ 4207 - ", 4208 - "◒ ...", 4209 - " 4210 - ", 4211 - "", 4212 - "", 4213 - "◐ foo...", 4214 - ] 4215 - `; 4216 - 4217 - exports[`prompts (isCI = true) > spinner > process exit handling > prioritizes direct options over global settings 1`] = ` 4218 - [ 4219 - "[?25l", 4220 - "│ 4221 - ", 4222 - "■ Spinner cancel message 4223 - ", 4224 - "[?25h", 4225 - ] 4226 - `; 4227 - 4228 - exports[`prompts (isCI = true) > spinner > process exit handling > prioritizes direct options over global settings 2`] = ` 4229 - [ 4230 - "[?25l", 4231 - "│ 4232 - ", 4233 - "▲ Spinner error message 4234 - ", 4235 - "[?25h", 4236 - ] 4237 - `; 4238 - 4239 - exports[`prompts (isCI = true) > spinner > process exit handling > uses custom cancel message when provided directly 1`] = ` 4240 - [ 4241 - "[?25l", 4242 - "│ 4243 - ", 4244 - "■ Custom cancel message 4245 - ", 4246 - "[?25h", 4247 - ] 4248 - `; 4249 - 4250 - exports[`prompts (isCI = true) > spinner > process exit handling > uses custom error message when provided directly 1`] = ` 4251 - [ 4252 - "[?25l", 4253 - "│ 4254 - ", 4255 - "▲ Custom error message 4256 - ", 4257 - "[?25h", 4258 - ] 4259 - `; 4260 - 4261 - exports[`prompts (isCI = true) > spinner > process exit handling > uses default cancel message 1`] = ` 4262 - [ 4263 - "[?25l", 4264 - "│ 4265 - ", 4266 - "■ Canceled 4267 - ", 4268 - "[?25h", 4269 - ] 4270 - `; 4271 - 4272 - exports[`prompts (isCI = true) > spinner > process exit handling > uses global custom cancel message from settings 1`] = ` 4273 - [ 4274 - "[?25l", 4275 - "│ 4276 - ", 4277 - "■ Global cancel message 4278 - ", 4279 - "[?25h", 4280 - ] 4281 - `; 4282 - 4283 - exports[`prompts (isCI = true) > spinner > process exit handling > uses global custom error message from settings 1`] = ` 4284 - [ 4285 - "[?25l", 4286 - "│ 4287 - ", 4288 - "▲ Global error message 4289 - ", 4290 - "[?25h", 4291 - ] 4292 - `; 4293 - 4294 - exports[`prompts (isCI = true) > spinner > start > renders frames at interval 1`] = ` 4295 - [ 4296 - "[?25l", 4297 - "│ 4298 - ", 4299 - "◒ ...", 4300 - ] 4301 - `; 4302 - 4303 - exports[`prompts (isCI = true) > spinner > start > renders message 1`] = ` 4304 - [ 4305 - "[?25l", 4306 - "│ 4307 - ", 4308 - "◒ foo...", 4309 - ] 4310 - `; 4311 - 4312 - exports[`prompts (isCI = true) > spinner > start > renders timer when indicator is "timer" 1`] = ` 4313 - [ 4314 - "[?25l", 4315 - "│ 4316 - ", 4317 - "◒ ...", 4318 - ] 4319 - `; 4320 - 4321 - exports[`prompts (isCI = true) > spinner > stop > renders cancel symbol if code = 1 1`] = ` 4322 - [ 4323 - "[?25l", 4324 - "│ 4325 - ", 4326 - "◒ ...", 4327 - " 4328 - ", 4329 - "", 4330 - "", 4331 - "■ 4332 - ", 4333 - "[?25h", 4334 - ] 4335 - `; 4336 - 4337 - exports[`prompts (isCI = true) > spinner > stop > renders error symbol if code > 1 1`] = ` 4338 - [ 4339 - "[?25l", 4340 - "│ 4341 - ", 4342 - "◒ ...", 4343 - " 4344 - ", 4345 - "", 4346 - "", 4347 - "▲ 4348 - ", 4349 - "[?25h", 4350 - ] 4351 - `; 4352 - 4353 - exports[`prompts (isCI = true) > spinner > stop > renders message 1`] = ` 4354 - [ 4355 - "[?25l", 4356 - "│ 4357 - ", 4358 - "◒ ...", 4359 - " 4360 - ", 4361 - "", 4362 - "", 4363 - "◇ foo 4364 - ", 4365 - "[?25h", 4366 - ] 4367 - `; 4368 - 4369 - exports[`prompts (isCI = true) > spinner > stop > renders message without removing dots 1`] = ` 4370 - [ 4371 - "[?25l", 4372 - "│ 4373 - ", 4374 - "◒ ...", 4375 - " 4376 - ", 4377 - "", 4378 - "", 4379 - "◇ foo. 4380 - ", 4381 - "[?25h", 4382 - ] 4383 - `; 4384 - 4385 - exports[`prompts (isCI = true) > spinner > stop > renders submit symbol and stops spinner 1`] = ` 4386 - [ 4387 - "[?25l", 4388 - "│ 4389 - ", 4390 - "◒ ...", 4391 - " 4392 - ", 4393 - "", 4394 - "", 4395 - "◇ 4396 - ", 4397 - "[?25h", 4398 - ] 4399 - `; 4400 - 4401 - exports[`prompts (isCI = true) > taskLog > error > clears output if showLog = false 1`] = ` 4402 - [ 4403 - "│ 4404 - ", 4405 - "◇ foo 4406 - ", 4407 - "│ 4408 - ", 4409 - "", 4410 - "", 4411 - "│ 4412 - ■ some error! 4413 - ", 4414 - ] 4415 - `; 4416 - 4417 - exports[`prompts (isCI = true) > taskLog > error > renders output with message 1`] = ` 4418 - [ 4419 - "│ 4420 - ", 4421 - "◇ foo 4422 - ", 4423 - "│ 4424 - ", 4425 - "", 4426 - "", 4427 - "│ 4428 - ■ some error! 4429 - ", 4430 - "│ 4431 - │ line 0 4432 - │ line 1 4433 - ", 4434 - ] 4435 - `; 4436 - 4437 - exports[`prompts (isCI = true) > taskLog > message > can write line by line 1`] = ` 4438 - [ 4439 - "│ 4440 - ", 4441 - "◇ foo 4442 - ", 4443 - "│ 4444 - ", 4445 - "", 4446 - ] 4447 - `; 4448 - 4449 - exports[`prompts (isCI = true) > taskLog > message > can write multiple lines 1`] = ` 4450 - [ 4451 - "│ 4452 - ", 4453 - "◇ foo 4454 - ", 4455 - "│ 4456 - ", 4457 - ] 4458 - `; 4459 - 4460 - exports[`prompts (isCI = true) > taskLog > message > enforces limit if set 1`] = ` 4461 - [ 4462 - "│ 4463 - ", 4464 - "◇ foo 4465 - ", 4466 - "│ 4467 - ", 4468 - "", 4469 - "", 4470 - ] 4471 - `; 4472 - 4473 - exports[`prompts (isCI = true) > taskLog > message > prints empty lines 1`] = ` 4474 - [ 4475 - "│ 4476 - ", 4477 - "◇ foo 4478 - ", 4479 - "│ 4480 - ", 4481 - "", 4482 - "", 4483 - ] 4484 - `; 4485 - 4486 - exports[`prompts (isCI = true) > taskLog > message > raw = true appends message text until newline 1`] = ` 4487 - [ 4488 - "│ 4489 - ", 4490 - "◇ foo 4491 - ", 4492 - "│ 4493 - ", 4494 - "", 4495 - "", 4496 - ] 4497 - `; 4498 - 4499 - exports[`prompts (isCI = true) > taskLog > message > raw = true works when mixed with non-raw messages 1`] = ` 4500 - [ 4501 - "│ 4502 - ", 4503 - "◇ foo 4504 - ", 4505 - "│ 4506 - ", 4507 - "", 4508 - "", 4509 - ] 4510 - `; 4511 - 4512 - exports[`prompts (isCI = true) > taskLog > message > raw = true works when started with non-raw messages 1`] = ` 4513 - [ 4514 - "│ 4515 - ", 4516 - "◇ foo 4517 - ", 4518 - "│ 4519 - ", 4520 - "", 4521 - "", 4522 - ] 4523 - `; 4524 - 4525 - exports[`prompts (isCI = true) > taskLog > retainLog > error > outputs limited log with limit by default 1`] = ` 4526 - [ 4527 - "│ 4528 - ", 4529 - "◇ foo 4530 - ", 4531 - "│ 4532 - ", 4533 - "", 4534 - "", 4535 - "", 4536 - "", 4537 - "│ 4538 - ■ woo! 4539 - ", 4540 - "│ 4541 - │ line 2 4542 - │ line 3 4543 - ", 4544 - ] 4545 - `; 4546 - 4547 - exports[`prompts (isCI = true) > taskLog > retainLog > error > retainLog = false outputs full log without limit 1`] = ` 4548 - [ 4549 - "│ 4550 - ", 4551 - "◇ foo 4552 - ", 4553 - "│ 4554 - ", 4555 - "", 4556 - "", 4557 - "", 4558 - "", 4559 - "│ 4560 - ■ woo! 4561 - ", 4562 - "│ 4563 - │ line 0 4564 - │ line 1 4565 - │ line 2 4566 - │ line 3 4567 - ", 4568 - ] 4569 - `; 4570 - 4571 - exports[`prompts (isCI = true) > taskLog > retainLog > error > retainLog = false outputs limited log with limit 1`] = ` 4572 - [ 4573 - "│ 4574 - ", 4575 - "◇ foo 4576 - ", 4577 - "│ 4578 - ", 4579 - "", 4580 - "", 4581 - "", 4582 - "", 4583 - "│ 4584 - ■ woo! 4585 - ", 4586 - "│ 4587 - │ line 2 4588 - │ line 3 4589 - ", 4590 - ] 4591 - `; 4592 - 4593 - exports[`prompts (isCI = true) > taskLog > retainLog > error > retainLog = true outputs full log 1`] = ` 4594 - [ 4595 - "│ 4596 - ", 4597 - "◇ foo 4598 - ", 4599 - "│ 4600 - ", 4601 - "", 4602 - "", 4603 - "", 4604 - "", 4605 - "│ 4606 - ■ woo! 4607 - ", 4608 - "│ 4609 - │ line 0 4610 - │ line 1 4611 - │ line 2 4612 - │ line 3 4613 - ", 4614 - ] 4615 - `; 4616 - 4617 - exports[`prompts (isCI = true) > taskLog > retainLog > error > retainLog = true outputs full log with limit 1`] = ` 4618 - [ 4619 - "│ 4620 - ", 4621 - "◇ foo 4622 - ", 4623 - "│ 4624 - ", 4625 - "", 4626 - "", 4627 - "", 4628 - "", 4629 - "│ 4630 - ■ woo! 4631 - ", 4632 - "│ 4633 - │ line 0 4634 - │ line 1 4635 - │ line 2 4636 - │ line 3 4637 - ", 4638 - ] 4639 - `; 4640 - 4641 - exports[`prompts (isCI = true) > taskLog > retainLog > success > outputs limited log with limit by default 1`] = ` 4642 - [ 4643 - "│ 4644 - ", 4645 - "◇ foo 4646 - ", 4647 - "│ 4648 - ", 4649 - "", 4650 - "", 4651 - "", 4652 - "", 4653 - "│ 4654 - ◆ woo! 4655 - ", 4656 - "│ 4657 - │ line 2 4658 - │ line 3 4659 - ", 4660 - ] 4661 - `; 4662 - 4663 - exports[`prompts (isCI = true) > taskLog > retainLog > success > retainLog = false outputs full log without limit 1`] = ` 4664 - [ 4665 - "│ 4666 - ", 4667 - "◇ foo 4668 - ", 4669 - "│ 4670 - ", 4671 - "", 4672 - "", 4673 - "", 4674 - "", 4675 - "│ 4676 - ◆ woo! 4677 - ", 4678 - "│ 4679 - │ line 0 4680 - │ line 1 4681 - │ line 2 4682 - │ line 3 4683 - ", 4684 - ] 4685 - `; 4686 - 4687 - exports[`prompts (isCI = true) > taskLog > retainLog > success > retainLog = false outputs limited log with limit 1`] = ` 4688 - [ 4689 - "│ 4690 - ", 4691 - "◇ foo 4692 - ", 4693 - "│ 4694 - ", 4695 - "", 4696 - "", 4697 - "", 4698 - "", 4699 - "│ 4700 - ◆ woo! 4701 - ", 4702 - "│ 4703 - │ line 2 4704 - │ line 3 4705 - ", 4706 - ] 4707 - `; 4708 - 4709 - exports[`prompts (isCI = true) > taskLog > retainLog > success > retainLog = true outputs full log 1`] = ` 4710 - [ 4711 - "│ 4712 - ", 4713 - "◇ foo 4714 - ", 4715 - "│ 4716 - ", 4717 - "", 4718 - "", 4719 - "", 4720 - "", 4721 - "│ 4722 - ◆ woo! 4723 - ", 4724 - "│ 4725 - │ line 0 4726 - │ line 1 4727 - │ line 2 4728 - │ line 3 4729 - ", 4730 - ] 4731 - `; 4732 - 4733 - exports[`prompts (isCI = true) > taskLog > retainLog > success > retainLog = true outputs full log with limit 1`] = ` 4734 - [ 4735 - "│ 4736 - ", 4737 - "◇ foo 4738 - ", 4739 - "│ 4740 - ", 4741 - "", 4742 - "", 4743 - "", 4744 - "", 4745 - "│ 4746 - ◆ woo! 4747 - ", 4748 - "│ 4749 - │ line 0 4750 - │ line 1 4751 - │ line 2 4752 - │ line 3 4753 - ", 4754 - ] 4755 - `; 4756 - 4757 - exports[`prompts (isCI = true) > taskLog > success > clears output and renders message 1`] = ` 4758 - [ 4759 - "│ 4760 - ", 4761 - "◇ foo 4762 - ", 4763 - "│ 4764 - ", 4765 - "", 4766 - "", 4767 - "│ 4768 - ◆ success! 4769 - ", 4770 - ] 4771 - `; 4772 - 4773 - exports[`prompts (isCI = true) > taskLog > success > renders output if showLog = true 1`] = ` 4774 - [ 4775 - "│ 4776 - ", 4777 - "◇ foo 4778 - ", 4779 - "│ 4780 - ", 4781 - "", 4782 - "", 4783 - "│ 4784 - ◆ success! 4785 - ", 4786 - "│ 4787 - │ line 0 4788 - │ line 1 4789 - ", 4790 - ] 4791 - `; 4792 - 4793 - exports[`prompts (isCI = true) > taskLog > writes message header 1`] = ` 4794 - [ 4795 - "│ 4796 - ", 4797 - "◇ foo 4798 - ", 4799 - "│ 4800 - ", 4801 - ] 4802 - `; 4803 - 4804 - exports[`prompts (isCI = true) > text > can cancel 1`] = ` 4805 - [ 4806 - "[?25l", 4807 - "│ 4808 - ◆ foo 4809 - │ _ 4810 - └ 4811 - ", 4812 - "", 4813 - "", 4814 - "", 4815 - "■ foo 4816 - │", 4817 - " 4818 - ", 4819 - "[?25h", 4820 - ] 4821 - `; 4822 - 4823 - exports[`prompts (isCI = true) > text > defaultValue sets the value but does not render 1`] = ` 4824 - [ 4825 - "[?25l", 4826 - "│ 4827 - ◆ foo 4828 - │ _ 4829 - └ 4830 - ", 4831 - "", 4832 - "", 4833 - "", 4834 - "◇ foo 4835 - │ bar", 4836 - " 4837 - ", 4838 - "[?25h", 4839 - ] 4840 - `; 4841 - 4842 - exports[`prompts (isCI = true) > text > renders cancelled value if one set 1`] = ` 4843 - [ 4844 - "[?25l", 4845 - "│ 4846 - ◆ foo 4847 - │ _ 4848 - └ 4849 - ", 4850 - "", 4851 - "", 4852 - "", 4853 - "│ x█", 4854 - "", 4855 - "", 4856 - "", 4857 - "", 4858 - "│ xy█", 4859 - "", 4860 - "", 4861 - "", 4862 - "", 4863 - "■ foo 4864 - │ xy 4865 - │", 4866 - " 4867 - ", 4868 - "[?25h", 4869 - ] 4870 - `; 4871 - 4872 - exports[`prompts (isCI = true) > text > renders message 1`] = ` 4873 - [ 4874 - "[?25l", 4875 - "│ 4876 - ◆ foo 4877 - │ _ 4878 - └ 4879 - ", 4880 - "", 4881 - "", 4882 - "", 4883 - "◇ foo 4884 - │ undefined", 4885 - " 4886 - ", 4887 - "[?25h", 4888 - ] 4889 - `; 4890 - 4891 - exports[`prompts (isCI = true) > text > renders placeholder if set 1`] = ` 4892 - [ 4893 - "[?25l", 4894 - "│ 4895 - ◆ foo 4896 - │ bar 4897 - └ 4898 - ", 4899 - "", 4900 - "", 4901 - "", 4902 - "◇ foo 4903 - │ bar", 4904 - " 4905 - ", 4906 - "[?25h", 4907 - ] 4908 - `; 4909 - 4910 - exports[`prompts (isCI = true) > text > renders submitted value 1`] = ` 4911 - [ 4912 - "[?25l", 4913 - "│ 4914 - ◆ foo 4915 - │ _ 4916 - └ 4917 - ", 4918 - "", 4919 - "", 4920 - "", 4921 - "│ x█", 4922 - "", 4923 - "", 4924 - "", 4925 - "", 4926 - "│ xy█", 4927 - "", 4928 - "", 4929 - "", 4930 - "", 4931 - "◇ foo 4932 - │ xy", 4933 - " 4934 - ", 4935 - "[?25h", 4936 - ] 4937 - `; 4938 - 4939 - exports[`prompts (isCI = true) > text > validation errors render and clear (using Error) 1`] = ` 4940 - [ 4941 - "[?25l", 4942 - "│ 4943 - ◆ foo 4944 - │ _ 4945 - └ 4946 - ", 4947 - "", 4948 - "", 4949 - "", 4950 - "│ x█", 4951 - "", 4952 - "", 4953 - "", 4954 - "", 4955 - "▲ foo 4956 - │ x█ 4957 - └ should be xy 4958 - ", 4959 - "", 4960 - "", 4961 - "", 4962 - "◆ foo 4963 - │ xy█ 4964 - └ 4965 - ", 4966 - "", 4967 - "", 4968 - "", 4969 - "◇ foo 4970 - │ xy", 4971 - " 4972 - ", 4973 - "[?25h", 4974 - ] 4975 - `; 4976 - 4977 - exports[`prompts (isCI = true) > text > validation errors render and clear 1`] = ` 4978 - [ 4979 - "[?25l", 4980 - "│ 4981 - ◆ foo 4982 - │ _ 4983 - └ 4984 - ", 4985 - "", 4986 - "", 4987 - "", 4988 - "│ x█", 4989 - "", 4990 - "", 4991 - "", 4992 - "", 4993 - "▲ foo 4994 - │ x█ 4995 - └ should be xy 4996 - ", 4997 - "", 4998 - "", 4999 - "", 5000 - "◆ foo 5001 - │ xy█ 5002 - └ 5003 - ", 5004 - "", 5005 - "", 5006 - "", 5007 - "◇ foo 5008 - │ xy", 5009 - " 5010 - ", 5011 - "[?25h", 5012 - ] 5013 - `;
+1191
packages/prompts/src/__snapshots__/multi-select.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`multiselect (isCI = false) > can cancel 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ◆ foo 8 + │ ◻ opt0 9 + │ ◻ opt1 10 + └ 11 + ", 12 + "", 13 + "", 14 + "", 15 + "■ foo 16 + │", 17 + " 18 + ", 19 + "[?25h", 20 + ] 21 + `; 22 + 23 + exports[`multiselect (isCI = false) > can render option hints 1`] = ` 24 + [ 25 + "[?25l", 26 + "│ 27 + ◆ foo 28 + │ ◻ opt0 (Hint 0) 29 + │ ◻ opt1 30 + └ 31 + ", 32 + "", 33 + "", 34 + "", 35 + "│ ◼ opt0 (Hint 0)", 36 + "", 37 + "", 38 + "", 39 + "", 40 + "◇ foo 41 + │ opt0", 42 + " 43 + ", 44 + "[?25h", 45 + ] 46 + `; 47 + 48 + exports[`multiselect (isCI = false) > can set cursorAt to preselect an option 1`] = ` 49 + [ 50 + "[?25l", 51 + "│ 52 + ◆ foo 53 + │ ◻ opt0 54 + │ ◻ opt1 55 + └ 56 + ", 57 + "", 58 + "", 59 + "", 60 + "│ ◼ opt1", 61 + "", 62 + "", 63 + "", 64 + "", 65 + "◇ foo 66 + │ opt1", 67 + " 68 + ", 69 + "[?25h", 70 + ] 71 + `; 72 + 73 + exports[`multiselect (isCI = false) > can set custom labels 1`] = ` 74 + [ 75 + "[?25l", 76 + "│ 77 + ◆ foo 78 + │ ◻ Option 0 79 + │ ◻ Option 1 80 + └ 81 + ", 82 + "", 83 + "", 84 + "", 85 + "│ ◼ Option 0", 86 + "", 87 + "", 88 + "", 89 + "", 90 + "◇ foo 91 + │ Option 0", 92 + " 93 + ", 94 + "[?25h", 95 + ] 96 + `; 97 + 98 + exports[`multiselect (isCI = false) > can set initial values 1`] = ` 99 + [ 100 + "[?25l", 101 + "│ 102 + ◆ foo 103 + │ ◻ opt0 104 + │ ◼ opt1 105 + └ 106 + ", 107 + "", 108 + "", 109 + "", 110 + "◇ foo 111 + │ opt1", 112 + " 113 + ", 114 + "[?25h", 115 + ] 116 + `; 117 + 118 + exports[`multiselect (isCI = false) > can submit without selection when required = false 1`] = ` 119 + [ 120 + "[?25l", 121 + "│ 122 + ◆ foo 123 + │ ◻ opt0 124 + │ ◻ opt1 125 + └ 126 + ", 127 + "", 128 + "", 129 + "", 130 + "◇ foo 131 + │ none", 132 + " 133 + ", 134 + "[?25h", 135 + ] 136 + `; 137 + 138 + exports[`multiselect (isCI = false) > maxItems renders a sliding window 1`] = ` 139 + [ 140 + "[?25l", 141 + "│ 142 + ◆ foo 143 + │ ◻ opt0 144 + │ ◻ opt1 145 + │ ◻ opt2 146 + │ ◻ opt3 147 + │ ◻ opt4 148 + │ ... 149 + └ 150 + ", 151 + "", 152 + "", 153 + "", 154 + "│ ◻ opt0 155 + │ ◻ opt1 156 + │ ◻ opt2 157 + │ ◻ opt3 158 + │ ◻ opt4 159 + │ ... 160 + └ 161 + ", 162 + "", 163 + "", 164 + "", 165 + "│ ◻ opt1 166 + │ ◻ opt2 167 + │ ◻ opt3 168 + │ ◻ opt4 169 + │ ... 170 + └ 171 + ", 172 + "", 173 + "", 174 + "", 175 + "│ ◻ opt2 176 + │ ◻ opt3 177 + │ ◻ opt4 178 + │ ... 179 + └ 180 + ", 181 + "", 182 + "", 183 + "", 184 + "│ ... 185 + │ ◻ opt2 186 + │ ◻ opt3 187 + │ ◻ opt4 188 + │ ◻ opt5 189 + │ ... 190 + └ 191 + ", 192 + "", 193 + "", 194 + "", 195 + "│ ◻ opt3 196 + │ ◻ opt4 197 + │ ◻ opt5 198 + │ ◻ opt6 199 + │ ... 200 + └ 201 + ", 202 + "", 203 + "", 204 + "", 205 + "│ ◻ opt4 206 + │ ◻ opt5 207 + │ ◻ opt6 208 + │ ◻ opt7 209 + │ ... 210 + └ 211 + ", 212 + "", 213 + "", 214 + "", 215 + "│ ◼ opt6", 216 + "", 217 + "", 218 + "", 219 + "", 220 + "◇ foo 221 + │ opt6", 222 + " 223 + ", 224 + "[?25h", 225 + ] 226 + `; 227 + 228 + exports[`multiselect (isCI = false) > renders message 1`] = ` 229 + [ 230 + "[?25l", 231 + "│ 232 + ◆ foo 233 + │ ◻ opt0 234 + │ ◻ opt1 235 + └ 236 + ", 237 + "", 238 + "", 239 + "", 240 + "│ ◼ opt0", 241 + "", 242 + "", 243 + "", 244 + "", 245 + "◇ foo 246 + │ opt0", 247 + " 248 + ", 249 + "[?25h", 250 + ] 251 + `; 252 + 253 + exports[`multiselect (isCI = false) > renders multiple cancelled values 1`] = ` 254 + [ 255 + "[?25l", 256 + "│ 257 + ◆ foo 258 + │ ◻ opt0 259 + │ ◻ opt1 260 + │ ◻ opt2 261 + └ 262 + ", 263 + "", 264 + "", 265 + "", 266 + "│ ◼ opt0", 267 + "", 268 + "", 269 + "", 270 + "", 271 + "│ ◼ opt0 272 + │ ◻ opt1 273 + │ ◻ opt2 274 + └ 275 + ", 276 + "", 277 + "", 278 + "", 279 + "│ ◼ opt1", 280 + "", 281 + "", 282 + "", 283 + "", 284 + "■ foo 285 + │ opt0, opt1 286 + │", 287 + " 288 + ", 289 + "[?25h", 290 + ] 291 + `; 292 + 293 + exports[`multiselect (isCI = false) > renders multiple selected options 1`] = ` 294 + [ 295 + "[?25l", 296 + "│ 297 + ◆ foo 298 + │ ◻ opt0 299 + │ ◻ opt1 300 + │ ◻ opt2 301 + └ 302 + ", 303 + "", 304 + "", 305 + "", 306 + "│ ◼ opt0", 307 + "", 308 + "", 309 + "", 310 + "", 311 + "│ ◼ opt0 312 + │ ◻ opt1 313 + │ ◻ opt2 314 + └ 315 + ", 316 + "", 317 + "", 318 + "", 319 + "│ ◼ opt1", 320 + "", 321 + "", 322 + "", 323 + "", 324 + "│ ◼ opt1 325 + │ ◻ opt2 326 + └ 327 + ", 328 + "", 329 + "", 330 + "", 331 + "◇ foo 332 + │ opt0, opt1", 333 + " 334 + ", 335 + "[?25h", 336 + ] 337 + `; 338 + 339 + exports[`multiselect (isCI = false) > renders validation errors 1`] = ` 340 + [ 341 + "[?25l", 342 + "│ 343 + ◆ foo 344 + │ ◻ opt0 345 + │ ◻ opt1 346 + └ 347 + ", 348 + "", 349 + "", 350 + "", 351 + "▲ foo 352 + │ ◻ opt0 353 + │ ◻ opt1 354 + └ Please select at least one option. 355 + Press  space  to select,  enter  to submit 356 + ", 357 + "", 358 + "", 359 + "", 360 + "◆ foo 361 + │ ◼ opt0 362 + │ ◻ opt1 363 + └ 364 + ", 365 + "", 366 + "", 367 + "", 368 + "◇ foo 369 + │ opt0", 370 + " 371 + ", 372 + "[?25h", 373 + ] 374 + `; 375 + 376 + exports[`multiselect (isCI = false) > shows hints for all selected options 1`] = ` 377 + [ 378 + "[?25l", 379 + "│ 380 + ◆ foo 381 + │ ◼ opt0 (Hint 0) 382 + │ ◼ opt1 (Hint 1) 383 + │ ◻ opt2 384 + └ 385 + ", 386 + "", 387 + "", 388 + "", 389 + "│ ◼ opt0 (Hint 0) 390 + │ ◼ opt1 (Hint 1) 391 + │ ◻ opt2 392 + └ 393 + ", 394 + "", 395 + "", 396 + "", 397 + "│ ◼ opt1 (Hint 1) 398 + │ ◻ opt2 (Hint 2) 399 + └ 400 + ", 401 + "", 402 + "", 403 + "", 404 + "◇ foo 405 + │ opt0, opt1", 406 + " 407 + ", 408 + "[?25h", 409 + ] 410 + `; 411 + 412 + exports[`multiselect (isCI = false) > sliding window loops downwards 1`] = ` 413 + [ 414 + "[?25l", 415 + "│ 416 + ◆ foo 417 + │ ◻ opt0 418 + │ ◻ opt1 419 + │ ◻ opt2 420 + │ ◻ opt3 421 + │ ◻ opt4 422 + │ ... 423 + └ 424 + ", 425 + "", 426 + "", 427 + "", 428 + "│ ◻ opt0 429 + │ ◻ opt1 430 + │ ◻ opt2 431 + │ ◻ opt3 432 + │ ◻ opt4 433 + │ ... 434 + └ 435 + ", 436 + "", 437 + "", 438 + "", 439 + "│ ◻ opt1 440 + │ ◻ opt2 441 + │ ◻ opt3 442 + │ ◻ opt4 443 + │ ... 444 + └ 445 + ", 446 + "", 447 + "", 448 + "", 449 + "│ ◻ opt2 450 + │ ◻ opt3 451 + │ ◻ opt4 452 + │ ... 453 + └ 454 + ", 455 + "", 456 + "", 457 + "", 458 + "│ ... 459 + │ ◻ opt2 460 + │ ◻ opt3 461 + │ ◻ opt4 462 + │ ◻ opt5 463 + │ ... 464 + └ 465 + ", 466 + "", 467 + "", 468 + "", 469 + "│ ◻ opt3 470 + │ ◻ opt4 471 + │ ◻ opt5 472 + │ ◻ opt6 473 + │ ... 474 + └ 475 + ", 476 + "", 477 + "", 478 + "", 479 + "│ ◻ opt4 480 + │ ◻ opt5 481 + │ ◻ opt6 482 + │ ◻ opt7 483 + │ ... 484 + └ 485 + ", 486 + "", 487 + "", 488 + "", 489 + "│ ◻ opt5 490 + │ ◻ opt6 491 + │ ◻ opt7 492 + │ ◻ opt8 493 + │ ... 494 + └ 495 + ", 496 + "", 497 + "", 498 + "", 499 + "│ ◻ opt6 500 + │ ◻ opt7 501 + │ ◻ opt8 502 + │ ◻ opt9 503 + │ ... 504 + └ 505 + ", 506 + "", 507 + "", 508 + "", 509 + "│ ◻ opt7 510 + │ ◻ opt8 511 + │ ◻ opt9 512 + │ ◻ opt10 513 + │ ◻ opt11 514 + └ 515 + ", 516 + "", 517 + "", 518 + "", 519 + "│ ◻ opt9 520 + │ ◻ opt10 521 + │ ◻ opt11 522 + └ 523 + ", 524 + "", 525 + "", 526 + "", 527 + "│ ◻ opt10 528 + │ ◻ opt11 529 + └ 530 + ", 531 + "", 532 + "", 533 + "", 534 + "│ ◻ opt0 535 + │ ◻ opt1 536 + │ ◻ opt2 537 + │ ◻ opt3 538 + │ ◻ opt4 539 + │ ... 540 + └ 541 + ", 542 + "", 543 + "", 544 + "", 545 + "│ ◼ opt0", 546 + "", 547 + "", 548 + "", 549 + "", 550 + "◇ foo 551 + │ opt0", 552 + " 553 + ", 554 + "[?25h", 555 + ] 556 + `; 557 + 558 + exports[`multiselect (isCI = false) > sliding window loops upwards 1`] = ` 559 + [ 560 + "[?25l", 561 + "│ 562 + ◆ foo 563 + │ ◻ opt0 564 + │ ◻ opt1 565 + │ ◻ opt2 566 + │ ◻ opt3 567 + │ ◻ opt4 568 + │ ... 569 + └ 570 + ", 571 + "", 572 + "", 573 + "", 574 + "│ ... 575 + │ ◻ opt7 576 + │ ◻ opt8 577 + │ ◻ opt9 578 + │ ◻ opt10 579 + │ ◻ opt11 580 + └ 581 + ", 582 + "", 583 + "", 584 + "", 585 + "│ ◼ opt11", 586 + "", 587 + "", 588 + "", 589 + "", 590 + "◇ foo 591 + │ opt11", 592 + " 593 + ", 594 + "[?25h", 595 + ] 596 + `; 597 + 598 + exports[`multiselect (isCI = true) > can cancel 1`] = ` 599 + [ 600 + "[?25l", 601 + "│ 602 + ◆ foo 603 + │ ◻ opt0 604 + │ ◻ opt1 605 + └ 606 + ", 607 + "", 608 + "", 609 + "", 610 + "■ foo 611 + │", 612 + " 613 + ", 614 + "[?25h", 615 + ] 616 + `; 617 + 618 + exports[`multiselect (isCI = true) > can render option hints 1`] = ` 619 + [ 620 + "[?25l", 621 + "│ 622 + ◆ foo 623 + │ ◻ opt0 (Hint 0) 624 + │ ◻ opt1 625 + └ 626 + ", 627 + "", 628 + "", 629 + "", 630 + "│ ◼ opt0 (Hint 0)", 631 + "", 632 + "", 633 + "", 634 + "", 635 + "◇ foo 636 + │ opt0", 637 + " 638 + ", 639 + "[?25h", 640 + ] 641 + `; 642 + 643 + exports[`multiselect (isCI = true) > can set cursorAt to preselect an option 1`] = ` 644 + [ 645 + "[?25l", 646 + "│ 647 + ◆ foo 648 + │ ◻ opt0 649 + │ ◻ opt1 650 + └ 651 + ", 652 + "", 653 + "", 654 + "", 655 + "│ ◼ opt1", 656 + "", 657 + "", 658 + "", 659 + "", 660 + "◇ foo 661 + │ opt1", 662 + " 663 + ", 664 + "[?25h", 665 + ] 666 + `; 667 + 668 + exports[`multiselect (isCI = true) > can set custom labels 1`] = ` 669 + [ 670 + "[?25l", 671 + "│ 672 + ◆ foo 673 + │ ◻ Option 0 674 + │ ◻ Option 1 675 + └ 676 + ", 677 + "", 678 + "", 679 + "", 680 + "│ ◼ Option 0", 681 + "", 682 + "", 683 + "", 684 + "", 685 + "◇ foo 686 + │ Option 0", 687 + " 688 + ", 689 + "[?25h", 690 + ] 691 + `; 692 + 693 + exports[`multiselect (isCI = true) > can set initial values 1`] = ` 694 + [ 695 + "[?25l", 696 + "│ 697 + ◆ foo 698 + │ ◻ opt0 699 + │ ◼ opt1 700 + └ 701 + ", 702 + "", 703 + "", 704 + "", 705 + "◇ foo 706 + │ opt1", 707 + " 708 + ", 709 + "[?25h", 710 + ] 711 + `; 712 + 713 + exports[`multiselect (isCI = true) > can submit without selection when required = false 1`] = ` 714 + [ 715 + "[?25l", 716 + "│ 717 + ◆ foo 718 + │ ◻ opt0 719 + │ ◻ opt1 720 + └ 721 + ", 722 + "", 723 + "", 724 + "", 725 + "◇ foo 726 + │ none", 727 + " 728 + ", 729 + "[?25h", 730 + ] 731 + `; 732 + 733 + exports[`multiselect (isCI = true) > maxItems renders a sliding window 1`] = ` 734 + [ 735 + "[?25l", 736 + "│ 737 + ◆ foo 738 + │ ◻ opt0 739 + │ ◻ opt1 740 + │ ◻ opt2 741 + │ ◻ opt3 742 + │ ◻ opt4 743 + │ ... 744 + └ 745 + ", 746 + "", 747 + "", 748 + "", 749 + "│ ◻ opt0 750 + │ ◻ opt1 751 + │ ◻ opt2 752 + │ ◻ opt3 753 + │ ◻ opt4 754 + │ ... 755 + └ 756 + ", 757 + "", 758 + "", 759 + "", 760 + "│ ◻ opt1 761 + │ ◻ opt2 762 + │ ◻ opt3 763 + │ ◻ opt4 764 + │ ... 765 + └ 766 + ", 767 + "", 768 + "", 769 + "", 770 + "│ ◻ opt2 771 + │ ◻ opt3 772 + │ ◻ opt4 773 + │ ... 774 + └ 775 + ", 776 + "", 777 + "", 778 + "", 779 + "│ ... 780 + │ ◻ opt2 781 + │ ◻ opt3 782 + │ ◻ opt4 783 + │ ◻ opt5 784 + │ ... 785 + └ 786 + ", 787 + "", 788 + "", 789 + "", 790 + "│ ◻ opt3 791 + │ ◻ opt4 792 + │ ◻ opt5 793 + │ ◻ opt6 794 + │ ... 795 + └ 796 + ", 797 + "", 798 + "", 799 + "", 800 + "│ ◻ opt4 801 + │ ◻ opt5 802 + │ ◻ opt6 803 + │ ◻ opt7 804 + │ ... 805 + └ 806 + ", 807 + "", 808 + "", 809 + "", 810 + "│ ◼ opt6", 811 + "", 812 + "", 813 + "", 814 + "", 815 + "◇ foo 816 + │ opt6", 817 + " 818 + ", 819 + "[?25h", 820 + ] 821 + `; 822 + 823 + exports[`multiselect (isCI = true) > renders message 1`] = ` 824 + [ 825 + "[?25l", 826 + "│ 827 + ◆ foo 828 + │ ◻ opt0 829 + │ ◻ opt1 830 + └ 831 + ", 832 + "", 833 + "", 834 + "", 835 + "│ ◼ opt0", 836 + "", 837 + "", 838 + "", 839 + "", 840 + "◇ foo 841 + │ opt0", 842 + " 843 + ", 844 + "[?25h", 845 + ] 846 + `; 847 + 848 + exports[`multiselect (isCI = true) > renders multiple cancelled values 1`] = ` 849 + [ 850 + "[?25l", 851 + "│ 852 + ◆ foo 853 + │ ◻ opt0 854 + │ ◻ opt1 855 + │ ◻ opt2 856 + └ 857 + ", 858 + "", 859 + "", 860 + "", 861 + "│ ◼ opt0", 862 + "", 863 + "", 864 + "", 865 + "", 866 + "│ ◼ opt0 867 + │ ◻ opt1 868 + │ ◻ opt2 869 + └ 870 + ", 871 + "", 872 + "", 873 + "", 874 + "│ ◼ opt1", 875 + "", 876 + "", 877 + "", 878 + "", 879 + "■ foo 880 + │ opt0, opt1 881 + │", 882 + " 883 + ", 884 + "[?25h", 885 + ] 886 + `; 887 + 888 + exports[`multiselect (isCI = true) > renders multiple selected options 1`] = ` 889 + [ 890 + "[?25l", 891 + "│ 892 + ◆ foo 893 + │ ◻ opt0 894 + │ ◻ opt1 895 + │ ◻ opt2 896 + └ 897 + ", 898 + "", 899 + "", 900 + "", 901 + "│ ◼ opt0", 902 + "", 903 + "", 904 + "", 905 + "", 906 + "│ ◼ opt0 907 + │ ◻ opt1 908 + │ ◻ opt2 909 + └ 910 + ", 911 + "", 912 + "", 913 + "", 914 + "│ ◼ opt1", 915 + "", 916 + "", 917 + "", 918 + "", 919 + "│ ◼ opt1 920 + │ ◻ opt2 921 + └ 922 + ", 923 + "", 924 + "", 925 + "", 926 + "◇ foo 927 + │ opt0, opt1", 928 + " 929 + ", 930 + "[?25h", 931 + ] 932 + `; 933 + 934 + exports[`multiselect (isCI = true) > renders validation errors 1`] = ` 935 + [ 936 + "[?25l", 937 + "│ 938 + ◆ foo 939 + │ ◻ opt0 940 + │ ◻ opt1 941 + └ 942 + ", 943 + "", 944 + "", 945 + "", 946 + "▲ foo 947 + │ ◻ opt0 948 + │ ◻ opt1 949 + └ Please select at least one option. 950 + Press  space  to select,  enter  to submit 951 + ", 952 + "", 953 + "", 954 + "", 955 + "◆ foo 956 + │ ◼ opt0 957 + │ ◻ opt1 958 + └ 959 + ", 960 + "", 961 + "", 962 + "", 963 + "◇ foo 964 + │ opt0", 965 + " 966 + ", 967 + "[?25h", 968 + ] 969 + `; 970 + 971 + exports[`multiselect (isCI = true) > shows hints for all selected options 1`] = ` 972 + [ 973 + "[?25l", 974 + "│ 975 + ◆ foo 976 + │ ◼ opt0 (Hint 0) 977 + │ ◼ opt1 (Hint 1) 978 + │ ◻ opt2 979 + └ 980 + ", 981 + "", 982 + "", 983 + "", 984 + "│ ◼ opt0 (Hint 0) 985 + │ ◼ opt1 (Hint 1) 986 + │ ◻ opt2 987 + └ 988 + ", 989 + "", 990 + "", 991 + "", 992 + "│ ◼ opt1 (Hint 1) 993 + │ ◻ opt2 (Hint 2) 994 + └ 995 + ", 996 + "", 997 + "", 998 + "", 999 + "◇ foo 1000 + │ opt0, opt1", 1001 + " 1002 + ", 1003 + "[?25h", 1004 + ] 1005 + `; 1006 + 1007 + exports[`multiselect (isCI = true) > sliding window loops downwards 1`] = ` 1008 + [ 1009 + "[?25l", 1010 + "│ 1011 + ◆ foo 1012 + │ ◻ opt0 1013 + │ ◻ opt1 1014 + │ ◻ opt2 1015 + │ ◻ opt3 1016 + │ ◻ opt4 1017 + │ ... 1018 + └ 1019 + ", 1020 + "", 1021 + "", 1022 + "", 1023 + "│ ◻ opt0 1024 + │ ◻ opt1 1025 + │ ◻ opt2 1026 + │ ◻ opt3 1027 + │ ◻ opt4 1028 + │ ... 1029 + └ 1030 + ", 1031 + "", 1032 + "", 1033 + "", 1034 + "│ ◻ opt1 1035 + │ ◻ opt2 1036 + │ ◻ opt3 1037 + │ ◻ opt4 1038 + │ ... 1039 + └ 1040 + ", 1041 + "", 1042 + "", 1043 + "", 1044 + "│ ◻ opt2 1045 + │ ◻ opt3 1046 + │ ◻ opt4 1047 + │ ... 1048 + └ 1049 + ", 1050 + "", 1051 + "", 1052 + "", 1053 + "│ ... 1054 + │ ◻ opt2 1055 + │ ◻ opt3 1056 + │ ◻ opt4 1057 + │ ◻ opt5 1058 + │ ... 1059 + └ 1060 + ", 1061 + "", 1062 + "", 1063 + "", 1064 + "│ ◻ opt3 1065 + │ ◻ opt4 1066 + │ ◻ opt5 1067 + │ ◻ opt6 1068 + │ ... 1069 + └ 1070 + ", 1071 + "", 1072 + "", 1073 + "", 1074 + "│ ◻ opt4 1075 + │ ◻ opt5 1076 + │ ◻ opt6 1077 + │ ◻ opt7 1078 + │ ... 1079 + └ 1080 + ", 1081 + "", 1082 + "", 1083 + "", 1084 + "│ ◻ opt5 1085 + │ ◻ opt6 1086 + │ ◻ opt7 1087 + │ ◻ opt8 1088 + │ ... 1089 + └ 1090 + ", 1091 + "", 1092 + "", 1093 + "", 1094 + "│ ◻ opt6 1095 + │ ◻ opt7 1096 + │ ◻ opt8 1097 + │ ◻ opt9 1098 + │ ... 1099 + └ 1100 + ", 1101 + "", 1102 + "", 1103 + "", 1104 + "│ ◻ opt7 1105 + │ ◻ opt8 1106 + │ ◻ opt9 1107 + │ ◻ opt10 1108 + │ ◻ opt11 1109 + └ 1110 + ", 1111 + "", 1112 + "", 1113 + "", 1114 + "│ ◻ opt9 1115 + │ ◻ opt10 1116 + │ ◻ opt11 1117 + └ 1118 + ", 1119 + "", 1120 + "", 1121 + "", 1122 + "│ ◻ opt10 1123 + │ ◻ opt11 1124 + └ 1125 + ", 1126 + "", 1127 + "", 1128 + "", 1129 + "│ ◻ opt0 1130 + │ ◻ opt1 1131 + │ ◻ opt2 1132 + │ ◻ opt3 1133 + │ ◻ opt4 1134 + │ ... 1135 + └ 1136 + ", 1137 + "", 1138 + "", 1139 + "", 1140 + "│ ◼ opt0", 1141 + "", 1142 + "", 1143 + "", 1144 + "", 1145 + "◇ foo 1146 + │ opt0", 1147 + " 1148 + ", 1149 + "[?25h", 1150 + ] 1151 + `; 1152 + 1153 + exports[`multiselect (isCI = true) > sliding window loops upwards 1`] = ` 1154 + [ 1155 + "[?25l", 1156 + "│ 1157 + ◆ foo 1158 + │ ◻ opt0 1159 + │ ◻ opt1 1160 + │ ◻ opt2 1161 + │ ◻ opt3 1162 + │ ◻ opt4 1163 + │ ... 1164 + └ 1165 + ", 1166 + "", 1167 + "", 1168 + "", 1169 + "│ ... 1170 + │ ◻ opt7 1171 + │ ◻ opt8 1172 + │ ◻ opt9 1173 + │ ◻ opt10 1174 + │ ◻ opt11 1175 + └ 1176 + ", 1177 + "", 1178 + "", 1179 + "", 1180 + "│ ◼ opt11", 1181 + "", 1182 + "", 1183 + "", 1184 + "", 1185 + "◇ foo 1186 + │ opt11", 1187 + " 1188 + ", 1189 + "[?25h", 1190 + ] 1191 + `;
+107
packages/prompts/src/__snapshots__/note.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`note (isCI = false) > formatter which adds colors works 1`] = ` 4 + [ 5 + "│ 6 + ◇ title ──╮ 7 + │ │ 8 + │ line 0 │ 9 + │ line 1 │ 10 + │ line 2 │ 11 + │ │ 12 + ├──────────╯ 13 + ", 14 + ] 15 + `; 16 + 17 + exports[`note (isCI = false) > formatter which adds length works 1`] = ` 18 + [ 19 + "│ 20 + ◇ title ──────╮ 21 + │ │ 22 + │ * line 0 * │ 23 + │ * line 1 * │ 24 + │ * line 2 * │ 25 + │ │ 26 + ├──────────────╯ 27 + ", 28 + ] 29 + `; 30 + 31 + exports[`note (isCI = false) > renders as wide as longest line 1`] = ` 32 + [ 33 + "│ 34 + ◇ title ───────────────────────────╮ 35 + │ │ 36 + │ short │ 37 + │ somewhat questionably long line │ 38 + │ │ 39 + ├───────────────────────────────────╯ 40 + ", 41 + ] 42 + `; 43 + 44 + exports[`note (isCI = false) > renders message with title 1`] = ` 45 + [ 46 + "│ 47 + ◇ title ───╮ 48 + │ │ 49 + │ message │ 50 + │ │ 51 + ├───────────╯ 52 + ", 53 + ] 54 + `; 55 + 56 + exports[`note (isCI = true) > formatter which adds colors works 1`] = ` 57 + [ 58 + "│ 59 + ◇ title ──╮ 60 + │ │ 61 + │ line 0 │ 62 + │ line 1 │ 63 + │ line 2 │ 64 + │ │ 65 + ├──────────╯ 66 + ", 67 + ] 68 + `; 69 + 70 + exports[`note (isCI = true) > formatter which adds length works 1`] = ` 71 + [ 72 + "│ 73 + ◇ title ──────╮ 74 + │ │ 75 + │ * line 0 * │ 76 + │ * line 1 * │ 77 + │ * line 2 * │ 78 + │ │ 79 + ├──────────────╯ 80 + ", 81 + ] 82 + `; 83 + 84 + exports[`note (isCI = true) > renders as wide as longest line 1`] = ` 85 + [ 86 + "│ 87 + ◇ title ───────────────────────────╮ 88 + │ │ 89 + │ short │ 90 + │ somewhat questionably long line │ 91 + │ │ 92 + ├───────────────────────────────────╯ 93 + ", 94 + ] 95 + `; 96 + 97 + exports[`note (isCI = true) > renders message with title 1`] = ` 98 + [ 99 + "│ 100 + ◇ title ───╮ 101 + │ │ 102 + │ message │ 103 + │ │ 104 + ├───────────╯ 105 + ", 106 + ] 107 + `;
+281
packages/prompts/src/__snapshots__/password.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`password (isCI = false) > renders and clears validation errors 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ◆ foo 8 + │ _ 9 + └ 10 + ", 11 + "", 12 + "", 13 + "", 14 + "│ ▪_", 15 + "", 16 + "", 17 + "", 18 + "", 19 + "▲ foo 20 + │ ▪ 21 + └ Password must be at least 2 characters 22 + ", 23 + "", 24 + "", 25 + "", 26 + "◆ foo 27 + │ ▪▪_ 28 + └ 29 + ", 30 + "", 31 + "", 32 + "", 33 + "◇ foo 34 + │ ▪▪", 35 + " 36 + ", 37 + "[?25h", 38 + ] 39 + `; 40 + 41 + exports[`password (isCI = false) > renders cancelled value 1`] = ` 42 + [ 43 + "[?25l", 44 + "│ 45 + ◆ foo 46 + │ _ 47 + └ 48 + ", 49 + "", 50 + "", 51 + "", 52 + "│ ▪_", 53 + "", 54 + "", 55 + "", 56 + "", 57 + "■ foo 58 + │ ▪ 59 + │", 60 + " 61 + ", 62 + "[?25h", 63 + ] 64 + `; 65 + 66 + exports[`password (isCI = false) > renders custom mask 1`] = ` 67 + [ 68 + "[?25l", 69 + "│ 70 + ◆ foo 71 + │ _ 72 + └ 73 + ", 74 + "", 75 + "", 76 + "", 77 + "│ *_", 78 + "", 79 + "", 80 + "", 81 + "", 82 + "│ **_", 83 + "", 84 + "", 85 + "", 86 + "", 87 + "◇ foo 88 + │ **", 89 + " 90 + ", 91 + "[?25h", 92 + ] 93 + `; 94 + 95 + exports[`password (isCI = false) > renders masked value 1`] = ` 96 + [ 97 + "[?25l", 98 + "│ 99 + ◆ foo 100 + │ _ 101 + └ 102 + ", 103 + "", 104 + "", 105 + "", 106 + "│ ▪_", 107 + "", 108 + "", 109 + "", 110 + "", 111 + "│ ▪▪_", 112 + "", 113 + "", 114 + "", 115 + "", 116 + "◇ foo 117 + │ ▪▪", 118 + " 119 + ", 120 + "[?25h", 121 + ] 122 + `; 123 + 124 + exports[`password (isCI = false) > renders message 1`] = ` 125 + [ 126 + "[?25l", 127 + "│ 128 + ◆ foo 129 + │ _ 130 + └ 131 + ", 132 + "", 133 + "", 134 + "", 135 + "◇ foo 136 + │", 137 + " 138 + ", 139 + "[?25h", 140 + ] 141 + `; 142 + 143 + exports[`password (isCI = true) > renders and clears validation errors 1`] = ` 144 + [ 145 + "[?25l", 146 + "│ 147 + ◆ foo 148 + │ _ 149 + └ 150 + ", 151 + "", 152 + "", 153 + "", 154 + "│ ▪_", 155 + "", 156 + "", 157 + "", 158 + "", 159 + "▲ foo 160 + │ ▪ 161 + └ Password must be at least 2 characters 162 + ", 163 + "", 164 + "", 165 + "", 166 + "◆ foo 167 + │ ▪▪_ 168 + └ 169 + ", 170 + "", 171 + "", 172 + "", 173 + "◇ foo 174 + │ ▪▪", 175 + " 176 + ", 177 + "[?25h", 178 + ] 179 + `; 180 + 181 + exports[`password (isCI = true) > renders cancelled value 1`] = ` 182 + [ 183 + "[?25l", 184 + "│ 185 + ◆ foo 186 + │ _ 187 + └ 188 + ", 189 + "", 190 + "", 191 + "", 192 + "│ ▪_", 193 + "", 194 + "", 195 + "", 196 + "", 197 + "■ foo 198 + │ ▪ 199 + │", 200 + " 201 + ", 202 + "[?25h", 203 + ] 204 + `; 205 + 206 + exports[`password (isCI = true) > renders custom mask 1`] = ` 207 + [ 208 + "[?25l", 209 + "│ 210 + ◆ foo 211 + │ _ 212 + └ 213 + ", 214 + "", 215 + "", 216 + "", 217 + "│ *_", 218 + "", 219 + "", 220 + "", 221 + "", 222 + "│ **_", 223 + "", 224 + "", 225 + "", 226 + "", 227 + "◇ foo 228 + │ **", 229 + " 230 + ", 231 + "[?25h", 232 + ] 233 + `; 234 + 235 + exports[`password (isCI = true) > renders masked value 1`] = ` 236 + [ 237 + "[?25l", 238 + "│ 239 + ◆ foo 240 + │ _ 241 + └ 242 + ", 243 + "", 244 + "", 245 + "", 246 + "│ ▪_", 247 + "", 248 + "", 249 + "", 250 + "", 251 + "│ ▪▪_", 252 + "", 253 + "", 254 + "", 255 + "", 256 + "◇ foo 257 + │ ▪▪", 258 + " 259 + ", 260 + "[?25h", 261 + ] 262 + `; 263 + 264 + exports[`password (isCI = true) > renders message 1`] = ` 265 + [ 266 + "[?25l", 267 + "│ 268 + ◆ foo 269 + │ _ 270 + └ 271 + ", 272 + "", 273 + "", 274 + "", 275 + "◇ foo 276 + │", 277 + " 278 + ", 279 + "[?25h", 280 + ] 281 + `;
+285
packages/prompts/src/__snapshots__/select.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`select (isCI = false) > can cancel 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ◆ foo 8 + │ ● opt0 9 + │ ○ opt1 10 + └ 11 + ", 12 + "", 13 + "", 14 + "", 15 + "■ foo 16 + │ opt0 17 + │", 18 + " 19 + ", 20 + "[?25h", 21 + ] 22 + `; 23 + 24 + exports[`select (isCI = false) > down arrow selects next option 1`] = ` 25 + [ 26 + "[?25l", 27 + "│ 28 + ◆ foo 29 + │ ● opt0 30 + │ ○ opt1 31 + └ 32 + ", 33 + "", 34 + "", 35 + "", 36 + "│ ○ opt0 37 + │ ● opt1 38 + └ 39 + ", 40 + "", 41 + "", 42 + "", 43 + "◇ foo 44 + │ opt1", 45 + " 46 + ", 47 + "[?25h", 48 + ] 49 + `; 50 + 51 + exports[`select (isCI = false) > renders option hints 1`] = ` 52 + [ 53 + "[?25l", 54 + "│ 55 + ◆ foo 56 + │ ● opt0 (Hint 0) 57 + │ ○ opt1 58 + └ 59 + ", 60 + "", 61 + "", 62 + "", 63 + "◇ foo 64 + │ opt0", 65 + " 66 + ", 67 + "[?25h", 68 + ] 69 + `; 70 + 71 + exports[`select (isCI = false) > renders option labels 1`] = ` 72 + [ 73 + "[?25l", 74 + "│ 75 + ◆ foo 76 + │ ● Option 0 77 + │ ○ Option 1 78 + └ 79 + ", 80 + "", 81 + "", 82 + "", 83 + "◇ foo 84 + │ Option 0", 85 + " 86 + ", 87 + "[?25h", 88 + ] 89 + `; 90 + 91 + exports[`select (isCI = false) > renders options and message 1`] = ` 92 + [ 93 + "[?25l", 94 + "│ 95 + ◆ foo 96 + │ ● opt0 97 + │ ○ opt1 98 + └ 99 + ", 100 + "", 101 + "", 102 + "", 103 + "◇ foo 104 + │ opt0", 105 + " 106 + ", 107 + "[?25h", 108 + ] 109 + `; 110 + 111 + exports[`select (isCI = false) > up arrow selects previous option 1`] = ` 112 + [ 113 + "[?25l", 114 + "│ 115 + ◆ foo 116 + │ ● opt0 117 + │ ○ opt1 118 + └ 119 + ", 120 + "", 121 + "", 122 + "", 123 + "│ ○ opt0 124 + │ ● opt1 125 + └ 126 + ", 127 + "", 128 + "", 129 + "", 130 + "│ ● opt0 131 + │ ○ opt1 132 + └ 133 + ", 134 + "", 135 + "", 136 + "", 137 + "◇ foo 138 + │ opt0", 139 + " 140 + ", 141 + "[?25h", 142 + ] 143 + `; 144 + 145 + exports[`select (isCI = true) > can cancel 1`] = ` 146 + [ 147 + "[?25l", 148 + "│ 149 + ◆ foo 150 + │ ● opt0 151 + │ ○ opt1 152 + └ 153 + ", 154 + "", 155 + "", 156 + "", 157 + "■ foo 158 + │ opt0 159 + │", 160 + " 161 + ", 162 + "[?25h", 163 + ] 164 + `; 165 + 166 + exports[`select (isCI = true) > down arrow selects next option 1`] = ` 167 + [ 168 + "[?25l", 169 + "│ 170 + ◆ foo 171 + │ ● opt0 172 + │ ○ opt1 173 + └ 174 + ", 175 + "", 176 + "", 177 + "", 178 + "│ ○ opt0 179 + │ ● opt1 180 + └ 181 + ", 182 + "", 183 + "", 184 + "", 185 + "◇ foo 186 + │ opt1", 187 + " 188 + ", 189 + "[?25h", 190 + ] 191 + `; 192 + 193 + exports[`select (isCI = true) > renders option hints 1`] = ` 194 + [ 195 + "[?25l", 196 + "│ 197 + ◆ foo 198 + │ ● opt0 (Hint 0) 199 + │ ○ opt1 200 + └ 201 + ", 202 + "", 203 + "", 204 + "", 205 + "◇ foo 206 + │ opt0", 207 + " 208 + ", 209 + "[?25h", 210 + ] 211 + `; 212 + 213 + exports[`select (isCI = true) > renders option labels 1`] = ` 214 + [ 215 + "[?25l", 216 + "│ 217 + ◆ foo 218 + │ ● Option 0 219 + │ ○ Option 1 220 + └ 221 + ", 222 + "", 223 + "", 224 + "", 225 + "◇ foo 226 + │ Option 0", 227 + " 228 + ", 229 + "[?25h", 230 + ] 231 + `; 232 + 233 + exports[`select (isCI = true) > renders options and message 1`] = ` 234 + [ 235 + "[?25l", 236 + "│ 237 + ◆ foo 238 + │ ● opt0 239 + │ ○ opt1 240 + └ 241 + ", 242 + "", 243 + "", 244 + "", 245 + "◇ foo 246 + │ opt0", 247 + " 248 + ", 249 + "[?25h", 250 + ] 251 + `; 252 + 253 + exports[`select (isCI = true) > up arrow selects previous option 1`] = ` 254 + [ 255 + "[?25l", 256 + "│ 257 + ◆ foo 258 + │ ● opt0 259 + │ ○ opt1 260 + └ 261 + ", 262 + "", 263 + "", 264 + "", 265 + "│ ○ opt0 266 + │ ● opt1 267 + └ 268 + ", 269 + "", 270 + "", 271 + "", 272 + "│ ● opt0 273 + │ ○ opt1 274 + └ 275 + ", 276 + "", 277 + "", 278 + "", 279 + "◇ foo 280 + │ opt0", 281 + " 282 + ", 283 + "[?25h", 284 + ] 285 + `;
+394
packages/prompts/src/__snapshots__/spinner.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`spinner (isCI = false) > message > sets message for next frame 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ", 8 + "◒ ", 9 + "", 10 + "", 11 + "◐ foo", 12 + ] 13 + `; 14 + 15 + exports[`spinner (isCI = false) > process exit handling > prioritizes direct options over global settings 1`] = ` 16 + [ 17 + "[?25l", 18 + "│ 19 + ", 20 + "■ Spinner cancel message 21 + ", 22 + "[?25h", 23 + ] 24 + `; 25 + 26 + exports[`spinner (isCI = false) > process exit handling > prioritizes direct options over global settings 2`] = ` 27 + [ 28 + "[?25l", 29 + "│ 30 + ", 31 + "▲ Spinner error message 32 + ", 33 + "[?25h", 34 + ] 35 + `; 36 + 37 + exports[`spinner (isCI = false) > process exit handling > uses custom cancel message when provided directly 1`] = ` 38 + [ 39 + "[?25l", 40 + "│ 41 + ", 42 + "■ Custom cancel message 43 + ", 44 + "[?25h", 45 + ] 46 + `; 47 + 48 + exports[`spinner (isCI = false) > process exit handling > uses custom error message when provided directly 1`] = ` 49 + [ 50 + "[?25l", 51 + "│ 52 + ", 53 + "▲ Custom error message 54 + ", 55 + "[?25h", 56 + ] 57 + `; 58 + 59 + exports[`spinner (isCI = false) > process exit handling > uses default cancel message 1`] = ` 60 + [ 61 + "[?25l", 62 + "│ 63 + ", 64 + "■ Canceled 65 + ", 66 + "[?25h", 67 + ] 68 + `; 69 + 70 + exports[`spinner (isCI = false) > process exit handling > uses global custom cancel message from settings 1`] = ` 71 + [ 72 + "[?25l", 73 + "│ 74 + ", 75 + "■ Global cancel message 76 + ", 77 + "[?25h", 78 + ] 79 + `; 80 + 81 + exports[`spinner (isCI = false) > process exit handling > uses global custom error message from settings 1`] = ` 82 + [ 83 + "[?25l", 84 + "│ 85 + ", 86 + "▲ Global error message 87 + ", 88 + "[?25h", 89 + ] 90 + `; 91 + 92 + exports[`spinner (isCI = false) > start > renders frames at interval 1`] = ` 93 + [ 94 + "[?25l", 95 + "│ 96 + ", 97 + "◒ ", 98 + "", 99 + "", 100 + "◐ ", 101 + "", 102 + "", 103 + "◓ ", 104 + "", 105 + "", 106 + "◑ ", 107 + ] 108 + `; 109 + 110 + exports[`spinner (isCI = false) > start > renders message 1`] = ` 111 + [ 112 + "[?25l", 113 + "│ 114 + ", 115 + "◒ foo", 116 + ] 117 + `; 118 + 119 + exports[`spinner (isCI = false) > start > renders timer when indicator is "timer" 1`] = ` 120 + [ 121 + "[?25l", 122 + "│ 123 + ", 124 + "◒ [0s]", 125 + ] 126 + `; 127 + 128 + exports[`spinner (isCI = false) > stop > renders cancel symbol if code = 1 1`] = ` 129 + [ 130 + "[?25l", 131 + "│ 132 + ", 133 + "◒ ", 134 + "", 135 + "", 136 + "■ 137 + ", 138 + "[?25h", 139 + ] 140 + `; 141 + 142 + exports[`spinner (isCI = false) > stop > renders error symbol if code > 1 1`] = ` 143 + [ 144 + "[?25l", 145 + "│ 146 + ", 147 + "◒ ", 148 + "", 149 + "", 150 + "▲ 151 + ", 152 + "[?25h", 153 + ] 154 + `; 155 + 156 + exports[`spinner (isCI = false) > stop > renders message 1`] = ` 157 + [ 158 + "[?25l", 159 + "│ 160 + ", 161 + "◒ ", 162 + "", 163 + "", 164 + "◇ foo 165 + ", 166 + "[?25h", 167 + ] 168 + `; 169 + 170 + exports[`spinner (isCI = false) > stop > renders message without removing dots 1`] = ` 171 + [ 172 + "[?25l", 173 + "│ 174 + ", 175 + "◒ ", 176 + "", 177 + "", 178 + "◇ foo. 179 + ", 180 + "[?25h", 181 + ] 182 + `; 183 + 184 + exports[`spinner (isCI = false) > stop > renders submit symbol and stops spinner 1`] = ` 185 + [ 186 + "[?25l", 187 + "│ 188 + ", 189 + "◒ ", 190 + "", 191 + "", 192 + "◇ 193 + ", 194 + "[?25h", 195 + ] 196 + `; 197 + 198 + exports[`spinner (isCI = true) > message > sets message for next frame 1`] = ` 199 + [ 200 + "[?25l", 201 + "│ 202 + ", 203 + "◒ ...", 204 + " 205 + ", 206 + "", 207 + "", 208 + "◐ foo...", 209 + ] 210 + `; 211 + 212 + exports[`spinner (isCI = true) > process exit handling > prioritizes direct options over global settings 1`] = ` 213 + [ 214 + "[?25l", 215 + "│ 216 + ", 217 + "■ Spinner cancel message 218 + ", 219 + "[?25h", 220 + ] 221 + `; 222 + 223 + exports[`spinner (isCI = true) > process exit handling > prioritizes direct options over global settings 2`] = ` 224 + [ 225 + "[?25l", 226 + "│ 227 + ", 228 + "▲ Spinner error message 229 + ", 230 + "[?25h", 231 + ] 232 + `; 233 + 234 + exports[`spinner (isCI = true) > process exit handling > uses custom cancel message when provided directly 1`] = ` 235 + [ 236 + "[?25l", 237 + "│ 238 + ", 239 + "■ Custom cancel message 240 + ", 241 + "[?25h", 242 + ] 243 + `; 244 + 245 + exports[`spinner (isCI = true) > process exit handling > uses custom error message when provided directly 1`] = ` 246 + [ 247 + "[?25l", 248 + "│ 249 + ", 250 + "▲ Custom error message 251 + ", 252 + "[?25h", 253 + ] 254 + `; 255 + 256 + exports[`spinner (isCI = true) > process exit handling > uses default cancel message 1`] = ` 257 + [ 258 + "[?25l", 259 + "│ 260 + ", 261 + "■ Canceled 262 + ", 263 + "[?25h", 264 + ] 265 + `; 266 + 267 + exports[`spinner (isCI = true) > process exit handling > uses global custom cancel message from settings 1`] = ` 268 + [ 269 + "[?25l", 270 + "│ 271 + ", 272 + "■ Global cancel message 273 + ", 274 + "[?25h", 275 + ] 276 + `; 277 + 278 + exports[`spinner (isCI = true) > process exit handling > uses global custom error message from settings 1`] = ` 279 + [ 280 + "[?25l", 281 + "│ 282 + ", 283 + "▲ Global error message 284 + ", 285 + "[?25h", 286 + ] 287 + `; 288 + 289 + exports[`spinner (isCI = true) > start > renders frames at interval 1`] = ` 290 + [ 291 + "[?25l", 292 + "│ 293 + ", 294 + "◒ ...", 295 + ] 296 + `; 297 + 298 + exports[`spinner (isCI = true) > start > renders message 1`] = ` 299 + [ 300 + "[?25l", 301 + "│ 302 + ", 303 + "◒ foo...", 304 + ] 305 + `; 306 + 307 + exports[`spinner (isCI = true) > start > renders timer when indicator is "timer" 1`] = ` 308 + [ 309 + "[?25l", 310 + "│ 311 + ", 312 + "◒ ...", 313 + ] 314 + `; 315 + 316 + exports[`spinner (isCI = true) > stop > renders cancel symbol if code = 1 1`] = ` 317 + [ 318 + "[?25l", 319 + "│ 320 + ", 321 + "◒ ...", 322 + " 323 + ", 324 + "", 325 + "", 326 + "■ 327 + ", 328 + "[?25h", 329 + ] 330 + `; 331 + 332 + exports[`spinner (isCI = true) > stop > renders error symbol if code > 1 1`] = ` 333 + [ 334 + "[?25l", 335 + "│ 336 + ", 337 + "◒ ...", 338 + " 339 + ", 340 + "", 341 + "", 342 + "▲ 343 + ", 344 + "[?25h", 345 + ] 346 + `; 347 + 348 + exports[`spinner (isCI = true) > stop > renders message 1`] = ` 349 + [ 350 + "[?25l", 351 + "│ 352 + ", 353 + "◒ ...", 354 + " 355 + ", 356 + "", 357 + "", 358 + "◇ foo 359 + ", 360 + "[?25h", 361 + ] 362 + `; 363 + 364 + exports[`spinner (isCI = true) > stop > renders message without removing dots 1`] = ` 365 + [ 366 + "[?25l", 367 + "│ 368 + ", 369 + "◒ ...", 370 + " 371 + ", 372 + "", 373 + "", 374 + "◇ foo. 375 + ", 376 + "[?25h", 377 + ] 378 + `; 379 + 380 + exports[`spinner (isCI = true) > stop > renders submit symbol and stops spinner 1`] = ` 381 + [ 382 + "[?25l", 383 + "│ 384 + ", 385 + "◒ ...", 386 + " 387 + ", 388 + "", 389 + "", 390 + "◇ 391 + ", 392 + "[?25h", 393 + ] 394 + `;
+998
packages/prompts/src/__snapshots__/task-log.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`taskLog (isCI = false) > error > clears output if showLog = false 1`] = ` 4 + [ 5 + "│ 6 + ", 7 + "◇ foo 8 + ", 9 + "│ 10 + ", 11 + "│ line 0 12 + ", 13 + "", 14 + "│ line 0 15 + │ line 1 16 + ", 17 + "", 18 + "│ 19 + ■ some error! 20 + ", 21 + ] 22 + `; 23 + 24 + exports[`taskLog (isCI = false) > error > renders output with message 1`] = ` 25 + [ 26 + "│ 27 + ", 28 + "◇ foo 29 + ", 30 + "│ 31 + ", 32 + "│ line 0 33 + ", 34 + "", 35 + "│ line 0 36 + │ line 1 37 + ", 38 + "", 39 + "│ 40 + ■ some error! 41 + ", 42 + "│ 43 + │ line 0 44 + │ line 1 45 + ", 46 + ] 47 + `; 48 + 49 + exports[`taskLog (isCI = false) > message > can write line by line 1`] = ` 50 + [ 51 + "│ 52 + ", 53 + "◇ foo 54 + ", 55 + "│ 56 + ", 57 + "│ line 0 58 + ", 59 + "", 60 + "│ line 0 61 + │ line 1 62 + ", 63 + ] 64 + `; 65 + 66 + exports[`taskLog (isCI = false) > message > can write multiple lines 1`] = ` 67 + [ 68 + "│ 69 + ", 70 + "◇ foo 71 + ", 72 + "│ 73 + ", 74 + "│ line 0 75 + │ line 1 76 + ", 77 + ] 78 + `; 79 + 80 + exports[`taskLog (isCI = false) > message > enforces limit if set 1`] = ` 81 + [ 82 + "│ 83 + ", 84 + "◇ foo 85 + ", 86 + "│ 87 + ", 88 + "│ line 0 89 + ", 90 + "", 91 + "│ line 0 92 + │ line 1 93 + ", 94 + "", 95 + "│ line 1 96 + │ line 2 97 + ", 98 + ] 99 + `; 100 + 101 + exports[`taskLog (isCI = false) > message > prints empty lines 1`] = ` 102 + [ 103 + "│ 104 + ", 105 + "◇ foo 106 + ", 107 + "│ 108 + ", 109 + "│  110 + ", 111 + "│ line 1 112 + ", 113 + "", 114 + "│ line 1 115 + │  116 + ", 117 + "", 118 + "│ line 1 119 + │  120 + │ line 3 121 + ", 122 + ] 123 + `; 124 + 125 + exports[`taskLog (isCI = false) > message > raw = true appends message text until newline 1`] = ` 126 + [ 127 + "│ 128 + ", 129 + "◇ foo 130 + ", 131 + "│ 132 + ", 133 + "│ line 0 134 + ", 135 + "", 136 + "│ line 0still line 0 137 + ", 138 + "", 139 + "│ line 0still line 0 140 + │ line 1 141 + ", 142 + ] 143 + `; 144 + 145 + exports[`taskLog (isCI = false) > message > raw = true works when mixed with non-raw messages 1`] = ` 146 + [ 147 + "│ 148 + ", 149 + "◇ foo 150 + ", 151 + "│ 152 + ", 153 + "│ line 0 154 + ", 155 + "", 156 + "│ line 0still line 0 157 + ", 158 + "", 159 + "│ line 0still line 0 160 + │ line 1 161 + ", 162 + ] 163 + `; 164 + 165 + exports[`taskLog (isCI = false) > message > raw = true works when started with non-raw messages 1`] = ` 166 + [ 167 + "│ 168 + ", 169 + "◇ foo 170 + ", 171 + "│ 172 + ", 173 + "│ line 0 174 + ", 175 + "", 176 + "│ line 0 177 + │ line 1 178 + ", 179 + "", 180 + "│ line 0 181 + │ line 1still line 1 182 + ", 183 + ] 184 + `; 185 + 186 + exports[`taskLog (isCI = false) > retainLog > error > outputs limited log with limit by default 1`] = ` 187 + [ 188 + "│ 189 + ", 190 + "◇ foo 191 + ", 192 + "│ 193 + ", 194 + "│ line 0 195 + ", 196 + "", 197 + "│ line 0 198 + │ line 1 199 + ", 200 + "", 201 + "│ line 1 202 + │ line 2 203 + ", 204 + "", 205 + "│ line 2 206 + │ line 3 207 + ", 208 + "", 209 + "│ 210 + ■ woo! 211 + ", 212 + "│ 213 + │ line 2 214 + │ line 3 215 + ", 216 + ] 217 + `; 218 + 219 + exports[`taskLog (isCI = false) > retainLog > error > retainLog = false outputs full log without limit 1`] = ` 220 + [ 221 + "│ 222 + ", 223 + "◇ foo 224 + ", 225 + "│ 226 + ", 227 + "│ line 0 228 + ", 229 + "", 230 + "│ line 0 231 + │ line 1 232 + ", 233 + "", 234 + "│ line 0 235 + │ line 1 236 + │ line 2 237 + ", 238 + "", 239 + "│ line 0 240 + │ line 1 241 + │ line 2 242 + │ line 3 243 + ", 244 + "", 245 + "│ 246 + ■ woo! 247 + ", 248 + "│ 249 + │ line 0 250 + │ line 1 251 + │ line 2 252 + │ line 3 253 + ", 254 + ] 255 + `; 256 + 257 + exports[`taskLog (isCI = false) > retainLog > error > retainLog = false outputs limited log with limit 1`] = ` 258 + [ 259 + "│ 260 + ", 261 + "◇ foo 262 + ", 263 + "│ 264 + ", 265 + "│ line 0 266 + ", 267 + "", 268 + "│ line 0 269 + │ line 1 270 + ", 271 + "", 272 + "│ line 1 273 + │ line 2 274 + ", 275 + "", 276 + "│ line 2 277 + │ line 3 278 + ", 279 + "", 280 + "│ 281 + ■ woo! 282 + ", 283 + "│ 284 + │ line 2 285 + │ line 3 286 + ", 287 + ] 288 + `; 289 + 290 + exports[`taskLog (isCI = false) > retainLog > error > retainLog = true outputs full log 1`] = ` 291 + [ 292 + "│ 293 + ", 294 + "◇ foo 295 + ", 296 + "│ 297 + ", 298 + "│ line 0 299 + ", 300 + "", 301 + "│ line 0 302 + │ line 1 303 + ", 304 + "", 305 + "│ line 0 306 + │ line 1 307 + │ line 2 308 + ", 309 + "", 310 + "│ line 0 311 + │ line 1 312 + │ line 2 313 + │ line 3 314 + ", 315 + "", 316 + "│ 317 + ■ woo! 318 + ", 319 + "│ 320 + │ line 0 321 + │ line 1 322 + │ line 2 323 + │ line 3 324 + ", 325 + ] 326 + `; 327 + 328 + exports[`taskLog (isCI = false) > retainLog > error > retainLog = true outputs full log with limit 1`] = ` 329 + [ 330 + "│ 331 + ", 332 + "◇ foo 333 + ", 334 + "│ 335 + ", 336 + "│ line 0 337 + ", 338 + "", 339 + "│ line 0 340 + │ line 1 341 + ", 342 + "", 343 + "│ line 1 344 + │ line 2 345 + ", 346 + "", 347 + "│ line 2 348 + │ line 3 349 + ", 350 + "", 351 + "│ 352 + ■ woo! 353 + ", 354 + "│ 355 + │ line 0 356 + │ line 1 357 + │ line 2 358 + │ line 3 359 + ", 360 + ] 361 + `; 362 + 363 + exports[`taskLog (isCI = false) > retainLog > success > outputs limited log with limit by default 1`] = ` 364 + [ 365 + "│ 366 + ", 367 + "◇ foo 368 + ", 369 + "│ 370 + ", 371 + "│ line 0 372 + ", 373 + "", 374 + "│ line 0 375 + │ line 1 376 + ", 377 + "", 378 + "│ line 1 379 + │ line 2 380 + ", 381 + "", 382 + "│ line 2 383 + │ line 3 384 + ", 385 + "", 386 + "│ 387 + ◆ woo! 388 + ", 389 + "│ 390 + │ line 2 391 + │ line 3 392 + ", 393 + ] 394 + `; 395 + 396 + exports[`taskLog (isCI = false) > retainLog > success > retainLog = false outputs full log without limit 1`] = ` 397 + [ 398 + "│ 399 + ", 400 + "◇ foo 401 + ", 402 + "│ 403 + ", 404 + "│ line 0 405 + ", 406 + "", 407 + "│ line 0 408 + │ line 1 409 + ", 410 + "", 411 + "│ line 0 412 + │ line 1 413 + │ line 2 414 + ", 415 + "", 416 + "│ line 0 417 + │ line 1 418 + │ line 2 419 + │ line 3 420 + ", 421 + "", 422 + "│ 423 + ◆ woo! 424 + ", 425 + "│ 426 + │ line 0 427 + │ line 1 428 + │ line 2 429 + │ line 3 430 + ", 431 + ] 432 + `; 433 + 434 + exports[`taskLog (isCI = false) > retainLog > success > retainLog = false outputs limited log with limit 1`] = ` 435 + [ 436 + "│ 437 + ", 438 + "◇ foo 439 + ", 440 + "│ 441 + ", 442 + "│ line 0 443 + ", 444 + "", 445 + "│ line 0 446 + │ line 1 447 + ", 448 + "", 449 + "│ line 1 450 + │ line 2 451 + ", 452 + "", 453 + "│ line 2 454 + │ line 3 455 + ", 456 + "", 457 + "│ 458 + ◆ woo! 459 + ", 460 + "│ 461 + │ line 2 462 + │ line 3 463 + ", 464 + ] 465 + `; 466 + 467 + exports[`taskLog (isCI = false) > retainLog > success > retainLog = true outputs full log 1`] = ` 468 + [ 469 + "│ 470 + ", 471 + "◇ foo 472 + ", 473 + "│ 474 + ", 475 + "│ line 0 476 + ", 477 + "", 478 + "│ line 0 479 + │ line 1 480 + ", 481 + "", 482 + "│ line 0 483 + │ line 1 484 + │ line 2 485 + ", 486 + "", 487 + "│ line 0 488 + │ line 1 489 + │ line 2 490 + │ line 3 491 + ", 492 + "", 493 + "│ 494 + ◆ woo! 495 + ", 496 + "│ 497 + │ line 0 498 + │ line 1 499 + │ line 2 500 + │ line 3 501 + ", 502 + ] 503 + `; 504 + 505 + exports[`taskLog (isCI = false) > retainLog > success > retainLog = true outputs full log with limit 1`] = ` 506 + [ 507 + "│ 508 + ", 509 + "◇ foo 510 + ", 511 + "│ 512 + ", 513 + "│ line 0 514 + ", 515 + "", 516 + "│ line 0 517 + │ line 1 518 + ", 519 + "", 520 + "│ line 1 521 + │ line 2 522 + ", 523 + "", 524 + "│ line 2 525 + │ line 3 526 + ", 527 + "", 528 + "│ 529 + ◆ woo! 530 + ", 531 + "│ 532 + │ line 0 533 + │ line 1 534 + │ line 2 535 + │ line 3 536 + ", 537 + ] 538 + `; 539 + 540 + exports[`taskLog (isCI = false) > success > clears output and renders message 1`] = ` 541 + [ 542 + "│ 543 + ", 544 + "◇ foo 545 + ", 546 + "│ 547 + ", 548 + "│ line 0 549 + ", 550 + "", 551 + "│ line 0 552 + │ line 1 553 + ", 554 + "", 555 + "│ 556 + ◆ success! 557 + ", 558 + ] 559 + `; 560 + 561 + exports[`taskLog (isCI = false) > success > renders output if showLog = true 1`] = ` 562 + [ 563 + "│ 564 + ", 565 + "◇ foo 566 + ", 567 + "│ 568 + ", 569 + "│ line 0 570 + ", 571 + "", 572 + "│ line 0 573 + │ line 1 574 + ", 575 + "", 576 + "│ 577 + ◆ success! 578 + ", 579 + "│ 580 + │ line 0 581 + │ line 1 582 + ", 583 + ] 584 + `; 585 + 586 + exports[`taskLog (isCI = false) > writes message header 1`] = ` 587 + [ 588 + "│ 589 + ", 590 + "◇ foo 591 + ", 592 + "│ 593 + ", 594 + ] 595 + `; 596 + 597 + exports[`taskLog (isCI = true) > error > clears output if showLog = false 1`] = ` 598 + [ 599 + "│ 600 + ", 601 + "◇ foo 602 + ", 603 + "│ 604 + ", 605 + "", 606 + "", 607 + "│ 608 + ■ some error! 609 + ", 610 + ] 611 + `; 612 + 613 + exports[`taskLog (isCI = true) > error > renders output with message 1`] = ` 614 + [ 615 + "│ 616 + ", 617 + "◇ foo 618 + ", 619 + "│ 620 + ", 621 + "", 622 + "", 623 + "│ 624 + ■ some error! 625 + ", 626 + "│ 627 + │ line 0 628 + │ line 1 629 + ", 630 + ] 631 + `; 632 + 633 + exports[`taskLog (isCI = true) > message > can write line by line 1`] = ` 634 + [ 635 + "│ 636 + ", 637 + "◇ foo 638 + ", 639 + "│ 640 + ", 641 + "", 642 + ] 643 + `; 644 + 645 + exports[`taskLog (isCI = true) > message > can write multiple lines 1`] = ` 646 + [ 647 + "│ 648 + ", 649 + "◇ foo 650 + ", 651 + "│ 652 + ", 653 + ] 654 + `; 655 + 656 + exports[`taskLog (isCI = true) > message > enforces limit if set 1`] = ` 657 + [ 658 + "│ 659 + ", 660 + "◇ foo 661 + ", 662 + "│ 663 + ", 664 + "", 665 + "", 666 + ] 667 + `; 668 + 669 + exports[`taskLog (isCI = true) > message > prints empty lines 1`] = ` 670 + [ 671 + "│ 672 + ", 673 + "◇ foo 674 + ", 675 + "│ 676 + ", 677 + "", 678 + "", 679 + ] 680 + `; 681 + 682 + exports[`taskLog (isCI = true) > message > raw = true appends message text until newline 1`] = ` 683 + [ 684 + "│ 685 + ", 686 + "◇ foo 687 + ", 688 + "│ 689 + ", 690 + "", 691 + "", 692 + ] 693 + `; 694 + 695 + exports[`taskLog (isCI = true) > message > raw = true works when mixed with non-raw messages 1`] = ` 696 + [ 697 + "│ 698 + ", 699 + "◇ foo 700 + ", 701 + "│ 702 + ", 703 + "", 704 + "", 705 + ] 706 + `; 707 + 708 + exports[`taskLog (isCI = true) > message > raw = true works when started with non-raw messages 1`] = ` 709 + [ 710 + "│ 711 + ", 712 + "◇ foo 713 + ", 714 + "│ 715 + ", 716 + "", 717 + "", 718 + ] 719 + `; 720 + 721 + exports[`taskLog (isCI = true) > retainLog > error > outputs limited log with limit by default 1`] = ` 722 + [ 723 + "│ 724 + ", 725 + "◇ foo 726 + ", 727 + "│ 728 + ", 729 + "", 730 + "", 731 + "", 732 + "", 733 + "│ 734 + ■ woo! 735 + ", 736 + "│ 737 + │ line 2 738 + │ line 3 739 + ", 740 + ] 741 + `; 742 + 743 + exports[`taskLog (isCI = true) > retainLog > error > retainLog = false outputs full log without limit 1`] = ` 744 + [ 745 + "│ 746 + ", 747 + "◇ foo 748 + ", 749 + "│ 750 + ", 751 + "", 752 + "", 753 + "", 754 + "", 755 + "│ 756 + ■ woo! 757 + ", 758 + "│ 759 + │ line 0 760 + │ line 1 761 + │ line 2 762 + │ line 3 763 + ", 764 + ] 765 + `; 766 + 767 + exports[`taskLog (isCI = true) > retainLog > error > retainLog = false outputs limited log with limit 1`] = ` 768 + [ 769 + "│ 770 + ", 771 + "◇ foo 772 + ", 773 + "│ 774 + ", 775 + "", 776 + "", 777 + "", 778 + "", 779 + "│ 780 + ■ woo! 781 + ", 782 + "│ 783 + │ line 2 784 + │ line 3 785 + ", 786 + ] 787 + `; 788 + 789 + exports[`taskLog (isCI = true) > retainLog > error > retainLog = true outputs full log 1`] = ` 790 + [ 791 + "│ 792 + ", 793 + "◇ foo 794 + ", 795 + "│ 796 + ", 797 + "", 798 + "", 799 + "", 800 + "", 801 + "│ 802 + ■ woo! 803 + ", 804 + "│ 805 + │ line 0 806 + │ line 1 807 + │ line 2 808 + │ line 3 809 + ", 810 + ] 811 + `; 812 + 813 + exports[`taskLog (isCI = true) > retainLog > error > retainLog = true outputs full log with limit 1`] = ` 814 + [ 815 + "│ 816 + ", 817 + "◇ foo 818 + ", 819 + "│ 820 + ", 821 + "", 822 + "", 823 + "", 824 + "", 825 + "│ 826 + ■ woo! 827 + ", 828 + "│ 829 + │ line 0 830 + │ line 1 831 + │ line 2 832 + │ line 3 833 + ", 834 + ] 835 + `; 836 + 837 + exports[`taskLog (isCI = true) > retainLog > success > outputs limited log with limit by default 1`] = ` 838 + [ 839 + "│ 840 + ", 841 + "◇ foo 842 + ", 843 + "│ 844 + ", 845 + "", 846 + "", 847 + "", 848 + "", 849 + "│ 850 + ◆ woo! 851 + ", 852 + "│ 853 + │ line 2 854 + │ line 3 855 + ", 856 + ] 857 + `; 858 + 859 + exports[`taskLog (isCI = true) > retainLog > success > retainLog = false outputs full log without limit 1`] = ` 860 + [ 861 + "│ 862 + ", 863 + "◇ foo 864 + ", 865 + "│ 866 + ", 867 + "", 868 + "", 869 + "", 870 + "", 871 + "│ 872 + ◆ woo! 873 + ", 874 + "│ 875 + │ line 0 876 + │ line 1 877 + │ line 2 878 + │ line 3 879 + ", 880 + ] 881 + `; 882 + 883 + exports[`taskLog (isCI = true) > retainLog > success > retainLog = false outputs limited log with limit 1`] = ` 884 + [ 885 + "│ 886 + ", 887 + "◇ foo 888 + ", 889 + "│ 890 + ", 891 + "", 892 + "", 893 + "", 894 + "", 895 + "│ 896 + ◆ woo! 897 + ", 898 + "│ 899 + │ line 2 900 + │ line 3 901 + ", 902 + ] 903 + `; 904 + 905 + exports[`taskLog (isCI = true) > retainLog > success > retainLog = true outputs full log 1`] = ` 906 + [ 907 + "│ 908 + ", 909 + "◇ foo 910 + ", 911 + "│ 912 + ", 913 + "", 914 + "", 915 + "", 916 + "", 917 + "│ 918 + ◆ woo! 919 + ", 920 + "│ 921 + │ line 0 922 + │ line 1 923 + │ line 2 924 + │ line 3 925 + ", 926 + ] 927 + `; 928 + 929 + exports[`taskLog (isCI = true) > retainLog > success > retainLog = true outputs full log with limit 1`] = ` 930 + [ 931 + "│ 932 + ", 933 + "◇ foo 934 + ", 935 + "│ 936 + ", 937 + "", 938 + "", 939 + "", 940 + "", 941 + "│ 942 + ◆ woo! 943 + ", 944 + "│ 945 + │ line 0 946 + │ line 1 947 + │ line 2 948 + │ line 3 949 + ", 950 + ] 951 + `; 952 + 953 + exports[`taskLog (isCI = true) > success > clears output and renders message 1`] = ` 954 + [ 955 + "│ 956 + ", 957 + "◇ foo 958 + ", 959 + "│ 960 + ", 961 + "", 962 + "", 963 + "│ 964 + ◆ success! 965 + ", 966 + ] 967 + `; 968 + 969 + exports[`taskLog (isCI = true) > success > renders output if showLog = true 1`] = ` 970 + [ 971 + "│ 972 + ", 973 + "◇ foo 974 + ", 975 + "│ 976 + ", 977 + "", 978 + "", 979 + "│ 980 + ◆ success! 981 + ", 982 + "│ 983 + │ line 0 984 + │ line 1 985 + ", 986 + ] 987 + `; 988 + 989 + exports[`taskLog (isCI = true) > writes message header 1`] = ` 990 + [ 991 + "│ 992 + ", 993 + "◇ foo 994 + ", 995 + "│ 996 + ", 997 + ] 998 + `;
+423
packages/prompts/src/__snapshots__/text.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`text (isCI = false) > can cancel 1`] = ` 4 + [ 5 + "[?25l", 6 + "│ 7 + ◆ foo 8 + │ _ 9 + └ 10 + ", 11 + "", 12 + "", 13 + "", 14 + "■ foo 15 + │", 16 + " 17 + ", 18 + "[?25h", 19 + ] 20 + `; 21 + 22 + exports[`text (isCI = false) > defaultValue sets the value but does not render 1`] = ` 23 + [ 24 + "[?25l", 25 + "│ 26 + ◆ foo 27 + │ _ 28 + └ 29 + ", 30 + "", 31 + "", 32 + "", 33 + "◇ foo 34 + │ bar", 35 + " 36 + ", 37 + "[?25h", 38 + ] 39 + `; 40 + 41 + exports[`text (isCI = false) > renders cancelled value if one set 1`] = ` 42 + [ 43 + "[?25l", 44 + "│ 45 + ◆ foo 46 + │ _ 47 + └ 48 + ", 49 + "", 50 + "", 51 + "", 52 + "│ x█", 53 + "", 54 + "", 55 + "", 56 + "", 57 + "│ xy█", 58 + "", 59 + "", 60 + "", 61 + "", 62 + "■ foo 63 + │ xy 64 + │", 65 + " 66 + ", 67 + "[?25h", 68 + ] 69 + `; 70 + 71 + exports[`text (isCI = false) > renders message 1`] = ` 72 + [ 73 + "[?25l", 74 + "│ 75 + ◆ foo 76 + │ _ 77 + └ 78 + ", 79 + "", 80 + "", 81 + "", 82 + "◇ foo 83 + │ undefined", 84 + " 85 + ", 86 + "[?25h", 87 + ] 88 + `; 89 + 90 + exports[`text (isCI = false) > renders placeholder if set 1`] = ` 91 + [ 92 + "[?25l", 93 + "│ 94 + ◆ foo 95 + │ bar 96 + └ 97 + ", 98 + "", 99 + "", 100 + "", 101 + "◇ foo 102 + │ bar", 103 + " 104 + ", 105 + "[?25h", 106 + ] 107 + `; 108 + 109 + exports[`text (isCI = false) > renders submitted value 1`] = ` 110 + [ 111 + "[?25l", 112 + "│ 113 + ◆ foo 114 + │ _ 115 + └ 116 + ", 117 + "", 118 + "", 119 + "", 120 + "│ x█", 121 + "", 122 + "", 123 + "", 124 + "", 125 + "│ xy█", 126 + "", 127 + "", 128 + "", 129 + "", 130 + "◇ foo 131 + │ xy", 132 + " 133 + ", 134 + "[?25h", 135 + ] 136 + `; 137 + 138 + exports[`text (isCI = false) > validation errors render and clear (using Error) 1`] = ` 139 + [ 140 + "[?25l", 141 + "│ 142 + ◆ foo 143 + │ _ 144 + └ 145 + ", 146 + "", 147 + "", 148 + "", 149 + "│ x█", 150 + "", 151 + "", 152 + "", 153 + "", 154 + "▲ foo 155 + │ x█ 156 + └ should be xy 157 + ", 158 + "", 159 + "", 160 + "", 161 + "◆ foo 162 + │ xy█ 163 + └ 164 + ", 165 + "", 166 + "", 167 + "", 168 + "◇ foo 169 + │ xy", 170 + " 171 + ", 172 + "[?25h", 173 + ] 174 + `; 175 + 176 + exports[`text (isCI = false) > validation errors render and clear 1`] = ` 177 + [ 178 + "[?25l", 179 + "│ 180 + ◆ foo 181 + │ _ 182 + └ 183 + ", 184 + "", 185 + "", 186 + "", 187 + "│ x█", 188 + "", 189 + "", 190 + "", 191 + "", 192 + "▲ foo 193 + │ x█ 194 + └ should be xy 195 + ", 196 + "", 197 + "", 198 + "", 199 + "◆ foo 200 + │ xy█ 201 + └ 202 + ", 203 + "", 204 + "", 205 + "", 206 + "◇ foo 207 + │ xy", 208 + " 209 + ", 210 + "[?25h", 211 + ] 212 + `; 213 + 214 + exports[`text (isCI = true) > can cancel 1`] = ` 215 + [ 216 + "[?25l", 217 + "│ 218 + ◆ foo 219 + │ _ 220 + └ 221 + ", 222 + "", 223 + "", 224 + "", 225 + "■ foo 226 + │", 227 + " 228 + ", 229 + "[?25h", 230 + ] 231 + `; 232 + 233 + exports[`text (isCI = true) > defaultValue sets the value but does not render 1`] = ` 234 + [ 235 + "[?25l", 236 + "│ 237 + ◆ foo 238 + │ _ 239 + └ 240 + ", 241 + "", 242 + "", 243 + "", 244 + "◇ foo 245 + │ bar", 246 + " 247 + ", 248 + "[?25h", 249 + ] 250 + `; 251 + 252 + exports[`text (isCI = true) > renders cancelled value if one set 1`] = ` 253 + [ 254 + "[?25l", 255 + "│ 256 + ◆ foo 257 + │ _ 258 + └ 259 + ", 260 + "", 261 + "", 262 + "", 263 + "│ x█", 264 + "", 265 + "", 266 + "", 267 + "", 268 + "│ xy█", 269 + "", 270 + "", 271 + "", 272 + "", 273 + "■ foo 274 + │ xy 275 + │", 276 + " 277 + ", 278 + "[?25h", 279 + ] 280 + `; 281 + 282 + exports[`text (isCI = true) > renders message 1`] = ` 283 + [ 284 + "[?25l", 285 + "│ 286 + ◆ foo 287 + │ _ 288 + └ 289 + ", 290 + "", 291 + "", 292 + "", 293 + "◇ foo 294 + │ undefined", 295 + " 296 + ", 297 + "[?25h", 298 + ] 299 + `; 300 + 301 + exports[`text (isCI = true) > renders placeholder if set 1`] = ` 302 + [ 303 + "[?25l", 304 + "│ 305 + ◆ foo 306 + │ bar 307 + └ 308 + ", 309 + "", 310 + "", 311 + "", 312 + "◇ foo 313 + │ bar", 314 + " 315 + ", 316 + "[?25h", 317 + ] 318 + `; 319 + 320 + exports[`text (isCI = true) > renders submitted value 1`] = ` 321 + [ 322 + "[?25l", 323 + "│ 324 + ◆ foo 325 + │ _ 326 + └ 327 + ", 328 + "", 329 + "", 330 + "", 331 + "│ x█", 332 + "", 333 + "", 334 + "", 335 + "", 336 + "│ xy█", 337 + "", 338 + "", 339 + "", 340 + "", 341 + "◇ foo 342 + │ xy", 343 + " 344 + ", 345 + "[?25h", 346 + ] 347 + `; 348 + 349 + exports[`text (isCI = true) > validation errors render and clear (using Error) 1`] = ` 350 + [ 351 + "[?25l", 352 + "│ 353 + ◆ foo 354 + │ _ 355 + └ 356 + ", 357 + "", 358 + "", 359 + "", 360 + "│ x█", 361 + "", 362 + "", 363 + "", 364 + "", 365 + "▲ foo 366 + │ x█ 367 + └ should be xy 368 + ", 369 + "", 370 + "", 371 + "", 372 + "◆ foo 373 + │ xy█ 374 + └ 375 + ", 376 + "", 377 + "", 378 + "", 379 + "◇ foo 380 + │ xy", 381 + " 382 + ", 383 + "[?25h", 384 + ] 385 + `; 386 + 387 + exports[`text (isCI = true) > validation errors render and clear 1`] = ` 388 + [ 389 + "[?25l", 390 + "│ 391 + ◆ foo 392 + │ _ 393 + └ 394 + ", 395 + "", 396 + "", 397 + "", 398 + "│ x█", 399 + "", 400 + "", 401 + "", 402 + "", 403 + "▲ foo 404 + │ x█ 405 + └ should be xy 406 + ", 407 + "", 408 + "", 409 + "", 410 + "◆ foo 411 + │ xy█ 412 + └ 413 + ", 414 + "", 415 + "", 416 + "", 417 + "◇ foo 418 + │ xy", 419 + " 420 + ", 421 + "[?25h", 422 + ] 423 + `;
+138
packages/prompts/src/confirm.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('confirm (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('renders message with choices', async () => { 29 + const result = prompts.confirm({ 30 + message: 'foo', 31 + input, 32 + output, 33 + }); 34 + 35 + input.emit('keypress', '', { name: 'return' }); 36 + 37 + const value = await result; 38 + 39 + expect(value).toBe(true); 40 + expect(output.buffer).toMatchSnapshot(); 41 + }); 42 + 43 + test('renders custom active choice', async () => { 44 + const result = prompts.confirm({ 45 + message: 'foo', 46 + active: 'bleep', 47 + input, 48 + output, 49 + }); 50 + 51 + input.emit('keypress', '', { name: 'return' }); 52 + 53 + const value = await result; 54 + 55 + expect(value).toBe(true); 56 + expect(output.buffer).toMatchSnapshot(); 57 + }); 58 + 59 + test('renders custom inactive choice', async () => { 60 + const result = prompts.confirm({ 61 + message: 'foo', 62 + inactive: 'bleep', 63 + input, 64 + output, 65 + }); 66 + 67 + input.emit('keypress', '', { name: 'return' }); 68 + 69 + const value = await result; 70 + 71 + expect(value).toBe(true); 72 + expect(output.buffer).toMatchSnapshot(); 73 + }); 74 + 75 + test('right arrow moves to next choice', async () => { 76 + const result = prompts.confirm({ 77 + message: 'foo', 78 + input, 79 + output, 80 + }); 81 + 82 + input.emit('keypress', 'right', { name: 'right' }); 83 + input.emit('keypress', '', { name: 'return' }); 84 + 85 + const value = await result; 86 + 87 + expect(value).toBe(false); 88 + expect(output.buffer).toMatchSnapshot(); 89 + }); 90 + 91 + test('left arrow moves to previous choice', async () => { 92 + const result = prompts.confirm({ 93 + message: 'foo', 94 + input, 95 + output, 96 + }); 97 + 98 + input.emit('keypress', 'right', { name: 'right' }); 99 + input.emit('keypress', 'left', { name: 'left' }); 100 + input.emit('keypress', '', { name: 'return' }); 101 + 102 + const value = await result; 103 + 104 + expect(value).toBe(true); 105 + expect(output.buffer).toMatchSnapshot(); 106 + }); 107 + 108 + test('can cancel', async () => { 109 + const result = prompts.confirm({ 110 + message: 'foo', 111 + input, 112 + output, 113 + }); 114 + 115 + input.emit('keypress', 'escape', { name: 'escape' }); 116 + 117 + const value = await result; 118 + 119 + expect(prompts.isCancel(value)).toBe(true); 120 + expect(output.buffer).toMatchSnapshot(); 121 + }); 122 + 123 + test('can set initialValue', async () => { 124 + const result = prompts.confirm({ 125 + message: 'foo', 126 + initialValue: false, 127 + input, 128 + output, 129 + }); 130 + 131 + input.emit('keypress', '', { name: 'return' }); 132 + 133 + const value = await result; 134 + 135 + expect(value).toBe(false); 136 + expect(output.buffer).toMatchSnapshot(); 137 + }); 138 + });
+351
packages/prompts/src/group-multi-select.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('groupMultiselect (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('renders message with options', async () => { 29 + const result = prompts.groupMultiselect({ 30 + message: 'foo', 31 + input, 32 + output, 33 + options: { 34 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 35 + group2: [{ value: 'group2value0' }], 36 + }, 37 + }); 38 + 39 + // Select the first non-group option 40 + input.emit('keypress', '', { name: 'down' }); 41 + input.emit('keypress', '', { name: 'space' }); 42 + 43 + // submit 44 + input.emit('keypress', '', { name: 'return' }); 45 + 46 + const value = await result; 47 + 48 + expect(value).toEqual(['group1value0']); 49 + expect(output.buffer).toMatchSnapshot(); 50 + }); 51 + 52 + test('can select multiple options', async () => { 53 + const result = prompts.groupMultiselect({ 54 + message: 'foo', 55 + input, 56 + output, 57 + options: { 58 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }, { value: 'group1value2' }], 59 + }, 60 + }); 61 + 62 + // Select the first non-group option 63 + input.emit('keypress', '', { name: 'down' }); 64 + input.emit('keypress', '', { name: 'space' }); 65 + // Select the second non-group option 66 + input.emit('keypress', '', { name: 'down' }); 67 + input.emit('keypress', '', { name: 'space' }); 68 + 69 + // submit 70 + input.emit('keypress', '', { name: 'return' }); 71 + 72 + const value = await result; 73 + 74 + expect(value).toEqual(['group1value0', 'group1value1']); 75 + expect(output.buffer).toMatchSnapshot(); 76 + }); 77 + 78 + test('can select a group', async () => { 79 + const result = prompts.groupMultiselect({ 80 + message: 'foo', 81 + input, 82 + output, 83 + options: { 84 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 85 + }, 86 + }); 87 + 88 + // Select the group as a whole 89 + input.emit('keypress', '', { name: 'space' }); 90 + 91 + // submit 92 + input.emit('keypress', '', { name: 'return' }); 93 + 94 + const value = await result; 95 + 96 + expect(value).toEqual(['group1value0', 'group1value1']); 97 + expect(output.buffer).toMatchSnapshot(); 98 + }); 99 + 100 + test('can select a group by selecting all members', async () => { 101 + const result = prompts.groupMultiselect({ 102 + message: 'foo', 103 + input, 104 + output, 105 + options: { 106 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 107 + }, 108 + }); 109 + 110 + // Select the first group option 111 + input.emit('keypress', '', { name: 'down' }); 112 + input.emit('keypress', '', { name: 'space' }); 113 + // Select the second group option 114 + input.emit('keypress', '', { name: 'down' }); 115 + input.emit('keypress', '', { name: 'space' }); 116 + 117 + // submit 118 + input.emit('keypress', '', { name: 'return' }); 119 + 120 + const value = await result; 121 + 122 + expect(value).toEqual(['group1value0', 'group1value1']); 123 + expect(output.buffer).toMatchSnapshot(); 124 + }); 125 + 126 + test('can deselect an option', async () => { 127 + const result = prompts.groupMultiselect({ 128 + message: 'foo', 129 + input, 130 + output, 131 + options: { 132 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 133 + }, 134 + }); 135 + 136 + // Select the first group option 137 + input.emit('keypress', '', { name: 'down' }); 138 + input.emit('keypress', '', { name: 'space' }); 139 + // Select the second group option 140 + input.emit('keypress', '', { name: 'down' }); 141 + input.emit('keypress', '', { name: 'space' }); 142 + // Deselect it 143 + input.emit('keypress', '', { name: 'space' }); 144 + 145 + // submit 146 + input.emit('keypress', '', { name: 'return' }); 147 + 148 + const value = await result; 149 + 150 + expect(value).toEqual(['group1value0']); 151 + expect(output.buffer).toMatchSnapshot(); 152 + }); 153 + 154 + test('renders error when nothing selected', async () => { 155 + const result = prompts.groupMultiselect({ 156 + message: 'foo', 157 + input, 158 + output, 159 + options: { 160 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 161 + }, 162 + }); 163 + 164 + // try submit 165 + input.emit('keypress', '', { name: 'return' }); 166 + // now select something and submit 167 + input.emit('keypress', '', { name: 'down' }); 168 + input.emit('keypress', '', { name: 'space' }); 169 + input.emit('keypress', '', { name: 'return' }); 170 + 171 + const value = await result; 172 + 173 + expect(value).toEqual(['group1value0']); 174 + expect(output.buffer).toMatchSnapshot(); 175 + }); 176 + 177 + describe('selectableGroups = false', () => { 178 + test('cannot select groups', async () => { 179 + const result = prompts.groupMultiselect({ 180 + message: 'foo', 181 + input, 182 + output, 183 + options: { 184 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 185 + }, 186 + selectableGroups: false, 187 + }); 188 + 189 + // first selectable item should be group's child 190 + input.emit('keypress', '', { name: 'space' }); 191 + input.emit('keypress', '', { name: 'return' }); 192 + 193 + const value = await result; 194 + 195 + expect(value).toEqual(['group1value0']); 196 + expect(output.buffer).toMatchSnapshot(); 197 + }); 198 + 199 + test('selecting all members of group does not select group', async () => { 200 + const result = prompts.groupMultiselect({ 201 + message: 'foo', 202 + input, 203 + output, 204 + options: { 205 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 206 + }, 207 + selectableGroups: false, 208 + }); 209 + 210 + // first selectable item should be group's child 211 + input.emit('keypress', '', { name: 'space' }); 212 + // select second item 213 + input.emit('keypress', '', { name: 'down' }); 214 + input.emit('keypress', '', { name: 'space' }); 215 + // submit 216 + input.emit('keypress', '', { name: 'return' }); 217 + 218 + const value = await result; 219 + 220 + expect(value).toEqual(['group1value0', 'group1value1']); 221 + expect(output.buffer).toMatchSnapshot(); 222 + }); 223 + }); 224 + 225 + test('can submit empty selection when require = false', async () => { 226 + const result = prompts.groupMultiselect({ 227 + message: 'foo', 228 + input, 229 + output, 230 + options: { 231 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 232 + }, 233 + required: false, 234 + }); 235 + 236 + input.emit('keypress', '', { name: 'return' }); 237 + 238 + const value = await result; 239 + 240 + expect(value).toEqual([]); 241 + expect(output.buffer).toMatchSnapshot(); 242 + }); 243 + 244 + test('cursorAt sets initial selection', async () => { 245 + const result = prompts.groupMultiselect({ 246 + message: 'foo', 247 + input, 248 + output, 249 + options: { 250 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 251 + }, 252 + cursorAt: 'group1value1', 253 + }); 254 + 255 + input.emit('keypress', '', { name: 'space' }); 256 + input.emit('keypress', '', { name: 'return' }); 257 + 258 + const value = await result; 259 + 260 + expect(value).toEqual(['group1value1']); 261 + expect(output.buffer).toMatchSnapshot(); 262 + }); 263 + 264 + test('initial values can be set', async () => { 265 + const result = prompts.groupMultiselect({ 266 + message: 'foo', 267 + input, 268 + output, 269 + options: { 270 + group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 271 + }, 272 + initialValues: ['group1value1'], 273 + }); 274 + 275 + input.emit('keypress', '', { name: 'return' }); 276 + 277 + const value = await result; 278 + 279 + expect(value).toEqual(['group1value1']); 280 + expect(output.buffer).toMatchSnapshot(); 281 + }); 282 + 283 + test('values can be non-primitive', async () => { 284 + const value0 = Symbol(); 285 + const value1 = Symbol(); 286 + const result = prompts.groupMultiselect({ 287 + message: 'foo', 288 + input, 289 + output, 290 + options: { 291 + group1: [ 292 + { value: value0, label: 'value0' }, 293 + { value: value1, label: 'value1' }, 294 + ], 295 + }, 296 + }); 297 + 298 + input.emit('keypress', '', { name: 'down' }); 299 + input.emit('keypress', '', { name: 'space' }); 300 + input.emit('keypress', '', { name: 'return' }); 301 + 302 + const value = await result; 303 + 304 + expect(value).toEqual([value0]); 305 + expect(output.buffer).toMatchSnapshot(); 306 + }); 307 + 308 + describe('groupSpacing', () => { 309 + test('renders spaced groups', async () => { 310 + const result = prompts.groupMultiselect({ 311 + message: 'foo', 312 + input, 313 + output, 314 + options: { 315 + group1: [{ value: 'group1value0' }], 316 + group2: [{ value: 'group2value0' }], 317 + }, 318 + groupSpacing: 2, 319 + }); 320 + 321 + input.emit('keypress', '', { name: 'down' }); 322 + input.emit('keypress', '', { name: 'space' }); 323 + input.emit('keypress', '', { name: 'return' }); 324 + 325 + await result; 326 + 327 + expect(output.buffer).toMatchSnapshot(); 328 + }); 329 + 330 + test('negative spacing is ignored', async () => { 331 + const result = prompts.groupMultiselect({ 332 + message: 'foo', 333 + input, 334 + output, 335 + options: { 336 + group1: [{ value: 'group1value0' }], 337 + group2: [{ value: 'group2value0' }], 338 + }, 339 + groupSpacing: -2, 340 + }); 341 + 342 + input.emit('keypress', '', { name: 'down' }); 343 + input.emit('keypress', '', { name: 'space' }); 344 + input.emit('keypress', '', { name: 'return' }); 345 + 346 + await result; 347 + 348 + expect(output.buffer).toMatchSnapshot(); 349 + }); 350 + }); 351 + });
-1659
packages/prompts/src/index.test.ts
··· 1 - import { EventEmitter } from 'node:stream'; 2 - import colors from 'picocolors'; 3 - import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 4 - import * as prompts from './index.js'; 5 - import { MockReadable, MockWritable } from './test-utils.js'; 6 - 7 - describe.each(['true', 'false'])('prompts (isCI = %s)', (isCI) => { 8 - let originalCI: string | undefined; 9 - let output: MockWritable; 10 - let input: MockReadable; 11 - 12 - beforeAll(() => { 13 - originalCI = process.env.CI; 14 - process.env.CI = isCI; 15 - }); 16 - 17 - afterAll(() => { 18 - process.env.CI = originalCI; 19 - }); 20 - 21 - beforeEach(() => { 22 - output = new MockWritable(); 23 - input = new MockReadable(); 24 - }); 25 - 26 - afterEach(() => { 27 - vi.restoreAllMocks(); 28 - }); 29 - 30 - describe('spinner', () => { 31 - beforeEach(() => { 32 - vi.useFakeTimers(); 33 - }); 34 - 35 - afterEach(() => { 36 - vi.useRealTimers(); 37 - }); 38 - 39 - test('returns spinner API', () => { 40 - const api = prompts.spinner({ output }); 41 - 42 - expect(api.stop).toBeTypeOf('function'); 43 - expect(api.start).toBeTypeOf('function'); 44 - expect(api.message).toBeTypeOf('function'); 45 - }); 46 - 47 - describe('start', () => { 48 - test('renders frames at interval', () => { 49 - const result = prompts.spinner({ output }); 50 - 51 - result.start(); 52 - 53 - // there are 4 frames 54 - for (let i = 0; i < 4; i++) { 55 - vi.advanceTimersByTime(80); 56 - } 57 - 58 - expect(output.buffer).toMatchSnapshot(); 59 - }); 60 - 61 - test('renders message', () => { 62 - const result = prompts.spinner({ output }); 63 - 64 - result.start('foo'); 65 - 66 - vi.advanceTimersByTime(80); 67 - 68 - expect(output.buffer).toMatchSnapshot(); 69 - }); 70 - 71 - test('renders timer when indicator is "timer"', () => { 72 - const result = prompts.spinner({ output, indicator: 'timer' }); 73 - 74 - result.start(); 75 - 76 - vi.advanceTimersByTime(80); 77 - 78 - expect(output.buffer).toMatchSnapshot(); 79 - }); 80 - }); 81 - 82 - describe('stop', () => { 83 - test('renders submit symbol and stops spinner', () => { 84 - const result = prompts.spinner({ output }); 85 - 86 - result.start(); 87 - 88 - vi.advanceTimersByTime(80); 89 - 90 - result.stop(); 91 - 92 - vi.advanceTimersByTime(80); 93 - 94 - expect(output.buffer).toMatchSnapshot(); 95 - }); 96 - 97 - test('renders cancel symbol if code = 1', () => { 98 - const result = prompts.spinner({ output }); 99 - 100 - result.start(); 101 - 102 - vi.advanceTimersByTime(80); 103 - 104 - result.stop('', 1); 105 - 106 - expect(output.buffer).toMatchSnapshot(); 107 - }); 108 - 109 - test('renders error symbol if code > 1', () => { 110 - const result = prompts.spinner({ output }); 111 - 112 - result.start(); 113 - 114 - vi.advanceTimersByTime(80); 115 - 116 - result.stop('', 2); 117 - 118 - expect(output.buffer).toMatchSnapshot(); 119 - }); 120 - 121 - test('renders message', () => { 122 - const result = prompts.spinner({ output }); 123 - 124 - result.start(); 125 - 126 - vi.advanceTimersByTime(80); 127 - 128 - result.stop('foo'); 129 - 130 - expect(output.buffer).toMatchSnapshot(); 131 - }); 132 - 133 - test('renders message without removing dots', () => { 134 - const result = prompts.spinner({ output }); 135 - 136 - result.start(); 137 - 138 - vi.advanceTimersByTime(80); 139 - 140 - result.stop('foo.'); 141 - 142 - expect(output.buffer).toMatchSnapshot(); 143 - }); 144 - }); 145 - 146 - describe('message', () => { 147 - test('sets message for next frame', () => { 148 - const result = prompts.spinner({ output }); 149 - 150 - result.start(); 151 - 152 - vi.advanceTimersByTime(80); 153 - 154 - result.message('foo'); 155 - 156 - vi.advanceTimersByTime(80); 157 - 158 - expect(output.buffer).toMatchSnapshot(); 159 - }); 160 - }); 161 - 162 - describe('process exit handling', () => { 163 - let processEmitter: EventEmitter; 164 - 165 - beforeEach(() => { 166 - processEmitter = new EventEmitter(); 167 - 168 - // Spy on process methods 169 - vi.spyOn(process, 'on').mockImplementation((ev, listener) => { 170 - processEmitter.on(ev, listener); 171 - return process; 172 - }); 173 - vi.spyOn(process, 'removeListener').mockImplementation((ev, listener) => { 174 - processEmitter.removeListener(ev, listener); 175 - return process; 176 - }); 177 - }); 178 - 179 - afterEach(() => { 180 - processEmitter.removeAllListeners(); 181 - }); 182 - 183 - test('uses default cancel message', () => { 184 - const result = prompts.spinner({ output }); 185 - result.start('Test operation'); 186 - 187 - processEmitter.emit('SIGINT'); 188 - 189 - expect(output.buffer).toMatchSnapshot(); 190 - }); 191 - 192 - test('uses custom cancel message when provided directly', () => { 193 - const result = prompts.spinner({ 194 - output, 195 - cancelMessage: 'Custom cancel message', 196 - }); 197 - result.start('Test operation'); 198 - 199 - processEmitter.emit('SIGINT'); 200 - 201 - expect(output.buffer).toMatchSnapshot(); 202 - }); 203 - 204 - test('uses custom error message when provided directly', () => { 205 - const result = prompts.spinner({ 206 - output, 207 - errorMessage: 'Custom error message', 208 - }); 209 - result.start('Test operation'); 210 - 211 - processEmitter.emit('exit', 2); 212 - 213 - expect(output.buffer).toMatchSnapshot(); 214 - }); 215 - 216 - test('uses global custom cancel message from settings', () => { 217 - // Store original message 218 - const originalCancelMessage = prompts.settings.messages.cancel; 219 - // Set custom message 220 - prompts.settings.messages.cancel = 'Global cancel message'; 221 - 222 - const result = prompts.spinner({ output }); 223 - result.start('Test operation'); 224 - 225 - processEmitter.emit('SIGINT'); 226 - 227 - expect(output.buffer).toMatchSnapshot(); 228 - 229 - // Reset to original 230 - prompts.settings.messages.cancel = originalCancelMessage; 231 - }); 232 - 233 - test('uses global custom error message from settings', () => { 234 - // Store original message 235 - const originalErrorMessage = prompts.settings.messages.error; 236 - // Set custom message 237 - prompts.settings.messages.error = 'Global error message'; 238 - 239 - const result = prompts.spinner({ output }); 240 - result.start('Test operation'); 241 - 242 - processEmitter.emit('exit', 2); 243 - 244 - expect(output.buffer).toMatchSnapshot(); 245 - 246 - // Reset to original 247 - prompts.settings.messages.error = originalErrorMessage; 248 - }); 249 - 250 - test('prioritizes direct options over global settings', () => { 251 - // Store original messages 252 - const originalCancelMessage = prompts.settings.messages.cancel; 253 - const originalErrorMessage = prompts.settings.messages.error; 254 - 255 - // Set custom global messages 256 - prompts.settings.messages.cancel = 'Global cancel message'; 257 - prompts.settings.messages.error = 'Global error message'; 258 - 259 - const result = prompts.spinner({ 260 - output, 261 - cancelMessage: 'Spinner cancel message', 262 - errorMessage: 'Spinner error message', 263 - }); 264 - result.start('Test operation'); 265 - 266 - processEmitter.emit('SIGINT'); 267 - expect(output.buffer).toMatchSnapshot(); 268 - 269 - // Reset buffer 270 - output.buffer = []; 271 - 272 - const result2 = prompts.spinner({ 273 - output, 274 - cancelMessage: 'Spinner cancel message', 275 - errorMessage: 'Spinner error message', 276 - }); 277 - result2.start('Test operation'); 278 - 279 - processEmitter.emit('exit', 2); 280 - expect(output.buffer).toMatchSnapshot(); 281 - 282 - // Reset to original values 283 - prompts.settings.messages.cancel = originalCancelMessage; 284 - prompts.settings.messages.error = originalErrorMessage; 285 - }); 286 - }); 287 - }); 288 - 289 - describe('text', () => { 290 - test('renders message', async () => { 291 - const result = prompts.text({ 292 - message: 'foo', 293 - input, 294 - output, 295 - }); 296 - 297 - input.emit('keypress', '', { name: 'return' }); 298 - 299 - await result; 300 - 301 - expect(output.buffer).toMatchSnapshot(); 302 - }); 303 - 304 - test('renders placeholder if set', async () => { 305 - const result = prompts.text({ 306 - message: 'foo', 307 - placeholder: 'bar', 308 - input, 309 - output, 310 - }); 311 - 312 - input.emit('keypress', '', { name: 'return' }); 313 - 314 - const value = await result; 315 - 316 - expect(output.buffer).toMatchSnapshot(); 317 - 318 - expect(value).toBe('bar'); 319 - }); 320 - 321 - test('<tab> applies placeholder', async () => { 322 - const result = prompts.text({ 323 - message: 'foo', 324 - placeholder: 'bar', 325 - input, 326 - output, 327 - }); 328 - 329 - input.emit('keypress', '\t', { name: 'tab' }); 330 - input.emit('keypress', '', { name: 'return' }); 331 - 332 - const value = await result; 333 - 334 - expect(value).toBe('bar'); 335 - }); 336 - 337 - test('can cancel', async () => { 338 - const result = prompts.text({ 339 - message: 'foo', 340 - input, 341 - output, 342 - }); 343 - 344 - input.emit('keypress', 'escape', { name: 'escape' }); 345 - 346 - const value = await result; 347 - 348 - expect(prompts.isCancel(value)).toBe(true); 349 - expect(output.buffer).toMatchSnapshot(); 350 - }); 351 - 352 - test('renders cancelled value if one set', async () => { 353 - const result = prompts.text({ 354 - message: 'foo', 355 - input, 356 - output, 357 - }); 358 - 359 - input.emit('keypress', 'x', { name: 'x' }); 360 - input.emit('keypress', 'y', { name: 'y' }); 361 - input.emit('keypress', '', { name: 'escape' }); 362 - 363 - const value = await result; 364 - 365 - expect(prompts.isCancel(value)).toBe(true); 366 - expect(output.buffer).toMatchSnapshot(); 367 - }); 368 - 369 - test('renders submitted value', async () => { 370 - const result = prompts.text({ 371 - message: 'foo', 372 - input, 373 - output, 374 - }); 375 - 376 - input.emit('keypress', 'x', { name: 'x' }); 377 - input.emit('keypress', 'y', { name: 'y' }); 378 - input.emit('keypress', '', { name: 'return' }); 379 - 380 - const value = await result; 381 - 382 - expect(value).toBe('xy'); 383 - expect(output.buffer).toMatchSnapshot(); 384 - }); 385 - 386 - test('defaultValue sets the value but does not render', async () => { 387 - const result = prompts.text({ 388 - message: 'foo', 389 - defaultValue: 'bar', 390 - input, 391 - output, 392 - }); 393 - 394 - input.emit('keypress', '', { name: 'return' }); 395 - 396 - const value = await result; 397 - 398 - expect(value).toBe('bar'); 399 - expect(output.buffer).toMatchSnapshot(); 400 - }); 401 - 402 - test('validation errors render and clear', async () => { 403 - const result = prompts.text({ 404 - message: 'foo', 405 - validate: (val) => (val !== 'xy' ? 'should be xy' : undefined), 406 - input, 407 - output, 408 - }); 409 - 410 - input.emit('keypress', 'x', { name: 'x' }); 411 - input.emit('keypress', '', { name: 'return' }); 412 - input.emit('keypress', 'y', { name: 'y' }); 413 - input.emit('keypress', '', { name: 'return' }); 414 - 415 - const value = await result; 416 - 417 - expect(value).toBe('xy'); 418 - expect(output.buffer).toMatchSnapshot(); 419 - }); 420 - 421 - test('validation errors render and clear (using Error)', async () => { 422 - const result = prompts.text({ 423 - message: 'foo', 424 - validate: (val) => (val !== 'xy' ? new Error('should be xy') : undefined), 425 - input, 426 - output, 427 - }); 428 - 429 - input.emit('keypress', 'x', { name: 'x' }); 430 - input.emit('keypress', '', { name: 'return' }); 431 - input.emit('keypress', 'y', { name: 'y' }); 432 - input.emit('keypress', '', { name: 'return' }); 433 - 434 - const value = await result; 435 - 436 - expect(value).toBe('xy'); 437 - expect(output.buffer).toMatchSnapshot(); 438 - }); 439 - }); 440 - 441 - describe('confirm', () => { 442 - test('renders message with choices', async () => { 443 - const result = prompts.confirm({ 444 - message: 'foo', 445 - input, 446 - output, 447 - }); 448 - 449 - input.emit('keypress', '', { name: 'return' }); 450 - 451 - const value = await result; 452 - 453 - expect(value).toBe(true); 454 - expect(output.buffer).toMatchSnapshot(); 455 - }); 456 - 457 - test('renders custom active choice', async () => { 458 - const result = prompts.confirm({ 459 - message: 'foo', 460 - active: 'bleep', 461 - input, 462 - output, 463 - }); 464 - 465 - input.emit('keypress', '', { name: 'return' }); 466 - 467 - const value = await result; 468 - 469 - expect(value).toBe(true); 470 - expect(output.buffer).toMatchSnapshot(); 471 - }); 472 - 473 - test('renders custom inactive choice', async () => { 474 - const result = prompts.confirm({ 475 - message: 'foo', 476 - inactive: 'bleep', 477 - input, 478 - output, 479 - }); 480 - 481 - input.emit('keypress', '', { name: 'return' }); 482 - 483 - const value = await result; 484 - 485 - expect(value).toBe(true); 486 - expect(output.buffer).toMatchSnapshot(); 487 - }); 488 - 489 - test('right arrow moves to next choice', async () => { 490 - const result = prompts.confirm({ 491 - message: 'foo', 492 - input, 493 - output, 494 - }); 495 - 496 - input.emit('keypress', 'right', { name: 'right' }); 497 - input.emit('keypress', '', { name: 'return' }); 498 - 499 - const value = await result; 500 - 501 - expect(value).toBe(false); 502 - expect(output.buffer).toMatchSnapshot(); 503 - }); 504 - 505 - test('left arrow moves to previous choice', async () => { 506 - const result = prompts.confirm({ 507 - message: 'foo', 508 - input, 509 - output, 510 - }); 511 - 512 - input.emit('keypress', 'right', { name: 'right' }); 513 - input.emit('keypress', 'left', { name: 'left' }); 514 - input.emit('keypress', '', { name: 'return' }); 515 - 516 - const value = await result; 517 - 518 - expect(value).toBe(true); 519 - expect(output.buffer).toMatchSnapshot(); 520 - }); 521 - 522 - test('can cancel', async () => { 523 - const result = prompts.confirm({ 524 - message: 'foo', 525 - input, 526 - output, 527 - }); 528 - 529 - input.emit('keypress', 'escape', { name: 'escape' }); 530 - 531 - const value = await result; 532 - 533 - expect(prompts.isCancel(value)).toBe(true); 534 - expect(output.buffer).toMatchSnapshot(); 535 - }); 536 - 537 - test('can set initialValue', async () => { 538 - const result = prompts.confirm({ 539 - message: 'foo', 540 - initialValue: false, 541 - input, 542 - output, 543 - }); 544 - 545 - input.emit('keypress', '', { name: 'return' }); 546 - 547 - const value = await result; 548 - 549 - expect(value).toBe(false); 550 - expect(output.buffer).toMatchSnapshot(); 551 - }); 552 - }); 553 - 554 - describe('select', () => { 555 - test('renders options and message', async () => { 556 - const result = prompts.select({ 557 - message: 'foo', 558 - options: [{ value: 'opt0' }, { value: 'opt1' }], 559 - input, 560 - output, 561 - }); 562 - 563 - input.emit('keypress', '', { name: 'return' }); 564 - 565 - const value = await result; 566 - 567 - expect(value).toBe('opt0'); 568 - expect(output.buffer).toMatchSnapshot(); 569 - }); 570 - 571 - test('down arrow selects next option', async () => { 572 - const result = prompts.select({ 573 - message: 'foo', 574 - options: [{ value: 'opt0' }, { value: 'opt1' }], 575 - input, 576 - output, 577 - }); 578 - 579 - input.emit('keypress', '', { name: 'down' }); 580 - input.emit('keypress', '', { name: 'return' }); 581 - 582 - const value = await result; 583 - 584 - expect(value).toBe('opt1'); 585 - expect(output.buffer).toMatchSnapshot(); 586 - }); 587 - 588 - test('up arrow selects previous option', async () => { 589 - const result = prompts.select({ 590 - message: 'foo', 591 - options: [{ value: 'opt0' }, { value: 'opt1' }], 592 - input, 593 - output, 594 - }); 595 - 596 - input.emit('keypress', '', { name: 'down' }); 597 - input.emit('keypress', '', { name: 'up' }); 598 - input.emit('keypress', '', { name: 'return' }); 599 - 600 - const value = await result; 601 - 602 - expect(value).toBe('opt0'); 603 - expect(output.buffer).toMatchSnapshot(); 604 - }); 605 - 606 - test('can cancel', async () => { 607 - const result = prompts.select({ 608 - message: 'foo', 609 - options: [{ value: 'opt0' }, { value: 'opt1' }], 610 - input, 611 - output, 612 - }); 613 - 614 - input.emit('keypress', 'escape', { name: 'escape' }); 615 - 616 - const value = await result; 617 - 618 - expect(prompts.isCancel(value)).toBe(true); 619 - expect(output.buffer).toMatchSnapshot(); 620 - }); 621 - 622 - test('renders option labels', async () => { 623 - const result = prompts.select({ 624 - message: 'foo', 625 - options: [ 626 - { value: 'opt0', label: 'Option 0' }, 627 - { value: 'opt1', label: 'Option 1' }, 628 - ], 629 - input, 630 - output, 631 - }); 632 - 633 - input.emit('keypress', '', { name: 'return' }); 634 - 635 - const value = await result; 636 - 637 - expect(value).toBe('opt0'); 638 - expect(output.buffer).toMatchSnapshot(); 639 - }); 640 - 641 - test('renders option hints', async () => { 642 - const result = prompts.select({ 643 - message: 'foo', 644 - options: [ 645 - { value: 'opt0', hint: 'Hint 0' }, 646 - { value: 'opt1', hint: 'Hint 1' }, 647 - ], 648 - input, 649 - output, 650 - }); 651 - 652 - input.emit('keypress', '', { name: 'return' }); 653 - 654 - const value = await result; 655 - 656 - expect(value).toBe('opt0'); 657 - expect(output.buffer).toMatchSnapshot(); 658 - }); 659 - }); 660 - 661 - describe('multiselect', () => { 662 - test('renders message', async () => { 663 - const result = prompts.multiselect({ 664 - message: 'foo', 665 - options: [{ value: 'opt0' }, { value: 'opt1' }], 666 - input, 667 - output, 668 - }); 669 - 670 - input.emit('keypress', '', { name: 'space' }); 671 - input.emit('keypress', '', { name: 'return' }); 672 - 673 - const value = await result; 674 - 675 - expect(value).toEqual(['opt0']); 676 - expect(output.buffer).toMatchSnapshot(); 677 - }); 678 - 679 - test('renders multiple selected options', async () => { 680 - const result = prompts.multiselect({ 681 - message: 'foo', 682 - options: [{ value: 'opt0' }, { value: 'opt1' }, { value: 'opt2' }], 683 - input, 684 - output, 685 - }); 686 - 687 - input.emit('keypress', '', { name: 'space' }); 688 - input.emit('keypress', '', { name: 'down' }); 689 - input.emit('keypress', '', { name: 'space' }); 690 - input.emit('keypress', '', { name: 'down' }); 691 - input.emit('keypress', '', { name: 'return' }); 692 - 693 - const value = await result; 694 - 695 - expect(value).toEqual(['opt0', 'opt1']); 696 - expect(output.buffer).toMatchSnapshot(); 697 - }); 698 - 699 - test('can cancel', async () => { 700 - const result = prompts.multiselect({ 701 - message: 'foo', 702 - options: [{ value: 'opt0' }, { value: 'opt1' }], 703 - input, 704 - output, 705 - }); 706 - 707 - input.emit('keypress', 'escape', { name: 'escape' }); 708 - 709 - const value = await result; 710 - 711 - expect(prompts.isCancel(value)).toBe(true); 712 - expect(output.buffer).toMatchSnapshot(); 713 - }); 714 - 715 - test('renders validation errors', async () => { 716 - const result = prompts.multiselect({ 717 - message: 'foo', 718 - options: [{ value: 'opt0' }, { value: 'opt1' }], 719 - input, 720 - output, 721 - }); 722 - 723 - // try submit with nothing selected 724 - input.emit('keypress', '', { name: 'return' }); 725 - // select and submit 726 - input.emit('keypress', '', { name: 'space' }); 727 - input.emit('keypress', '', { name: 'return' }); 728 - 729 - const value = await result; 730 - 731 - expect(value).toEqual(['opt0']); 732 - expect(output.buffer).toMatchSnapshot(); 733 - }); 734 - 735 - test('can submit without selection when required = false', async () => { 736 - const result = prompts.multiselect({ 737 - message: 'foo', 738 - options: [{ value: 'opt0' }, { value: 'opt1' }], 739 - required: false, 740 - input, 741 - output, 742 - }); 743 - 744 - input.emit('keypress', '', { name: 'return' }); 745 - 746 - const value = await result; 747 - 748 - expect(value).toEqual([]); 749 - expect(output.buffer).toMatchSnapshot(); 750 - }); 751 - 752 - test('can set cursorAt to preselect an option', async () => { 753 - const result = prompts.multiselect({ 754 - message: 'foo', 755 - options: [{ value: 'opt0' }, { value: 'opt1' }], 756 - cursorAt: 'opt1', 757 - input, 758 - output, 759 - }); 760 - 761 - input.emit('keypress', '', { name: 'space' }); 762 - input.emit('keypress', '', { name: 'return' }); 763 - 764 - const value = await result; 765 - 766 - expect(value).toEqual(['opt1']); 767 - expect(output.buffer).toMatchSnapshot(); 768 - }); 769 - 770 - test('can set initial values', async () => { 771 - const result = prompts.multiselect({ 772 - message: 'foo', 773 - options: [{ value: 'opt0' }, { value: 'opt1' }], 774 - initialValues: ['opt1'], 775 - input, 776 - output, 777 - }); 778 - 779 - input.emit('keypress', '', { name: 'return' }); 780 - 781 - const value = await result; 782 - 783 - expect(value).toEqual(['opt1']); 784 - expect(output.buffer).toMatchSnapshot(); 785 - }); 786 - 787 - test('maxItems renders a sliding window', async () => { 788 - const result = prompts.multiselect({ 789 - message: 'foo', 790 - options: [...Array(12).keys()].map((k) => ({ 791 - value: `opt${k}`, 792 - })), 793 - maxItems: 6, 794 - input, 795 - output, 796 - }); 797 - 798 - for (let i = 0; i < 6; i++) { 799 - input.emit('keypress', '', { name: 'down' }); 800 - } 801 - input.emit('keypress', '', { name: 'space' }); 802 - input.emit('keypress', '', { name: 'return' }); 803 - 804 - const value = await result; 805 - 806 - expect(value).toEqual(['opt6']); 807 - expect(output.buffer).toMatchSnapshot(); 808 - }); 809 - 810 - test('sliding window loops upwards', async () => { 811 - const result = prompts.multiselect({ 812 - message: 'foo', 813 - options: [...Array(12).keys()].map((k) => ({ 814 - value: `opt${k}`, 815 - })), 816 - maxItems: 6, 817 - input, 818 - output, 819 - }); 820 - 821 - input.emit('keypress', '', { name: 'up' }); 822 - input.emit('keypress', '', { name: 'space' }); 823 - input.emit('keypress', '', { name: 'return' }); 824 - 825 - const value = await result; 826 - 827 - expect(value).toEqual(['opt11']); 828 - expect(output.buffer).toMatchSnapshot(); 829 - }); 830 - 831 - test('sliding window loops downwards', async () => { 832 - const result = prompts.multiselect({ 833 - message: 'foo', 834 - options: [...Array(12).keys()].map((k) => ({ 835 - value: `opt${k}`, 836 - })), 837 - maxItems: 6, 838 - input, 839 - output, 840 - }); 841 - 842 - for (let i = 0; i < 12; i++) { 843 - input.emit('keypress', '', { name: 'down' }); 844 - } 845 - input.emit('keypress', '', { name: 'space' }); 846 - input.emit('keypress', '', { name: 'return' }); 847 - 848 - const value = await result; 849 - 850 - expect(value).toEqual(['opt0']); 851 - expect(output.buffer).toMatchSnapshot(); 852 - }); 853 - 854 - test('can set custom labels', async () => { 855 - const result = prompts.multiselect({ 856 - message: 'foo', 857 - options: [ 858 - { value: 'opt0', label: 'Option 0' }, 859 - { value: 'opt1', label: 'Option 1' }, 860 - ], 861 - input, 862 - output, 863 - }); 864 - 865 - input.emit('keypress', '', { name: 'space' }); 866 - input.emit('keypress', '', { name: 'return' }); 867 - 868 - const value = await result; 869 - 870 - expect(value).toEqual(['opt0']); 871 - expect(output.buffer).toMatchSnapshot(); 872 - }); 873 - 874 - test('can render option hints', async () => { 875 - const result = prompts.multiselect({ 876 - message: 'foo', 877 - options: [ 878 - { value: 'opt0', hint: 'Hint 0' }, 879 - { value: 'opt1', hint: 'Hint 1' }, 880 - ], 881 - input, 882 - output, 883 - }); 884 - 885 - input.emit('keypress', '', { name: 'space' }); 886 - input.emit('keypress', '', { name: 'return' }); 887 - 888 - const value = await result; 889 - 890 - expect(value).toEqual(['opt0']); 891 - expect(output.buffer).toMatchSnapshot(); 892 - }); 893 - 894 - test('shows hints for all selected options', async () => { 895 - const result = prompts.multiselect({ 896 - message: 'foo', 897 - options: [ 898 - { value: 'opt0', hint: 'Hint 0' }, 899 - { value: 'opt1', hint: 'Hint 1' }, 900 - { value: 'opt2', hint: 'Hint 2' }, 901 - ], 902 - initialValues: ['opt0', 'opt1'], 903 - input, 904 - output, 905 - }); 906 - 907 - // Check that both selected options show their hints 908 - input.emit('keypress', '', { name: 'down' }); 909 - input.emit('keypress', '', { name: 'down' }); 910 - input.emit('keypress', '', { name: 'return' }); 911 - 912 - const value = await result; 913 - 914 - expect(value).toEqual(['opt0', 'opt1']); 915 - expect(output.buffer).toMatchSnapshot(); 916 - }); 917 - 918 - test('renders multiple cancelled values', async () => { 919 - const result = prompts.multiselect({ 920 - message: 'foo', 921 - options: [{ value: 'opt0' }, { value: 'opt1' }, { value: 'opt2' }], 922 - input, 923 - output, 924 - }); 925 - 926 - input.emit('keypress', '', { name: 'space' }); 927 - input.emit('keypress', '', { name: 'down' }); 928 - input.emit('keypress', '', { name: 'space' }); 929 - input.emit('keypress', '', { name: 'escape' }); 930 - 931 - const value = await result; 932 - 933 - expect(prompts.isCancel(value)).toBe(true); 934 - expect(output.buffer).toMatchSnapshot(); 935 - }); 936 - }); 937 - 938 - describe('password', () => { 939 - test('renders message', async () => { 940 - const result = prompts.password({ 941 - message: 'foo', 942 - input, 943 - output, 944 - }); 945 - 946 - input.emit('keypress', '', { name: 'return' }); 947 - 948 - await result; 949 - 950 - expect(output.buffer).toMatchSnapshot(); 951 - }); 952 - 953 - test('renders masked value', async () => { 954 - const result = prompts.password({ 955 - message: 'foo', 956 - input, 957 - output, 958 - }); 959 - 960 - input.emit('keypress', 'x', { name: 'x' }); 961 - input.emit('keypress', 'y', { name: 'y' }); 962 - input.emit('keypress', '', { name: 'return' }); 963 - 964 - const value = await result; 965 - 966 - expect(value).toBe('xy'); 967 - expect(output.buffer).toMatchSnapshot(); 968 - }); 969 - 970 - test('renders custom mask', async () => { 971 - const result = prompts.password({ 972 - message: 'foo', 973 - mask: '*', 974 - input, 975 - output, 976 - }); 977 - 978 - input.emit('keypress', 'x', { name: 'x' }); 979 - input.emit('keypress', 'y', { name: 'y' }); 980 - input.emit('keypress', '', { name: 'return' }); 981 - 982 - await result; 983 - 984 - expect(output.buffer).toMatchSnapshot(); 985 - }); 986 - 987 - test('renders and clears validation errors', async () => { 988 - const result = prompts.password({ 989 - message: 'foo', 990 - validate: (value) => { 991 - if (value.length < 2) { 992 - return 'Password must be at least 2 characters'; 993 - } 994 - 995 - return undefined; 996 - }, 997 - input, 998 - output, 999 - }); 1000 - 1001 - input.emit('keypress', 'x', { name: 'x' }); 1002 - input.emit('keypress', '', { name: 'return' }); 1003 - input.emit('keypress', 'y', { name: 'y' }); 1004 - input.emit('keypress', '', { name: 'return' }); 1005 - 1006 - await result; 1007 - 1008 - expect(output.buffer).toMatchSnapshot(); 1009 - }); 1010 - 1011 - test('renders cancelled value', async () => { 1012 - const result = prompts.password({ 1013 - message: 'foo', 1014 - input, 1015 - output, 1016 - }); 1017 - 1018 - input.emit('keypress', 'x', { name: 'x' }); 1019 - input.emit('keypress', '', { name: 'escape' }); 1020 - 1021 - const value = await result; 1022 - 1023 - expect(prompts.isCancel(value)).toBe(true); 1024 - expect(output.buffer).toMatchSnapshot(); 1025 - }); 1026 - }); 1027 - 1028 - describe('groupMultiselect', () => { 1029 - test('renders message with options', async () => { 1030 - const result = prompts.groupMultiselect({ 1031 - message: 'foo', 1032 - input, 1033 - output, 1034 - options: { 1035 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1036 - group2: [{ value: 'group2value0' }], 1037 - }, 1038 - }); 1039 - 1040 - // Select the first non-group option 1041 - input.emit('keypress', '', { name: 'down' }); 1042 - input.emit('keypress', '', { name: 'space' }); 1043 - 1044 - // submit 1045 - input.emit('keypress', '', { name: 'return' }); 1046 - 1047 - const value = await result; 1048 - 1049 - expect(value).toEqual(['group1value0']); 1050 - expect(output.buffer).toMatchSnapshot(); 1051 - }); 1052 - 1053 - test('can select multiple options', async () => { 1054 - const result = prompts.groupMultiselect({ 1055 - message: 'foo', 1056 - input, 1057 - output, 1058 - options: { 1059 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }, { value: 'group1value2' }], 1060 - }, 1061 - }); 1062 - 1063 - // Select the first non-group option 1064 - input.emit('keypress', '', { name: 'down' }); 1065 - input.emit('keypress', '', { name: 'space' }); 1066 - // Select the second non-group option 1067 - input.emit('keypress', '', { name: 'down' }); 1068 - input.emit('keypress', '', { name: 'space' }); 1069 - 1070 - // submit 1071 - input.emit('keypress', '', { name: 'return' }); 1072 - 1073 - const value = await result; 1074 - 1075 - expect(value).toEqual(['group1value0', 'group1value1']); 1076 - expect(output.buffer).toMatchSnapshot(); 1077 - }); 1078 - 1079 - test('can select a group', async () => { 1080 - const result = prompts.groupMultiselect({ 1081 - message: 'foo', 1082 - input, 1083 - output, 1084 - options: { 1085 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1086 - }, 1087 - }); 1088 - 1089 - // Select the group as a whole 1090 - input.emit('keypress', '', { name: 'space' }); 1091 - 1092 - // submit 1093 - input.emit('keypress', '', { name: 'return' }); 1094 - 1095 - const value = await result; 1096 - 1097 - expect(value).toEqual(['group1value0', 'group1value1']); 1098 - expect(output.buffer).toMatchSnapshot(); 1099 - }); 1100 - 1101 - test('can select a group by selecting all members', async () => { 1102 - const result = prompts.groupMultiselect({ 1103 - message: 'foo', 1104 - input, 1105 - output, 1106 - options: { 1107 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1108 - }, 1109 - }); 1110 - 1111 - // Select the first group option 1112 - input.emit('keypress', '', { name: 'down' }); 1113 - input.emit('keypress', '', { name: 'space' }); 1114 - // Select the second group option 1115 - input.emit('keypress', '', { name: 'down' }); 1116 - input.emit('keypress', '', { name: 'space' }); 1117 - 1118 - // submit 1119 - input.emit('keypress', '', { name: 'return' }); 1120 - 1121 - const value = await result; 1122 - 1123 - expect(value).toEqual(['group1value0', 'group1value1']); 1124 - expect(output.buffer).toMatchSnapshot(); 1125 - }); 1126 - 1127 - test('can deselect an option', async () => { 1128 - const result = prompts.groupMultiselect({ 1129 - message: 'foo', 1130 - input, 1131 - output, 1132 - options: { 1133 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1134 - }, 1135 - }); 1136 - 1137 - // Select the first group option 1138 - input.emit('keypress', '', { name: 'down' }); 1139 - input.emit('keypress', '', { name: 'space' }); 1140 - // Select the second group option 1141 - input.emit('keypress', '', { name: 'down' }); 1142 - input.emit('keypress', '', { name: 'space' }); 1143 - // Deselect it 1144 - input.emit('keypress', '', { name: 'space' }); 1145 - 1146 - // submit 1147 - input.emit('keypress', '', { name: 'return' }); 1148 - 1149 - const value = await result; 1150 - 1151 - expect(value).toEqual(['group1value0']); 1152 - expect(output.buffer).toMatchSnapshot(); 1153 - }); 1154 - 1155 - test('renders error when nothing selected', async () => { 1156 - const result = prompts.groupMultiselect({ 1157 - message: 'foo', 1158 - input, 1159 - output, 1160 - options: { 1161 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1162 - }, 1163 - }); 1164 - 1165 - // try submit 1166 - input.emit('keypress', '', { name: 'return' }); 1167 - // now select something and submit 1168 - input.emit('keypress', '', { name: 'down' }); 1169 - input.emit('keypress', '', { name: 'space' }); 1170 - input.emit('keypress', '', { name: 'return' }); 1171 - 1172 - const value = await result; 1173 - 1174 - expect(value).toEqual(['group1value0']); 1175 - expect(output.buffer).toMatchSnapshot(); 1176 - }); 1177 - 1178 - describe('selectableGroups = false', () => { 1179 - test('cannot select groups', async () => { 1180 - const result = prompts.groupMultiselect({ 1181 - message: 'foo', 1182 - input, 1183 - output, 1184 - options: { 1185 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1186 - }, 1187 - selectableGroups: false, 1188 - }); 1189 - 1190 - // first selectable item should be group's child 1191 - input.emit('keypress', '', { name: 'space' }); 1192 - input.emit('keypress', '', { name: 'return' }); 1193 - 1194 - const value = await result; 1195 - 1196 - expect(value).toEqual(['group1value0']); 1197 - expect(output.buffer).toMatchSnapshot(); 1198 - }); 1199 - 1200 - test('selecting all members of group does not select group', async () => { 1201 - const result = prompts.groupMultiselect({ 1202 - message: 'foo', 1203 - input, 1204 - output, 1205 - options: { 1206 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1207 - }, 1208 - selectableGroups: false, 1209 - }); 1210 - 1211 - // first selectable item should be group's child 1212 - input.emit('keypress', '', { name: 'space' }); 1213 - // select second item 1214 - input.emit('keypress', '', { name: 'down' }); 1215 - input.emit('keypress', '', { name: 'space' }); 1216 - // submit 1217 - input.emit('keypress', '', { name: 'return' }); 1218 - 1219 - const value = await result; 1220 - 1221 - expect(value).toEqual(['group1value0', 'group1value1']); 1222 - expect(output.buffer).toMatchSnapshot(); 1223 - }); 1224 - }); 1225 - 1226 - test('can submit empty selection when require = false', async () => { 1227 - const result = prompts.groupMultiselect({ 1228 - message: 'foo', 1229 - input, 1230 - output, 1231 - options: { 1232 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1233 - }, 1234 - required: false, 1235 - }); 1236 - 1237 - input.emit('keypress', '', { name: 'return' }); 1238 - 1239 - const value = await result; 1240 - 1241 - expect(value).toEqual([]); 1242 - expect(output.buffer).toMatchSnapshot(); 1243 - }); 1244 - 1245 - test('cursorAt sets initial selection', async () => { 1246 - const result = prompts.groupMultiselect({ 1247 - message: 'foo', 1248 - input, 1249 - output, 1250 - options: { 1251 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1252 - }, 1253 - cursorAt: 'group1value1', 1254 - }); 1255 - 1256 - input.emit('keypress', '', { name: 'space' }); 1257 - input.emit('keypress', '', { name: 'return' }); 1258 - 1259 - const value = await result; 1260 - 1261 - expect(value).toEqual(['group1value1']); 1262 - expect(output.buffer).toMatchSnapshot(); 1263 - }); 1264 - 1265 - test('initial values can be set', async () => { 1266 - const result = prompts.groupMultiselect({ 1267 - message: 'foo', 1268 - input, 1269 - output, 1270 - options: { 1271 - group1: [{ value: 'group1value0' }, { value: 'group1value1' }], 1272 - }, 1273 - initialValues: ['group1value1'], 1274 - }); 1275 - 1276 - input.emit('keypress', '', { name: 'return' }); 1277 - 1278 - const value = await result; 1279 - 1280 - expect(value).toEqual(['group1value1']); 1281 - expect(output.buffer).toMatchSnapshot(); 1282 - }); 1283 - 1284 - test('values can be non-primitive', async () => { 1285 - const value0 = Symbol(); 1286 - const value1 = Symbol(); 1287 - const result = prompts.groupMultiselect({ 1288 - message: 'foo', 1289 - input, 1290 - output, 1291 - options: { 1292 - group1: [ 1293 - { value: value0, label: 'value0' }, 1294 - { value: value1, label: 'value1' }, 1295 - ], 1296 - }, 1297 - }); 1298 - 1299 - input.emit('keypress', '', { name: 'down' }); 1300 - input.emit('keypress', '', { name: 'space' }); 1301 - input.emit('keypress', '', { name: 'return' }); 1302 - 1303 - const value = await result; 1304 - 1305 - expect(value).toEqual([value0]); 1306 - expect(output.buffer).toMatchSnapshot(); 1307 - }); 1308 - 1309 - describe('groupSpacing', () => { 1310 - test('renders spaced groups', async () => { 1311 - const result = prompts.groupMultiselect({ 1312 - message: 'foo', 1313 - input, 1314 - output, 1315 - options: { 1316 - group1: [{ value: 'group1value0' }], 1317 - group2: [{ value: 'group2value0' }], 1318 - }, 1319 - groupSpacing: 2, 1320 - }); 1321 - 1322 - input.emit('keypress', '', { name: 'down' }); 1323 - input.emit('keypress', '', { name: 'space' }); 1324 - input.emit('keypress', '', { name: 'return' }); 1325 - 1326 - await result; 1327 - 1328 - expect(output.buffer).toMatchSnapshot(); 1329 - }); 1330 - 1331 - test('negative spacing is ignored', async () => { 1332 - const result = prompts.groupMultiselect({ 1333 - message: 'foo', 1334 - input, 1335 - output, 1336 - options: { 1337 - group1: [{ value: 'group1value0' }], 1338 - group2: [{ value: 'group2value0' }], 1339 - }, 1340 - groupSpacing: -2, 1341 - }); 1342 - 1343 - input.emit('keypress', '', { name: 'down' }); 1344 - input.emit('keypress', '', { name: 'space' }); 1345 - input.emit('keypress', '', { name: 'return' }); 1346 - 1347 - await result; 1348 - 1349 - expect(output.buffer).toMatchSnapshot(); 1350 - }); 1351 - }); 1352 - }); 1353 - 1354 - describe('note', () => { 1355 - test('renders message with title', () => { 1356 - prompts.note('message', 'title', { 1357 - input, 1358 - output, 1359 - }); 1360 - 1361 - expect(output.buffer).toMatchSnapshot(); 1362 - }); 1363 - 1364 - test('renders as wide as longest line', () => { 1365 - prompts.note('short\nsomewhat questionably long line', 'title', { 1366 - input, 1367 - output, 1368 - }); 1369 - 1370 - expect(output.buffer).toMatchSnapshot(); 1371 - }); 1372 - 1373 - test('formatter which adds length works', () => { 1374 - prompts.note('line 0\nline 1\nline 2', 'title', { 1375 - format: (line) => `* ${line} *`, 1376 - input, 1377 - output, 1378 - }); 1379 - 1380 - expect(output.buffer).toMatchSnapshot(); 1381 - }); 1382 - 1383 - test('formatter which adds colors works', () => { 1384 - prompts.note('line 0\nline 1\nline 2', 'title', { 1385 - format: (line) => colors.red(line), 1386 - input, 1387 - output, 1388 - }); 1389 - 1390 - expect(output.buffer).toMatchSnapshot(); 1391 - }); 1392 - }); 1393 - 1394 - describe('taskLog', () => { 1395 - test('writes message header', () => { 1396 - prompts.taskLog({ 1397 - input, 1398 - output, 1399 - title: 'foo', 1400 - }); 1401 - 1402 - expect(output.buffer).toMatchSnapshot(); 1403 - }); 1404 - 1405 - describe('message', () => { 1406 - test('can write line by line', () => { 1407 - const log = prompts.taskLog({ 1408 - input, 1409 - output, 1410 - title: 'foo', 1411 - }); 1412 - 1413 - log.message('line 0'); 1414 - log.message('line 1'); 1415 - 1416 - expect(output.buffer).toMatchSnapshot(); 1417 - }); 1418 - 1419 - test('can write multiple lines', () => { 1420 - const log = prompts.taskLog({ 1421 - input, 1422 - output, 1423 - title: 'foo', 1424 - }); 1425 - 1426 - log.message('line 0\nline 1'); 1427 - 1428 - expect(output.buffer).toMatchSnapshot(); 1429 - }); 1430 - 1431 - test('enforces limit if set', () => { 1432 - const log = prompts.taskLog({ 1433 - input, 1434 - output, 1435 - title: 'foo', 1436 - limit: 2, 1437 - }); 1438 - 1439 - log.message('line 0'); 1440 - log.message('line 1'); 1441 - log.message('line 2'); 1442 - 1443 - expect(output.buffer).toMatchSnapshot(); 1444 - }); 1445 - 1446 - test('raw = true appends message text until newline', async () => { 1447 - const log = prompts.taskLog({ 1448 - input, 1449 - output, 1450 - title: 'foo', 1451 - }); 1452 - 1453 - log.message('line 0', { raw: true }); 1454 - log.message('still line 0', { raw: true }); 1455 - log.message('\nline 1', { raw: true }); 1456 - 1457 - expect(output.buffer).toMatchSnapshot(); 1458 - }); 1459 - 1460 - test('raw = true works when mixed with non-raw messages', async () => { 1461 - const log = prompts.taskLog({ 1462 - input, 1463 - output, 1464 - title: 'foo', 1465 - }); 1466 - 1467 - log.message('line 0', { raw: true }); 1468 - log.message('still line 0', { raw: true }); 1469 - log.message('line 1'); 1470 - 1471 - expect(output.buffer).toMatchSnapshot(); 1472 - }); 1473 - 1474 - test('raw = true works when started with non-raw messages', async () => { 1475 - const log = prompts.taskLog({ 1476 - input, 1477 - output, 1478 - title: 'foo', 1479 - }); 1480 - 1481 - log.message('line 0'); 1482 - log.message('line 1', { raw: true }); 1483 - log.message('still line 1', { raw: true }); 1484 - 1485 - expect(output.buffer).toMatchSnapshot(); 1486 - }); 1487 - 1488 - test('prints empty lines', async () => { 1489 - const log = prompts.taskLog({ 1490 - input, 1491 - output, 1492 - title: 'foo', 1493 - }); 1494 - 1495 - log.message(''); 1496 - log.message('line 1'); 1497 - log.message(''); 1498 - log.message('line 3'); 1499 - 1500 - expect(output.buffer).toMatchSnapshot(); 1501 - }); 1502 - }); 1503 - 1504 - describe('error', () => { 1505 - test('renders output with message', () => { 1506 - const log = prompts.taskLog({ 1507 - input, 1508 - output, 1509 - title: 'foo', 1510 - }); 1511 - 1512 - log.message('line 0'); 1513 - log.message('line 1'); 1514 - 1515 - log.error('some error!'); 1516 - 1517 - expect(output.buffer).toMatchSnapshot(); 1518 - }); 1519 - 1520 - test('clears output if showLog = false', () => { 1521 - const log = prompts.taskLog({ 1522 - input, 1523 - output, 1524 - title: 'foo', 1525 - }); 1526 - 1527 - log.message('line 0'); 1528 - log.message('line 1'); 1529 - 1530 - log.error('some error!', { showLog: false }); 1531 - 1532 - expect(output.buffer).toMatchSnapshot(); 1533 - }); 1534 - }); 1535 - 1536 - describe('success', () => { 1537 - test('clears output and renders message', () => { 1538 - const log = prompts.taskLog({ 1539 - input, 1540 - output, 1541 - title: 'foo', 1542 - }); 1543 - 1544 - log.message('line 0'); 1545 - log.message('line 1'); 1546 - 1547 - log.success('success!'); 1548 - 1549 - expect(output.buffer).toMatchSnapshot(); 1550 - }); 1551 - 1552 - test('renders output if showLog = true', () => { 1553 - const log = prompts.taskLog({ 1554 - input, 1555 - output, 1556 - title: 'foo', 1557 - }); 1558 - 1559 - log.message('line 0'); 1560 - log.message('line 1'); 1561 - 1562 - log.success('success!', { showLog: true }); 1563 - 1564 - expect(output.buffer).toMatchSnapshot(); 1565 - }); 1566 - }); 1567 - 1568 - describe('retainLog', () => { 1569 - describe.each(['error', 'success'] as const)('%s', (method) => { 1570 - test('retainLog = true outputs full log', () => { 1571 - const log = prompts.taskLog({ 1572 - input, 1573 - output, 1574 - title: 'foo', 1575 - retainLog: true, 1576 - }); 1577 - 1578 - for (let i = 0; i < 4; i++) { 1579 - log.message(`line ${i}`); 1580 - } 1581 - 1582 - log[method]('woo!', { showLog: true }); 1583 - 1584 - expect(output.buffer).toMatchSnapshot(); 1585 - }); 1586 - 1587 - test('retainLog = true outputs full log with limit', () => { 1588 - const log = prompts.taskLog({ 1589 - input, 1590 - output, 1591 - title: 'foo', 1592 - retainLog: true, 1593 - limit: 2, 1594 - }); 1595 - 1596 - for (let i = 0; i < 4; i++) { 1597 - log.message(`line ${i}`); 1598 - } 1599 - 1600 - log[method]('woo!', { showLog: true }); 1601 - 1602 - expect(output.buffer).toMatchSnapshot(); 1603 - }); 1604 - 1605 - test('retainLog = false outputs full log without limit', () => { 1606 - const log = prompts.taskLog({ 1607 - input, 1608 - output, 1609 - title: 'foo', 1610 - retainLog: false, 1611 - }); 1612 - 1613 - for (let i = 0; i < 4; i++) { 1614 - log.message(`line ${i}`); 1615 - } 1616 - 1617 - log[method]('woo!', { showLog: true }); 1618 - 1619 - expect(output.buffer).toMatchSnapshot(); 1620 - }); 1621 - 1622 - test('retainLog = false outputs limited log with limit', () => { 1623 - const log = prompts.taskLog({ 1624 - input, 1625 - output, 1626 - title: 'foo', 1627 - retainLog: false, 1628 - limit: 2, 1629 - }); 1630 - 1631 - for (let i = 0; i < 4; i++) { 1632 - log.message(`line ${i}`); 1633 - } 1634 - 1635 - log[method]('woo!', { showLog: true }); 1636 - 1637 - expect(output.buffer).toMatchSnapshot(); 1638 - }); 1639 - 1640 - test('outputs limited log with limit by default', () => { 1641 - const log = prompts.taskLog({ 1642 - input, 1643 - output, 1644 - title: 'foo', 1645 - limit: 2, 1646 - }); 1647 - 1648 - for (let i = 0; i < 4; i++) { 1649 - log.message(`line ${i}`); 1650 - } 1651 - 1652 - log[method]('woo!', { showLog: true }); 1653 - 1654 - expect(output.buffer).toMatchSnapshot(); 1655 - }); 1656 - }); 1657 - }); 1658 - }); 1659 - });
+302
packages/prompts/src/multi-select.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('multiselect (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('renders message', async () => { 29 + const result = prompts.multiselect({ 30 + message: 'foo', 31 + options: [{ value: 'opt0' }, { value: 'opt1' }], 32 + input, 33 + output, 34 + }); 35 + 36 + input.emit('keypress', '', { name: 'space' }); 37 + input.emit('keypress', '', { name: 'return' }); 38 + 39 + const value = await result; 40 + 41 + expect(value).toEqual(['opt0']); 42 + expect(output.buffer).toMatchSnapshot(); 43 + }); 44 + 45 + test('renders multiple selected options', async () => { 46 + const result = prompts.multiselect({ 47 + message: 'foo', 48 + options: [{ value: 'opt0' }, { value: 'opt1' }, { value: 'opt2' }], 49 + input, 50 + output, 51 + }); 52 + 53 + input.emit('keypress', '', { name: 'space' }); 54 + input.emit('keypress', '', { name: 'down' }); 55 + input.emit('keypress', '', { name: 'space' }); 56 + input.emit('keypress', '', { name: 'down' }); 57 + input.emit('keypress', '', { name: 'return' }); 58 + 59 + const value = await result; 60 + 61 + expect(value).toEqual(['opt0', 'opt1']); 62 + expect(output.buffer).toMatchSnapshot(); 63 + }); 64 + 65 + test('can cancel', async () => { 66 + const result = prompts.multiselect({ 67 + message: 'foo', 68 + options: [{ value: 'opt0' }, { value: 'opt1' }], 69 + input, 70 + output, 71 + }); 72 + 73 + input.emit('keypress', 'escape', { name: 'escape' }); 74 + 75 + const value = await result; 76 + 77 + expect(prompts.isCancel(value)).toBe(true); 78 + expect(output.buffer).toMatchSnapshot(); 79 + }); 80 + 81 + test('renders validation errors', async () => { 82 + const result = prompts.multiselect({ 83 + message: 'foo', 84 + options: [{ value: 'opt0' }, { value: 'opt1' }], 85 + input, 86 + output, 87 + }); 88 + 89 + // try submit with nothing selected 90 + input.emit('keypress', '', { name: 'return' }); 91 + // select and submit 92 + input.emit('keypress', '', { name: 'space' }); 93 + input.emit('keypress', '', { name: 'return' }); 94 + 95 + const value = await result; 96 + 97 + expect(value).toEqual(['opt0']); 98 + expect(output.buffer).toMatchSnapshot(); 99 + }); 100 + 101 + test('can submit without selection when required = false', async () => { 102 + const result = prompts.multiselect({ 103 + message: 'foo', 104 + options: [{ value: 'opt0' }, { value: 'opt1' }], 105 + required: false, 106 + input, 107 + output, 108 + }); 109 + 110 + input.emit('keypress', '', { name: 'return' }); 111 + 112 + const value = await result; 113 + 114 + expect(value).toEqual([]); 115 + expect(output.buffer).toMatchSnapshot(); 116 + }); 117 + 118 + test('can set cursorAt to preselect an option', async () => { 119 + const result = prompts.multiselect({ 120 + message: 'foo', 121 + options: [{ value: 'opt0' }, { value: 'opt1' }], 122 + cursorAt: 'opt1', 123 + input, 124 + output, 125 + }); 126 + 127 + input.emit('keypress', '', { name: 'space' }); 128 + input.emit('keypress', '', { name: 'return' }); 129 + 130 + const value = await result; 131 + 132 + expect(value).toEqual(['opt1']); 133 + expect(output.buffer).toMatchSnapshot(); 134 + }); 135 + 136 + test('can set initial values', async () => { 137 + const result = prompts.multiselect({ 138 + message: 'foo', 139 + options: [{ value: 'opt0' }, { value: 'opt1' }], 140 + initialValues: ['opt1'], 141 + input, 142 + output, 143 + }); 144 + 145 + input.emit('keypress', '', { name: 'return' }); 146 + 147 + const value = await result; 148 + 149 + expect(value).toEqual(['opt1']); 150 + expect(output.buffer).toMatchSnapshot(); 151 + }); 152 + 153 + test('maxItems renders a sliding window', async () => { 154 + const result = prompts.multiselect({ 155 + message: 'foo', 156 + options: [...Array(12).keys()].map((k) => ({ 157 + value: `opt${k}`, 158 + })), 159 + maxItems: 6, 160 + input, 161 + output, 162 + }); 163 + 164 + for (let i = 0; i < 6; i++) { 165 + input.emit('keypress', '', { name: 'down' }); 166 + } 167 + input.emit('keypress', '', { name: 'space' }); 168 + input.emit('keypress', '', { name: 'return' }); 169 + 170 + const value = await result; 171 + 172 + expect(value).toEqual(['opt6']); 173 + expect(output.buffer).toMatchSnapshot(); 174 + }); 175 + 176 + test('sliding window loops upwards', async () => { 177 + const result = prompts.multiselect({ 178 + message: 'foo', 179 + options: [...Array(12).keys()].map((k) => ({ 180 + value: `opt${k}`, 181 + })), 182 + maxItems: 6, 183 + input, 184 + output, 185 + }); 186 + 187 + input.emit('keypress', '', { name: 'up' }); 188 + input.emit('keypress', '', { name: 'space' }); 189 + input.emit('keypress', '', { name: 'return' }); 190 + 191 + const value = await result; 192 + 193 + expect(value).toEqual(['opt11']); 194 + expect(output.buffer).toMatchSnapshot(); 195 + }); 196 + 197 + test('sliding window loops downwards', async () => { 198 + const result = prompts.multiselect({ 199 + message: 'foo', 200 + options: [...Array(12).keys()].map((k) => ({ 201 + value: `opt${k}`, 202 + })), 203 + maxItems: 6, 204 + input, 205 + output, 206 + }); 207 + 208 + for (let i = 0; i < 12; i++) { 209 + input.emit('keypress', '', { name: 'down' }); 210 + } 211 + input.emit('keypress', '', { name: 'space' }); 212 + input.emit('keypress', '', { name: 'return' }); 213 + 214 + const value = await result; 215 + 216 + expect(value).toEqual(['opt0']); 217 + expect(output.buffer).toMatchSnapshot(); 218 + }); 219 + 220 + test('can set custom labels', async () => { 221 + const result = prompts.multiselect({ 222 + message: 'foo', 223 + options: [ 224 + { value: 'opt0', label: 'Option 0' }, 225 + { value: 'opt1', label: 'Option 1' }, 226 + ], 227 + input, 228 + output, 229 + }); 230 + 231 + input.emit('keypress', '', { name: 'space' }); 232 + input.emit('keypress', '', { name: 'return' }); 233 + 234 + const value = await result; 235 + 236 + expect(value).toEqual(['opt0']); 237 + expect(output.buffer).toMatchSnapshot(); 238 + }); 239 + 240 + test('can render option hints', async () => { 241 + const result = prompts.multiselect({ 242 + message: 'foo', 243 + options: [ 244 + { value: 'opt0', hint: 'Hint 0' }, 245 + { value: 'opt1', hint: 'Hint 1' }, 246 + ], 247 + input, 248 + output, 249 + }); 250 + 251 + input.emit('keypress', '', { name: 'space' }); 252 + input.emit('keypress', '', { name: 'return' }); 253 + 254 + const value = await result; 255 + 256 + expect(value).toEqual(['opt0']); 257 + expect(output.buffer).toMatchSnapshot(); 258 + }); 259 + 260 + test('shows hints for all selected options', async () => { 261 + const result = prompts.multiselect({ 262 + message: 'foo', 263 + options: [ 264 + { value: 'opt0', hint: 'Hint 0' }, 265 + { value: 'opt1', hint: 'Hint 1' }, 266 + { value: 'opt2', hint: 'Hint 2' }, 267 + ], 268 + initialValues: ['opt0', 'opt1'], 269 + input, 270 + output, 271 + }); 272 + 273 + // Check that both selected options show their hints 274 + input.emit('keypress', '', { name: 'down' }); 275 + input.emit('keypress', '', { name: 'down' }); 276 + input.emit('keypress', '', { name: 'return' }); 277 + 278 + const value = await result; 279 + 280 + expect(value).toEqual(['opt0', 'opt1']); 281 + expect(output.buffer).toMatchSnapshot(); 282 + }); 283 + 284 + test('renders multiple cancelled values', async () => { 285 + const result = prompts.multiselect({ 286 + message: 'foo', 287 + options: [{ value: 'opt0' }, { value: 'opt1' }, { value: 'opt2' }], 288 + input, 289 + output, 290 + }); 291 + 292 + input.emit('keypress', '', { name: 'space' }); 293 + input.emit('keypress', '', { name: 'down' }); 294 + input.emit('keypress', '', { name: 'space' }); 295 + input.emit('keypress', '', { name: 'escape' }); 296 + 297 + const value = await result; 298 + 299 + expect(prompts.isCancel(value)).toBe(true); 300 + expect(output.buffer).toMatchSnapshot(); 301 + }); 302 + });
+66
packages/prompts/src/note.test.ts
··· 1 + import colors from 'picocolors'; 2 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 3 + import * as prompts from './index.js'; 4 + import { MockReadable, MockWritable } from './test-utils.js'; 5 + 6 + describe.each(['true', 'false'])('note (isCI = %s)', (isCI) => { 7 + let originalCI: string | undefined; 8 + let output: MockWritable; 9 + let input: MockReadable; 10 + 11 + beforeAll(() => { 12 + originalCI = process.env.CI; 13 + process.env.CI = isCI; 14 + }); 15 + 16 + afterAll(() => { 17 + process.env.CI = originalCI; 18 + }); 19 + 20 + beforeEach(() => { 21 + output = new MockWritable(); 22 + input = new MockReadable(); 23 + }); 24 + 25 + afterEach(() => { 26 + vi.restoreAllMocks(); 27 + }); 28 + 29 + test('renders message with title', () => { 30 + prompts.note('message', 'title', { 31 + input, 32 + output, 33 + }); 34 + 35 + expect(output.buffer).toMatchSnapshot(); 36 + }); 37 + 38 + test('renders as wide as longest line', () => { 39 + prompts.note('short\nsomewhat questionably long line', 'title', { 40 + input, 41 + output, 42 + }); 43 + 44 + expect(output.buffer).toMatchSnapshot(); 45 + }); 46 + 47 + test('formatter which adds length works', () => { 48 + prompts.note('line 0\nline 1\nline 2', 'title', { 49 + format: (line) => `* ${line} *`, 50 + input, 51 + output, 52 + }); 53 + 54 + expect(output.buffer).toMatchSnapshot(); 55 + }); 56 + 57 + test('formatter which adds colors works', () => { 58 + prompts.note('line 0\nline 1\nline 2', 'title', { 59 + format: (line) => colors.red(line), 60 + input, 61 + output, 62 + }); 63 + 64 + expect(output.buffer).toMatchSnapshot(); 65 + }); 66 + });
+115
packages/prompts/src/password.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('password (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('renders message', async () => { 29 + const result = prompts.password({ 30 + message: 'foo', 31 + input, 32 + output, 33 + }); 34 + 35 + input.emit('keypress', '', { name: 'return' }); 36 + 37 + await result; 38 + 39 + expect(output.buffer).toMatchSnapshot(); 40 + }); 41 + 42 + test('renders masked value', async () => { 43 + const result = prompts.password({ 44 + message: 'foo', 45 + input, 46 + output, 47 + }); 48 + 49 + input.emit('keypress', 'x', { name: 'x' }); 50 + input.emit('keypress', 'y', { name: 'y' }); 51 + input.emit('keypress', '', { name: 'return' }); 52 + 53 + const value = await result; 54 + 55 + expect(value).toBe('xy'); 56 + expect(output.buffer).toMatchSnapshot(); 57 + }); 58 + 59 + test('renders custom mask', async () => { 60 + const result = prompts.password({ 61 + message: 'foo', 62 + mask: '*', 63 + input, 64 + output, 65 + }); 66 + 67 + input.emit('keypress', 'x', { name: 'x' }); 68 + input.emit('keypress', 'y', { name: 'y' }); 69 + input.emit('keypress', '', { name: 'return' }); 70 + 71 + await result; 72 + 73 + expect(output.buffer).toMatchSnapshot(); 74 + }); 75 + 76 + test('renders and clears validation errors', async () => { 77 + const result = prompts.password({ 78 + message: 'foo', 79 + validate: (value) => { 80 + if (value.length < 2) { 81 + return 'Password must be at least 2 characters'; 82 + } 83 + 84 + return undefined; 85 + }, 86 + input, 87 + output, 88 + }); 89 + 90 + input.emit('keypress', 'x', { name: 'x' }); 91 + input.emit('keypress', '', { name: 'return' }); 92 + input.emit('keypress', 'y', { name: 'y' }); 93 + input.emit('keypress', '', { name: 'return' }); 94 + 95 + await result; 96 + 97 + expect(output.buffer).toMatchSnapshot(); 98 + }); 99 + 100 + test('renders cancelled value', async () => { 101 + const result = prompts.password({ 102 + message: 'foo', 103 + input, 104 + output, 105 + }); 106 + 107 + input.emit('keypress', 'x', { name: 'x' }); 108 + input.emit('keypress', '', { name: 'escape' }); 109 + 110 + const value = await result; 111 + 112 + expect(prompts.isCancel(value)).toBe(true); 113 + expect(output.buffer).toMatchSnapshot(); 114 + }); 115 + });
+132
packages/prompts/src/select.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('select (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('renders options and message', async () => { 29 + const result = prompts.select({ 30 + message: 'foo', 31 + options: [{ value: 'opt0' }, { value: 'opt1' }], 32 + input, 33 + output, 34 + }); 35 + 36 + input.emit('keypress', '', { name: 'return' }); 37 + 38 + const value = await result; 39 + 40 + expect(value).toBe('opt0'); 41 + expect(output.buffer).toMatchSnapshot(); 42 + }); 43 + 44 + test('down arrow selects next option', async () => { 45 + const result = prompts.select({ 46 + message: 'foo', 47 + options: [{ value: 'opt0' }, { value: 'opt1' }], 48 + input, 49 + output, 50 + }); 51 + 52 + input.emit('keypress', '', { name: 'down' }); 53 + input.emit('keypress', '', { name: 'return' }); 54 + 55 + const value = await result; 56 + 57 + expect(value).toBe('opt1'); 58 + expect(output.buffer).toMatchSnapshot(); 59 + }); 60 + 61 + test('up arrow selects previous option', async () => { 62 + const result = prompts.select({ 63 + message: 'foo', 64 + options: [{ value: 'opt0' }, { value: 'opt1' }], 65 + input, 66 + output, 67 + }); 68 + 69 + input.emit('keypress', '', { name: 'down' }); 70 + input.emit('keypress', '', { name: 'up' }); 71 + input.emit('keypress', '', { name: 'return' }); 72 + 73 + const value = await result; 74 + 75 + expect(value).toBe('opt0'); 76 + expect(output.buffer).toMatchSnapshot(); 77 + }); 78 + 79 + test('can cancel', async () => { 80 + const result = prompts.select({ 81 + message: 'foo', 82 + options: [{ value: 'opt0' }, { value: 'opt1' }], 83 + input, 84 + output, 85 + }); 86 + 87 + input.emit('keypress', 'escape', { name: 'escape' }); 88 + 89 + const value = await result; 90 + 91 + expect(prompts.isCancel(value)).toBe(true); 92 + expect(output.buffer).toMatchSnapshot(); 93 + }); 94 + 95 + test('renders option labels', async () => { 96 + const result = prompts.select({ 97 + message: 'foo', 98 + options: [ 99 + { value: 'opt0', label: 'Option 0' }, 100 + { value: 'opt1', label: 'Option 1' }, 101 + ], 102 + input, 103 + output, 104 + }); 105 + 106 + input.emit('keypress', '', { name: 'return' }); 107 + 108 + const value = await result; 109 + 110 + expect(value).toBe('opt0'); 111 + expect(output.buffer).toMatchSnapshot(); 112 + }); 113 + 114 + test('renders option hints', async () => { 115 + const result = prompts.select({ 116 + message: 'foo', 117 + options: [ 118 + { value: 'opt0', hint: 'Hint 0' }, 119 + { value: 'opt1', hint: 'Hint 1' }, 120 + ], 121 + input, 122 + output, 123 + }); 124 + 125 + input.emit('keypress', '', { name: 'return' }); 126 + 127 + const value = await result; 128 + 129 + expect(value).toBe('opt0'); 130 + expect(output.buffer).toMatchSnapshot(); 131 + }); 132 + });
+277
packages/prompts/src/spinner.test.ts
··· 1 + import { EventEmitter } from 'node:stream'; 2 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 3 + import * as prompts from './index.js'; 4 + import { MockWritable } from './test-utils.js'; 5 + 6 + describe.each(['true', 'false'])('spinner (isCI = %s)', (isCI) => { 7 + let originalCI: string | undefined; 8 + let output: MockWritable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + vi.useFakeTimers(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.useRealTimers(); 26 + vi.restoreAllMocks(); 27 + }); 28 + 29 + test('returns spinner API', () => { 30 + const api = prompts.spinner({ output }); 31 + 32 + expect(api.stop).toBeTypeOf('function'); 33 + expect(api.start).toBeTypeOf('function'); 34 + expect(api.message).toBeTypeOf('function'); 35 + }); 36 + 37 + describe('start', () => { 38 + test('renders frames at interval', () => { 39 + const result = prompts.spinner({ output }); 40 + 41 + result.start(); 42 + 43 + // there are 4 frames 44 + for (let i = 0; i < 4; i++) { 45 + vi.advanceTimersByTime(80); 46 + } 47 + 48 + expect(output.buffer).toMatchSnapshot(); 49 + }); 50 + 51 + test('renders message', () => { 52 + const result = prompts.spinner({ output }); 53 + 54 + result.start('foo'); 55 + 56 + vi.advanceTimersByTime(80); 57 + 58 + expect(output.buffer).toMatchSnapshot(); 59 + }); 60 + 61 + test('renders timer when indicator is "timer"', () => { 62 + const result = prompts.spinner({ output, indicator: 'timer' }); 63 + 64 + result.start(); 65 + 66 + vi.advanceTimersByTime(80); 67 + 68 + expect(output.buffer).toMatchSnapshot(); 69 + }); 70 + }); 71 + 72 + describe('stop', () => { 73 + test('renders submit symbol and stops spinner', () => { 74 + const result = prompts.spinner({ output }); 75 + 76 + result.start(); 77 + 78 + vi.advanceTimersByTime(80); 79 + 80 + result.stop(); 81 + 82 + vi.advanceTimersByTime(80); 83 + 84 + expect(output.buffer).toMatchSnapshot(); 85 + }); 86 + 87 + test('renders cancel symbol if code = 1', () => { 88 + const result = prompts.spinner({ output }); 89 + 90 + result.start(); 91 + 92 + vi.advanceTimersByTime(80); 93 + 94 + result.stop('', 1); 95 + 96 + expect(output.buffer).toMatchSnapshot(); 97 + }); 98 + 99 + test('renders error symbol if code > 1', () => { 100 + const result = prompts.spinner({ output }); 101 + 102 + result.start(); 103 + 104 + vi.advanceTimersByTime(80); 105 + 106 + result.stop('', 2); 107 + 108 + expect(output.buffer).toMatchSnapshot(); 109 + }); 110 + 111 + test('renders message', () => { 112 + const result = prompts.spinner({ output }); 113 + 114 + result.start(); 115 + 116 + vi.advanceTimersByTime(80); 117 + 118 + result.stop('foo'); 119 + 120 + expect(output.buffer).toMatchSnapshot(); 121 + }); 122 + 123 + test('renders message without removing dots', () => { 124 + const result = prompts.spinner({ output }); 125 + 126 + result.start(); 127 + 128 + vi.advanceTimersByTime(80); 129 + 130 + result.stop('foo.'); 131 + 132 + expect(output.buffer).toMatchSnapshot(); 133 + }); 134 + }); 135 + 136 + describe('message', () => { 137 + test('sets message for next frame', () => { 138 + const result = prompts.spinner({ output }); 139 + 140 + result.start(); 141 + 142 + vi.advanceTimersByTime(80); 143 + 144 + result.message('foo'); 145 + 146 + vi.advanceTimersByTime(80); 147 + 148 + expect(output.buffer).toMatchSnapshot(); 149 + }); 150 + }); 151 + 152 + describe('process exit handling', () => { 153 + let processEmitter: EventEmitter; 154 + 155 + beforeEach(() => { 156 + processEmitter = new EventEmitter(); 157 + 158 + // Spy on process methods 159 + vi.spyOn(process, 'on').mockImplementation((ev, listener) => { 160 + processEmitter.on(ev, listener); 161 + return process; 162 + }); 163 + vi.spyOn(process, 'removeListener').mockImplementation((ev, listener) => { 164 + processEmitter.removeListener(ev, listener); 165 + return process; 166 + }); 167 + }); 168 + 169 + afterEach(() => { 170 + processEmitter.removeAllListeners(); 171 + }); 172 + 173 + test('uses default cancel message', () => { 174 + const result = prompts.spinner({ output }); 175 + result.start('Test operation'); 176 + 177 + processEmitter.emit('SIGINT'); 178 + 179 + expect(output.buffer).toMatchSnapshot(); 180 + }); 181 + 182 + test('uses custom cancel message when provided directly', () => { 183 + const result = prompts.spinner({ 184 + output, 185 + cancelMessage: 'Custom cancel message', 186 + }); 187 + result.start('Test operation'); 188 + 189 + processEmitter.emit('SIGINT'); 190 + 191 + expect(output.buffer).toMatchSnapshot(); 192 + }); 193 + 194 + test('uses custom error message when provided directly', () => { 195 + const result = prompts.spinner({ 196 + output, 197 + errorMessage: 'Custom error message', 198 + }); 199 + result.start('Test operation'); 200 + 201 + processEmitter.emit('exit', 2); 202 + 203 + expect(output.buffer).toMatchSnapshot(); 204 + }); 205 + 206 + test('uses global custom cancel message from settings', () => { 207 + // Store original message 208 + const originalCancelMessage = prompts.settings.messages.cancel; 209 + // Set custom message 210 + prompts.settings.messages.cancel = 'Global cancel message'; 211 + 212 + const result = prompts.spinner({ output }); 213 + result.start('Test operation'); 214 + 215 + processEmitter.emit('SIGINT'); 216 + 217 + expect(output.buffer).toMatchSnapshot(); 218 + 219 + // Reset to original 220 + prompts.settings.messages.cancel = originalCancelMessage; 221 + }); 222 + 223 + test('uses global custom error message from settings', () => { 224 + // Store original message 225 + const originalErrorMessage = prompts.settings.messages.error; 226 + // Set custom message 227 + prompts.settings.messages.error = 'Global error message'; 228 + 229 + const result = prompts.spinner({ output }); 230 + result.start('Test operation'); 231 + 232 + processEmitter.emit('exit', 2); 233 + 234 + expect(output.buffer).toMatchSnapshot(); 235 + 236 + // Reset to original 237 + prompts.settings.messages.error = originalErrorMessage; 238 + }); 239 + 240 + test('prioritizes direct options over global settings', () => { 241 + // Store original messages 242 + const originalCancelMessage = prompts.settings.messages.cancel; 243 + const originalErrorMessage = prompts.settings.messages.error; 244 + 245 + // Set custom global messages 246 + prompts.settings.messages.cancel = 'Global cancel message'; 247 + prompts.settings.messages.error = 'Global error message'; 248 + 249 + const result = prompts.spinner({ 250 + output, 251 + cancelMessage: 'Spinner cancel message', 252 + errorMessage: 'Spinner error message', 253 + }); 254 + result.start('Test operation'); 255 + 256 + processEmitter.emit('SIGINT'); 257 + expect(output.buffer).toMatchSnapshot(); 258 + 259 + // Reset buffer 260 + output.buffer = []; 261 + 262 + const result2 = prompts.spinner({ 263 + output, 264 + cancelMessage: 'Spinner cancel message', 265 + errorMessage: 'Spinner error message', 266 + }); 267 + result2.start('Test operation'); 268 + 269 + processEmitter.emit('exit', 2); 270 + expect(output.buffer).toMatchSnapshot(); 271 + 272 + // Reset to original values 273 + prompts.settings.messages.cancel = originalCancelMessage; 274 + prompts.settings.messages.error = originalErrorMessage; 275 + }); 276 + }); 277 + });
+291
packages/prompts/src/task-log.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('taskLog (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('writes message header', () => { 29 + prompts.taskLog({ 30 + input, 31 + output, 32 + title: 'foo', 33 + }); 34 + 35 + expect(output.buffer).toMatchSnapshot(); 36 + }); 37 + 38 + describe('message', () => { 39 + test('can write line by line', () => { 40 + const log = prompts.taskLog({ 41 + input, 42 + output, 43 + title: 'foo', 44 + }); 45 + 46 + log.message('line 0'); 47 + log.message('line 1'); 48 + 49 + expect(output.buffer).toMatchSnapshot(); 50 + }); 51 + 52 + test('can write multiple lines', () => { 53 + const log = prompts.taskLog({ 54 + input, 55 + output, 56 + title: 'foo', 57 + }); 58 + 59 + log.message('line 0\nline 1'); 60 + 61 + expect(output.buffer).toMatchSnapshot(); 62 + }); 63 + 64 + test('enforces limit if set', () => { 65 + const log = prompts.taskLog({ 66 + input, 67 + output, 68 + title: 'foo', 69 + limit: 2, 70 + }); 71 + 72 + log.message('line 0'); 73 + log.message('line 1'); 74 + log.message('line 2'); 75 + 76 + expect(output.buffer).toMatchSnapshot(); 77 + }); 78 + 79 + test('raw = true appends message text until newline', async () => { 80 + const log = prompts.taskLog({ 81 + input, 82 + output, 83 + title: 'foo', 84 + }); 85 + 86 + log.message('line 0', { raw: true }); 87 + log.message('still line 0', { raw: true }); 88 + log.message('\nline 1', { raw: true }); 89 + 90 + expect(output.buffer).toMatchSnapshot(); 91 + }); 92 + 93 + test('raw = true works when mixed with non-raw messages', async () => { 94 + const log = prompts.taskLog({ 95 + input, 96 + output, 97 + title: 'foo', 98 + }); 99 + 100 + log.message('line 0', { raw: true }); 101 + log.message('still line 0', { raw: true }); 102 + log.message('line 1'); 103 + 104 + expect(output.buffer).toMatchSnapshot(); 105 + }); 106 + 107 + test('raw = true works when started with non-raw messages', async () => { 108 + const log = prompts.taskLog({ 109 + input, 110 + output, 111 + title: 'foo', 112 + }); 113 + 114 + log.message('line 0'); 115 + log.message('line 1', { raw: true }); 116 + log.message('still line 1', { raw: true }); 117 + 118 + expect(output.buffer).toMatchSnapshot(); 119 + }); 120 + 121 + test('prints empty lines', async () => { 122 + const log = prompts.taskLog({ 123 + input, 124 + output, 125 + title: 'foo', 126 + }); 127 + 128 + log.message(''); 129 + log.message('line 1'); 130 + log.message(''); 131 + log.message('line 3'); 132 + 133 + expect(output.buffer).toMatchSnapshot(); 134 + }); 135 + }); 136 + 137 + describe('error', () => { 138 + test('renders output with message', () => { 139 + const log = prompts.taskLog({ 140 + input, 141 + output, 142 + title: 'foo', 143 + }); 144 + 145 + log.message('line 0'); 146 + log.message('line 1'); 147 + 148 + log.error('some error!'); 149 + 150 + expect(output.buffer).toMatchSnapshot(); 151 + }); 152 + 153 + test('clears output if showLog = false', () => { 154 + const log = prompts.taskLog({ 155 + input, 156 + output, 157 + title: 'foo', 158 + }); 159 + 160 + log.message('line 0'); 161 + log.message('line 1'); 162 + 163 + log.error('some error!', { showLog: false }); 164 + 165 + expect(output.buffer).toMatchSnapshot(); 166 + }); 167 + }); 168 + 169 + describe('success', () => { 170 + test('clears output and renders message', () => { 171 + const log = prompts.taskLog({ 172 + input, 173 + output, 174 + title: 'foo', 175 + }); 176 + 177 + log.message('line 0'); 178 + log.message('line 1'); 179 + 180 + log.success('success!'); 181 + 182 + expect(output.buffer).toMatchSnapshot(); 183 + }); 184 + 185 + test('renders output if showLog = true', () => { 186 + const log = prompts.taskLog({ 187 + input, 188 + output, 189 + title: 'foo', 190 + }); 191 + 192 + log.message('line 0'); 193 + log.message('line 1'); 194 + 195 + log.success('success!', { showLog: true }); 196 + 197 + expect(output.buffer).toMatchSnapshot(); 198 + }); 199 + }); 200 + 201 + describe('retainLog', () => { 202 + describe.each(['error', 'success'] as const)('%s', (method) => { 203 + test('retainLog = true outputs full log', () => { 204 + const log = prompts.taskLog({ 205 + input, 206 + output, 207 + title: 'foo', 208 + retainLog: true, 209 + }); 210 + 211 + for (let i = 0; i < 4; i++) { 212 + log.message(`line ${i}`); 213 + } 214 + 215 + log[method]('woo!', { showLog: true }); 216 + 217 + expect(output.buffer).toMatchSnapshot(); 218 + }); 219 + 220 + test('retainLog = true outputs full log with limit', () => { 221 + const log = prompts.taskLog({ 222 + input, 223 + output, 224 + title: 'foo', 225 + retainLog: true, 226 + limit: 2, 227 + }); 228 + 229 + for (let i = 0; i < 4; i++) { 230 + log.message(`line ${i}`); 231 + } 232 + 233 + log[method]('woo!', { showLog: true }); 234 + 235 + expect(output.buffer).toMatchSnapshot(); 236 + }); 237 + 238 + test('retainLog = false outputs full log without limit', () => { 239 + const log = prompts.taskLog({ 240 + input, 241 + output, 242 + title: 'foo', 243 + retainLog: false, 244 + }); 245 + 246 + for (let i = 0; i < 4; i++) { 247 + log.message(`line ${i}`); 248 + } 249 + 250 + log[method]('woo!', { showLog: true }); 251 + 252 + expect(output.buffer).toMatchSnapshot(); 253 + }); 254 + 255 + test('retainLog = false outputs limited log with limit', () => { 256 + const log = prompts.taskLog({ 257 + input, 258 + output, 259 + title: 'foo', 260 + retainLog: false, 261 + limit: 2, 262 + }); 263 + 264 + for (let i = 0; i < 4; i++) { 265 + log.message(`line ${i}`); 266 + } 267 + 268 + log[method]('woo!', { showLog: true }); 269 + 270 + expect(output.buffer).toMatchSnapshot(); 271 + }); 272 + 273 + test('outputs limited log with limit by default', () => { 274 + const log = prompts.taskLog({ 275 + input, 276 + output, 277 + title: 'foo', 278 + limit: 2, 279 + }); 280 + 281 + for (let i = 0; i < 4; i++) { 282 + log.message(`line ${i}`); 283 + } 284 + 285 + log[method]('woo!', { showLog: true }); 286 + 287 + expect(output.buffer).toMatchSnapshot(); 288 + }); 289 + }); 290 + }); 291 + });
+177
packages/prompts/src/text.test.ts
··· 1 + import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; 2 + import * as prompts from './index.js'; 3 + import { MockReadable, MockWritable } from './test-utils.js'; 4 + 5 + describe.each(['true', 'false'])('text (isCI = %s)', (isCI) => { 6 + let originalCI: string | undefined; 7 + let output: MockWritable; 8 + let input: MockReadable; 9 + 10 + beforeAll(() => { 11 + originalCI = process.env.CI; 12 + process.env.CI = isCI; 13 + }); 14 + 15 + afterAll(() => { 16 + process.env.CI = originalCI; 17 + }); 18 + 19 + beforeEach(() => { 20 + output = new MockWritable(); 21 + input = new MockReadable(); 22 + }); 23 + 24 + afterEach(() => { 25 + vi.restoreAllMocks(); 26 + }); 27 + 28 + test('renders message', async () => { 29 + const result = prompts.text({ 30 + message: 'foo', 31 + input, 32 + output, 33 + }); 34 + 35 + input.emit('keypress', '', { name: 'return' }); 36 + 37 + await result; 38 + 39 + expect(output.buffer).toMatchSnapshot(); 40 + }); 41 + 42 + test('renders placeholder if set', async () => { 43 + const result = prompts.text({ 44 + message: 'foo', 45 + placeholder: 'bar', 46 + input, 47 + output, 48 + }); 49 + 50 + input.emit('keypress', '', { name: 'return' }); 51 + 52 + const value = await result; 53 + 54 + expect(output.buffer).toMatchSnapshot(); 55 + 56 + expect(value).toBe('bar'); 57 + }); 58 + 59 + test('<tab> applies placeholder', async () => { 60 + const result = prompts.text({ 61 + message: 'foo', 62 + placeholder: 'bar', 63 + input, 64 + output, 65 + }); 66 + 67 + input.emit('keypress', '\t', { name: 'tab' }); 68 + input.emit('keypress', '', { name: 'return' }); 69 + 70 + const value = await result; 71 + 72 + expect(value).toBe('bar'); 73 + }); 74 + 75 + test('can cancel', async () => { 76 + const result = prompts.text({ 77 + message: 'foo', 78 + input, 79 + output, 80 + }); 81 + 82 + input.emit('keypress', 'escape', { name: 'escape' }); 83 + 84 + const value = await result; 85 + 86 + expect(prompts.isCancel(value)).toBe(true); 87 + expect(output.buffer).toMatchSnapshot(); 88 + }); 89 + 90 + test('renders cancelled value if one set', async () => { 91 + const result = prompts.text({ 92 + message: 'foo', 93 + input, 94 + output, 95 + }); 96 + 97 + input.emit('keypress', 'x', { name: 'x' }); 98 + input.emit('keypress', 'y', { name: 'y' }); 99 + input.emit('keypress', '', { name: 'escape' }); 100 + 101 + const value = await result; 102 + 103 + expect(prompts.isCancel(value)).toBe(true); 104 + expect(output.buffer).toMatchSnapshot(); 105 + }); 106 + 107 + test('renders submitted value', async () => { 108 + const result = prompts.text({ 109 + message: 'foo', 110 + input, 111 + output, 112 + }); 113 + 114 + input.emit('keypress', 'x', { name: 'x' }); 115 + input.emit('keypress', 'y', { name: 'y' }); 116 + input.emit('keypress', '', { name: 'return' }); 117 + 118 + const value = await result; 119 + 120 + expect(value).toBe('xy'); 121 + expect(output.buffer).toMatchSnapshot(); 122 + }); 123 + 124 + test('defaultValue sets the value but does not render', async () => { 125 + const result = prompts.text({ 126 + message: 'foo', 127 + defaultValue: 'bar', 128 + input, 129 + output, 130 + }); 131 + 132 + input.emit('keypress', '', { name: 'return' }); 133 + 134 + const value = await result; 135 + 136 + expect(value).toBe('bar'); 137 + expect(output.buffer).toMatchSnapshot(); 138 + }); 139 + 140 + test('validation errors render and clear', async () => { 141 + const result = prompts.text({ 142 + message: 'foo', 143 + validate: (val) => (val !== 'xy' ? 'should be xy' : undefined), 144 + input, 145 + output, 146 + }); 147 + 148 + input.emit('keypress', 'x', { name: 'x' }); 149 + input.emit('keypress', '', { name: 'return' }); 150 + input.emit('keypress', 'y', { name: 'y' }); 151 + input.emit('keypress', '', { name: 'return' }); 152 + 153 + const value = await result; 154 + 155 + expect(value).toBe('xy'); 156 + expect(output.buffer).toMatchSnapshot(); 157 + }); 158 + 159 + test('validation errors render and clear (using Error)', async () => { 160 + const result = prompts.text({ 161 + message: 'foo', 162 + validate: (val) => (val !== 'xy' ? new Error('should be xy') : undefined), 163 + input, 164 + output, 165 + }); 166 + 167 + input.emit('keypress', 'x', { name: 'x' }); 168 + input.emit('keypress', '', { name: 'return' }); 169 + input.emit('keypress', 'y', { name: 'y' }); 170 + input.emit('keypress', '', { name: 'return' }); 171 + 172 + const value = await result; 173 + 174 + expect(value).toBe('xy'); 175 + expect(output.buffer).toMatchSnapshot(); 176 + }); 177 + });