#!/bin/bash # Arrange for some cleanup to be executed if the user interrupts the # test sutie (for example, by pressing ControlC at the controlling # terminal). cleanup_and_report() { empathy_deactivate_all >/dev/null 2>&1 TEST_REPORT exit $? } trap cleanup_and_report INT usage () { echo "Usage:$0 " } if [ $# -lt 1 ]; then echo "Error: No test URL given." >&2 echo "" >&2 usage >&2 exit 1 fi URL=$1 CURL="curl --silent --show-error" _TEST_SECTION() { echo "" echo $1 echo $1 | sed -e "s/./$2/g" } TEST_SECTION() { _TEST_SECTION "$1" = } TEST_SUBSECTION() { _TEST_SECTION "$1" - } TEST() { printf " $1" printf "%*s" $(( 52 - ${#1} )) | tr ' ' '.' (( tests_total++ )) || true } # Result of test depends on the exit status of last command TEST_END() { if [ $? -eq 0 ]; then echo -n "OK" else (( tests_failed++ )) || true echo -n "FAIL" fi # If we got an argument, append it after test result if [ -n "$1" ]; then echo " $1" else echo "" fi } # Print report of all previous test results TEST_REPORT() { echo "" echo "" echo "Test Report" echo "===========" if [ "$tests_failed" == "" ]; then echo "All $tests_total tests passed." echo "" return 0 else echo "$tests_failed of $tests_total tests failed." echo "" return 1 fi } # Does a string contain a regular expression pattern # # Example: # # contains "All's well that ends well" "s.well" contains() { grep -q "$2" <<< $1 } # POST to a URL endpoint with optional JSON data # # Usage: # # curl_post [data] [CURL_OPTIONS] curl_post() { $CURL ${3:-} -X POST ${2:+-H 'Content-Type: application/json' -d "$2"} $URL/$1 } # POST to a URL endpoint with optional JSON data using a cookie # # Usage: # # curl_post_cookie [data] [CURL_OPTIONS] # # Where is a string for which there is a defined variable # named ${name}_cookie which in turn holds a value that is a filename # of a valid cookie curl_post_cookie() { cookie=${1}_cookie curl_post $2 "${3:-}" "-b ${!cookie} ${4:-}" } # PUT to a URL endpoint with optional JSON data # # Usage: # # curl_post [data] [CURL_OPTIONS] curl_put() { $CURL ${3:-} -X PUT ${2:+-H 'Content-Type: application/json' -d "$2"} $URL/$1 } # GET from a URL endpoint # # Usage: # # curl_get [CURL_OPTIONS] curl_get() { $CURL ${2:-} $URL/$1 } # GET from a URL endpoint using a cookie # # Usage: # # curl_get_cookie [CURL_OPTIONS] # # Where is a string for which there is a defined variable # named ${name}_cookie which in turn holds a value that is a filename # of a valid cookie curl_get_cookie() { cookie=${1}_cookie curl_get $2 "-b ${!cookie} ${3:-}" } # Create a new game of the specified engine type # # Usage: # # new_game new_game() { curl_post new/$1 | jq -r . } TEST_SECTION "LMNO (super-site for games)" TEST_SUBSECTION "Testing home page" home_page=$($CURL $URL) TEST "Contains 'Join Game'" contains "$home_page" "Join Game" TEST_END TEST "Contains 'Host a new game'" contains "$home_page" "Host a new game" TEST_END TEST_SUBSECTION "Creating some new games" TEST "Empires" empires_game_id=$(new_game empires) test "$empires_game_id" != "" TEST_END $empires_game_id TEST "Tic Tac Toe" tictactoe_game_id=$(new_game tictactoe) test "$tictactoe_game_id" != "" TEST_END $tictactoe_game_id TEST_SUBSECTION "Test redirects" TEST "Redirect of /GAMEID at top level" redirect=$(curl_get $empires_game_id) test "$redirect" = "Moved Permanently. Redirecting to /empires/$empires_game_id/" TEST_END TEST "Redirect of lowercase /gameid at top level" empires_game_id_lower=$(tr '[:upper:]' '[:lower:]' <<< $empires_game_id) redirect=$(curl_get $empires_game_id_lower) test "$redirect" = "Moved Permanently. Redirecting to /$empires_game_id/" TEST_END TEST "Redirect of lowercase /empires/gameid" redirect=$(curl_get empires/$empires_game_id_lower) test "$redirect" = "Moved Permanently. Redirecting to /empires/$empires_game_id/" TEST_END TEST_SECTION "Empires game" empires_game_path=empires/$empires_game_id TEST_SUBSECTION "Empires game /register" empires_register() { curl_post $empires_game_path/register "{\"name\": \"$1\", \"character\": \"$2\"}" } empires_players_string() { curl_get $empires_game_path/players | jq -r .[].name | tr '\n' ',' } empires_characters_string() { curl_get $empires_game_path/characters | jq -r .[] | tr '\n' ',' } TEST "Registering a player returns an ID" carl_id=$(empires_register Carl "Bugs Bunny" | jq -r .) test "$carl_id" = "1" TEST_END TEST "Registering several more players" empires_register Richard "Bob Hope" > /dev/null empires_register Kevin "Elvis Presley" > /dev/null empires_register Stacy Phineas > /dev/null empires_register David "Red Power Ranger" > /dev/null empires_register Nancy "Audrey Hepburn" > /dev/null bogus_id=$(empires_register Bogus "Mr. Bogus") TEST_END TEST 'Verify complete players list (with "Bogus")' players=$(empires_players_string) test "$players" = "Carl,Richard,Kevin,Stacy,David,Nancy,Bogus," TEST_END TEST 'Verify complete players list (with "Mr. Bogus")' characters=$(empires_characters_string) test "$characters" = "Bugs Bunny,Bob Hope,Elvis Presley,Phineas,Red Power Ranger,Audrey Hepburn,Mr. Bogus," TEST_END TEST_SUBSECTION "Empires game /deregister" empires_deregister() { curl_post $empires_game_path/deregister/$1 } TEST "Removing the bogus player" empires_deregister $bogus_id TEST_END TEST 'Verify modified players list (w/o "Bogus")"' players=$(empires_players_string) test "$players" = "Carl,Richard,Kevin,Stacy,David,Nancy," TEST_END TEST 'Verify modified characters list (w/o "Mr. Bogus")' characters=$(empires_characters_string) test "$characters" = "Bugs Bunny,Bob Hope,Elvis Presley,Phineas,Red Power Ranger,Audrey Hepburn," TEST_END TEST_SUBSECTION "Empires game /capture" empires_capture() { curl_post $empires_game_path/capture/$1/$2 } empires_empires_string() { # Get empires as a compact string (much more compact than JSON) curl_get $empires_game_path/empires | jq -c '.[] | [.id,.captures]' | tr '\n' ',' } TEST "Verify empires before any captures" empires=$(empires_empires_string) test "$empires" = "[1,[]],[2,[]],[3,[]],[4,[]],[5,[]],[6,[]]," TEST_END TEST "Perform some captures" empires_capture 1 2 empires_capture 3 5 empires_capture 4 6 empires_capture 3 4 TEST_END TEST "Verify empires after captures" empires=$(empires_empires_string) test "$empires" = "[1,[2]],[2,[]],[3,[5,4]],[4,[6]],[5,[]],[6,[]]," TEST_END TEST_SUBSECTION "Empires game /liberate" empires_liberate() { curl_post $empires_game_path/liberate/$1 } TEST "Liberate a player" empires_liberate 2 TEST_END TEST "Verify empires after liberate" empires=$(empires_empires_string) test "$empires" = "[1,[]],[2,[]],[3,[5,4]],[4,[6]],[5,[]],[6,[]]," TEST_END TEST_SUBSECTION "Empires game /reset" empires_reset() { curl_post $empires_game_path/reset } TEST "Reset the game" empires_reset TEST_END TEST "Verify players is now empty" players=$(empires_players_string) test "$players" = "" TEST_END TEST_SECTION "Tic Tac Toe game" tictactoe_game_path=tictactoe/$tictactoe_game_id tictactoe_profile() { curl_put /profile "{ \"nickname\": \"$1\" }" "-c .cookie-tictactoe" } tictactoe_move() { curl_post $tictactoe_game_path/move "{ \"move\": $1 }" "-b .cookie-tictactoe" } tictactoe_player_info() { curl_get $tictactoe_game_path/events "-m 0.1 -b .cookie-tictactoe" 2>&1 \ | grep player-info -A 1 \ | grep ^data } tictactoe_player_name() { curl_put $tictactoe_game_path/player "{ \"name\": \"$1\" }" "-b .cookie-tictactoe" } tictactoe_player_team() { curl_put $tictactoe_game_path/player "{ \"team\": \"$1\" }" "-b .cookie-tictactoe" } TEST_SUBSECTION "Tic Tac Toe player-info" TEST "Hit LMNO /profile to set name to 'curl'" tictactoe_profile curl TEST_END TEST "Verify player-info event reports 'curl' name" result=$(tictactoe_player_info) test "$result" = 'data: {"id":1,"active":true,"name":"curl","team":""}' TEST_END TEST_SUBSECTION "Tic Tac Toe /player" TEST "Change name to 'newname'" tictactoe_player_name newname result=$(tictactoe_player_info) test "$result" = 'data: {"id":1,"active":true,"name":"newname","team":""}' TEST_END TEST "Change team to 'X'" tictactoe_player_team X result=$(tictactoe_player_info) test "$result" = 'data: {"id":1,"active":true,"name":"newname","team":"X"}' TEST_END TEST "Change team to 'O'" tictactoe_player_team O result=$(tictactoe_player_info) test "$result" = 'data: {"id":1,"active":true,"name":"newname","team":"O"}' TEST_END TEST "Verify cannot change team to 'Z'" tictactoe_player_team Z result=$(tictactoe_player_info) test "$result" = 'data: {"id":1,"active":true,"name":"newname","team":"O"}' TEST_END TEST "Leave current team" tictactoe_player_team "" result=$(tictactoe_player_info) test "$result" = 'data: {"id":1,"active":true,"name":"newname","team":""}' TEST_END TEST_SUBSECTION "Tic Tac Toe /move" TEST "First move doesn't require a team" result=$(tictactoe_move 0) test "$result" = '{"legal":true}' TEST_END TEST "Second move does require a team" result=$(tictactoe_move 4) test "$result" = '{"legal":false,"message":"It'"'"'s not your turn to move"}' TEST_END TEST "Illegal to move when it's not your turn" tictactoe_player_team X result=$(tictactoe_move 4) test "$result" = '{"legal":false,"message":"It'"'"'s not your turn to move"}' TEST_END TEST "Legal move to center square" tictactoe_player_team O result=$(tictactoe_move 4) test "$result" = '{"legal":true}' TEST_END TEST "Move to center square again is now illegal" tictactoe_player_team X result=$(tictactoe_move 4) test "$result" = '{"legal":false,"message":"Square is already occupied"}' TEST_END TEST_SECTION "Scribe game" TEST "Create Scribe game" scribe_game_id=$(new_game scribe) test "$scribe_game_id" != "" TEST_END $scribe_game_id scribe_game_path=scribe/$scribe_game_id # Usage: scribe_profile scribe_profile() { curl_put /profile "{ \"nickname\": \"$1\" }" "-c .cookie-scribe" } # Pulls a single named event out of the scribe event stream # # Usage: scribe_get_event scribe_get_event() { curl_get $scribe_game_path/events "-m 0.1 -b .cookie-scribe" 2>&1 \ | grep "^event: $1" -A 1 \ | grep ^data: \ | sed -e 's,^data: *,,' } # Usage: scribe_player_name scribe_get_player_name() { scribe_get_event player-info | jq -r .name } TEST_SUBSECTION "Scribe player-info" TEST "Hit LMNO /profile to set name to 'test-suite'" scribe_profile test-suite TEST_END TEST "Verify player-info event reports 'test-suite' name" result=$(scribe_get_player_name) test "$result" = "test-suite" TEST_END scribe_player_info() { scribe_get_event player-info } scribe_set_player_name() { curl_put $scribe_game_path/player "{ \"name\": \"$1\" }" "-b .cookie-scribe" } scribe_set_player_team() { curl_put $scribe_game_path/player "{ \"team\": \"$1\" }" "-b .cookie-scribe" } TEST_SUBSECTION "Scribe /player" TEST "Change name to 'testy'" scribe_set_player_name testy result=$(scribe_player_info) test "$result" = '{"id":1,"active":true,"name":"testy","team":""}' TEST_END TEST "Change team to '+'" scribe_set_player_team + result=$(scribe_player_info) test "$result" = '{"id":1,"active":true,"name":"testy","team":"+"}' TEST_END TEST "Change team to 'o'" scribe_set_player_team o result=$(scribe_player_info) test "$result" = '{"id":1,"active":true,"name":"testy","team":"o"}' TEST_END TEST "Verify cannot change team to 'X'" scribe_set_player_team X result=$(scribe_player_info) test "$result" = '{"id":1,"active":true,"name":"testy","team":"o"}' TEST_END TEST "Leave current team" scribe_set_player_team "" result=$(scribe_player_info) test "$result" = '{"id":1,"active":true,"name":"testy","team":""}' TEST_END scribe_move() { curl_post $scribe_game_path/move "{ \"move\": $1 }" "-b .cookie-scribe" } TEST_SUBSECTION "Scribe /move" TEST "First move doesn't require a team" result=$(scribe_move '[4,0]') test "$result" = '{"legal":true}' TEST_END TEST "Second move does require a team" result=$(scribe_move '[0,3]') test "$result" = '{"legal":false,"message":"It'"'"'s not your turn to move"}' TEST_END TEST "Illegal to move when it's not your turn" scribe_set_player_team + result=$(scribe_move '[0,3]') test "$result" = '{"legal":false,"message":"It'"'"'s not your turn to move"}' TEST_END TEST "Legal move to an empty square" scribe_set_player_team o result=$(scribe_move '[0,3]') test "$result" = '{"legal":true}' TEST_END TEST "Move to same again is now illegal" scribe_set_player_team + result=$(scribe_move '[0,3]') test "$result" = '{"legal":false,"message":"Square is already occupied"}' TEST_END TEST "Move must be in correct mini-grid by last move" scribe_set_player_team + result=$(scribe_move '[1,8]') test "$result" = '{"legal":false,"message":"Move is inconsistent with your previous move"}' TEST_END TEST "Move in correct mini-grid is now legal" result=$(scribe_move '[0,8]') test "$result" = '{"legal":true}' TEST_END TEST "Several moves to fill up the mini-grid 0" scribe_set_player_team o scribe_move '[3,0]' >/dev/null scribe_set_player_team + scribe_move '[8,0]' >/dev/null scribe_set_player_team o scribe_move '[0,0]' >/dev/null scribe_set_player_team + scribe_move '[0,1]' >/dev/null scribe_set_player_team o scribe_move '[0,2]' >/dev/null scribe_set_player_team + scribe_move '[1,0]' >/dev/null scribe_set_player_team o scribe_move '[2,0]' >/dev/null scribe_set_player_team + scribe_move '[0,5]' >/dev/null scribe_set_player_team o scribe_move '[0,6]' >/dev/null scribe_set_player_team + scribe_move '[5,0]' >/dev/null scribe_set_player_team o scribe_move '[6,0]' >/dev/null scribe_set_player_team + scribe_move '[0,7]' >/dev/null scribe_set_player_team o scribe_move '[0,4]' >/dev/null scribe_set_player_team + result=$(scribe_move '[7,0]') test "$result" = '{"legal":true}' TEST_END TEST "Full mini grid allows a free move" scribe_set_player_team o scribe_move '[4,1]' >/dev/null scribe_set_player_team + result=$(scribe_move '[1,1]') test "$result" = '{"legal":true}' TEST_END TEST "Player o forms Cross glyph" scribe_set_player_team o scribe_move '[1,4]' >/dev/null scribe_set_player_team + scribe_move '[1,2]' >/dev/null scribe_set_player_team o scribe_move '[4,4]' >/dev/null scribe_set_player_team + scribe_move '[2,1]' >/dev/null scribe_set_player_team o scribe_move '[4,7]' >/dev/null scribe_set_player_team + scribe_move '[1,5]' >/dev/null scribe_set_player_team o scribe_move '[7,4]' >/dev/null scribe_set_player_team + scribe_move '[5,1]' >/dev/null scribe_set_player_team o scribe_move '[4,3]' >/dev/null scribe_set_player_team + scribe_move '[1,8]' >/dev/null scribe_set_player_team o scribe_move '[3,4]' >/dev/null scribe_set_player_team + scribe_move '[8,1]' >/dev/null scribe_set_player_team o result=$(scribe_move '[4,5]') test "$result" = '{"legal":true}' TEST_END TEST "Player + forms J glyph" scribe_set_player_team + result=$(scribe_move '[1,7]') test "$result" = '{"legal":true}' TEST_END TEST "Player + forms Earring glyph" scribe_set_player_team o scribe_move '[5,4]' >/dev/null scribe_set_player_team + scribe_move '[7,1]' >/dev/null scribe_set_player_team o scribe_move '[4,6]' >/dev/null scribe_set_player_team + result=$(scribe_move '[1,3]') test "$result" = '{"legal":true}' TEST_END TEST "Player o forms House glyph" scribe_set_player_team o scribe_move '[6,4]' >/dev/null scribe_set_player_team + scribe_move '[3,1]' >/dev/null scribe_set_player_team o result=$(scribe_move '[4,8]') test "$result" = '{"legal":true}' TEST_END TEST "Player + forms O glyph" scribe_set_player_team + result=$(scribe_move '[1,6]') test "$result" = '{"legal":true}' TEST_END TEST "Player o forms T glyph" scribe_set_player_team o scribe_move '[8,6]' >/dev/null scribe_set_player_team + scribe_move '[6,7]' >/dev/null scribe_set_player_team o scribe_move '[6,3]' >/dev/null scribe_set_player_team + scribe_move '[7,8]' >/dev/null scribe_set_player_team o scribe_move '[3,6]' >/dev/null scribe_set_player_team + scribe_move '[8,2]' >/dev/null scribe_set_player_team o scribe_move '[6,6]' >/dev/null scribe_set_player_team + scribe_move '[2,8]' >/dev/null scribe_set_player_team o result=$(scribe_move '[6,5]') test "$result" = '{"legal":true}' TEST_END TEST "Player o forms Chair glyph" scribe_set_player_team + scribe_move '[8,5]' >/dev/null scribe_set_player_team o scribe_move '[5,6]' >/dev/null scribe_set_player_team + scribe_move '[5,8]' >/dev/null scribe_set_player_team o result=$(scribe_move '[6,2]') test "$result" = '{"legal":true}' TEST_END TEST "Player + forms Bomber glyph" scribe_set_player_team + scribe_move '[8,8]' >/dev/null scribe_set_player_team o scribe_move '[2,6]' >/dev/null scribe_set_player_team + result=$(scribe_move '[8,4]') test "$result" = '{"legal":true}' TEST_END TEST "Player o forms H glyph" scribe_set_player_team o result=$(scribe_move '[6,8]') test "$result" = '{"legal":true}' TEST_END TEST "Player + forms 6-Block glyph" scribe_set_player_team + scribe_move '[4,2]' >/dev/null scribe_set_player_team o scribe_move '[8,3]' >/dev/null scribe_set_player_team + scribe_move '[2,4]' >/dev/null scribe_set_player_team o scribe_move '[3,3]' >/dev/null scribe_set_player_team + scribe_move '[2,2]' >/dev/null scribe_set_player_team o scribe_move '[3,7]' >/dev/null scribe_set_player_team + scribe_move '[2,5]' >/dev/null scribe_set_player_team o scribe_move '[7,3]' >/dev/null scribe_set_player_team + scribe_move '[5,2]' >/dev/null scribe_set_player_team o scribe_move '[3,2]' >/dev/null scribe_set_player_team + result=$(scribe_move '[2,7]') test "$result" = '{"legal":true}' TEST_END TEST "Player o forms Ottoman glyph" scribe_set_player_team o scribe_move '[2,3]' >/dev/null scribe_set_player_team + scribe_move '[7,7]' >/dev/null scribe_set_player_team o scribe_move '[3,5]' >/dev/null scribe_set_player_team + scribe_move '[7,2]' >/dev/null scribe_set_player_team o scribe_move '[5,3]' >/dev/null scribe_set_player_team + scribe_move '[7,6]' >/dev/null scribe_set_player_team o result=$(scribe_move '[3,8]') test "$result"='{"legal":true}' TEST_END TEST "Player + forms J glyph" scribe_set_player_team + scribe_move '[6,1]' >/dev/null scribe_set_player_team o scribe_move '[8,7]' >/dev/null scribe_set_player_team + scribe_move '[5,5]' >/dev/null scribe_set_player_team o scribe_move '[7,5]' >/dev/null scribe_set_player_team + result=$(scribe_move '[5,7]') test "$result"='{"legal":true}' TEST_END TEST_SECTION "Empathy game" TEST_SUBSECTION "Create a game and register 3 players" TEST "Create the game" empathy_game_id=$(new_game empathy) test "$empathy_game_id" != "" TEST_END $empathy_game_id empathy_game_path=empathy/$empathy_game_id # Usage: empathy_get [curl_options] empathy_get() { curl_get_cookie $1 $empathy_game_path/$2 "${3:-}" } # Usage: empathy_post [data] empathy_post() { curl_post_cookie $1 $empathy_game_path/$2 "${3:-}" } # Given a player name as $1 (eg. "empathy_player_activate alice") set both # $1_cookie and $1_pid (that is $alice_cookie and $alice_pid) to # a filename containing a cookie and the PID of a running event-streaming # process. empathy_player_activate() { player="$1" player_cookie=${player}_cookie player_pid=${player}_pid eval ${player_cookie}=".cookie-empathy-$player" curl_put /profile "{ \"nickname\": \"$player\" }" "-c ${!player_cookie}" empathy_get $player events >/dev/null 2>&1 & eval ${player_pid}=$! empathy_players+=($player) } empathy_player_reactivate() { player="$1" player_pid=${player}_pid empathy_get $player events >/dev/null 2>&1 & eval ${player_pid}=$! } # Usage: empathy_player_deactivate empathy_player_deactivate() { player="$1" player_pid=${player}_pid if [ "${!player_pid}" != "" ]; then pkill -P ${!player_pid} fi eval ${player_pid}="" } empathy_deactivate_all() { for player in ${empathy_players[*]}; do empathy_player_deactivate $player done } # Pulls a single named event out of the empathy event stream # # Usage: empathy_get_event empathy_get_event() { empathy_get $1 events "-m 0.1" 2>&1 \ | grep "^event: $2" -A 1 \ | grep ^data: \ | sed -e 's,^data: *,,' } # Usage: empathy_player_name empathy_player_name() { empathy_get_event $1 player-info | jq -r .name } TEST "Set 'alice' in session" empathy_player_activate alice test "$alice_cookie" = ".cookie-empathy-alice" TEST_END TEST "Register alice and verify name" result=$(empathy_player_name alice) test "$result" = "alice" TEST_END TEST "Register bob" empathy_player_activate bob result=$(empathy_player_name bob) test "$result" = "bob" TEST_END TEST "Register charlie" empathy_player_activate charlie result=$(empathy_player_name charlie) test "$result" = "charlie" TEST_END TEST_SUBSECTION "Category selection" # Usage: empathy_submit_prompt empathy_submit_prompt() { empathy_post $1 prompts "{ \"items\": $2, \"prompt\": \"$3\"}" } TEST "Huge numbers are rejected" result=$(empathy_submit_prompt alice 10000 "10,000 Maniacs") test "$result" = '{"valid":false,"message":"Maximum number of items is 20"}' TEST_END TEST "Submit a category" prompt_id=$(empathy_submit_prompt alice 4 "4 things on a beach" | jq .id) test "$prompt_id" = "1" TEST_END # Usage: empathy_vote empathy_vote() { empathy_post $1 vote/$2 } TEST "Vote on this category" empathy_vote alice $prompt_id test "$?" = "0" TEST_END # Usage: empathy_start empathy_start() { empathy_post $1 start/$2 } TEST "Start the game with this category" empathy_start alice $prompt_id test "$?" = "0" TEST_END # Usage: empathy_answer empathy_answer() { empathy_post $1 answer/$2 "{ \"answers\": [$3]}" } TEST_SUBSECTION "Submitting answers" TEST "Submit from a non-player fails" bogus_cookie=/dev/null result=$(empathy_answer bogus $prompt_id '"Sun", "Sand", "Water", "People"') test "$result" = '{"valid":false,"message":"Player not found"}' TEST_END TEST "Submit from alice succeeds" result=$(empathy_answer alice $prompt_id '"sun", "sand", "water", "people"') test "$result" = '{"valid":true}' TEST_END TEST "Submit from bob succeeds" result=$(empathy_answer bob $prompt_id '"sand", "sands", "SunLight", "towels"') test "$result" = '{"valid":true}' TEST_END # Usage: empathy_ambiguities empathy_ambiguities() { empathy_get_event $1 game-state | jq .ambiguities } TEST "Judging hasn't started with player unsubmitted" result=$(echo $(empathy_ambiguities alice)) test "$result" = "null" TEST_END TEST "Submit from charlie succeeds" result=$(empathy_answer charlie $prompt_id '"SunShine", "Grains of Sand", "wafer", "people"') test "$result" = '{"valid":true}' TEST_END TEST_SUBSECTION "Transition from answering to judging (no voting needed)" TEST "Judging already started" result=$(echo $(empathy_ambiguities alice)) test "$result" != "null" TEST_END TEST_SUBSECTION "Judging answers" # Usage: empathy_ambiguities_list empathy_ambiguities_list() { empathy_get_event $1 game-state | jq .ambiguities[] } TEST "Received all unique words" # echo here is to strip newlines result=$(echo $(empathy_ambiguities_list alice)) test "$result" = '"Grains of Sand" "people" "sand" "sands" "sun" "SunLight" "SunShine" "towels" "wafer" "water"' TEST_END # Usage: empathy_judged empathy_judged() { empathy_post $1 judged/$2 "{ \"word_groups\": $3}" } TEST "Submit word groups from alice" result=$(empathy_judged alice $prompt_id '[{"words":["sun","SunLight","SunShine"],"kudos":false},{"words":["sand","sands","Grains of Sand"],"kudos":false},{"words":["water","wafer"],"kudos":false}]') test "$result" = '{"valid":true}' TEST_END TEST "Submit word groups from bob" result=$(empathy_judged bob $prompt_id '[{"words":["sands","grains of sand"],"kudos":false},{"words":["water","wafer"],"kudos":false}]') test "$result" = '{"valid":true}' TEST_END # Usage: empathy_scores empathy_scores() { empathy_get_event $1 game-state | jq .scores } TEST "Scoring hasn't started with player unsubmitted" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END TEST "Submit word groups from charlie" result=$(empathy_judged charlie $prompt_id '[{"words":["SunLight","SunShine"],"kudos":false},{"words":["sand","Grains of Sand"],"kudos":false}]') test "$result" = '{"valid":true}' TEST_END TEST_SUBSECTION "Transition from judging to scoring (no voting needed)" TEST "Scoring already started" result=$(echo $(empathy_scores alice)) test "$result" != "null" TEST_END # Usage: empathy_scores_names_numbers empathy_scores_names_numbers() { empathy_get_event $1 game-state | jq '.scores.scores[]|.players[],.score' } TEST_SUBSECTION "Scoring" TEST "Verify final scores as expected" # echo here is to strip newlines result=$(echo $(empathy_scores_names_numbers alice)) test "$result" = '"charlie" 9 "alice" 8 "bob" 6' TEST_END # Usage: empathy_words_submitted empathy_words_submitted() { empathy_get_event $1 game-state | jq '.scores.words[].word' } TEST "Verify final list of words submitted" # echo here is to strip newlines result=$(echo $(empathy_words_submitted alice)) test "$result" = '"Grains of Sand/sand/sands" "SunLight/SunShine" "wafer/water" "people" "sun" "towels"' TEST_END TEST_SUBSECTION "New game (using voting to advance phases)" empathy_reset() { curl_post $empathy_game_path/reset } TEST "Any post to /reset resets the game" empathy_reset test "$?" = "0" TEST_END TEST "Verify scoring is over" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END # Usage: empathy_answering empathy_answering() { empathy_post $1 answering/$2 } TEST "Start 4-player game, 3 submissions" empathy_player_activate dale result=$(empathy_player_name dale) test "$result" = "dale" prompt_id=$(empathy_submit_prompt alice 4 "3 little words" | jq .id) empathy_start alice $prompt_id empathy_answer alice $prompt_id '"I", "love", "you"' >/dev/null empathy_answer bob $prompt_id '"I", "love", "food"' >/dev/null empathy_answer charlie $prompt_id '"food", "is", "good"' >/dev/null result=$(empathy_answering dale $prompt_id) test "$result" = '{"valid":true}' TEST_END TEST "Judging hasn't started with player unsubmitted" result=$(echo $(empathy_ambiguities alice)) test "$result" = "null" TEST_END # Usage: empathy_end_answers empathy_end_answers() { empathy_post $1 end-answers/$2 } TEST "Minority of players vote to end answering" empathy_end_answers alice $prompt_id empathy_end_answers bob $prompt_id test "$?" = "0" TEST_END TEST "Judging still hasn't started" result=$(echo $(empathy_ambiguities alice)) test "$result" = "null" TEST_END TEST "Majority of players vote to end answering" empathy_end_answers charlie $prompt_id test "$?" = "0" TEST_END TEST "Judging has now started" result=$(echo $(empathy_ambiguities alice)) test "$result" != "null" TEST_END # Usage: empathy_players_judging empathy_players_judging() { empathy_get_event $1 game-state | jq .players_judging[] } TEST "Verify active players listed as judging" # echo here is to strip newlines result=$(echo $(empathy_players_judging alice)) test "$result" = '"alice" "bob" "charlie"' TEST_END TEST "Submit word groups from majority" empathy_judged alice $prompt_id '[]' >/dev/null result=$(empathy_judged bob $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Scoring hasn't started with player unsubmitted" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END # Usage: empathy_end_judging empathy_end_judging() { empathy_post $1 end-judging/$2 } TEST "Minority of players vote to end judging" empathy_end_judging alice $prompt_id test "$?" = "0" TEST_END TEST "Scoring still hasn't started" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END TEST "Majority of players vote to end judging" empathy_end_judging bob $prompt_id test "$?" = "0" TEST_END TEST "Scoring has now started" result=$(echo $(empathy_scores alice)) test "$result" != "null" TEST_END TEST_SUBSECTION "New game (no voting needed when all answered players judge)" TEST "Start 4-player game, 3 submissions" empathy_reset prompt_id=$(empathy_submit_prompt alice 4 "1 truth or dare" | jq .id) empathy_start alice $prompt_id empathy_answer alice $prompt_id '"truth"' >/dev/null empathy_answer bob $prompt_id '"truth"' >/dev/null empathy_answer charlie $prompt_id '"dare"' >/dev/null empathy_end_answers alice $prompt_id empathy_end_answers bob $prompt_id empathy_end_answers charlie $prompt_id test "$?" = "0" TEST_END TEST "Submit word groups from 2 players" empathy_judged alice $prompt_id '[]' >/dev/null result=$(empathy_judged bob $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Scoring hasn't started with player unsubmitted" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END TEST "Submit word groups from a non-answering player" result=$(empathy_judged dale $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Scoring still hasn't started" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END TEST "Submit word groups from last answering player" result=$(empathy_judged charlie $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Scoring has now started" result=$(echo $(empathy_scores alice)) test "$result" != "null" TEST_END TEST_SUBSECTION "Non players don't affect judging requirements" TEST "Start 2-player game with 6 registered players" empathy_reset empathy_player_activate eric empathy_player_activate fred prompt_id=$(empathy_submit_prompt alice 4 "1 truth or dare" | jq .id) empathy_start alice $prompt_id empathy_answer alice $prompt_id '"truth"' >/dev/null empathy_answer bob $prompt_id '"true"' >/dev/null empathy_end_answers alice $prompt_id empathy_end_answers bob $prompt_id test "$?" = "0" TEST_END TEST "1 player votes for a match" empathy_judged alice $prompt_id '[{"words":["truth","true"],"kudos":false}]' >/dev/null result=$(empathy_judged bob $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Verify the match passed the vote" # echo here is to strip newlines result=$(echo $(empathy_scores_names_numbers alice)) test "$result" = '"alice" "bob" 2 "charlie" "dale" "eric" "fred" 0' TEST_END echo "" echo "NOTE: Slow tests ahead!" echo "If you are impatient and somehow \"know\" you don't care about the" echo "tests below then you can interrupt the test suite with Control-C" echo "to get a summary report on the tests that have already been run." TEST_SUBSECTION "Inactive players don't appear in scores" TEST "Start 2-player game with 6 registered players" empathy_reset prompt_id=$(empathy_submit_prompt alice 4 "1 best pet" | jq .id) empathy_start alice $prompt_id empathy_answer alice $prompt_id '"cats"' >/dev/null empathy_answer bob $prompt_id '"dogs"' >/dev/null empathy_end_answers alice $prompt_id empathy_end_answers bob $prompt_id test "$?" = "0" TEST_END TEST "Deactivate 3 players" empathy_player_deactivate dale empathy_player_deactivate eric empathy_player_deactivate fred sleep 30 test "$?" = "0" TEST_END TEST "Finish game with 2 active players" empathy_judged alice $prompt_id '[]' >/dev/null result=$(empathy_judged bob $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Verify scores don't include inactive players" # echo here is to strip newlines result=$(echo $(empathy_scores_names_numbers alice)) test "$result" = '"alice" "bob" 1 "charlie" 0' TEST_END TEST_SUBSECTION "Deactivated players don't block future game phase advances" TEST "New 3-player game, 2 submit right away" empathy_reset prompt_id=$(empathy_submit_prompt charlie 4 "2 legit 2 quit" | jq .id) empathy_start alice $prompt_id empathy_answer alice $prompt_id '"what", "gives?"' >/dev/null empathy_answer bob $prompt_id '"so", "confused"' >/dev/null test "$?" = "0" TEST_END TEST "Judging hasn't started with player unsubmitted" result=$(echo $(empathy_ambiguities alice)) test "$result" = "null" TEST_END TEST "Final active player submits" result=$(empathy_answer charlie $prompt_id '"best", "category"') test "$result" = '{"valid":true}' TEST_END TEST "Judging has started (don't need inactive players)" result=$(echo $(empathy_ambiguities alice)) test "$result" != "null" TEST_END TEST "Submit word groups from 2 players" empathy_judged alice $prompt_id '[]' >/dev/null result=$(empathy_judged bob $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Scoring hasn't started with player unsubmitted" result=$(echo $(empathy_scores alice)) test "$result" = "null" TEST_END TEST "Submit word groups from last answering player" result=$(empathy_judged charlie $prompt_id '[]') test "$result" = '{"valid":true}' TEST_END TEST "Scoring has now started" result=$(echo $(empathy_scores alice)) test "$result" != "null" TEST_END TEST_SUBSECTION "Reactivated player is fully active" TEST "The dale player is currently deactivated" test "$dale_pid" = "" TEST_END TEST "Reactivate dale" empathy_player_reactivate dale test "$dale_pid" != "" TEST_END TEST "New 4-player game, 3 submit right away" empathy_reset prompt_id=$(empathy_submit_prompt alice 1 "favorite letter" | jq .id) empathy_start alice $prompt_id empathy_answer alice $prompt_id '"A"' >/dev/null empathy_answer bob $prompt_id '"B"' >/dev/null empathy_answer charlie $prompt_id '"C"' >/dev/null test "$?" = "0" TEST_END TEST "Judging hasn't started with player unsubmitted" result=$(echo $(empathy_ambiguities alice)) test "$result" = "null" TEST_END TEST "Final active player submits" result=$(empathy_answer dale $prompt_id '"D"') test "$result" = '{"valid":true}' TEST_END TEST "Judging has started now" result=$(echo $(empathy_ambiguities alice)) test "$result" != "null" TEST_END cleanup_and_report