diff --git a/.github/workflows/check-code-samples.sh b/.github/workflows/check-code-samples.sh new file mode 100755 index 00000000..2dd6d771 --- /dev/null +++ b/.github/workflows/check-code-samples.sh @@ -0,0 +1,75 @@ +cd ./code-samples/ +files=$(ls | wc -l) +echo "Check $files files …" +failedFiles=() +notRunnable=0 +i=0 +for file in *.pony; do # actors-sequential.pony + ((i++)) + percentage=$(((i*100)/files)) + echo -e "#$i Test $file … ($i/$files \u2192 $percentage %)" + contents=$(cat "$file") # code-samples/ + #echo "contents: $contents" + regex='^"""\n(?^(?[a-z_]+):\s?(?.*?)$\n)+"""' # TODO: Get frontmatter from AST + regex='^"""\n(.*)\n"""' + expectations=$(jq --arg file "${file}" ".[\"$file\"]" ../code-samples.json) # -r + #echo "Expectations for $file $expectations" + isRunnable=$(echo "$expectations" | jq '.runnable') + if ! [ -z "$expectations" ] && ! $isRunnable; then + echo -e "\u2139\uFE0F File not runnable. Skip" + ((notRunnable++)) + continue + fi + expectedStdout=$(echo "$expectations" | jq '.stdout') + expectedStderr=$(echo "$expectations" | jq '.stderr') + expectedExitcode=$(echo "$expectations" | jq '.exitcode') + #echo "stdout for $file: " + #echo "$contents" | grep -e $regex + if [ $(echo "$contents" | grep -qe $regex) ]; then # TODO: fix regex + frontmatter="${BASH_REMATCH[0]}" + readarray -d "\n" -t lines <<< frontmatter + echo "Expectations 1: ${lines[0]}" + fi + if [[ "$contents" =~ $regex ]]; then + frontmatter="${BASH_REMATCH[0]}" + readarray -d "\n" -t lines <<< frontmatter + echo "Expectations: ${lines[0]}" + fi + encoded=$(sed -E -e ':a;N;$!ba;s/\r\n|\r|\n/\\n/g' "$file") #code-samples/ + encoded=${encoded//\"/\\\"} + encoded=${encoded// /\\t} + json="{\"code\": \"$encoded\", \"separate_output\": true, \"color\": true, \"branch\": \"release\"}" + #echo "Send $json…" + response=$(curl -s --header "Content-Type: application/json" \ + --request POST \ + --data "$json" \ + "https://playground.ponylang.io/evaluate.json") + success=$(echo "$response" | jq '.success') + actualStdout=$(echo "$response" | jq '.stdout') + actualStderr=$(echo "$response" | jq '.stderr') + if $success && ! [ -z "$expectations" ] && [ "$expectedExitcode" = "0" ] && [ "$actualStdout" = "$expectedStdout" ]; then + echo -e "\e[1;32m\u2705 File fulfilled expectations\e[0m" + elif ! $success && ! [ -z "$expectations" ] && [ "$expectedExitcode" = "1" ] && [ "$actualStderr" = "$expectedStderr" ]; then + echo -e "\e[1;32m\u2705 File fulfilled expectations\e[0m" + else + failedFiles+=(file) + echo -e "\e[1;31m\u274C File didn't fulfill expectations\e[0m" + if [ "$expectedExitcode" = "0" ]; then + echo "Success = true (actual: $success), stdout = $expectedStdout (actual: ${actualStdout-null})" + else + echo "Success = false (actual: $success), stderr = $expectedStderr (actual: ${actualStderr-null})" + fi + echo $response + echo $expectations + echo $expectedExitcode + fi + #break +done +runnableFiles=$((files-notRunnable)) +if [ "${#failedFiles[@]}" != 0 ]; then + echo -e "\e[1;31m💥 ${#failedFiles[@]}/$runnableFiles file(s) ($files total) had errors\e[0m" + exit 1 +else + echo -e "\e[1;32m🎉 All $files files ($runnableFiles runnable) were checked successfully\e[0m" + exit 0 +fi \ No newline at end of file diff --git a/.github/workflows/check-code-samples.yml b/.github/workflows/check-code-samples.yml new file mode 100644 index 00000000..7e2959e7 --- /dev/null +++ b/.github/workflows/check-code-samples.yml @@ -0,0 +1,17 @@ +name: Check code samples + +on: + pull_request: + push: + +jobs: + check-code-samples: + name: Check code samples + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Install jq + run: curl -sS https://webi.sh/jq | bash + - name: Check code samples + run: ${GITHUB_WORKSPACE}/.github/workflows/check-code-samples.sh diff --git a/code-samples.json b/code-samples.json new file mode 100644 index 00000000..80c1b022 --- /dev/null +++ b/code-samples.json @@ -0,0 +1,23 @@ +{ + "actors-sequential.pony": { + "runnable": true, + "stdout": "This is printed first\nThis is printed last\n", + "stderr": null, + "exitcode": 0 + }, + "traits-and-interfaces-private-methods.pony": { + "runnable": true, + "stdout": null, + "stderr": "interfaces can't have private methods, only traits can\n", + "exitcode": 1 + }, + "actors-behaviors.pony": { + "runnable": false + }, + "appendices-examples-access-command-line-arguments.pony": { + "runnable": true, + "stdout": "This is printed first\nThis is printed last\n", + "stderr": null, + "exitcode": 0 + } +} \ No newline at end of file diff --git a/code-samples/actors-sequential.pony b/code-samples/actors-sequential.pony index 49915fdf..9b3c4799 100644 --- a/code-samples/actors-sequential.pony +++ b/code-samples/actors-sequential.pony @@ -1,3 +1,10 @@ +""" +description: "Execution order of actor behaviors" +stdout: This is printed first\nThis is printed last\n +stderr: +exitcode: 0 +""" + actor Main new create(env: Env) => call_me_later(env)