From 09b768a5a25288a9981badd65493ad2561e77d50 Mon Sep 17 00:00:00 2001 From: Gimpei Misono Date: Fri, 7 May 2021 08:35:47 +0900 Subject: [PATCH 1/5] Initial commit --- kadai4/misonog/.gitignore | 16 ++++++++++++++++ kadai4/misonog/Makefile | 9 +++++++++ kadai4/misonog/README.md | 7 +++++++ kadai4/misonog/go.mod | 3 +++ 4 files changed, 35 insertions(+) create mode 100644 kadai4/misonog/.gitignore create mode 100644 kadai4/misonog/Makefile create mode 100644 kadai4/misonog/README.md create mode 100644 kadai4/misonog/go.mod diff --git a/kadai4/misonog/.gitignore b/kadai4/misonog/.gitignore new file mode 100644 index 00000000..fe037cc6 --- /dev/null +++ b/kadai4/misonog/.gitignore @@ -0,0 +1,16 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +/omikuji-server + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ diff --git a/kadai4/misonog/Makefile b/kadai4/misonog/Makefile new file mode 100644 index 00000000..63066b83 --- /dev/null +++ b/kadai4/misonog/Makefile @@ -0,0 +1,9 @@ +BINARY_NAME=omikuji-server + +all: test build + +build: + go build -o $(BINARY_NAME) + +test: + go test -v ./... diff --git a/kadai4/misonog/README.md b/kadai4/misonog/README.md new file mode 100644 index 00000000..c8c5663b --- /dev/null +++ b/kadai4/misonog/README.md @@ -0,0 +1,7 @@ +# おみくじ API + +## 仕様 + +- JSON 形式でおみくじの結果を返す +- 正月(1/1-1/3)だけ大吉にする +- ハンドラのテストを書いてみる diff --git a/kadai4/misonog/go.mod b/kadai4/misonog/go.mod new file mode 100644 index 00000000..e63fff4a --- /dev/null +++ b/kadai4/misonog/go.mod @@ -0,0 +1,3 @@ +module github.com/misonog/gopherdojo-studyroom/kadai4/misonog + +go 1.16 From cd20fd3af9a34d37f1e8437f89aaff268e32a64b Mon Sep 17 00:00:00 2001 From: Gimpei Misono Date: Fri, 7 May 2021 09:01:10 +0900 Subject: [PATCH 2/5] Add basic omikuji logic --- kadai4/misonog/main.go | 15 +++++++++++++++ kadai4/misonog/omikuji.go | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 kadai4/misonog/main.go create mode 100644 kadai4/misonog/omikuji.go diff --git a/kadai4/misonog/main.go b/kadai4/misonog/main.go new file mode 100644 index 00000000..dd42b732 --- /dev/null +++ b/kadai4/misonog/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "log" + "net/http" +) + +func main() { + http.HandleFunc("/", handler) + + err := http.ListenAndServe(":8080", nil) + if err != nil { + log.Fatal(err) + } +} diff --git a/kadai4/misonog/omikuji.go b/kadai4/misonog/omikuji.go new file mode 100644 index 00000000..f8a0f8c6 --- /dev/null +++ b/kadai4/misonog/omikuji.go @@ -0,0 +1,20 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" +) + +type omikujiResult struct { + Result string `json:"result"` +} + +func handler(w http.ResponseWriter, r *http.Request) { + data := &omikujiResult{Result: "吉"} + + w.Header().Set("Content-Type", "application/json; charset=utf-8") + if err := json.NewEncoder(w).Encode(data); err != nil { + log.Fatal(err) + } +} From 9c7d300a357fe0a9d6fdc8101abe3cb0fec48291 Mon Sep 17 00:00:00 2001 From: Gimpei Misono Date: Sun, 9 May 2021 11:22:32 +0900 Subject: [PATCH 3/5] Add handler test --- kadai4/misonog/omikuji_test.go | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 kadai4/misonog/omikuji_test.go diff --git a/kadai4/misonog/omikuji_test.go b/kadai4/misonog/omikuji_test.go new file mode 100644 index 00000000..be528b70 --- /dev/null +++ b/kadai4/misonog/omikuji_test.go @@ -0,0 +1,46 @@ +package main + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" +) + +func TestHandler(t *testing.T) { + cases := []struct { + name string + date string + fixedResult bool + expected string + }{ + {name: "no date", date: ""}, + {name: "12/31", date: "2020-12-31"}, + {name: "shogatsu", date: "2021-01-01", fixedResult: true, expected: "大吉"}, + {name: "1/4", date: "2021-01-04"}, + } + + for _, c := range cases { + c := c + t.Run(c.name, func(t *testing.T) { + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/?date="+c.date, nil) + handler(w, r) + rw := w.Result() + defer rw.Body.Close() + if rw.StatusCode != http.StatusOK { + t.Fatal("unexpected status code") + } + + var res omikujiResult + dec := json.NewDecoder(rw.Body) + if err := dec.Decode(&res); err != nil { + t.Fatal(err) + } + if c.fixedResult && c.expected != res.Result { + t.Errorf("want omikujiResult.Result = %v, got %v", + res.Result, c.expected) + } + }) + } +} From cbec6de1c2a30f69899d3799743138ebfc9c5789 Mon Sep 17 00:00:00 2001 From: Gimpei Misono Date: Sun, 9 May 2021 12:38:23 +0900 Subject: [PATCH 4/5] Add omikuji draw func --- kadai4/misonog/omikuji.go | 55 +++++++++++++++++++++++++++++++++- kadai4/misonog/omikuji_test.go | 24 +++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/kadai4/misonog/omikuji.go b/kadai4/misonog/omikuji.go index f8a0f8c6..a6367b38 100644 --- a/kadai4/misonog/omikuji.go +++ b/kadai4/misonog/omikuji.go @@ -3,18 +3,71 @@ package main import ( "encoding/json" "log" + "math/rand" "net/http" + "time" ) +const ( + timeForm = "2006-1-2" + daikichi = "大吉" +) + +var omikujiResults = []string{"吉", "小吉", "凶"} + type omikujiResult struct { Result string `json:"result"` } +type omikuji struct { + result string + date time.Time +} + func handler(w http.ResponseWriter, r *http.Request) { - data := &omikujiResult{Result: "吉"} + var o omikuji + + dateValue := r.FormValue("date") + if dateValue != "" { + date, err := time.Parse(timeForm, dateValue) + if err != nil { + log.Fatal(err) + } + o = omikuji{date: date} + } else { + o = omikuji{} + } + + o.Draw() + data := &omikujiResult{Result: o.result} w.Header().Set("Content-Type", "application/json; charset=utf-8") if err := json.NewEncoder(w).Encode(data); err != nil { log.Fatal(err) } } + +func (o *omikuji) Draw() { + if isShogatsu(o.date) { + o.result = daikichi + } else { + rand.Seed(time.Now().UnixNano()) + i := rand.Intn(len(omikujiResults)) + o.result = omikujiResults[i] + } +} + +func isShogatsu(t time.Time) bool { + // 0001/1/1は正月と判定できない + if t.IsZero() { + return false + } + + _, month, date := t.Date() + if month == time.January { + if date == 1 || date == 2 || date == 3 { + return true + } + } + return false +} diff --git a/kadai4/misonog/omikuji_test.go b/kadai4/misonog/omikuji_test.go index be528b70..4cf0425c 100644 --- a/kadai4/misonog/omikuji_test.go +++ b/kadai4/misonog/omikuji_test.go @@ -5,6 +5,7 @@ import ( "net/http" "net/http/httptest" "testing" + "time" ) func TestHandler(t *testing.T) { @@ -44,3 +45,26 @@ func TestHandler(t *testing.T) { }) } } + +func TestIsShogatsu(t *testing.T) { + cases := []struct { + name string + input time.Time + expected bool + }{ + {name: "nil", expected: false}, + {name: "shogatsu 1/1", input: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), expected: true}, + {name: "shogatsu 1/2", input: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC), expected: true}, + {name: "not shogatsu", input: time.Date(2021, 1, 4, 0, 0, 0, 0, time.UTC), expected: false}, + } + + for _, c := range cases { + c := c + t.Run(c.name, func(t *testing.T) { + if actual := isShogatsu(c.input); actual != c.expected { + t.Errorf("want isShogatsu(%v) = %v, got %v", + c.input, c.expected, actual) + } + }) + } +} From 79a78a7c38322af30e0495cd987b315b77bcd0c4 Mon Sep 17 00:00:00 2001 From: Gimpei Misono Date: Sun, 9 May 2021 13:38:48 +0900 Subject: [PATCH 5/5] Update README --- kadai4/misonog/README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/kadai4/misonog/README.md b/kadai4/misonog/README.md index c8c5663b..59ed0ab0 100644 --- a/kadai4/misonog/README.md +++ b/kadai4/misonog/README.md @@ -5,3 +5,39 @@ - JSON 形式でおみくじの結果を返す - 正月(1/1-1/3)だけ大吉にする - ハンドラのテストを書いてみる + +## 利用方法 + +### setup + +```shell +$ make # テスト & ビルド +``` + +### サーバーの起動 + +```shell +$ ./omikuji-server +``` + +### おみくじを引く + +```shell +$ curl "http://127.0.0.1:8080/" +> {"result":"小吉"} +$ curl "http://127.0.0.1:8080/?date=2021-01-01" +> {"result":"大吉"} +``` + +## ディレクトリ構造 + +```shell +. +├── Makefile +├── README.md +├── go.mod +├── main.go +├── omikuji-server +├── omikuji.go +└── omikuji_test.go +```