From f89865921cb0d4780faf7e751fd3a038b7525c55 Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Fri, 18 Feb 2022 07:13:03 +0000 Subject: [PATCH] - Add approvals.bash testing library --- lib/bashly/commands/add.rb | 6 ++ lib/bashly/libraries.yml | 15 ++++ lib/bashly/library.rb | 5 +- lib/bashly/templates/test/approvals.bash | 93 ++++++++++++++++++++++++ lib/bashly/templates/test/approve | 20 +++++ spec/approvals/cli/add/help | 4 + spec/approvals/cli/add/test | 9 +++ spec/approvals/cli/generate/usage | 1 + spec/approvals/library/config-keys | 1 + spec/bashly/commands/add_spec.rb | 14 ++++ 10 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 lib/bashly/templates/test/approvals.bash create mode 100644 lib/bashly/templates/test/approve create mode 100644 spec/approvals/cli/add/test diff --git a/lib/bashly/commands/add.rb b/lib/bashly/commands/add.rb index 0dba7b8c..4376bd92 100644 --- a/lib/bashly/commands/add.rb +++ b/lib/bashly/commands/add.rb @@ -9,6 +9,7 @@ class Add < Base usage "bashly add colors [--force]" usage "bashly add yaml [--force]" usage "bashly add validations [--force]" + usage "bashly add test [--force]" usage "bashly add comp FORMAT [OUTPUT --force]" usage "bashly add (-h|--help)" @@ -23,6 +24,7 @@ class Add < Base command "colors", "Add standard functions for printing colorful and formatted text to the lib directory." command "yaml", "Add standard functions for reading YAML files to the lib directory." command "validations", "Add argument validation functions to the lib directory." + command "test", "Add approval testing." command "comp", "Generate a bash completions script or function." example "bashly add strings --force" @@ -55,6 +57,10 @@ def validations_command add_lib 'validations' end + def test_command + add_lib 'test' + end + def comp_command format = args['FORMAT'] output = args['OUTPUT'] diff --git a/lib/bashly/libraries.yml b/lib/bashly/libraries.yml index 7515e925..20641e6b 100644 --- a/lib/bashly/libraries.yml +++ b/lib/bashly/libraries.yml @@ -23,6 +23,21 @@ strings: - source: "templates/strings.yml" target: "%{user_source_dir}/bashly-strings.yml" +test: + files: + - source: "templates/test/approvals.bash" + target: "%{user_target_dir}/test/approvals.bash" + - source: "templates/test/approve" + target: "%{user_target_dir}/test/approve" + + post_install_message: | + Edit your tests in !txtgrn!test/approve!txtrst! and then run: + + !txtpur!$ ./test/approve!txtrst!" + + Docs: !undblu!https://github.com/DannyBen/approvals.bash + + validations: files: - source: "templates/lib/validations/validate_dir_exists.sh" diff --git a/lib/bashly/library.rb b/lib/bashly/library.rb index 6db49e3d..a6f9990e 100644 --- a/lib/bashly/library.rb +++ b/lib/bashly/library.rb @@ -57,7 +57,10 @@ def config end def target_file_args - { user_source_dir: Settings.source_dir } + { + user_source_dir: Settings.source_dir, + user_target_dir: Settings.target_dir + } end end end diff --git a/lib/bashly/templates/test/approvals.bash b/lib/bashly/templates/test/approvals.bash new file mode 100644 index 00000000..6c4e8fc0 --- /dev/null +++ b/lib/bashly/templates/test/approvals.bash @@ -0,0 +1,93 @@ +# approvals.bash v0.2.7 +# +# Interactive approval testing for Bash. +# https://github.com/DannyBen/approvals.bash +approve() { + local expected approval approval_file actual cmd + approvals_dir=${APPROVALS_DIR:=approvals} + + cmd=$1 + actual=$(eval "$cmd" 2>&1) + last_exit_code=$? + approval=$(printf "%b" "$cmd" | tr -s -c "[:alnum:]" _) + approval_file="$approvals_dir/${2:-"$approval"}" + + [[ -d "$approvals_dir" ]] || mkdir "$approvals_dir" + + if [[ -f "$approval_file" ]]; then + expected=$(cat "$approval_file") + else + echo "--- [$(blue "new: $cmd")] ---" + printf "%b\n" "$actual" + echo "--- [$(blue "new: $cmd")] ---" + expected="$actual" + user_approval "$cmd" "$actual" "$approval_file" + return + fi + + if [[ "$(printf "%b" "$actual")" = "$(printf "%b" "$expected")" ]]; then + green "PASS $cmd" + else + echo "--- [$(blue "diff: $cmd")] ---" + $diff_cmd <(printf "%b" "$expected\n") <(printf "%b" "$actual\n" ) | tail -n +4 + echo "--- [$(blue "diff: $cmd")] ---" + user_approval "$cmd" "$actual" "$approval_file" + fi +} + +describe() { + cyan "TEST $*" +} + +fail() { + red "FAIL $*" + exit 1 +} + +pass() { + green "PASS $*" + return 0 +} + +expect_exit_code() { + if [[ $last_exit_code == "$1" ]]; then + pass "exit $last_exit_code" + else + fail "Expected exit code $1, got $last_exit_code" + fi +} + +red() { printf "\e[31m%b\e[0m\n" "$*"; } +green() { printf "\e[32m%b\e[0m\n" "$*"; } +blue() { printf "\e[34m%b\e[0m\n" "$*"; } +magenta() { printf "\e[35m%b\e[0m\n" "$*"; } +cyan() { printf "\e[36m%b\e[0m\n" "$*"; } + +# Private + +user_approval() { + local cmd="$1" + local actual="$2" + local approval_file="$3" + + if [[ -v CI || -v GITHUB_ACTIONS ]]; then + fail "$cmd" + fi + + echo + printf "[A]pprove? \n" + response=$(bash -c "read -n 1 key; echo \$key") + printf "\r" + if [[ $response =~ [Aa] ]]; then + printf "%b\n" "$actual" > "$approval_file" + pass "$cmd" + else + fail "$cmd" + fi +} + +if diff --help | grep -- --color > /dev/null 2>&1; then + diff_cmd="diff --unified --color=always" +else + diff_cmd="diff --unified" +fi diff --git a/lib/bashly/templates/test/approve b/lib/bashly/templates/test/approve new file mode 100644 index 00000000..0d0ba84d --- /dev/null +++ b/lib/bashly/templates/test/approve @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# Run this from the root directory + +cd ./test || exit +source approvals.bash +PATH="$PATH:../" + +# Update me +cli=download + +# Tests +describe "root command" + approve "$cli" + approve "$cli --help" + +describe "some other command" + approve "$cli other" + approve "$cli other --help" + +# ...more tests... \ No newline at end of file diff --git a/spec/approvals/cli/add/help b/spec/approvals/cli/add/help index c4bbed62..cfec1deb 100644 --- a/spec/approvals/cli/add/help +++ b/spec/approvals/cli/add/help @@ -7,6 +7,7 @@ Usage: bashly add colors [--force] bashly add yaml [--force] bashly add validations [--force] + bashly add test [--force] bashly add comp FORMAT [OUTPUT --force] bashly add (-h|--help) @@ -32,6 +33,9 @@ Commands: validations Add argument validation functions to the lib directory. + test + Add approval testing. + comp Generate a bash completions script or function. diff --git a/spec/approvals/cli/add/test b/spec/approvals/cli/add/test new file mode 100644 index 00000000..a40f2fce --- /dev/null +++ b/spec/approvals/cli/add/test @@ -0,0 +1,9 @@ +created spec/tmp/test/approvals.bash +created spec/tmp/test/approve + +Edit your tests in test/approve and then run: + + $ ./test/approve" + +Docs: https://github.com/DannyBen/approvals.bash + diff --git a/spec/approvals/cli/generate/usage b/spec/approvals/cli/generate/usage index 152f0f0e..baab7b59 100644 --- a/spec/approvals/cli/generate/usage +++ b/spec/approvals/cli/generate/usage @@ -5,5 +5,6 @@ Usage: bashly add colors [--force] bashly add yaml [--force] bashly add validations [--force] + bashly add test [--force] bashly add comp FORMAT [OUTPUT --force] bashly add (-h|--help) diff --git a/spec/approvals/library/config-keys b/spec/approvals/library/config-keys index 866b3a3c..b60c60ee 100644 --- a/spec/approvals/library/config-keys +++ b/spec/approvals/library/config-keys @@ -4,6 +4,7 @@ - yaml - lib - strings +- test - validations - completions - completions_script diff --git a/spec/bashly/commands/add_spec.rb b/spec/bashly/commands/add_spec.rb index 296efb11..c2ec2bbc 100644 --- a/spec/bashly/commands/add_spec.rb +++ b/spec/bashly/commands/add_spec.rb @@ -99,6 +99,20 @@ end end + context "with test command" do + let(:lib_file) { "#{target_dir}/test/approvals.bash" } + + before do + reset_tmp_dir create_src: true + end + + it "copies the test folder to the user space" do + expect { subject.run %w[add test] }.to output_approval('cli/add/test') + expect(File).to exist(lib_file) + end + end + + context "with colors command" do let(:lib_file) { "#{source_dir}/lib/colors.sh" }