From d4c79cc5bc6e499b2a29dda1e3ed84a89abb73da Mon Sep 17 00:00:00 2001 From: en-ken Date: Sun, 11 Aug 2019 20:52:54 +0900 Subject: [PATCH 1/6] feat: added fortune logic. --- kadai4/en-ken/kadai4/export_test.go | 16 +++++++ kadai4/en-ken/kadai4/fortune.go | 28 ++++++++++++ kadai4/en-ken/kadai4/fortune_test.go | 64 ++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 kadai4/en-ken/kadai4/export_test.go create mode 100644 kadai4/en-ken/kadai4/fortune.go create mode 100644 kadai4/en-ken/kadai4/fortune_test.go diff --git a/kadai4/en-ken/kadai4/export_test.go b/kadai4/en-ken/kadai4/export_test.go new file mode 100644 index 0000000..9f95ea0 --- /dev/null +++ b/kadai4/en-ken/kadai4/export_test.go @@ -0,0 +1,16 @@ +package main + +import ( + "time" +) + +var GetFortune = getFortune +var Handler = handler + +func SetNow(n func() time.Time) { + now = n +} + +func SetFortunes(f []string) { + fortunes = f +} diff --git a/kadai4/en-ken/kadai4/fortune.go b/kadai4/en-ken/kadai4/fortune.go new file mode 100644 index 0000000..aab8c95 --- /dev/null +++ b/kadai4/en-ken/kadai4/fortune.go @@ -0,0 +1,28 @@ +package main + +import ( + "math/rand" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// For testing +var now = time.Now +var fortunes []string + +func getFortune() string { + i := rand.Int() % len(fortunes) + f := fortunes[i] + + t := now() + if t.Month() == 1 { + if t.Day() >= 1 && t.Day() <= 3 { + f = "大吉" + } + } + + return f +} diff --git a/kadai4/en-ken/kadai4/fortune_test.go b/kadai4/en-ken/kadai4/fortune_test.go new file mode 100644 index 0000000..56b80f1 --- /dev/null +++ b/kadai4/en-ken/kadai4/fortune_test.go @@ -0,0 +1,64 @@ +package main_test + +import ( + "fmt" + "testing" + "time" + + main "github.com/gopherdojo/dojo6/kadai4/en-ken/kadai4" +) + +func TestGetLuck(t *testing.T) { + + cases := []struct { + now time.Time + expected string + }{ + { + now: time.Date(2018, time.December, 31, 0, 0, 0, 0, time.Local), + expected: "凶", + }, + { + now: time.Date(2018, time.December, 31, 23, 59, 59, 999, time.Local), + expected: "凶", + }, + { + now: time.Date(2019, time.January, 1, 0, 0, 0, 0, time.Local), + expected: "大吉", + }, + { + now: time.Date(2019, time.January, 2, 0, 0, 0, 0, time.Local), + expected: "大吉", + }, + { + now: time.Date(2019, time.January, 3, 0, 0, 0, 0, time.Local), + expected: "大吉", + }, + { + now: time.Date(2018, time.January, 3, 23, 59, 59, 999, time.Local), + expected: "大吉", + }, + { + now: time.Date(2019, time.January, 4, 0, 0, 0, 0, time.Local), + expected: "凶", + }, + } + + main.SetFortunes([]string{"凶", "凶", "凶"}) + + for i, c := range cases { + c := c + t.Run( + fmt.Sprintf("case[%v]", i), + func(t *testing.T) { + main.SetNow(func() time.Time { + return c.now + }) + + if actual := main.GetFortune(); actual != c.expected { + t.Errorf("actual:%v, expected:%v\n", actual, c.expected) + } + }) + } + +} From ae34fafa23aa54c1ecd90275e24e790804602a98 Mon Sep 17 00:00:00 2001 From: en-ken Date: Sun, 11 Aug 2019 20:53:37 +0900 Subject: [PATCH 2/6] feat: added handler logic. --- kadai4/en-ken/kadai4/main.go | 33 +++++++++++++++++++++++++++++++ kadai4/en-ken/kadai4/main_test.go | 29 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 kadai4/en-ken/kadai4/main.go create mode 100644 kadai4/en-ken/kadai4/main_test.go diff --git a/kadai4/en-ken/kadai4/main.go b/kadai4/en-ken/kadai4/main.go new file mode 100644 index 0000000..8732308 --- /dev/null +++ b/kadai4/en-ken/kadai4/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "encoding/json" + "net/http" +) + +func init() { + fortunes = []string{"大吉", "吉", "中吉", "小吉", "末吉", "凶", "大凶"} +} + +type response struct { + Fortune string `json:"fortune"` +} + +func handler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "applicaiton/json; charset=utf-8") + + enc := json.NewEncoder(w) + + resp := &response{ + Fortune: getFortune(), + } + + if err := enc.Encode(resp); err != nil { + http.Error(w, "Server error", http.StatusInternalServerError) + } +} + +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/kadai4/en-ken/kadai4/main_test.go b/kadai4/en-ken/kadai4/main_test.go new file mode 100644 index 0000000..882ff2a --- /dev/null +++ b/kadai4/en-ken/kadai4/main_test.go @@ -0,0 +1,29 @@ +package main_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + main "github.com/gopherdojo/dojo6/kadai4/en-ken/kadai4" +) + +type data struct { + Fortune string `json:"fortune"` +} + +func TestServer(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(main.Handler)) + defer ts.Close() + + res, err := http.Get(ts.URL) + if err != nil { + t.Errorf("%v", err) + } + + var d data + if err = json.NewDecoder(res.Body).Decode(&d); err != nil { + t.Errorf("%v", err) + } +} From ad05f8c0cbe8555cc160ab1a533d783e49c0e4ea Mon Sep 17 00:00:00 2001 From: en-ken Date: Mon, 12 Aug 2019 01:14:41 +0900 Subject: [PATCH 3/6] docs: updated readme. --- kadai4/en-ken/reame.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 kadai4/en-ken/reame.md diff --git a/kadai4/en-ken/reame.md b/kadai4/en-ken/reame.md new file mode 100644 index 0000000..6cd0128 --- /dev/null +++ b/kadai4/en-ken/reame.md @@ -0,0 +1,14 @@ +# 課題4 + +おみくじ API を作りましょう + +- JSON形式でおみくじの結果を返す +- 正月 (1/1-1/3) だけ大吉にする +- ハンドラのテストを書いてみる + +## 使い方 + +```go +go get github.com/gopherdojo/dojo6/kadai4/en-ken/kadai4 +kadai4 +``` From 1de12797d5a62bfefc9a41a38ddec57e1f14156d Mon Sep 17 00:00:00 2001 From: en-ken Date: Mon, 12 Aug 2019 12:22:28 +0900 Subject: [PATCH 4/6] test: added handler test. --- kadai4/en-ken/kadai4/main_test.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/kadai4/en-ken/kadai4/main_test.go b/kadai4/en-ken/kadai4/main_test.go index 882ff2a..0229080 100644 --- a/kadai4/en-ken/kadai4/main_test.go +++ b/kadai4/en-ken/kadai4/main_test.go @@ -19,11 +19,32 @@ func TestServer(t *testing.T) { res, err := http.Get(ts.URL) if err != nil { - t.Errorf("%v", err) + t.Errorf("Response error:%v", err) } var d data if err = json.NewDecoder(res.Body).Decode(&d); err != nil { - t.Errorf("%v", err) + t.Errorf("Data format error:%v", err) + } +} + +func TestHandler(t *testing.T) { + r := httptest.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + main.SetFortunes([]string{"大凶"}) + + main.Handler(w, r) + + if w.Code != 200 { + t.Errorf("Invalid code: %v", w.Code) + } + if w.Header().Get("Content-Type") != "applicaiton/json; charset=utf-8" { + t.Errorf("Insufficient headers: %v", w.Header()) + } + body := w.Body + dec := json.NewDecoder(body) + var d data + if err := dec.Decode(&d); err != nil || d.Fortune != "大凶" { + t.Errorf("Failed to decode: %v", err) } } From e3e0644203ea6fbf20aa75dcdac47ff1e42e1358 Mon Sep 17 00:00:00 2001 From: en-ken Date: Mon, 12 Aug 2019 12:51:32 +0900 Subject: [PATCH 5/6] refactor: restructured for test. --- kadai4/en-ken/kadai4/export_test.go | 4 ++++ kadai4/en-ken/kadai4/fortune.go | 9 ++++---- kadai4/en-ken/kadai4/main.go | 32 ++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/kadai4/en-ken/kadai4/export_test.go b/kadai4/en-ken/kadai4/export_test.go index 9f95ea0..f3e1aff 100644 --- a/kadai4/en-ken/kadai4/export_test.go +++ b/kadai4/en-ken/kadai4/export_test.go @@ -14,3 +14,7 @@ func SetNow(n func() time.Time) { func SetFortunes(f []string) { fortunes = f } + +func SetNewEncoder(n NewEncoder) { + newEncoder = n +} diff --git a/kadai4/en-ken/kadai4/fortune.go b/kadai4/en-ken/kadai4/fortune.go index aab8c95..7eebd47 100644 --- a/kadai4/en-ken/kadai4/fortune.go +++ b/kadai4/en-ken/kadai4/fortune.go @@ -5,14 +5,15 @@ import ( "time" ) -func init() { - rand.Seed(time.Now().UnixNano()) -} - // For testing var now = time.Now var fortunes []string +func init() { + rand.Seed(time.Now().UnixNano()) + fortunes = []string{"大吉", "吉", "中吉", "小吉", "末吉", "凶", "大凶"} +} + func getFortune() string { i := rand.Int() % len(fortunes) f := fortunes[i] diff --git a/kadai4/en-ken/kadai4/main.go b/kadai4/en-ken/kadai4/main.go index 8732308..dd31146 100644 --- a/kadai4/en-ken/kadai4/main.go +++ b/kadai4/en-ken/kadai4/main.go @@ -2,23 +2,40 @@ package main import ( "encoding/json" + "io" "net/http" ) +// Encoder is I/F to json.Encoder +type Encoder interface { + Encode(v interface{}) error +} + +// NewEncoder is I/F to json.NewEncoder +type NewEncoder func(w io.Writer) Encoder + +var newEncoder NewEncoder + func init() { - fortunes = []string{"大吉", "吉", "中吉", "小吉", "末吉", "凶", "大凶"} + // For testing + newEncoder = func(w io.Writer) Encoder { + return json.NewEncoder(w) + } } -type response struct { - Fortune string `json:"fortune"` +func main() { + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) } func handler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "applicaiton/json; charset=utf-8") - enc := json.NewEncoder(w) + enc := newEncoder(w) - resp := &response{ + resp := &struct { + Fortune string `json:"fortune"` + }{ Fortune: getFortune(), } @@ -26,8 +43,3 @@ func handler(w http.ResponseWriter, r *http.Request) { http.Error(w, "Server error", http.StatusInternalServerError) } } - -func main() { - http.HandleFunc("/", handler) - http.ListenAndServe(":8080", nil) -} From 1f888e8576a8f0a40ddc909a5349694c8c04be08 Mon Sep 17 00:00:00 2001 From: en-ken Date: Mon, 12 Aug 2019 13:09:23 +0900 Subject: [PATCH 6/6] test: added internal server error test. --- kadai4/en-ken/kadai4/main_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/kadai4/en-ken/kadai4/main_test.go b/kadai4/en-ken/kadai4/main_test.go index 0229080..1b970bb 100644 --- a/kadai4/en-ken/kadai4/main_test.go +++ b/kadai4/en-ken/kadai4/main_test.go @@ -2,6 +2,8 @@ package main_test import ( "encoding/json" + "fmt" + "io" "net/http" "net/http/httptest" "testing" @@ -28,6 +30,33 @@ func TestServer(t *testing.T) { } } +type EncoderMock struct { +} + +func NewEncoderMock(w io.Writer) main.Encoder { + return &EncoderMock{} +} + +func (enc *EncoderMock) Encode(v interface{}) error { + return fmt.Errorf("Internal server error") +} + +func TestServerInternalServerError(t *testing.T) { + main.SetNewEncoder(NewEncoderMock) + defer main.SetNewEncoder(main.NewEncoder(func(w io.Writer) main.Encoder { + return json.NewEncoder(w) + })) + + ts := httptest.NewServer(http.HandlerFunc(main.Handler)) + defer ts.Close() + + res, _ := http.Get(ts.URL) + if res.StatusCode != 500 { + t.Errorf("Response code error:%v", res.StatusCode) + } + +} + func TestHandler(t *testing.T) { r := httptest.NewRequest("GET", "/", nil) w := httptest.NewRecorder()