]> git.cworth.org Git - lmno-server/blob - test
game: Allow either player to play the first move
[lmno-server] / test
1 #!/bin/bash
2
3 usage ()
4 {
5     echo "Usage:$0 <URL-to-test>"
6 }
7
8 if [ $# -lt 1 ]; then
9     echo "Error: No test URL given." >&2
10     echo "" >&2
11     usage >&2
12     exit 1
13 fi
14
15 URL=$1
16 CURL="curl --silent --show-error"
17
18 _TEST_SECTION()
19 {
20     echo ""
21     echo $1
22     echo $1 | sed -e "s/./$2/g"
23 }
24
25 TEST_SECTION()
26 {
27     _TEST_SECTION "$1" =
28 }
29
30 TEST_SUBSECTION()
31 {
32     _TEST_SECTION "$1" -
33 }
34
35 TEST()
36 {
37     printf "    $1"
38     printf "%*s" $(( 52 - ${#1} )) | tr ' ' '.'
39     (( tests_total++ )) || true
40 }
41
42 # Result of test depends on the exit status of last command
43 TEST_END()
44 {
45     if [ $? -eq 0 ]; then
46         echo -n "OK"
47     else
48         (( tests_failed++ )) || true
49         echo -n "FAIL"
50     fi
51
52     # If we got an argument, append it after test result
53     if [ -n "$1" ]; then
54         echo " $1"
55     else
56         echo ""
57     fi
58 }
59
60 # Print report of all previous test results
61 TEST_REPORT()
62 {
63     echo ""
64     echo "Test Report"
65     echo "==========="
66
67     if [ "$tests_failed" == "" ]; then
68         echo "All $tests_total tests passed."
69         echo ""
70         return 0
71     else
72         echo "$tests_failed of $tests_total tests failed."
73         echo ""
74         return 1
75     fi
76 }
77
78 # Does a string contain a regular expression pattern
79 #
80 # Example:
81 #
82 #    contains "All's well that ends well" "s.well"
83 contains()
84 {
85     grep -q "$2" <<< $1
86 }
87
88 # POST to a URL endpoint with optional JSON data
89 #
90 # Usage:
91 #
92 # curl_post <ENDPOINT> [data] [CURL_OPTIONS]
93 curl_post()
94 {
95     $CURL ${3:-} -X POST ${2:+-H 'Content-Type: application/json' -d "$2"} $URL/$1
96 }
97
98 # PUT to a URL endpoint with optional JSON data
99 #
100 # Usage:
101 #
102 # curl_post <ENDPOINT> [data] [CURL_OPTIONS]
103 curl_put()
104 {
105     $CURL ${3:-} -X PUT ${2:+-H 'Content-Type: application/json' -d "$2"} $URL/$1
106 }
107
108 # GET from a URL endpoint
109 #
110 # Usage:
111 #
112 # curl_get <ENDPOINT> [CURL_OPTIONS]
113 curl_get()
114 {
115     $CURL ${2:-} $URL/$1
116 }
117
118 # Create a new game of the specified engine type
119 #
120 # Usage:
121 #
122 # new_game <ENGINE>
123 new_game()
124 {
125     curl_post new/$1 | jq -r .
126 }
127
128 TEST_SECTION "LMNO (super-site for games)"
129
130 TEST_SUBSECTION "Testing home page"
131 home_page=$($CURL $URL)
132
133 TEST "Contains 'Join Game'"
134 contains "$home_page" "Join Game"
135 TEST_END
136
137 TEST "Contains 'Host a new game'"
138 contains "$home_page" "Host a new game"
139 TEST_END
140
141 TEST_SUBSECTION "Creating some new games"
142
143 TEST "Empires"
144 empires_game_id=$(new_game empires)
145 test "$empires_game_id" != ""
146 TEST_END $empires_game_id
147
148 TEST "Tic Tac Toe"
149 tictactoe_game_id=$(new_game tictactoe)
150 test "$tictactoe_game_id" != ""
151 TEST_END $tictactoe_game_id
152
153 TEST_SUBSECTION "Test redirects"
154
155 TEST "Redirect of /GAMEID at top level"
156 redirect=$(curl_get $empires_game_id)
157 test "$redirect" = "Moved Permanently. Redirecting to /empires/$empires_game_id/"
158 TEST_END
159
160 TEST "Redirect of lowercase /gameid at top level"
161 empires_game_id_lower=$(tr '[:upper:]' '[:lower:]' <<< $empires_game_id)
162 redirect=$(curl_get $empires_game_id_lower)
163 test "$redirect" = "Moved Permanently. Redirecting to /$empires_game_id/"
164 TEST_END
165
166 TEST "Redirect of lowercase /empires/gameid"
167 redirect=$(curl_get empires/$empires_game_id_lower)
168 test "$redirect" = "Moved Permanently. Redirecting to /empires/$empires_game_id/"
169 TEST_END
170
171 TEST_SECTION "Empires game"
172
173 empires_game_path=empires/$empires_game_id
174
175 TEST_SUBSECTION "Empires game /register"
176
177 empires_register()
178 {
179     curl_post $empires_game_path/register "{\"name\": \"$1\", \"character\": \"$2\"}"
180 }
181
182 empires_players_string()
183 {
184     curl_get $empires_game_path/players | jq -r .[].name | tr '\n' ','
185 }
186
187 empires_characters_string()
188 {
189     curl_get $empires_game_path/characters | jq -r .[] | tr '\n' ','
190 }
191
192 TEST "Registering a player returns an ID"
193 carl_id=$(empires_register Carl "Bugs Bunny" | jq -r .)
194 test "$carl_id" = "1"
195 TEST_END
196
197 TEST "Registering several more players"
198 empires_register Richard "Bob Hope" > /dev/null
199 empires_register Kevin "Elvis Presley" > /dev/null
200 empires_register Stacy Phineas > /dev/null
201 empires_register David "Red Power Ranger" > /dev/null
202 empires_register Nancy "Audrey Hepburn" > /dev/null
203 bogus_id=$(empires_register Bogus "Mr. Bogus")
204 TEST_END
205
206 TEST 'Verify complete players list (with "Bogus")'
207 players=$(empires_players_string)
208 test "$players" = "Carl,Richard,Kevin,Stacy,David,Nancy,Bogus,"
209 TEST_END
210
211 TEST 'Verify complete players list (with "Mr. Bogus")'
212 characters=$(empires_characters_string)
213 test "$characters" = "Bugs Bunny,Bob Hope,Elvis Presley,Phineas,Red Power Ranger,Audrey Hepburn,Mr. Bogus,"
214 TEST_END
215
216 TEST_SUBSECTION "Empires game /deregister"
217
218 empires_deregister()
219 {
220     curl_post $empires_game_path/deregister/$1
221 }
222
223 TEST "Removing the bogus player"
224 empires_deregister $bogus_id
225 TEST_END
226
227 TEST 'Verify modified players list (w/o "Bogus")"'
228 players=$(empires_players_string)
229 test "$players" = "Carl,Richard,Kevin,Stacy,David,Nancy,"
230 TEST_END
231
232 TEST 'Verify modified characters list (w/o "Mr. Bogus")'
233 characters=$(empires_characters_string)
234 test "$characters" = "Bugs Bunny,Bob Hope,Elvis Presley,Phineas,Red Power Ranger,Audrey Hepburn,"
235 TEST_END
236
237 TEST_SUBSECTION "Empires game /capture"
238
239 empires_capture()
240 {
241     curl_post $empires_game_path/capture/$1/$2
242 }
243
244 empires_empires_string()
245 {
246     # Get empires as a compact string (much more compact than JSON)
247     curl_get $empires_game_path/empires | jq -c '.[] | [.id,.captures]' | tr '\n' ','
248 }
249
250 TEST "Verify empires before any captures"
251 empires=$(empires_empires_string)
252 test "$empires" = "[1,[]],[2,[]],[3,[]],[4,[]],[5,[]],[6,[]],"
253 TEST_END
254
255 TEST "Perform some captures"
256 empires_capture 1 2
257 empires_capture 3 5
258 empires_capture 4 6
259 empires_capture 3 4
260 TEST_END
261
262 TEST "Verify empires after captures"
263 empires=$(empires_empires_string)
264 test "$empires" = "[1,[2]],[2,[]],[3,[5,4]],[4,[6]],[5,[]],[6,[]],"
265 TEST_END
266
267 TEST_SUBSECTION "Empires game /liberate"
268
269 empires_liberate()
270 {
271     curl_post $empires_game_path/liberate/$1
272 }
273
274 TEST "Liberate a player"
275 empires_liberate 2
276 TEST_END
277
278 TEST "Verify empires after liberate"
279 empires=$(empires_empires_string)
280 test "$empires" = "[1,[]],[2,[]],[3,[5,4]],[4,[6]],[5,[]],[6,[]],"
281 TEST_END
282
283 TEST_SUBSECTION "Empires game /reset"
284
285 empires_reset()
286 {
287     curl_post $empires_game_path/reset
288 }
289
290 TEST "Reset the game"
291 empires_reset
292 TEST_END
293
294 TEST "Verify players is now empty"
295 players=$(empires_players_string)
296 test "$players" = ""
297 TEST_END
298
299 TEST_SECTION "Tic Tac Toe game"
300
301 tictactoe_game_path=tictactoe/$tictactoe_game_id
302
303 tictactoe_move()
304 {
305     curl_post $tictactoe_game_path/move "{ \"move\": $1 }" "-b .test-cookie"
306 }
307
308 lmno_profile()
309 {
310     curl_put /profile "{ \"nickname\": \"$1\" }" "-c .test-cookie"
311 }
312
313 tictactoe_player_info()
314 {
315     curl_get $tictactoe_game_path/events  "-m 0.1 -b .test-cookie" 2>&1 \
316         | grep player-info -A 1 \
317         | grep ^data
318 }
319
320 tictactoe_player_name()
321 {
322     curl_put $tictactoe_game_path/player "{ \"name\": \"$1\" }" "-b .test-cookie"
323 }
324
325 tictactoe_player_team()
326 {
327     curl_put $tictactoe_game_path/player "{ \"team\": \"$1\" }" "-b .test-cookie"
328 }
329
330 TEST_SUBSECTION "Tic Tac Toe player-info"
331
332 TEST "Hit LMNO /profile to set name to 'curl'"
333 lmno_profile curl
334 TEST_END
335
336 TEST "Verify player-info event reports 'curl' name"
337 result=$(tictactoe_player_info)
338 test "$result" = 'data: {"id":1,"name":"curl","team":""}'
339 TEST_END
340
341 TEST_SUBSECTION "Tic Tac Toe /player"
342
343 TEST "Change name to 'newname'"
344 tictactoe_player_name newname
345 result=$(tictactoe_player_info)
346 test "$result" = 'data: {"id":1,"name":"newname","team":""}'
347 TEST_END
348
349 TEST "Change team to 'X'"
350 tictactoe_player_team X
351 result=$(tictactoe_player_info)
352 test "$result" = 'data: {"id":1,"name":"newname","team":"X"}'
353 TEST_END
354
355 TEST "Change team to 'O'"
356 tictactoe_player_team O
357 result=$(tictactoe_player_info)
358 test "$result" = 'data: {"id":1,"name":"newname","team":"O"}'
359 TEST_END
360
361 TEST "Verify cannot change team to 'Z'"
362 tictactoe_player_team Z
363 result=$(tictactoe_player_info)
364 test "$result" = 'data: {"id":1,"name":"newname","team":"O"}'
365 TEST_END
366
367 TEST "Leave current team"
368 tictactoe_player_team ""
369 result=$(tictactoe_player_info)
370 test "$result" = 'data: {"id":1,"name":"newname","team":""}'
371 TEST_END
372
373 TEST_SUBSECTION "Tic Tac Toe /move"
374
375 TEST "First move doesn't require a team"
376 result=$(tictactoe_move 0)
377 test "$result" = '{"legal":true}'
378 TEST_END
379
380 TEST "Second move does require a team"
381 result=$(tictactoe_move 4)
382 test "$result" = '{"legal":false,"message":"It'"'"'s not your turn to move"}'
383 TEST_END
384
385 TEST "Illegal to move when it's not your turn"
386 tictactoe_player_team X
387 result=$(tictactoe_move 4)
388 test "$result" = '{"legal":false,"message":"It'"'"'s not your turn to move"}'
389 TEST_END
390
391 TEST "Legal move to center square"
392 tictactoe_player_team O
393 result=$(tictactoe_move 4)
394 test "$result" = '{"legal":true}'
395 TEST_END
396
397 TEST "Move to center square again is now illegal"
398 tictactoe_player_team X
399 result=$(tictactoe_move 4)
400 test "$result" = '{"legal":false,"message":"Square is already occupied"}'
401 TEST_END
402
403 TEST_REPORT