#!/usr/bin/env bats init_repo() { local repo_dir="$1" local main_branch="$2" mkdir "$repo_dir" cd "$repo_dir" git init -b "$main_branch" git config user.email "john.doe@example.com" git config user.name "John Doe" echo ".git-check-assertions-cache" >>.gitignore git add .gitignore git commit -m "add .git-check-assertions-cache to gitignore" touch readme git add readme git commit -m "add readme" } setup() { set -euo pipefail bats_load_library bats-support bats_load_library bats-assert bats_load_library bats-file DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")" >/dev/null 2>&1 && pwd)" PATH="$DIR/../bin:$PATH" init_repo "$BATS_TEST_TMPDIR/repo" main } commit_with_assertion() { git commit --allow-empty -F - <<-EOF test \`\`\`git-check-assertions $1 \`\`\` EOF } @test "should not run any assertion blocks when on main" { commit_with_assertion "touch ../test" run git-check-assertions assert_success assert_file_not_exists ../test } @test "should print success after completing" { run git-check-assertions assert_success assert_output --partial "Success!" } @test "should refuse to run when the index has changes" { echo "staged" >>readme git add readme run git-check-assertions assert_failure assert_output --partial "Uncommitted changes. Refusing to run." } @test "should refuse to run when the working tree has changes" { echo "unstaged" >>readme run git-check-assertions assert_failure assert_output --partial "Uncommitted changes. Refusing to run." } @test "should refuse to run when there are untracked files" { echo "new" >untracked run git-check-assertions assert_failure assert_output --partial "Uncommitted changes. Refusing to run." } @test "should not run any assertion blocks from main when on a feature branch" { commit_with_assertion "touch ../test" git checkout -b feature git commit --allow-empty -m "feature" run git-check-assertions assert_success assert_file_not_exists ../test } @test "should not run any assertion blocks from master when on a feature branch" { init_repo "$BATS_TEST_TMPDIR/repo-master" master commit_with_assertion "touch ../test" git checkout -b feature git commit --allow-empty -m "feature" run git-check-assertions assert_success assert_file_not_exists ../test } @test "should run all succeeding assertion blocks on the feature branch and finally return to the original branch" { git checkout -b feature commit_with_assertion "touch ../test1" commit_with_assertion "touch ../test2" run git-check-assertions assert_success assert_file_exists ../test1 assert_file_exists ../test2 run git symbolic-ref --short HEAD assert_output "feature" } @test "multiple git-check-assertions blocks in one commit message run in order" { git checkout -b feature git commit --allow-empty -F - <<-EOF test \`\`\`git-check-assertions touch ../test1 \`\`\` \`\`\`git-check-assertions touch ../test2 \`\`\` EOF run git-check-assertions assert_success assert_file_exists ../test1 assert_file_exists ../test2 } @test "should restore the commit between assertion blocks in one commit message" { git checkout -b feature echo old >readme git add readme git commit -m "old" echo new >readme git add readme git commit -F - <<-EOF update \`\`\`git-check-assertions git checkout HEAD~ \`\`\` \`\`\`git-check-assertions grep new readme \`\`\` EOF run git-check-assertions assert_success } @test "should stop at the first failing assertion block and return to the original branch" { git checkout -b feature commit_with_assertion "touch ../test1 && exit 3" commit_with_assertion "touch ../test2" run git-check-assertions assert_failure assert_file_exists ../test1 assert_file_not_exists ../test2 run git symbolic-ref --short HEAD assert_output "feature" } @test "should restore worktree when finished" { git checkout -b feature commit_with_assertion 'echo blah >> readme' run git-check-assertions assert_success assert_size_zero readme } @test "should restore worktree between commits" { git checkout -b feature commit_with_assertion 'echo blah >> readme' commit_with_assertion 'cp readme ../test' run git-check-assertions assert_success assert_size_zero ../test } @test "should restore worktree after a failure" { git checkout -b feature commit_with_assertion $'echo blah >> readme\nexit 3' run git-check-assertions assert_failure assert_size_zero readme } @test "should restore index when finished" { git checkout -b feature commit_with_assertion $'echo blah >> readme\ngit add readme' run git-check-assertions assert_success assert_size_zero readme } @test "should restore index between commits" { git checkout -b feature commit_with_assertion $'echo blah >> readme\ngit add readme' commit_with_assertion 'cp readme ../test' run git-check-assertions assert_success assert_size_zero ../test } @test "should restore index after a failure" { git checkout -b feature commit_with_assertion $'echo blah >> readme\ngit add readme\nexit 3' run git-check-assertions assert_failure assert_size_zero readme } @test "should skip cached commits on subsequent runs" { git checkout -b feature commit_with_assertion "touch ../test" run git-check-assertions assert_success assert_file_exists ../test rm ../test run git-check-assertions assert_success assert_file_not_exists ../test } @test "should not cache failed commits" { git checkout -b feature commit_with_assertion "touch ../test && exit 3" run git-check-assertions assert_failure assert_file_exists ../test rm ../test run git-check-assertions assert_failure assert_file_exists ../test } @test "should skip cached commits when multiple commits are cached" { git checkout -b feature commit_with_assertion "touch ../test1" commit_with_assertion "touch ../test2" run git-check-assertions assert_success assert_file_exists ../test1 assert_file_exists ../test2 rm ../test1 ../test2 run git-check-assertions assert_success assert_file_not_exists ../test1 assert_file_not_exists ../test2 } @test "assertions should run against the version of the code inside of the commit" { git checkout -b feature echo commit1 >readme git add readme commit_with_assertion 'grep commit1 readme' echo commit2 >readme git add readme commit_with_assertion 'grep commit2 readme' run git-check-assertions assert_success } @test "you can use git checkout in an assertion to assert against a mixed version of the code" { git checkout -b feature echo hello >src echo 'grep hello src' >tests git add src tests git commit -m 'add src and tests' echo goodbye >src echo 'grep goodbye src' >tests git add src tests commit_with_assertion $'git checkout HEAD~ src\nrun bash tests\nassert_failure' run git-check-assertions assert_success assert_file_contains src goodbye } @test "assert_success should succeed if the executed command succeeded" { git checkout -b feature commit_with_assertion $'run exit 0\nassert_success' run git-check-assertions assert_success } @test "assert_success should fail if the executed command failed" { git checkout -b feature commit_with_assertion $'run exit 1\nassert_success' run git-check-assertions assert_failure assert_output --partial "Expected command to succeed, but it failed." } @test "assert_failure should succeed if the executed command failed" { git checkout -b feature commit_with_assertion $'run exit 1\nassert_failure' run git-check-assertions assert_success } @test "assert_failure should fail if the executed command succeeded" { git checkout -b feature commit_with_assertion $'run exit 0\nassert_failure' run git-check-assertions assert_failure assert_output --partial "Expected command to fail, but it succeeded." } @test "assert_output should succeed if the output matches the given string" { git checkout -b feature commit_with_assertion $'run echo hello\nassert_output hello' run git-check-assertions assert_success } @test "assert_output should fail if the output does not match the given string" { git checkout -b feature commit_with_assertion $'run echo hello\nassert_output goodbye' run git-check-assertions assert_failure assert_output --partial "Expected output to equal: goodbye" assert_output --partial "Actual output: hello" } @test "assert_output should also check stderr output" { git checkout -b feature commit_with_assertion $'run sh -c "echo err 1>&2"\nassert_output err' run git-check-assertions assert_success } @test "assert_output --partial should succeed if output contains the given string" { git checkout -b feature commit_with_assertion $'run echo hello\nassert_output --partial ell' run git-check-assertions assert_success } @test "assert_output --partial should fail if output does not contain the given string" { git checkout -b feature commit_with_assertion $'run echo hello\nassert_output --partial xyz' run git-check-assertions assert_failure assert_output --partial "Expected output to contain: xyz" assert_output --partial "Actual output: hello" } @test "run should print command output" { git checkout -b feature commit_with_assertion $'run sh -c "echo -n hello; echo -n world"\nassert_success' run git-check-assertions assert_success assert_output --partial "helloworld" }