First commit
This commit is contained in:
parent
b29bfeb04f
commit
820e3a7d8c
6 changed files with 159 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
testhub
|
10
go.mod
Normal file
10
go.mod
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
module git.andreafazzi.eu/andrea/testhub
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/kr/pretty v0.2.1 // indirect
|
||||||
|
github.com/kr/text v0.1.0 // indirect
|
||||||
|
github.com/remogatto/prettytest v0.0.0-20200211072524-6d385e11dcb8 // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
|
)
|
9
go.sum
Normal file
9
go.sum
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/remogatto/prettytest v0.0.0-20200211072524-6d385e11dcb8 h1:nRDwTcxV9B3elxMt+1xINX0bwaPdpouqp5fbynexY8U=
|
||||||
|
github.com/remogatto/prettytest v0.0.0-20200211072524-6d385e11dcb8/go.mod h1:jOEnp79oIHy5cvQSHeLcgVJk1GHOOHJHQWps/d1N5Yo=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
11
main.go
Normal file
11
main.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
server := &PlayerServer{&InMemoryPlayerStore{}}
|
||||||
|
log.Fatal(http.ListenAndServe(":3000", server))
|
||||||
|
}
|
82
main_test.go
Normal file
82
main_test.go
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/remogatto/prettytest"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Start of setup
|
||||||
|
type testSuite struct {
|
||||||
|
prettytest.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
type StubPlayerStore struct {
|
||||||
|
scores map[string]int
|
||||||
|
winCalls []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (store *StubPlayerStore) GetPlayerScore(player string) int {
|
||||||
|
return store.scores[player]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StubPlayerStore) RecordWin(name string) {
|
||||||
|
s.winCalls = append(s.winCalls, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunner(t *testing.T) {
|
||||||
|
prettytest.Run(
|
||||||
|
t,
|
||||||
|
new(testSuite),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testSuite) TestGET() {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
expectedScore string
|
||||||
|
expectedHTTPStatus int
|
||||||
|
}{
|
||||||
|
{"Pepper", "20", http.StatusOK},
|
||||||
|
{"Floyd", "10", http.StatusOK},
|
||||||
|
{"Apollo", "0", http.StatusNotFound},
|
||||||
|
}
|
||||||
|
|
||||||
|
store := &StubPlayerStore{
|
||||||
|
map[string]int{
|
||||||
|
"Pepper": 20,
|
||||||
|
"Floyd": 10,
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &PlayerServer{store}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
request, _ := http.NewRequest(http.MethodGet, "/players/"+test.name, nil)
|
||||||
|
response := httptest.NewRecorder()
|
||||||
|
|
||||||
|
server.ServeHTTP(response, request)
|
||||||
|
t.Equal(test.expectedScore, response.Body.String())
|
||||||
|
t.Equal(test.expectedHTTPStatus, response.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testSuite) TestPOST() {
|
||||||
|
store := StubPlayerStore{
|
||||||
|
map[string]int{},
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &PlayerServer{&store}
|
||||||
|
|
||||||
|
request, _ := http.NewRequest(http.MethodPost, "/players/Pepper", nil)
|
||||||
|
response := httptest.NewRecorder()
|
||||||
|
|
||||||
|
server.ServeHTTP(response, request)
|
||||||
|
t.Equal(1, len(store.winCalls))
|
||||||
|
t.Equal(http.StatusAccepted, response.Code)
|
||||||
|
}
|
46
server.go
Normal file
46
server.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InMemoryPlayerStore struct{}
|
||||||
|
|
||||||
|
type PlayerStore interface {
|
||||||
|
GetPlayerScore(player string) int
|
||||||
|
RecordWin(player string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InMemoryPlayerStore) GetPlayerScore(player string) int {
|
||||||
|
return 123
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *InMemoryPlayerStore) RecordWin(player string) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlayerServer struct {
|
||||||
|
store PlayerStore
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *PlayerServer) processWin(w http.ResponseWriter, player string) {
|
||||||
|
ps.store.RecordWin(player)
|
||||||
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *PlayerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
player := strings.TrimPrefix(r.URL.Path, "/players/")
|
||||||
|
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodGet:
|
||||||
|
score := ps.store.GetPlayerScore(player)
|
||||||
|
if score == 0 {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, score)
|
||||||
|
case http.MethodPost:
|
||||||
|
ps.processWin(w, player)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue