Skip to content

Commit

Permalink
Add scripts to verify exercises
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom committed Jan 5, 2025
1 parent 8142d38 commit 836bbd6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 2 deletions.
24 changes: 24 additions & 0 deletions bin/verify-exercises
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

# Synopsis:
# Verify that each exercise's example/exemplar solution passes the tests.
# You can either verify all exercises or a single exercise.

# Example: verify all exercises
# bin/verify-exercises

# Example: verify single exercise
# bin/verify-exercises two-fer

set -eo pipefail

die() { echo "$*" >&2; exit 1; }

required_tool() {
command -v "${1}" >/dev/null 2>&1 ||
die "${1} is required but not installed. Please install it and make sure it's in your PATH."
}

required_tool bb

bb test.clj "$@"
92 changes: 92 additions & 0 deletions bin/verify-exercises-in-docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env bash

# Synopsis:
# Verify that each exercise's example/exemplar solution passes the tests
# using the track's test runner Docker image.
# You can either verify all exercises or a single exercise.

# Example: verify all exercises in Docker
# bin/verify-exercises-in-docker

# Example: verify single exercise in Docker
# bin/verify-exercises-in-docker two-fer

set -eo pipefail

die() { echo "$*" >&2; exit 1; }

required_tool() {
command -v "${1}" >/dev/null 2>&1 ||
die "${1} is required but not installed. Please install it and make sure it's in your PATH."
}

required_tool docker

copy_example_or_examplar_to_solution() {
jq -c '[.files.solution, .files.exemplar // .files.example] | transpose | map({src: .[1], dst: .[0]}) | .[]' .meta/config.json \
| while read -r src_and_dst; do
cp "$(jq -r '.src' <<< "${src_and_dst}")" "$(jq -r '.dst' <<< "${src_and_dst}")"
done
}

pull_docker_image() {
# shellcheck disable=SC1083
docker pull exercism/clojure-test-runner ||
die $'Could not find the `exercism/clojure-test-runner` Docker image.\nCheck the test runner docs at https://exercism.org/docs/building/tooling/test-runners for more information.'
}

run_tests() {
local slug
slug="${1}"

# shellcheck disable=SC1083
docker run \
--rm \
--network none \
--read-only \
--mount type=bind,src="${PWD}",dst=/solution \
--mount type=bind,src="${PWD}",dst=/output \
--mount type=tmpfs,dst=/tmp \
exercism/clojure-test-runner "${slug}" /solution /output
jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
}

verify_exercise() {
local dir
local slug
local tmp_dir
dir=$(realpath "${1}")
slug=$(basename "${dir}")
tmp_dir=$(mktemp -d -t "exercism-verify-${slug}-XXXXX")

echo "Verifying ${slug} exercise..."

(
trap 'rm -rf "$tmp_dir"' EXIT # remove tempdir when subshell ends
cp -r "${dir}/." "${tmp_dir}"
cd "${tmp_dir}"

copy_example_or_examplar_to_solution
run_tests "${slug}"
)
}

verify_exercises() {
local exercise_slug
exercise_slug="${1}"

shopt -s nullglob
count=0
for exercise_dir in ./exercises/{concept,practice}/${exercise_slug}/; do
if [[ -d "${exercise_dir}" ]]; then
verify_exercise "${exercise_dir}"
((++count))
fi
done
((count > 0)) || die 'no matching exercises found!'
}

pull_docker_image

exercise_slug="${1:-*}"
verify_exercises "${exercise_slug}"
6 changes: 4 additions & 2 deletions test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@
"status"))))

(defn test-exercises! []
(for [exercise (into practice-exercises concept-exercises)]
{(keyword exercise) (test-exercise exercise)}))
(let [exercises (or (seq (take 1 *command-line-args*))
(into practice-exercises concept-exercises))]
(for [exercise exercises]
{(keyword exercise) (test-exercise exercise)})))

(let [results (test-exercises!)
fails (filter #(false? (first (vals %))) results)]
Expand Down

0 comments on commit 836bbd6

Please sign in to comment.