usage_spec.sh (64958B)
1 # pashage - age-backed POSIX password manager 2 # Copyright (C) 2024-2025 Natasha Kerensikova 3 # 4 # This program is free software; you can redistribute it and/or 5 # modify it under the terms of the GNU General Public License 6 # as published by the Free Software Foundation; either version 2 7 # of the License, or (at your option) any later version. 8 # 9 # This program is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with this program; if not, write to the Free Software 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 18 # This test file fully covers all command functions in isolation, 19 # using mocks for all action and helper functions. 20 # It mostly tests command-line parsing and environment transmission to actions. 21 22 Describe 'Command-Line Parsing' 23 Include src/pashage.sh 24 if [ "${SHELLSPEC_SHELL_TYPE}" = sh ]; then 25 Set 'errexit:on' 'nounset:on' 26 else 27 Set 'errexit:on' 'nounset:on' 'pipefail:on' 28 fi 29 30 PREFIX=/prefix 31 PROGRAM=prg 32 33 CHARACTER_SET='[:punct:][:alnum:]' 34 CHARACTER_SET_NO_SYMBOLS='[:alnum:]' 35 36 # mocks 37 platform_tmpdir() { 38 SECURE_TMPDIR=/tmp/secure 39 } 40 41 check_sneaky_path() { mocklog check_sneaky_path "$@"; } 42 git() { mocklog git "$@"; } 43 scm_add() { mocklog scm_add "$@"; } 44 scm_begin() { mocklog scm_begin "$@"; } 45 scm_commit() { mocklog scm_commit "$@"; } 46 47 do_copy_move() { 48 mocklog do_copy_move "$@" 49 %text:expand >&2 50 #|ACTION=${ACTION} 51 #|DECISION=${DECISION} 52 #|OVERWRITE=${OVERWRITE} 53 #|SCM_ACTION=${SCM_ACTION} 54 } 55 do_decrypt() { 56 mocklog do_decrypt "$@" 57 } 58 do_decrypt_gpg() { 59 mocklog do_decrypt_gpg "$@" 60 } 61 do_deinit() { 62 mocklog do_deinit "$@" 63 %text:expand >&2 64 #|DECISION=${DECISION} 65 } 66 do_delete() { 67 mocklog do_delete "$@" 68 %text:expand >&2 69 #|DECISION=${DECISION} 70 #|RECURSIVE=${RECURSIVE} 71 } 72 do_edit() { 73 mocklog do_edit "$@" 74 %text:expand >&2 75 #|EDITOR=${EDITOR} 76 #|SECURE_TMPDIR=${SECURE_TMPDIR} 77 #|TERM=${TERM} 78 #|VISUAL=${VISUAL} 79 } 80 do_encrypt() { 81 mocklog do_encrypt "$@" 82 %text:expand >&2 83 #|IDENTITIES_FILE=${IDENTITIES_FILE} 84 #|LOCAL_RECIPIENT_FILE=${LOCAL_RECIPIENT_FILE} 85 #|PASHAGE_RECIPIENTS=${PASHAGE_RECIPIENTS} 86 #|PASHAGE_RECIPIENTS_FILE=${PASHAGE_RECIPIENTS_FILE} 87 #|PASSAGE_RECIPIENTS=${PASSAGE_RECIPIENTS} 88 #|PASSAGE_RECIPIENTS_FILE=${PASSAGE_RECIPIENTS_FILE} 89 } 90 do_generate() { 91 mocklog do_generate "$@" 92 %text:expand >&2 93 #|DECISION=${DECISION} 94 #|MULTILINE=${MULTILINE} 95 #|OVERWRITE=${OVERWRITE} 96 #|SELECTED_LINE=${SELECTED_LINE} 97 #|SHOW=${SHOW} 98 } 99 do_grep() { 100 mocklog do_grep "$@" 101 } 102 do_init() { 103 mocklog do_init "$@" 104 %text:expand >&2 105 #|DECISION=${DECISION} 106 #|OVERWRITE=${OVERWRITE} 107 } 108 do_insert() { 109 mocklog do_insert "$@" 110 %text:expand >&2 111 #|ECHO=${ECHO} 112 #|MULTILINE=${MULTILINE} 113 #|OVERWRITE=${OVERWRITE} 114 } 115 do_list() { 116 mocklog do_list "$@" 117 } 118 do_list_or_show() { 119 mocklog do_list_or_show "$@" 120 %text:expand >&2 121 #|LIST_VIEW=${LIST_VIEW} 122 #|SELECTED_LINE=${SELECTED_LINE} 123 #|SHOW=${SHOW} 124 } 125 do_reencrypt() { 126 mocklog do_reencrypt "$@" 127 %text:expand >&2 128 #|DECISION=${DECISION} 129 } 130 do_reencrypt_dir() { 131 mocklog do_reencrypt_dir "$@" 132 %text:expand >&2 133 #|DECISION=${DECISION} 134 } 135 do_reencrypt_file() { 136 mocklog do_reencrypt_file "$@" 137 %text:expand >&2 138 #|DECISION=${DECISION} 139 } 140 do_show() { 141 mocklog do_show "$@" 142 %text:expand >&2 143 #|SELECTED_LINE=${SELECTED_LINE} 144 #|SHOW=${SHOW} 145 } 146 do_tree() { 147 mocklog do_tree "$@" 148 } 149 150 Describe 'cmd_copy' 151 COMMAND=copy 152 153 It 'copies multiple files' 154 result() { 155 %text 156 #|$ check_sneaky_path src1 157 #|$ check_sneaky_path src2 158 #|$ check_sneaky_path src3 159 #|$ check_sneaky_path dest 160 #|$ do_copy_move src1 dest/ 161 #|ACTION=Copy 162 #|DECISION=default 163 #|OVERWRITE=no 164 #|SCM_ACTION=scm_cp 165 #|$ do_copy_move src2 dest/ 166 #|ACTION=Copy 167 #|DECISION=default 168 #|OVERWRITE=no 169 #|SCM_ACTION=scm_cp 170 #|$ do_copy_move src3 dest/ 171 #|ACTION=Copy 172 #|DECISION=default 173 #|OVERWRITE=no 174 #|SCM_ACTION=scm_cp 175 } 176 When call cmd_copy src1 src2 src3 dest 177 The status should be success 178 The output should be blank 179 The error should equal "$(result)" 180 End 181 182 It 'copies forcefully with a long option' 183 result() { 184 %text 185 #|$ check_sneaky_path src 186 #|$ check_sneaky_path dest 187 #|$ do_copy_move src dest 188 #|ACTION=Copy 189 #|DECISION=default 190 #|OVERWRITE=yes 191 #|SCM_ACTION=scm_cp 192 } 193 When call cmd_copy --force src dest 194 The status should be success 195 The output should be blank 196 The error should equal "$(result)" 197 End 198 199 It 'copies forcefully with a short option' 200 result() { 201 %text 202 #|$ check_sneaky_path src 203 #|$ check_sneaky_path dest 204 #|$ do_copy_move src dest 205 #|ACTION=Copy 206 #|DECISION=default 207 #|OVERWRITE=yes 208 #|SCM_ACTION=scm_cp 209 } 210 When call cmd_copy -f src dest 211 The status should be success 212 The output should be blank 213 The error should equal "$(result)" 214 End 215 216 It 'always reencrypts with a long option' 217 result() { 218 %text 219 #|$ check_sneaky_path src 220 #|$ check_sneaky_path dest 221 #|$ do_copy_move src dest 222 #|ACTION=Copy 223 #|DECISION=force 224 #|OVERWRITE=no 225 #|SCM_ACTION=scm_cp 226 } 227 When call cmd_copy --reencrypt src dest 228 The status should be success 229 The output should be blank 230 The error should equal "$(result)" 231 End 232 233 It 'always reencrypts with a short option' 234 result() { 235 %text 236 #|$ check_sneaky_path src 237 #|$ check_sneaky_path dest 238 #|$ do_copy_move src dest 239 #|ACTION=Copy 240 #|DECISION=force 241 #|OVERWRITE=no 242 #|SCM_ACTION=scm_cp 243 } 244 When call cmd_copy -e src dest 245 The status should be success 246 The output should be blank 247 The error should equal "$(result)" 248 End 249 250 It 'interactively reencrypts with a long option' 251 result() { 252 %text 253 #|$ check_sneaky_path src 254 #|$ check_sneaky_path dest 255 #|$ do_copy_move src dest 256 #|ACTION=Copy 257 #|DECISION=interactive 258 #|OVERWRITE=no 259 #|SCM_ACTION=scm_cp 260 } 261 When call cmd_copy --interactive src dest 262 The status should be success 263 The output should be blank 264 The error should equal "$(result)" 265 End 266 267 It 'interactively reencrypts with a short option' 268 result() { 269 %text 270 #|$ check_sneaky_path src 271 #|$ check_sneaky_path dest 272 #|$ do_copy_move src dest 273 #|ACTION=Copy 274 #|DECISION=interactive 275 #|OVERWRITE=no 276 #|SCM_ACTION=scm_cp 277 } 278 When call cmd_copy -i src dest 279 The status should be success 280 The output should be blank 281 The error should equal "$(result)" 282 End 283 284 It 'never reencrypts with a long option' 285 result() { 286 %text 287 #|$ check_sneaky_path src 288 #|$ check_sneaky_path dest 289 #|$ do_copy_move src dest 290 #|ACTION=Copy 291 #|DECISION=keep 292 #|OVERWRITE=no 293 #|SCM_ACTION=scm_cp 294 } 295 When call cmd_copy --keep src dest 296 The status should be success 297 The output should be blank 298 The error should equal "$(result)" 299 End 300 301 It 'never reencrypts with a short option' 302 result() { 303 %text 304 #|$ check_sneaky_path src 305 #|$ check_sneaky_path dest 306 #|$ do_copy_move src dest 307 #|ACTION=Copy 308 #|DECISION=keep 309 #|OVERWRITE=no 310 #|SCM_ACTION=scm_cp 311 } 312 When call cmd_copy -k src dest 313 The status should be success 314 The output should be blank 315 The error should equal "$(result)" 316 End 317 318 It 'copies a file named like a flag' 319 result() { 320 %text 321 #|$ check_sneaky_path -s 322 #|$ check_sneaky_path dest 323 #|$ do_copy_move -s dest 324 #|ACTION=Copy 325 #|DECISION=default 326 #|OVERWRITE=no 327 #|SCM_ACTION=scm_cp 328 } 329 When call cmd_copy -- -s dest 330 The status should be success 331 The output should be blank 332 The error should equal "$(result)" 333 End 334 335 usage_text() { %text 336 #|Usage: prg copy [--reencrypt,-e | --interactive,-i | --keep,-k ] 337 #| [--force,-f] old-path new-path 338 } 339 340 It 'reports a bad option' 341 cat() { @cat; } 342 When run cmd_copy -s arg 343 The output should be blank 344 The error should equal "$(usage_text)" 345 The status should equal 1 346 End 347 348 It 'reports incompatible re-encryption options (-e and -i)' 349 cat() { @cat; } 350 When run cmd_copy -ei src dest 351 The output should be blank 352 The error should equal "$(usage_text)" 353 The status should equal 1 354 End 355 356 It 'reports incompatible re-encryption options (-i and -k)' 357 cat() { @cat; } 358 When run cmd_copy -ik src dest 359 The output should be blank 360 The error should equal "$(usage_text)" 361 The status should equal 1 362 End 363 364 It 'reports incompatible re-encryption options (-k and -e)' 365 cat() { @cat; } 366 When run cmd_copy -ke src dest 367 The output should be blank 368 The error should equal "$(usage_text)" 369 The status should equal 1 370 End 371 372 It 'reports a lack of argument' 373 cat() { @cat; } 374 When run cmd_copy src 375 The output should be blank 376 The error should equal "$(usage_text)" 377 The status should equal 1 378 End 379 End 380 381 Describe 'cmd_copy_move' 382 COMMAND=wrong 383 384 It 'reports both commands when confused' 385 cat() { @cat; } 386 result() { %text 387 #|Usage: prg copy [--reencrypt,-e | --interactive,-i | --keep,-k ] 388 #| [--force,-f] old-path new-path 389 #| prg move [--reencrypt,-e | --interactive,-i | --keep,-k ] 390 #| [--force,-f] old-path new-path 391 } 392 When run cmd_copy src 393 The output should be blank 394 The error should equal "$(result)" 395 The status should equal 1 396 End 397 End 398 399 Describe 'cmd_delete' 400 COMMAND=delete 401 402 It 'removes a file forcefully with a long option' 403 result() { 404 %text 405 #|$ check_sneaky_path arg1 406 #|$ do_delete arg1 407 #|DECISION=force 408 #|RECURSIVE=no 409 } 410 When call cmd_delete --force arg1 411 The status should be success 412 The output should be blank 413 The error should equal "$(result)" 414 End 415 416 It 'removes a file forcefully with a short option' 417 result() { 418 %text 419 #|$ check_sneaky_path arg1 420 #|$ do_delete arg1 421 #|DECISION=force 422 #|RECURSIVE=no 423 } 424 When call cmd_delete -f arg1 425 The status should be success 426 The output should be blank 427 The error should equal "$(result)" 428 End 429 430 It 'removes a directory recursively with a long option' 431 result() { 432 %text 433 #|$ check_sneaky_path arg1 434 #|$ do_delete arg1 435 #|DECISION=default 436 #|RECURSIVE=yes 437 } 438 When call cmd_delete --recursive arg1 439 The status should be success 440 The output should be blank 441 The error should equal "$(result)" 442 End 443 444 It 'removes a directory recursively with a short option' 445 result() { 446 %text 447 #|$ check_sneaky_path arg1 448 #|$ do_delete arg1 449 #|DECISION=default 450 #|RECURSIVE=yes 451 } 452 When call cmd_delete -r arg1 453 The status should be success 454 The output should be blank 455 The error should equal "$(result)" 456 End 457 458 It 'removes a directory recursively and forcefully with long options' 459 result() { 460 %text 461 #|$ check_sneaky_path arg1 462 #|$ do_delete arg1 463 #|DECISION=force 464 #|RECURSIVE=yes 465 } 466 When call cmd_delete --recursive --force arg1 467 The status should be success 468 The output should be blank 469 The error should equal "$(result)" 470 End 471 472 It 'removes a directory recursively and forcefully with short options' 473 result() { 474 %text 475 #|$ check_sneaky_path arg1 476 #|$ do_delete arg1 477 #|DECISION=force 478 #|RECURSIVE=yes 479 } 480 When call cmd_delete -rf arg1 481 The status should be success 482 The output should be blank 483 The error should equal "$(result)" 484 End 485 486 It 'removes a directory forcefully and recursively with short options' 487 result() { 488 %text 489 #|$ check_sneaky_path arg1 490 #|$ do_delete arg1 491 #|DECISION=force 492 #|RECURSIVE=yes 493 } 494 When call cmd_delete -fr arg1 495 The status should be success 496 The output should be blank 497 The error should equal "$(result)" 498 End 499 500 It 'removes multiple files' 501 result() { 502 %text 503 #|$ check_sneaky_path arg1 504 #|$ check_sneaky_path arg2 505 #|$ check_sneaky_path arg3 506 #|$ do_delete arg1 507 #|DECISION=default 508 #|RECURSIVE=no 509 #|$ do_delete arg2 510 #|DECISION=default 511 #|RECURSIVE=no 512 #|$ do_delete arg3 513 #|DECISION=default 514 #|RECURSIVE=no 515 } 516 When call cmd_delete arg1 arg2 arg3 517 The status should be success 518 The output should be blank 519 The error should equal "$(result)" 520 End 521 522 It 'removes a file named like a flag' 523 result() { 524 %text 525 #|$ check_sneaky_path -f 526 #|$ check_sneaky_path arg2 527 #|$ do_delete -f 528 #|DECISION=default 529 #|RECURSIVE=no 530 #|$ do_delete arg2 531 #|DECISION=default 532 #|RECURSIVE=no 533 } 534 When call cmd_delete -- -f arg2 535 The status should be success 536 The output should be blank 537 The error should equal "$(result)" 538 End 539 540 It 'reports a bad option' 541 cat() { @cat; } 542 When run cmd_delete -u arg 543 The output should be blank 544 The error should equal \ 545 'Usage: prg delete [--recursive,-r] [--force,-f] pass-name' 546 The status should equal 1 547 End 548 549 It 'reports a lack of argument' 550 cat() { @cat; } 551 When run cmd_delete 552 The output should be blank 553 The error should equal \ 554 'Usage: prg delete [--recursive,-r] [--force,-f] pass-name' 555 The status should equal 1 556 End 557 End 558 559 Describe 'cmd_edit' 560 COMMAND=edit 561 EDITOR=ed 562 TERM=dumb 563 VISUAL=vi 564 565 It 'edits multiple files succesively' 566 result() { 567 %text 568 #|$ check_sneaky_path arg1 569 #|$ check_sneaky_path arg2 570 #|$ check_sneaky_path arg3 571 #|$ do_edit arg1 572 #|EDITOR=ed 573 #|SECURE_TMPDIR=/tmp/secure 574 #|TERM=dumb 575 #|VISUAL=vi 576 #|$ do_edit arg2 577 #|EDITOR=ed 578 #|SECURE_TMPDIR=/tmp/secure 579 #|TERM=dumb 580 #|VISUAL=vi 581 #|$ do_edit arg3 582 #|EDITOR=ed 583 #|SECURE_TMPDIR=/tmp/secure 584 #|TERM=dumb 585 #|VISUAL=vi 586 } 587 When call cmd_edit arg1 arg2 arg3 588 The status should be success 589 The output should be blank 590 The error should equal "$(result)" 591 End 592 593 It 'reports a lack of argument' 594 cat() { @cat; } 595 When run cmd_edit 596 The output should be blank 597 The error should equal 'Usage: prg edit pass-name' 598 The status should equal 1 599 End 600 End 601 602 Describe 'cmd_find' 603 COMMAND=find 604 605 It 'uses the argument list directly' 606 When call cmd_find -i pattern 607 The status should be success 608 The output should equal 'Search pattern: -i pattern' 609 The error should equal '$ do_tree /prefix -i pattern' 610 End 611 612 It 'interprets the raw list flag' 613 When call cmd_find -r pattern 614 The status should be success 615 The output should be blank 616 The error should equal '$ do_list pattern' 617 End 618 619 It 'reports a lack of argument' 620 cat() { @cat; } 621 When run cmd_find 622 The output should be blank 623 The error should equal 'Usage: prg find [--raw,-r] [GREP_OPTIONS] regex' 624 The status should equal 1 625 End 626 627 It 'reports a lack of argument for grep' 628 cat() { @cat; } 629 When run cmd_find -r 630 The output should be blank 631 The error should equal 'Usage: prg find [--raw,-r] [GREP_OPTIONS] regex' 632 The status should equal 1 633 End 634 End 635 636 Describe 'cmd_generate' 637 COMMAND=generate 638 GENERATED_LENGTH=25 639 640 usage_text() { %text 641 #|Usage: prg generate [--no-symbols,-n] [--clip,-c | --qrcode,-q] 642 #| [--in-place,-i | --force,-f] [--multiline,-m] 643 #| [--try,-t] pass-name [pass-length [character-set]] 644 } 645 646 It 'generates a new entry with default length' 647 result() { 648 %text 649 #|$ check_sneaky_path secret 650 #|$ do_generate secret 25 [:punct:][:alnum:] 651 #|DECISION=default 652 #|MULTILINE=no 653 #|OVERWRITE=no 654 #|SELECTED_LINE=1 655 #|SHOW=text 656 } 657 When call cmd_generate secret 658 The status should be success 659 The output should be blank 660 The error should equal "$(result)" 661 End 662 663 It 'generates a new entry with explicit length' 664 result() { 665 %text 666 #|$ check_sneaky_path secret 667 #|$ do_generate secret 12 [:punct:][:alnum:] 668 #|DECISION=default 669 #|MULTILINE=no 670 #|OVERWRITE=no 671 #|SELECTED_LINE=1 672 #|SHOW=text 673 } 674 When call cmd_generate secret 12 675 The status should be success 676 The output should be blank 677 The error should equal "$(result)" 678 End 679 680 It 'generates a new entry with explicit length and character set' 681 result() { 682 %text 683 #|$ check_sneaky_path secret 684 #|$ do_generate secret 12 [A-Z] 685 #|DECISION=default 686 #|MULTILINE=no 687 #|OVERWRITE=no 688 #|SELECTED_LINE=1 689 #|SHOW=text 690 } 691 When call cmd_generate secret 12 '[A-Z]' 692 The status should be success 693 The output should be blank 694 The error should equal "$(result)" 695 End 696 697 It 'generates a new flag-like entry' 698 result() { 699 %text 700 #|$ check_sneaky_path -f 701 #|$ do_generate -f 25 [:punct:][:alnum:] 702 #|DECISION=default 703 #|MULTILINE=no 704 #|OVERWRITE=no 705 #|SELECTED_LINE=1 706 #|SHOW=text 707 } 708 When call cmd_generate -- -f 709 The status should be success 710 The output should be blank 711 The error should equal "$(result)" 712 End 713 714 It 'generates a new entry and copies it into the clipboard (long)' 715 result() { 716 %text 717 #|$ check_sneaky_path secret 718 #|$ do_generate secret 25 [:punct:][:alnum:] 719 #|DECISION=default 720 #|MULTILINE=no 721 #|OVERWRITE=no 722 #|SELECTED_LINE=1 723 #|SHOW=clip 724 } 725 When call cmd_generate --clip secret 726 The status should be success 727 The output should be blank 728 The error should equal "$(result)" 729 End 730 731 It 'generates a new entry and copies it into the clipboard (short)' 732 result() { 733 %text 734 #|$ check_sneaky_path secret 735 #|$ do_generate secret 25 [:punct:][:alnum:] 736 #|DECISION=default 737 #|MULTILINE=no 738 #|OVERWRITE=no 739 #|SELECTED_LINE=1 740 #|SHOW=clip 741 } 742 When call cmd_generate -c secret 743 The status should be success 744 The output should be blank 745 The error should equal "$(result)" 746 End 747 748 It 'generates a new entry and shows it as a QR-code (long)' 749 result() { 750 %text 751 #|$ check_sneaky_path secret 752 #|$ do_generate secret 25 [:punct:][:alnum:] 753 #|DECISION=default 754 #|MULTILINE=no 755 #|OVERWRITE=no 756 #|SELECTED_LINE=1 757 #|SHOW=qrcode 758 } 759 When call cmd_generate --qrcode secret 760 The status should be success 761 The output should be blank 762 The error should equal "$(result)" 763 End 764 765 It 'generates a new entry and shows it as a QR-code (short)' 766 result() { 767 %text 768 #|$ check_sneaky_path secret 769 #|$ do_generate secret 25 [:punct:][:alnum:] 770 #|DECISION=default 771 #|MULTILINE=no 772 #|OVERWRITE=no 773 #|SELECTED_LINE=1 774 #|SHOW=qrcode 775 } 776 When call cmd_generate -q secret 777 The status should be success 778 The output should be blank 779 The error should equal "$(result)" 780 End 781 782 It 'generates a new alphanumeric entry and copies it into the clipboard (long)' 783 result() { 784 %text 785 #|$ check_sneaky_path secret 786 #|$ do_generate secret 25 [:alnum:] 787 #|DECISION=default 788 #|MULTILINE=no 789 #|OVERWRITE=no 790 #|SELECTED_LINE=1 791 #|SHOW=clip 792 } 793 When call cmd_generate --clip --no-symbols secret 794 The status should be success 795 The output should be blank 796 The error should equal "$(result)" 797 End 798 799 It 'generates a new alphanumeric entry and copies it into the clipboard (short)' 800 result() { 801 %text 802 #|$ check_sneaky_path secret 803 #|$ do_generate secret 25 [:alnum:] 804 #|DECISION=default 805 #|MULTILINE=no 806 #|OVERWRITE=no 807 #|SELECTED_LINE=1 808 #|SHOW=clip 809 } 810 When call cmd_generate -cn secret 811 The status should be success 812 The output should be blank 813 The error should equal "$(result)" 814 End 815 816 It 'generates a new alphanumeric entry and shows it as a QR-code (long)' 817 result() { 818 %text 819 #|$ check_sneaky_path secret 820 #|$ do_generate secret 25 [:alnum:] 821 #|DECISION=default 822 #|MULTILINE=no 823 #|OVERWRITE=no 824 #|SELECTED_LINE=1 825 #|SHOW=qrcode 826 } 827 When call cmd_generate --no-symbols --qrcode secret 828 The status should be success 829 The output should be blank 830 The error should equal "$(result)" 831 End 832 833 It 'generates a new alphanumeric entry and shows it as a QR-code (short)' 834 result() { 835 %text 836 #|$ check_sneaky_path secret 837 #|$ do_generate secret 25 [:alnum:] 838 #|DECISION=default 839 #|MULTILINE=no 840 #|OVERWRITE=no 841 #|SELECTED_LINE=1 842 #|SHOW=qrcode 843 } 844 When call cmd_generate -nq secret 845 The status should be success 846 The output should be blank 847 The error should equal "$(result)" 848 End 849 850 It 'generates a new entry in place (long)' 851 result() { 852 %text 853 #|$ check_sneaky_path secret 854 #|$ do_generate secret 25 [:punct:][:alnum:] 855 #|DECISION=default 856 #|MULTILINE=no 857 #|OVERWRITE=reuse 858 #|SELECTED_LINE=1 859 #|SHOW=text 860 } 861 When call cmd_generate --in-place secret 862 The status should be success 863 The output should be blank 864 The error should equal "$(result)" 865 End 866 867 It 'generates a new entry in place (short)' 868 result() { 869 %text 870 #|$ check_sneaky_path secret 871 #|$ do_generate secret 25 [:punct:][:alnum:] 872 #|DECISION=default 873 #|MULTILINE=no 874 #|OVERWRITE=reuse 875 #|SELECTED_LINE=1 876 #|SHOW=text 877 } 878 When call cmd_generate -i secret 879 The status should be success 880 The output should be blank 881 The error should equal "$(result)" 882 End 883 884 It 'overwrites an existing entry (long)' 885 result() { 886 %text 887 #|$ check_sneaky_path secret 888 #|$ do_generate secret 25 [:punct:][:alnum:] 889 #|DECISION=default 890 #|MULTILINE=no 891 #|OVERWRITE=yes 892 #|SELECTED_LINE=1 893 #|SHOW=text 894 } 895 When call cmd_generate --force secret 896 The status should be success 897 The output should be blank 898 The error should equal "$(result)" 899 End 900 901 It 'overwrites an existing entry (short)' 902 result() { 903 %text 904 #|$ check_sneaky_path secret 905 #|$ do_generate secret 25 [:punct:][:alnum:] 906 #|DECISION=default 907 #|MULTILINE=no 908 #|OVERWRITE=yes 909 #|SELECTED_LINE=1 910 #|SHOW=text 911 } 912 When call cmd_generate -f secret 913 The status should be success 914 The output should be blank 915 The error should equal "$(result)" 916 End 917 918 It 'asks for confirmation before saving the generated password (long)' 919 result() { 920 %text 921 #|$ check_sneaky_path secret 922 #|$ do_generate secret 25 [:punct:][:alnum:] 923 #|DECISION=interactive 924 #|MULTILINE=no 925 #|OVERWRITE=no 926 #|SELECTED_LINE=1 927 #|SHOW=text 928 } 929 When call cmd_generate --try secret 930 The status should be success 931 The output should be blank 932 The error should equal "$(result)" 933 End 934 935 It 'asks for confirmation before saving the generated password (short)' 936 result() { 937 %text 938 #|$ check_sneaky_path secret 939 #|$ do_generate secret 25 [:punct:][:alnum:] 940 #|DECISION=interactive 941 #|MULTILINE=no 942 #|OVERWRITE=no 943 #|SELECTED_LINE=1 944 #|SHOW=text 945 } 946 When call cmd_generate -t secret 947 The status should be success 948 The output should be blank 949 The error should equal "$(result)" 950 End 951 952 It 'accepts extra lines after the generated secret (long)' 953 result() { 954 %text 955 #|$ check_sneaky_path secret 956 #|$ do_generate secret 25 [:punct:][:alnum:] 957 #|DECISION=default 958 #|MULTILINE=yes 959 #|OVERWRITE=no 960 #|SELECTED_LINE=1 961 #|SHOW=text 962 } 963 When call cmd_generate --multiline secret 964 The status should be success 965 The output should be blank 966 The error should equal "$(result)" 967 End 968 969 It 'accepts extra lines after the generated secret (short)' 970 result() { 971 %text 972 #|$ check_sneaky_path secret 973 #|$ do_generate secret 25 [:punct:][:alnum:] 974 #|DECISION=default 975 #|MULTILINE=yes 976 #|OVERWRITE=no 977 #|SELECTED_LINE=1 978 #|SHOW=text 979 } 980 When call cmd_generate -m secret 981 The status should be success 982 The output should be blank 983 The error should equal "$(result)" 984 End 985 986 It 'reports incompatible generation long options' 987 cat() { @cat; } 988 When run cmd_generate --in-place --force secret 989 The output should be blank 990 The error should equal "$(usage_text)" 991 The status should equal 1 992 End 993 994 It 'reports incompatible generation short options' 995 cat() { @cat; } 996 When run cmd_generate -fi secret 997 The output should be blank 998 The error should equal "$(usage_text)" 999 The status should equal 1 1000 End 1001 1002 It 'reports incompatible show long options' 1003 cat() { @cat; } 1004 When run cmd_generate --qrcode --clip secret 1005 The output should be blank 1006 The error should equal "$(usage_text)" 1007 The status should equal 1 1008 End 1009 1010 It 'reports incompatible show short options' 1011 cat() { @cat; } 1012 When run cmd_generate -cq secret 1013 The output should be blank 1014 The error should equal "$(usage_text)" 1015 The status should equal 1 1016 End 1017 1018 It 'reports a bad option' 1019 cat() { @cat; } 1020 When run cmd_generate --bad secret 1021 The output should be blank 1022 The error should equal "$(usage_text)" 1023 The status should equal 1 1024 End 1025 1026 It 'reports a lack of argument' 1027 cat() { @cat; } 1028 When run cmd_generate 1029 The output should be blank 1030 The error should equal "$(usage_text)" 1031 The status should equal 1 1032 End 1033 End 1034 1035 Describe 'cmd_git' 1036 COMMAND=git 1037 1038 cmd_gitconfig() { mocklog cmd_gitconfig "$@"; } 1039 mkdir() { mocklog mkdir "$@"; @mkdir "$@"; } 1040 1041 setup() { 1042 @mkdir -p "${SHELLSPEC_WORKDIR}/repo/.git" 1043 @mkdir -p "${SHELLSPEC_WORKDIR}/repo/sub" 1044 } 1045 1046 cleanup() { 1047 @rm -rf "${SHELLSPEC_WORKDIR}/repo" 1048 } 1049 1050 BeforeEach setup 1051 AfterEach cleanup 1052 1053 It 'initializes a new repository' 1054 PREFIX="${SHELLSPEC_WORKDIR}/repo/sub" 1055 result() { 1056 %text:expand 1057 #|$ mkdir -p -- ${PREFIX} 1058 #|$ git -C ${PREFIX} init 1059 #|$ scm_add . 1060 #|$ scm_commit Add current contents of password store. 1061 #|$ cmd_gitconfig 1062 } 1063 When call cmd_git init 1064 The status should be success 1065 The output should be blank 1066 The error should equal "$(result)" 1067 End 1068 1069 It 'clones a new repository' 1070 PREFIX="${SHELLSPEC_WORKDIR}/repo/sub" 1071 result() { 1072 %text:expand 1073 #|$ git clone origin ${PREFIX} 1074 #|$ cmd_gitconfig 1075 } 1076 When call cmd_git clone origin 1077 The status should be success 1078 The output should be blank 1079 The error should equal "$(result)" 1080 End 1081 1082 It 'runs the git command into the store' 1083 PREFIX="${SHELLSPEC_WORKDIR}/repo" 1084 When call cmd_git log --oneline 1085 The status should be success 1086 The output should be blank 1087 The error should equal "$ git -C ${PREFIX} log --oneline" 1088 End 1089 1090 It 'transmits an empty argument list to git' 1091 PREFIX="${SHELLSPEC_WORKDIR}/repo" 1092 When run cmd_git 1093 The status should be success 1094 The output should be blank 1095 The error should equal "$ git -C ${PREFIX}" 1096 End 1097 1098 It 'aborts without a git repository' 1099 PREFIX="${SHELLSPEC_WORKDIR}/repo/sub" 1100 When run cmd_git log 1101 The output should be blank 1102 The error should equal 'Error: the password store is not a git repository. Try "prg git init".' 1103 The status should equal 1 1104 End 1105 End 1106 1107 Describe 'cmd_gitconfig' 1108 COMMAND=gitconfig 1109 AGE=age 1110 IDENTITIES_FILE=id 1111 1112 grep() { @grep "$@"; } 1113 1114 setup() { 1115 @mkdir -p "${SHELLSPEC_WORKDIR}/repo/.git" 1116 @mkdir -p "${SHELLSPEC_WORKDIR}/repo/sub-1/.git" 1117 %putsn data >"${SHELLSPEC_WORKDIR}/repo/sub-1/.gitattributes" 1118 @mkdir -p "${SHELLSPEC_WORKDIR}/repo/sub-2/.git" 1119 %putsn '*.age diff=age' >"${SHELLSPEC_WORKDIR}/repo/sub-2/.gitattributes" 1120 } 1121 1122 cleanup() { 1123 @rm -rf "${SHELLSPEC_WORKDIR}/repo" 1124 } 1125 1126 BeforeEach setup 1127 AfterEach cleanup 1128 1129 It 'configures a new repository' 1130 PREFIX="${SHELLSPEC_WORKDIR}/repo" 1131 result() { 1132 %text:expand 1133 #|$ scm_begin 1134 #|$ scm_add .gitattributes 1135 #|$ scm_commit Configure git repository for age file diff. 1136 #|$ git -C ${PREFIX} config --local diff.age.binary true 1137 #|$ git -C ${PREFIX} config --local diff.age.textconv age -d -i id 1138 } 1139 When call cmd_gitconfig 1140 The status should be success 1141 The output should be blank 1142 The error should equal "$(result)" 1143 The contents of file "${PREFIX}/.gitattributes" should equal '*.age diff=age' 1144 End 1145 1146 It 'expands an existing .gitattributes' 1147 PREFIX="${SHELLSPEC_WORKDIR}/repo/sub-1" 1148 result() { 1149 %text:expand 1150 #|$ scm_begin 1151 #|$ scm_add .gitattributes 1152 #|$ scm_commit Configure git repository for age file diff. 1153 #|$ git -C ${PREFIX} config --local diff.age.binary true 1154 #|$ git -C ${PREFIX} config --local diff.age.textconv age -d -i id 1155 } 1156 attrs() { 1157 %text 1158 #|data 1159 #|*.age diff=age 1160 } 1161 When call cmd_gitconfig 1162 The status should be success 1163 The output should be blank 1164 The error should equal "$(result)" 1165 The contents of file "${PREFIX}/.gitattributes" should equal "$(attrs)" 1166 End 1167 1168 It 'configures a repository with a valid .gitattributes' 1169 PREFIX="${SHELLSPEC_WORKDIR}/repo/sub-2" 1170 result() { 1171 %text:expand 1172 #|$ git -C ${PREFIX} config --local diff.age.binary true 1173 #|$ git -C ${PREFIX} config --local diff.age.textconv age -d -i id 1174 } 1175 When call cmd_gitconfig 1176 The status should be success 1177 The output should be blank 1178 The error should equal "$(result)" 1179 The contents of file "${PREFIX}/.gitattributes" should equal '*.age diff=age' 1180 End 1181 1182 It 'aborts without a git repository' 1183 PREFIX="${SHELLSPEC_WORKDIR}/repo/prefix" 1184 When run cmd_gitconfig 1185 The output should be blank 1186 The error should equal 'The store is not a git repository.' 1187 The status should equal 1 1188 End 1189 End 1190 1191 Describe 'cmd_grep' 1192 COMMAND=grep 1193 PREFIX="${SHELLSPEC_WORKDIR}" 1194 1195 It 'uses the argument list directly' 1196 When call cmd_grep -i pattern 1197 The status should be success 1198 The output should be blank 1199 The error should equal '$ do_grep -i pattern' 1200 End 1201 1202 It 'reports a lack of argument' 1203 cat() { @cat; } 1204 When run cmd_grep 1205 The output should be blank 1206 The error should equal 'Usage: prg grep [GREP_OPTIONS] search-regex' 1207 The status should equal 1 1208 End 1209 End 1210 1211 Describe 'cmd_help' 1212 COMMAND=help 1213 1214 It 'displays version and usage' 1215 cmd_usage() { mocklog cmd_usage "$@"; } 1216 cmd_version() { mocklog cmd_version "$@"; } 1217 result() { 1218 %text | @sed 's/\$$//' 1219 #|$ cmd_version 1220 #|$ cmd_usage $ 1221 } 1222 When call cmd_help 1223 The status should be success 1224 The output should be blank 1225 The error should equal "$(result)" 1226 End 1227 End 1228 1229 Describe 'cmd_init' 1230 COMMAND=init 1231 1232 It 'initializes the whole store' 1233 result() { 1234 %text | @sed 's/\$$//' 1235 #|$ check_sneaky_path $ 1236 #|$ do_init recipient-1 recipient-2 1237 #|DECISION=default 1238 #|OVERWRITE=yes 1239 } 1240 When call cmd_init recipient-1 recipient-2 1241 The status should be success 1242 The output should be blank 1243 The error should equal "$(result)" 1244 End 1245 1246 It 'initializes the whole store conservatively with a long option' 1247 result() { 1248 %text | @sed 's/\$$//' 1249 #|$ check_sneaky_path $ 1250 #|$ do_init recipient-1 recipient-2 1251 #|DECISION=keep 1252 #|OVERWRITE=yes 1253 } 1254 When call cmd_init --keep recipient-1 recipient-2 1255 The status should be success 1256 The output should be blank 1257 The error should equal "$(result)" 1258 End 1259 1260 It 'initializes the whole store conservatively with a short option' 1261 result() { 1262 %text | @sed 's/\$$//' 1263 #|$ check_sneaky_path $ 1264 #|$ do_init recipient-1 recipient-2 1265 #|DECISION=keep 1266 #|OVERWRITE=yes 1267 } 1268 When call cmd_init -k recipient-1 recipient-2 1269 The status should be success 1270 The output should be blank 1271 The error should equal "$(result)" 1272 End 1273 1274 It 'initializes the whole store interactively with a long option' 1275 result() { 1276 %text | @sed 's/\$$//' 1277 #|$ check_sneaky_path $ 1278 #|$ do_init recipient-1 recipient-2 1279 #|DECISION=interactive 1280 #|OVERWRITE=yes 1281 } 1282 When call cmd_init --interactive recipient-1 recipient-2 1283 The status should be success 1284 The output should be blank 1285 The error should equal "$(result)" 1286 End 1287 1288 It 'initializes the whole store interactively with a short option' 1289 result() { 1290 %text | @sed 's/\$$//' 1291 #|$ check_sneaky_path $ 1292 #|$ do_init recipient-1 recipient-2 1293 #|DECISION=interactive 1294 #|OVERWRITE=yes 1295 } 1296 When call cmd_init -i recipient-1 recipient-2 1297 The status should be success 1298 The output should be blank 1299 The error should equal "$(result)" 1300 End 1301 1302 It 'initializes a subdirectory with a collapsed long option' 1303 result() { 1304 %text 1305 #|$ check_sneaky_path sub 1306 #|$ do_init sub recipient 1307 #|DECISION=default 1308 #|OVERWRITE=yes 1309 } 1310 When call cmd_init --path=sub recipient 1311 The status should be success 1312 The output should be blank 1313 The error should equal "$(result)" 1314 End 1315 1316 It 'initializes a subdirectory with an expanded long option' 1317 result() { 1318 %text 1319 #|$ check_sneaky_path sub 1320 #|$ do_init sub recipient 1321 #|DECISION=default 1322 #|OVERWRITE=yes 1323 } 1324 When call cmd_init --path sub recipient 1325 The status should be success 1326 The output should be blank 1327 The error should equal "$(result)" 1328 End 1329 1330 It 'initializes a subdirectory with a collapsed short option' 1331 result() { 1332 %text 1333 #|$ check_sneaky_path sub 1334 #|$ do_init sub recipient 1335 #|DECISION=default 1336 #|OVERWRITE=yes 1337 } 1338 When call cmd_init -psub recipient 1339 The status should be success 1340 The output should be blank 1341 The error should equal "$(result)" 1342 End 1343 1344 It 'initializes a subdirectory with an expanded short option' 1345 result() { 1346 %text 1347 #|$ check_sneaky_path sub 1348 #|$ do_init sub recipient 1349 #|DECISION=default 1350 #|OVERWRITE=yes 1351 } 1352 When call cmd_init -p sub recipient 1353 The status should be success 1354 The output should be blank 1355 The error should equal "$(result)" 1356 End 1357 1358 It 'interactively initializes a directory with collapsed short options' 1359 result() { 1360 %text 1361 #|$ check_sneaky_path sub 1362 #|$ do_init sub recipient 1363 #|DECISION=interactive 1364 #|OVERWRITE=yes 1365 } 1366 When call cmd_init -ipsub recipient 1367 The status should be success 1368 The output should be blank 1369 The error should equal "$(result)" 1370 End 1371 1372 It 'conservatively initializes a directory with long options' 1373 result() { 1374 %text 1375 #|$ check_sneaky_path sub 1376 #|$ do_init sub recipient 1377 #|DECISION=keep 1378 #|OVERWRITE=yes 1379 } 1380 When call cmd_init --path sub --keep recipient 1381 The status should be success 1382 The output should be blank 1383 The error should equal "$(result)" 1384 End 1385 1386 It 'de-initializes a subdirectory' 1387 result() { 1388 %text 1389 #|$ check_sneaky_path sub 1390 #|$ do_deinit sub 1391 #|DECISION=default 1392 } 1393 When call cmd_init -p sub '' 1394 The status should be success 1395 The output should be blank 1396 The error should equal "$(result)" 1397 End 1398 1399 It 'supports recipients starting with dash' 1400 result() { 1401 %text | @sed 's/\$$//' 1402 #|$ check_sneaky_path $ 1403 #|$ do_init -recipient 1404 #|DECISION=default 1405 #|OVERWRITE=yes 1406 } 1407 When call cmd_init -- -recipient 1408 The status should be success 1409 The output should be blank 1410 The error should equal "$(result)" 1411 End 1412 1413 usage_text() { %text 1414 #|Usage: prg init [--interactive,-i | --keep,-k ] 1415 #| [--path=subfolder,-p subfolder] age-recipient ... 1416 } 1417 1418 It 'reports a bad option' 1419 cat() { @cat; } 1420 When run cmd_init -q arg 1421 The output should be blank 1422 The error should equal "$(usage_text)" 1423 The status should equal 1 1424 End 1425 1426 It 'reports conflicting options (`-i` then `-k`)' 1427 cat() { @cat; } 1428 When run cmd_init -ik arg 1429 The output should be blank 1430 The error should equal "$(usage_text)" 1431 The status should equal 1 1432 End 1433 1434 It 'reports conflicting options (`-k` then `-i`)' 1435 cat() { @cat; } 1436 When run cmd_init --keep --interactive arg 1437 The output should be blank 1438 The error should equal "$(usage_text)" 1439 The status should equal 1 1440 End 1441 1442 It 'reports a missing recipient' 1443 cat() { @cat; } 1444 When run cmd_init -p sub 1445 The output should be blank 1446 The error should equal "$(usage_text)" 1447 The status should equal 1 1448 End 1449 1450 It 'reports a missing path' 1451 cat() { @cat; } 1452 When run cmd_init -p 1453 The output should be blank 1454 The error should equal "$(usage_text)" 1455 The status should equal 1 1456 End 1457 1458 It 'reports a lack of argument' 1459 cat() { @cat; } 1460 When run cmd_init 1461 The output should be blank 1462 The error should equal "$(usage_text)" 1463 The status should equal 1 1464 End 1465 End 1466 1467 Describe 'cmd_insert' 1468 COMMAND=insert 1469 1470 It 'inserts a few new entries' 1471 result() { 1472 %text 1473 #|$ check_sneaky_path secret1 1474 #|$ check_sneaky_path secret2 1475 #|$ do_insert secret1 1476 #|ECHO=no 1477 #|MULTILINE=no 1478 #|OVERWRITE=no 1479 #|$ do_insert secret2 1480 #|ECHO=no 1481 #|MULTILINE=no 1482 #|OVERWRITE=no 1483 } 1484 When call cmd_insert secret1 secret2 1485 The status should be success 1486 The output should be blank 1487 The error should equal "$(result)" 1488 End 1489 1490 It 'inserts a new flag-like entry' 1491 result() { 1492 %text 1493 #|$ check_sneaky_path -c 1494 #|$ do_insert -c 1495 #|ECHO=no 1496 #|MULTILINE=no 1497 #|OVERWRITE=no 1498 } 1499 When call cmd_insert -- -c 1500 The status should be success 1501 The output should be blank 1502 The error should equal "$(result)" 1503 End 1504 1505 It 'inserts a new entry with echo (short option)' 1506 result() { 1507 %text 1508 #|$ check_sneaky_path secret 1509 #|$ do_insert secret 1510 #|ECHO=yes 1511 #|MULTILINE=no 1512 #|OVERWRITE=no 1513 } 1514 When call cmd_insert -e secret 1515 The status should be success 1516 The output should be blank 1517 The error should equal "$(result)" 1518 End 1519 1520 It 'inserts a new entry with echo (long option)' 1521 result() { 1522 %text 1523 #|$ check_sneaky_path secret 1524 #|$ do_insert secret 1525 #|ECHO=yes 1526 #|MULTILINE=no 1527 #|OVERWRITE=no 1528 } 1529 When call cmd_insert --echo secret 1530 The status should be success 1531 The output should be blank 1532 The error should equal "$(result)" 1533 End 1534 1535 It 'forcefully inserts a new entry with echo (short option)' 1536 result() { 1537 %text 1538 #|$ check_sneaky_path secret 1539 #|$ do_insert secret 1540 #|ECHO=yes 1541 #|MULTILINE=no 1542 #|OVERWRITE=yes 1543 } 1544 When call cmd_insert -fe secret 1545 The status should be success 1546 The output should be blank 1547 The error should equal "$(result)" 1548 End 1549 1550 It 'forcefully inserts a new entry with echo (short options)' 1551 result() { 1552 %text 1553 #|$ check_sneaky_path secret 1554 #|$ do_insert secret 1555 #|ECHO=yes 1556 #|MULTILINE=no 1557 #|OVERWRITE=yes 1558 } 1559 When call cmd_insert -e -f secret 1560 The status should be success 1561 The output should be blank 1562 The error should equal "$(result)" 1563 End 1564 1565 It 'forcefully inserts a new entry with echo (long option)' 1566 result() { 1567 %text 1568 #|$ check_sneaky_path secret 1569 #|$ do_insert secret 1570 #|ECHO=yes 1571 #|MULTILINE=no 1572 #|OVERWRITE=yes 1573 } 1574 When call cmd_insert --force --echo secret 1575 The status should be success 1576 The output should be blank 1577 The error should equal "$(result)" 1578 End 1579 1580 It 'inserts a new multiline entry (short option)' 1581 result() { 1582 %text 1583 #|$ check_sneaky_path secret 1584 #|$ do_insert secret 1585 #|ECHO=no 1586 #|MULTILINE=yes 1587 #|OVERWRITE=no 1588 } 1589 When call cmd_insert -m secret 1590 The status should be success 1591 The output should be blank 1592 The error should equal "$(result)" 1593 End 1594 1595 It 'inserts a new multiline entry (long option)' 1596 result() { 1597 %text 1598 #|$ check_sneaky_path secret 1599 #|$ do_insert secret 1600 #|ECHO=no 1601 #|MULTILINE=yes 1602 #|OVERWRITE=no 1603 } 1604 When call cmd_insert --multiline secret 1605 The status should be success 1606 The output should be blank 1607 The error should equal "$(result)" 1608 End 1609 1610 It 'forcefully inserts a new multiline entry (short option)' 1611 result() { 1612 %text 1613 #|$ check_sneaky_path secret 1614 #|$ do_insert secret 1615 #|ECHO=no 1616 #|MULTILINE=yes 1617 #|OVERWRITE=yes 1618 } 1619 When call cmd_insert -mf secret 1620 The status should be success 1621 The output should be blank 1622 The error should equal "$(result)" 1623 End 1624 1625 It 'forcefully inserts a new multiline entry (short options)' 1626 result() { 1627 %text 1628 #|$ check_sneaky_path secret 1629 #|$ do_insert secret 1630 #|ECHO=no 1631 #|MULTILINE=yes 1632 #|OVERWRITE=yes 1633 } 1634 When call cmd_insert -m -f secret 1635 The status should be success 1636 The output should be blank 1637 The error should equal "$(result)" 1638 End 1639 1640 It 'forcefully inserts a new multiline entry (long option)' 1641 result() { 1642 %text 1643 #|$ check_sneaky_path secret 1644 #|$ do_insert secret 1645 #|ECHO=no 1646 #|MULTILINE=yes 1647 #|OVERWRITE=yes 1648 } 1649 When call cmd_insert --force --multiline secret 1650 The status should be success 1651 The output should be blank 1652 The error should equal "$(result)" 1653 End 1654 1655 It 'reports a bad option' 1656 cat() { @cat; } 1657 When run cmd_insert -u secret 1658 The output should be blank 1659 The error should equal \ 1660 'Usage: prg insert [--echo,-e | --multiline,-m] [--force,-f] pass-name' 1661 The status should equal 1 1662 End 1663 1664 It 'reports incompatible long options' 1665 cat() { @cat; } 1666 When run cmd_insert --multiline --echo secret 1667 The output should be blank 1668 The error should equal \ 1669 'Usage: prg insert [--echo,-e | --multiline,-m] [--force,-f] pass-name' 1670 The status should equal 1 1671 End 1672 1673 It 'reports incompatible short options' 1674 cat() { @cat; } 1675 When run cmd_insert -em secret 1676 The output should be blank 1677 The error should equal \ 1678 'Usage: prg insert [--echo,-e | --multiline,-m] [--force,-f] pass-name' 1679 The status should equal 1 1680 End 1681 1682 It 'reports a lack of argument' 1683 cat() { @cat; } 1684 When run cmd_insert 1685 The output should be blank 1686 The error should equal \ 1687 'Usage: prg insert [--echo,-e | --multiline,-m] [--force,-f] pass-name' 1688 The status should equal 1 1689 End 1690 End 1691 1692 Describe 'cmd_list_or_show' 1693 COMMAND= 1694 1695 It 'lists the whole store as a list' 1696 result() { 1697 %text | @sed 's/\$$//' 1698 #|$ do_list_or_show $ 1699 #|LIST_VIEW=yes 1700 #|SELECTED_LINE=1 1701 #|SHOW=text 1702 } 1703 When call cmd_list_or_show -r 1704 The status should be success 1705 The output should be blank 1706 The error should equal "$(result)" 1707 End 1708 1709 It 'lists the whole store as a tree' 1710 result() { 1711 %text | @sed 's/\$$//' 1712 #|$ do_list_or_show $ 1713 #|LIST_VIEW=no 1714 #|SELECTED_LINE=1 1715 #|SHOW=text 1716 } 1717 When call cmd_list_or_show 1718 The status should be success 1719 The output should be blank 1720 The error should equal "$(result)" 1721 End 1722 1723 It 'shows multiple entries' 1724 result() { 1725 %text 1726 #|$ check_sneaky_path arg1 1727 #|$ check_sneaky_path arg2 1728 #|$ check_sneaky_path arg3 1729 #|$ do_list_or_show arg1 1730 #|LIST_VIEW=no 1731 #|SELECTED_LINE=1 1732 #|SHOW=text 1733 #|$ do_list_or_show arg2 1734 #|LIST_VIEW=no 1735 #|SELECTED_LINE=1 1736 #|SHOW=text 1737 #|$ do_list_or_show arg3 1738 #|LIST_VIEW=no 1739 #|SELECTED_LINE=1 1740 #|SHOW=text 1741 } 1742 When call cmd_list_or_show arg1 arg2 arg3 1743 The status should be success 1744 The output should be blank 1745 The error should equal "$(result)" 1746 End 1747 1748 It 'shows a flag-like entry' 1749 result() { 1750 %text 1751 #|$ check_sneaky_path -c 1752 #|$ do_list_or_show -c 1753 #|LIST_VIEW=no 1754 #|SELECTED_LINE=1 1755 #|SHOW=text 1756 } 1757 When call cmd_list_or_show -- -c 1758 The status should be success 1759 The output should be blank 1760 The error should equal "$(result)" 1761 End 1762 1763 It 'copies an entry into the clipboard (short option)' 1764 result() { 1765 %text 1766 #|$ check_sneaky_path arg 1767 #|$ do_list_or_show arg 1768 #|LIST_VIEW=no 1769 #|SELECTED_LINE=1 1770 #|SHOW=clip 1771 } 1772 When call cmd_list_or_show -c arg 1773 The status should be success 1774 The output should be blank 1775 The error should equal "$(result)" 1776 End 1777 1778 It 'copies an entry into the clipboard (long option)' 1779 result() { 1780 %text 1781 #|$ check_sneaky_path arg 1782 #|$ do_list_or_show arg 1783 #|LIST_VIEW=no 1784 #|SELECTED_LINE=1 1785 #|SHOW=clip 1786 } 1787 When call cmd_list_or_show --clip arg 1788 The status should be success 1789 The output should be blank 1790 The error should equal "$(result)" 1791 End 1792 1793 It 'copies a line of an entry into the clipboard (short option)' 1794 result() { 1795 %text 1796 #|$ check_sneaky_path arg 1797 #|$ do_list_or_show arg 1798 #|LIST_VIEW=no 1799 #|SELECTED_LINE=2 1800 #|SHOW=clip 1801 } 1802 When call cmd_list_or_show -c2 arg 1803 The status should be success 1804 The output should be blank 1805 The error should equal "$(result)" 1806 End 1807 1808 It 'copies a line of an entry into the clipboard (short option)' 1809 result() { 1810 %text 1811 #|$ check_sneaky_path arg 1812 #|$ do_list_or_show arg 1813 #|LIST_VIEW=no 1814 #|SELECTED_LINE=2 1815 #|SHOW=clip 1816 } 1817 When call cmd_list_or_show --clip=2 arg 1818 The status should be success 1819 The output should be blank 1820 The error should equal "$(result)" 1821 End 1822 1823 It 'shows an entry as a QR-code (short option)' 1824 result() { 1825 %text 1826 #|$ check_sneaky_path arg 1827 #|$ do_list_or_show arg 1828 #|LIST_VIEW=no 1829 #|SELECTED_LINE=1 1830 #|SHOW=qrcode 1831 } 1832 When call cmd_list_or_show -q arg 1833 The status should be success 1834 The output should be blank 1835 The error should equal "$(result)" 1836 End 1837 1838 It 'shows an entry as a QR-code (long option)' 1839 result() { 1840 %text 1841 #|$ check_sneaky_path arg 1842 #|$ do_list_or_show arg 1843 #|LIST_VIEW=no 1844 #|SELECTED_LINE=1 1845 #|SHOW=qrcode 1846 } 1847 When call cmd_list_or_show --qrcode arg 1848 The status should be success 1849 The output should be blank 1850 The error should equal "$(result)" 1851 End 1852 1853 It 'shows the line of an entry as a QR-code (short option)' 1854 result() { 1855 %text 1856 #|$ check_sneaky_path arg 1857 #|$ do_list_or_show arg 1858 #|LIST_VIEW=no 1859 #|SELECTED_LINE=3 1860 #|SHOW=qrcode 1861 } 1862 When call cmd_list_or_show -q3 arg 1863 The status should be success 1864 The output should be blank 1865 The error should equal "$(result)" 1866 End 1867 1868 It 'shows the line of an entry as a QR-code (long option)' 1869 result() { 1870 %text 1871 #|$ check_sneaky_path arg 1872 #|$ do_list_or_show arg 1873 #|LIST_VIEW=no 1874 #|SELECTED_LINE=3 1875 #|SHOW=qrcode 1876 } 1877 When call cmd_list_or_show --qrcode=3 arg 1878 The status should be success 1879 The output should be blank 1880 The error should equal "$(result)" 1881 End 1882 1883 It 'shows an entry as a raw list (shot option)' 1884 result() { 1885 %text 1886 #|$ check_sneaky_path arg 1887 #|$ do_list_or_show arg 1888 #|LIST_VIEW=yes 1889 #|SELECTED_LINE=1 1890 #|SHOW=text 1891 } 1892 When call cmd_list_or_show -r arg 1893 The status should be success 1894 The output should be blank 1895 The error should equal "$(result)" 1896 End 1897 1898 It 'shows an entry as a raw list (long option)' 1899 result() { 1900 %text 1901 #|$ check_sneaky_path arg 1902 #|$ do_list_or_show arg 1903 #|LIST_VIEW=yes 1904 #|SELECTED_LINE=1 1905 #|SHOW=text 1906 } 1907 When call cmd_list_or_show --raw arg 1908 The status should be success 1909 The output should be blank 1910 The error should equal "$(result)" 1911 End 1912 1913 It 'reports incompatible show options' 1914 cat() { @cat; } 1915 result() { %text 1916 #|Usage: prg [list] [--raw,-r] [subfolder] 1917 #| prg [show] [--clip[=line-number],-c[line-number] | 1918 #| --qrcode[=line-number],-q[line-number]] pass-name 1919 } 1920 When run cmd_list_or_show -q -c arg 1921 The output should be blank 1922 The error should equal "$(result)" 1923 The status should equal 1 1924 End 1925 1926 It 'reports a bad option for both commands' 1927 cat() { @cat; } 1928 result() { %text 1929 #|Usage: prg [list] [--raw,-r] [subfolder] 1930 #| prg [show] [--clip[=line-number],-c[line-number] | 1931 #| --qrcode[=line-number],-q[line-number]] pass-name 1932 } 1933 When run cmd_list_or_show -f arg 1934 The output should be blank 1935 The error should equal "$(result)" 1936 The status should equal 1 1937 End 1938 1939 It 'reports a bad option for list command' 1940 COMMAND=list 1941 cat() { @cat; } 1942 result() { %text 1943 #|Usage: prg [list] [--raw,-r] [subfolder] 1944 } 1945 When run cmd_list_or_show -f arg 1946 The output should be blank 1947 The error should equal "$(result)" 1948 The status should equal 1 1949 End 1950 1951 It 'reports a bad option for show command' 1952 COMMAND=show 1953 cat() { @cat; } 1954 result() { %text 1955 #|Usage: prg [show] [--clip[=line-number],-c[line-number] | 1956 #| --qrcode[=line-number],-q[line-number]] pass-name 1957 } 1958 When run cmd_list_or_show -f arg 1959 The output should be blank 1960 The error should equal "$(result)" 1961 The status should equal 1 1962 End 1963 End 1964 1965 Describe 'cmd_move' 1966 COMMAND=move 1967 1968 It 'moves multiple files' 1969 result() { 1970 %text 1971 #|$ check_sneaky_path src1 1972 #|$ check_sneaky_path src2 1973 #|$ check_sneaky_path src3 1974 #|$ check_sneaky_path dest 1975 #|$ do_copy_move src1 dest/ 1976 #|ACTION=Move 1977 #|DECISION=default 1978 #|OVERWRITE=no 1979 #|SCM_ACTION=scm_mv 1980 #|$ do_copy_move src2 dest/ 1981 #|ACTION=Move 1982 #|DECISION=default 1983 #|OVERWRITE=no 1984 #|SCM_ACTION=scm_mv 1985 #|$ do_copy_move src3 dest/ 1986 #|ACTION=Move 1987 #|DECISION=default 1988 #|OVERWRITE=no 1989 #|SCM_ACTION=scm_mv 1990 } 1991 When call cmd_move src1 src2 src3 dest 1992 The status should be success 1993 The output should be blank 1994 The error should equal "$(result)" 1995 End 1996 1997 It 'moves forcefully with a long option' 1998 result() { 1999 %text 2000 #|$ check_sneaky_path src 2001 #|$ check_sneaky_path dest 2002 #|$ do_copy_move src dest 2003 #|ACTION=Move 2004 #|DECISION=default 2005 #|OVERWRITE=yes 2006 #|SCM_ACTION=scm_mv 2007 } 2008 When call cmd_move --force src dest 2009 The status should be success 2010 The output should be blank 2011 The error should equal "$(result)" 2012 End 2013 2014 It 'moves forcefully with a short option' 2015 result() { 2016 %text 2017 #|$ check_sneaky_path src 2018 #|$ check_sneaky_path dest 2019 #|$ do_copy_move src dest 2020 #|ACTION=Move 2021 #|DECISION=default 2022 #|OVERWRITE=yes 2023 #|SCM_ACTION=scm_mv 2024 } 2025 When call cmd_move -f src dest 2026 The status should be success 2027 The output should be blank 2028 The error should equal "$(result)" 2029 End 2030 2031 It 'always reencrypts with a long option' 2032 result() { 2033 %text 2034 #|$ check_sneaky_path src 2035 #|$ check_sneaky_path dest 2036 #|$ do_copy_move src dest 2037 #|ACTION=Move 2038 #|DECISION=force 2039 #|OVERWRITE=no 2040 #|SCM_ACTION=scm_mv 2041 } 2042 When call cmd_move --reencrypt src dest 2043 The status should be success 2044 The output should be blank 2045 The error should equal "$(result)" 2046 End 2047 2048 It 'always reencrypts with a short option' 2049 result() { 2050 %text 2051 #|$ check_sneaky_path src 2052 #|$ check_sneaky_path dest 2053 #|$ do_copy_move src dest 2054 #|ACTION=Move 2055 #|DECISION=force 2056 #|OVERWRITE=no 2057 #|SCM_ACTION=scm_mv 2058 } 2059 When call cmd_move -e src dest 2060 The status should be success 2061 The output should be blank 2062 The error should equal "$(result)" 2063 End 2064 2065 It 'interactively reencrypts with a long option' 2066 result() { 2067 %text 2068 #|$ check_sneaky_path src 2069 #|$ check_sneaky_path dest 2070 #|$ do_copy_move src dest 2071 #|ACTION=Move 2072 #|DECISION=interactive 2073 #|OVERWRITE=no 2074 #|SCM_ACTION=scm_mv 2075 } 2076 When call cmd_move --interactive src dest 2077 The status should be success 2078 The output should be blank 2079 The error should equal "$(result)" 2080 End 2081 2082 It 'interactively reencrypts with a short option' 2083 result() { 2084 %text 2085 #|$ check_sneaky_path src 2086 #|$ check_sneaky_path dest 2087 #|$ do_copy_move src dest 2088 #|ACTION=Move 2089 #|DECISION=interactive 2090 #|OVERWRITE=no 2091 #|SCM_ACTION=scm_mv 2092 } 2093 When call cmd_move -i src dest 2094 The status should be success 2095 The output should be blank 2096 The error should equal "$(result)" 2097 End 2098 2099 It 'never reencrypts with a long option' 2100 result() { 2101 %text 2102 #|$ check_sneaky_path src 2103 #|$ check_sneaky_path dest 2104 #|$ do_copy_move src dest 2105 #|ACTION=Move 2106 #|DECISION=keep 2107 #|OVERWRITE=no 2108 #|SCM_ACTION=scm_mv 2109 } 2110 When call cmd_move --keep src dest 2111 The status should be success 2112 The output should be blank 2113 The error should equal "$(result)" 2114 End 2115 2116 It 'never reencrypts with a short option' 2117 result() { 2118 %text 2119 #|$ check_sneaky_path src 2120 #|$ check_sneaky_path dest 2121 #|$ do_copy_move src dest 2122 #|ACTION=Move 2123 #|DECISION=keep 2124 #|OVERWRITE=no 2125 #|SCM_ACTION=scm_mv 2126 } 2127 When call cmd_move -k src dest 2128 The status should be success 2129 The output should be blank 2130 The error should equal "$(result)" 2131 End 2132 2133 It 'moves a file named like a flag' 2134 result() { 2135 %text 2136 #|$ check_sneaky_path -s 2137 #|$ check_sneaky_path dest 2138 #|$ do_copy_move -s dest 2139 #|ACTION=Move 2140 #|DECISION=default 2141 #|OVERWRITE=no 2142 #|SCM_ACTION=scm_mv 2143 } 2144 When call cmd_move -- -s dest 2145 The status should be success 2146 The output should be blank 2147 The error should equal "$(result)" 2148 End 2149 2150 usage_text() { %text 2151 #|Usage: prg move [--reencrypt,-e | --interactive,-i | --keep,-k ] 2152 #| [--force,-f] old-path new-path 2153 } 2154 2155 It 'reports a bad option' 2156 cat() { @cat; } 2157 When run cmd_move -s arg 2158 The output should be blank 2159 The error should equal "$(usage_text)" 2160 The status should equal 1 2161 End 2162 2163 It 'reports incompatible re-encryption options (-e and -i)' 2164 cat() { @cat; } 2165 When run cmd_move -ei src dest 2166 The output should be blank 2167 The error should equal "$(usage_text)" 2168 The status should equal 1 2169 End 2170 2171 It 'reports incompatible re-encryption options (-i and -k)' 2172 cat() { @cat; } 2173 When run cmd_move -ik src dest 2174 The output should be blank 2175 The error should equal "$(usage_text)" 2176 The status should equal 1 2177 End 2178 2179 It 'reports incompatible re-encryption options (-k and -e)' 2180 cat() { @cat; } 2181 When run cmd_move -ke src dest 2182 The output should be blank 2183 The error should equal "$(usage_text)" 2184 The status should equal 1 2185 End 2186 2187 It 'reports a lack of argument' 2188 cat() { @cat; } 2189 When run cmd_move src 2190 The output should be blank 2191 The error should equal "$(usage_text)" 2192 The status should equal 1 2193 End 2194 End 2195 2196 Describe 'cmd_random' 2197 COMMAND=generate 2198 GENERATED_LENGTH=25 2199 2200 random_chars() { mocklog random_chars "$@"; } 2201 2202 It 'generates random characters with default parameters' 2203 When run cmd_random 2204 The status should be success 2205 The error should equal \ 2206 "$ random_chars ${GENERATED_LENGTH} ${CHARACTER_SET}" 2207 End 2208 2209 It 'generates random characters with default character set' 2210 When run cmd_random 8 2211 The status should be success 2212 The error should equal "$ random_chars 8 ${CHARACTER_SET}" 2213 End 2214 2215 It 'generates random characters with the given arguments' 2216 When run cmd_random 8 a-z 2217 The status should be success 2218 The error should equal "$ random_chars 8 a-z" 2219 End 2220 2221 It 'reports too many arguments' 2222 cat() { @cat; } 2223 When run cmd_random 1 2 3 2224 The output should be blank 2225 The error should equal 'Usage: prg random [pass-length [character-set]]' 2226 The status should equal 1 2227 End 2228 End 2229 2230 Describe 'cmd_reencrypt' 2231 COMMAND=reencrypt 2232 2233 It 're-encrypts multiple files and directories' 2234 result() { 2235 %text 2236 #|$ check_sneaky_path file-1 2237 #|$ check_sneaky_path dir/ 2238 #|$ check_sneaky_path sub/file-2 2239 #|$ do_reencrypt file-1 2240 #|DECISION=default 2241 #|$ do_reencrypt dir/ 2242 #|DECISION=default 2243 #|$ do_reencrypt sub/file-2 2244 #|DECISION=default 2245 } 2246 When call cmd_reencrypt file-1 dir/ sub/file-2 2247 The status should be success 2248 The output should be blank 2249 The error should equal "$(result)" 2250 End 2251 2252 It 'interactively re-encrypts with a long option' 2253 result() { 2254 %text 2255 #|$ check_sneaky_path arg 2256 #|$ do_reencrypt arg 2257 #|DECISION=interactive 2258 } 2259 When call cmd_reencrypt --interactive arg 2260 The status should be success 2261 The output should be blank 2262 The error should equal "$(result)" 2263 End 2264 2265 It 'interactively re-encrypts with a short option' 2266 result() { 2267 %text 2268 #|$ check_sneaky_path arg 2269 #|$ do_reencrypt arg 2270 #|DECISION=interactive 2271 } 2272 When call cmd_reencrypt -i arg 2273 The status should be success 2274 The output should be blank 2275 The error should equal "$(result)" 2276 End 2277 2278 It 're-encrypts a file named like a flag' 2279 result() { 2280 %text 2281 #|$ check_sneaky_path -s 2282 #|$ do_reencrypt -s 2283 #|DECISION=default 2284 } 2285 When call cmd_reencrypt -- -s 2286 The status should be success 2287 The output should be blank 2288 The error should equal "$(result)" 2289 End 2290 2291 usage_text() { %text 2292 #|Usage: prg reencrypt [--interactive,-i] pass-name|subfolder ... 2293 } 2294 2295 It 'reports a bad option' 2296 cat() { @cat; } 2297 When run cmd_reencrypt -s arg 2298 The status should equal 1 2299 The output should be blank 2300 The error should equal "$(usage_text)" 2301 End 2302 2303 It 'reports a lack of argument' 2304 cat() { @cat; } 2305 When run cmd_reencrypt 2306 The status should equal 1 2307 The output should be blank 2308 The error should equal "$(usage_text)" 2309 End 2310 End 2311 2312 Describe 'cmd_usage' 2313 COMMAND=usage 2314 CLIP_TIME='$CLIP_TIME' 2315 GENERATED_LENGTH='$GENERATED_LENGTH' 2316 cat() { @cat; } 2317 2318 It 'displays a human-reable usage string' 2319 When call cmd_usage 2320 The status should be success 2321 The first line of output should equal 'Usage:' 2322 The error should be blank 2323 End 2324 2325 It 'includes help about all commands' 2326 When call cmd_usage 2327 The status should be success 2328 The output should include 'prg copy' 2329 The output should include 'prg delete' 2330 The output should include 'prg edit' 2331 The output should include 'prg find' 2332 The output should include 'prg generate' 2333 The output should include 'prg git' 2334 The output should include 'prg gitconfig' 2335 The output should include 'prg grep' 2336 The output should include 'prg help' 2337 The output should include 'prg init' 2338 The output should include 'prg insert' 2339 The output should include 'prg [list]' 2340 The output should include 'prg move' 2341 The output should include 'prg random' 2342 The output should include 'prg reencrypt' 2343 The output should include 'prg [show]' 2344 The output should include 'prg version' 2345 End 2346 2347 It 'rejects unknown commands' 2348 When run cmd_usage '> ' foo 2349 The output should be blank 2350 The error should equal 'cmd_usage: unknown command "foo"' 2351 The status should equal 1 2352 End 2353 End 2354 2355 Describe 'cmd_version' 2356 COMMAND=version 2357 2358 It 'shows the version box' 2359 cat() { @cat; } 2360 result() { 2361 %text 2362 #|============================================== 2363 #|= pashage: age-backed POSIX password manager = 2364 #|= = 2365 #|= v* 2366 #|= = 2367 #|= Natasha Kerensikova = 2368 #|= = 2369 #|= Based on: = 2370 #|= password-store by Jason A. Donenfeld = 2371 #|= passage by Filippo Valsorda = 2372 #|= pash by Dylan Araps = 2373 #|============================================== 2374 } 2375 When call cmd_version 2376 The status should be success 2377 The output should match pattern "$(result)" 2378 End 2379 End 2380 End