From 5b0bb30afade18d2d4bd68a2cf1e2e84b1b32912 Mon Sep 17 00:00:00 2001 From: hakuta Date: Mon, 3 Dec 2018 01:32:48 +0900 Subject: [PATCH 1/3] implement fortune lot server --- kadai4/akuchii/fortune/fortune.go | 78 +++++++++++++++++++++++++++++++ kadai4/akuchii/main.go | 13 ++++++ 2 files changed, 91 insertions(+) create mode 100644 kadai4/akuchii/fortune/fortune.go create mode 100644 kadai4/akuchii/main.go diff --git a/kadai4/akuchii/fortune/fortune.go b/kadai4/akuchii/fortune/fortune.go new file mode 100644 index 0000000..026e4b3 --- /dev/null +++ b/kadai4/akuchii/fortune/fortune.go @@ -0,0 +1,78 @@ +package fortune + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "math/rand" + "net/http" + "time" +) + +var fortuneList = []string{"大吉", "吉", "中吉", "小吉", "末吉", "凶", "大凶"} + +// Clock is interface to get current time +type Clock interface { + GetCurrentTime() time.Time +} + +// DefaultClock equals current time +type DefaultClock struct{} + +// Fortune lots fortune depends on time +type Fortune struct { + clock Clock +} + +// LotResult contains result of fortune +type LotResult struct { + Result string `json:"result"` +} + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// GetCurrentTime returns current time +func (d DefaultClock) GetCurrentTime() time.Time { + return time.Now() +} + +// NewFortune returns fortune instance +func NewFortune(c Clock) *Fortune { + return &Fortune{clock: c} +} + +func (f Fortune) lotForNewYearDay() string { + return "大吉" +} + +func (f Fortune) defaultLot() 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 +} + +// Lot lots fortune +func (f Fortune) Lot() string { + if f.isNewYearDay() { + return f.lotForNewYearDay() + } + return f.defaultLot() +} + +// Handler returns fortune result +func (f Fortune) Handler(w http.ResponseWriter, r *http.Request) { + var buf bytes.Buffer + fr := LotResult{Result: f.Lot()} + enc := json.NewEncoder(&buf) + if err := enc.Encode(fr); err != nil { + log.Fatal(err) + } + fmt.Fprint(w, buf.String()) +} diff --git a/kadai4/akuchii/main.go b/kadai4/akuchii/main.go new file mode 100644 index 0000000..e798b0e --- /dev/null +++ b/kadai4/akuchii/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "net/http" + + "github.com/gopherdojo/dojo4/kadai4/akuchii/fortune" +) + +func main() { + f := fortune.NewFortune(fortune.DefaultClock{}) + http.HandleFunc("/", f.Handler) + http.ListenAndServe(":8080", nil) +} From 5c63beb5f508bbe0da1caaa8b8590166f4a2eb13 Mon Sep 17 00:00:00 2001 From: hakuta Date: Mon, 3 Dec 2018 01:33:05 +0900 Subject: [PATCH 2/3] add test for fortune lot handler --- kadai4/akuchii/fortune/export_test.go | 5 ++ kadai4/akuchii/fortune/fortune_test.go | 72 ++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 kadai4/akuchii/fortune/export_test.go create mode 100644 kadai4/akuchii/fortune/fortune_test.go diff --git a/kadai4/akuchii/fortune/export_test.go b/kadai4/akuchii/fortune/export_test.go new file mode 100644 index 0000000..96ac810 --- /dev/null +++ b/kadai4/akuchii/fortune/export_test.go @@ -0,0 +1,5 @@ +package fortune + +func (f Fortune) GetFortuneList() []string { + return fortuneList +} diff --git a/kadai4/akuchii/fortune/fortune_test.go b/kadai4/akuchii/fortune/fortune_test.go new file mode 100644 index 0000000..570bae4 --- /dev/null +++ b/kadai4/akuchii/fortune/fortune_test.go @@ -0,0 +1,72 @@ +package fortune_test + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/gopherdojo/dojo4/kadai4/akuchii/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.Fatal("unexpected status code") + } + b, err := ioutil.ReadAll(rw.Body) + if err != nil { + t.Fatal("unexpected error") + } + + fr := &fortune.LotResult{} + if err := json.Unmarshal(b, &fr); err != nil { + t.Fatal("failed json unmarshal") + } + + var fortuneList = f.GetFortuneList() + contain := false + for _, v := range fortuneList { + if v == fr.Result { + contain = true + break + } + } + + if !contain { + t.Fatalf("unexpected response: %s", string(b)) + } +} + +type MockClock struct { + currentTime time.Time +} + +func (mc MockClock) GetCurrentTime() time.Time { + return mc.currentTime +} + +func TestFortune_LotOnNewYearDay(t *testing.T) { + cases := []struct { + newYearDay time.Time + }{ + {time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)}, + {time.Date(2018, 1, 2, 0, 0, 0, 0, time.UTC)}, + {time.Date(2017, 1, 3, 23, 59, 59, 0, time.UTC)}, + } + for _, c := range cases { + mc := &MockClock{c.newYearDay} + f := fortune.NewFortune(mc) + result := f.Lot() + if result != "大吉" { + t.Errorf("unexpected result: %s on %v", result, mc.GetCurrentTime()) + } + } +} From d191ee37031d5dfef8983b1b40fbe786b9abc85f Mon Sep 17 00:00:00 2001 From: hakuta Date: Tue, 4 Dec 2018 23:39:33 +0900 Subject: [PATCH 3/3] enable to change server port --- kadai4/akuchii/main.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kadai4/akuchii/main.go b/kadai4/akuchii/main.go index e798b0e..21ea27a 100644 --- a/kadai4/akuchii/main.go +++ b/kadai4/akuchii/main.go @@ -1,13 +1,23 @@ package main import ( + "flag" + "fmt" "net/http" "github.com/gopherdojo/dojo4/kadai4/akuchii/fortune" ) +// servert port +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(":8080", nil) + http.ListenAndServe(fmt.Sprintf(":%d", port), nil) }