Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kadai4-pei #36

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions kadai4/pei/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
ROOT=github.com/gopherdojo/dojo6/kadai4/pei
BIN=fortune
MAIN=main.go
TEST=...

.PHONY: build
build: ${MAIN}
go build -o ${BIN} ${GOPATH}/src/${ROOT}/$?

.PHONY: test
test:
go test -v -cover ${ROOT}/${TEST}

.PHONY: clean
clean:
rm ${BIN}
go clean
5 changes: 5 additions & 0 deletions kadai4/pei/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## 課題4 おみくじAPIを作ってみよう

- JSON形式でおみくじの結果を返す
- 正月(1/1-1/3)だけ大吉にする
- ハンドラのテストを書いてみる
22 changes: 22 additions & 0 deletions kadai4/pei/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"flag"
"fmt"
"net/http"

"github.com/gopherdojo/dojo6/kadai4/pei/pkg/fortune"
)

var port int

func init() {
flag.IntVar(&port, "p", 8080, "server port")
}

func main() {
flag.Parse()
f := fortune.NewFortune(fortune.DefaultClock{})
http.HandleFunc("/", f.Handler)
http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}
88 changes: 88 additions & 0 deletions kadai4/pei/pkg/fortune/fortune.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package fortune

import (
"bytes"
"encoding/json"
"fmt"
"math/rand"
"net/http"
"time"
)

var fortuneList = []string{
"大吉",
"中吉",
"吉",
"小吉",
"凶",
}

// Clock
type Clock interface {
GetCurrentTime() time.Time
}

// DefaultClock
type DefaultClock struct{}

// Fortune
type Fortune struct {
clock Clock
}

// DrawingResult
type DrawingResult struct {
Result string `json:"result"`
}

func init() {
rand.Seed(time.Now().UnixNano())
}

// GetCurrentTime return current time
func (d DefaultClock) GetCurrentTime() time.Time {
return time.Now()
}

// NewFortune return fortune instance
func NewFortune(c Clock) * Fortune {
return &Fortune{clock: c}
}

func (f Fortune) drawingForNewYearDay() string {
return "大吉"
}

func (f Fortune) defaultDrawing() string {
return fortuneList[rand.Intn(len(fortuneList))]
}

func (f Fortune) isNewYearDay() bool {
c := f.clock.GetCurrentTime()

return c.Month() == 1 && 1 <= c.Day() && c.Day() <= 3
}

// Drawing return drawing result
func (f Fortune) Drawing() string {
if f.isNewYearDay() {
return f.drawingForNewYearDay()
}
return f.defaultDrawing()
}

// GetFortuneList return fortuneList
func (f Fortune) GetFortuneList() []string {
return fortuneList
}

// Handler
func (f Fortune) Handler(w http.ResponseWriter, r *http.Request) {
var buf bytes.Buffer
dr := DrawingResult{Result: f.Drawing()}
enc := json.NewEncoder(&buf)
if err := enc.Encode(dr); err != nil {
fmt.Errorf("error: %v", err)
}
fmt.Fprint(w, buf.String())
}
73 changes: 73 additions & 0 deletions kadai4/pei/pkg/fortune/fortune_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package fortune_test

import (
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/gopherdojo/dojo6/kadai4/pei/pkg/fortune"
)

func TestFortune_Handler(t *testing.T) {
f := fortune.NewFortune(fortune.DefaultClock{})
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
f.Handler(w, r)

rw := w.Result()
defer rw.Body.Close()
if rw.StatusCode != http.StatusOK {
t.Error("unexpected status code")
}

b, err := ioutil.ReadAll(rw.Body)
if err != nil {
t.Error("unexpected error")
}

dr := &fortune.DrawingResult{}
if err := json.Unmarshal(b, &dr); err != nil {
t.Error("failed json unmarshal")
}

fortuneList := f.GetFortuneList()
contain := false
for _, v := range fortuneList {
if v == dr.Result {
contain = true
break
}
}

if !contain {
t.Errorf("unexpected response: %s", string(b))
}
}

type MockClock struct {
currentTime time.Time
}

func (mc MockClock) GetCurrentTime() time.Time {
return mc.currentTime
}

func TestFortune_Drawing(t *testing.T) {
cases := []struct {
clock time.Time
}{
{time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)},
{time.Date(2019, 1, 3, 23, 59, 59, 0, time.UTC)},
}

for _, c := range cases {
mc := &MockClock{c.clock}
f := fortune.NewFortune(mc)
if actual := f.Drawing(); actual != "大吉" {
t.Errorf("unexpected result: %s on %v", actual, mc.GetCurrentTime())
}
}
}