From ef205e009f21faaf6a178a2f729d3d63b88bf5ae Mon Sep 17 00:00:00 2001 From: xlune Date: Mon, 28 May 2018 16:16:17 +0900 Subject: [PATCH] Add kadai4 --- kadai4/xlune/main.go | 12 +++ kadai4/xlune/omikuji/omikuji.go | 115 +++++++++++++++++++++++++++ kadai4/xlune/omikuji/omikuji_test.go | 50 ++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 kadai4/xlune/main.go create mode 100644 kadai4/xlune/omikuji/omikuji.go create mode 100644 kadai4/xlune/omikuji/omikuji_test.go diff --git a/kadai4/xlune/main.go b/kadai4/xlune/main.go new file mode 100644 index 0000000..d753ed5 --- /dev/null +++ b/kadai4/xlune/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "net/http" + + "github.com/xlune/dojo1/kadai4/xlune/omikuji" +) + +func main() { + http.HandleFunc("/", omikuji.Handler) + http.ListenAndServe(":8080", nil) +} diff --git a/kadai4/xlune/omikuji/omikuji.go b/kadai4/xlune/omikuji/omikuji.go new file mode 100644 index 0000000..c9f50f1 --- /dev/null +++ b/kadai4/xlune/omikuji/omikuji.go @@ -0,0 +1,115 @@ +package omikuji + +import ( + "encoding/json" + "fmt" + "log" + "math/rand" + "net/http" + "strings" + "time" +) + +// Fortune おみくじ結果タイプ +type Fortune int + +// JSONTime JSON出力時間 +type JSONTime struct { + time.Time +} + +const ( + // Kyo 凶 + Kyo Fortune = iota + // Kichi 吉 + Kichi + // Chukichi 中吉 + Chukichi + // Daikichi 大吉 + Daikichi +) + +// Result 返却データ +type Result struct { + Label string `json:"label"` + Type Fortune `json:"type"` + Date JSONTime `json:"date"` +} + +// MarshalJSON JSON文字列生成 +func (t JSONTime) MarshalJSON() ([]byte, error) { + timeStr := fmt.Sprintf("\"%s\"", t.Time.Format("2006-01-02 15:04:05")) + return []byte(timeStr), nil +} + +// UnmarshalJSON JSON文字列生成パース +func (t *JSONTime) UnmarshalJSON(data []byte) (err error) { + timeObj, err := strToTime(strings.Trim(string(data), "\"")) + if err != nil { + return err + } + t.Time = timeObj + return nil +} + +// Handler ハンドラ実装 +func Handler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.Header().Set("Access-Control-Allow-Origin", "*") + + dateStr, ok := r.URL.Query()["date"] + dateTime := time.Now() + + if ok && len(dateStr) > 0 { + t, err := strToTime(dateStr[0]) + if err == nil { + dateTime = t + } + } + + fortune := getFortune(dateTime) + result := Result{ + Type: fortune, + Label: getLabel(fortune), + Date: JSONTime{dateTime}, + } + + if err := json.NewEncoder(w).Encode(result); err != nil { + log.Println("Error:", err) + } +} + +func getFortune(t time.Time) Fortune { + // 1/1 - 1/3 は大吉 + if t.Month() == time.January && t.Day() <= 3 { + return Daikichi + } + // Seed指定でランダム選択 + rand.Seed(t.UnixNano()) + n := rand.Intn(4) + return Fortune(n) +} + +func getLabel(f Fortune) string { + switch f { + case Kichi: + return "吉" + case Chukichi: + return "中吉" + case Daikichi: + return "大吉" + default: + return "凶" + } +} + +func strToTime(str string) (time.Time, error) { + t, err := time.Parse("2006-01-02 15:04:05", str) + if err != nil { + t, err = time.Parse("2006/01/02 15:04:05", str) + if err != nil { + return time.Time{}, err + } + } + return t, nil +} diff --git a/kadai4/xlune/omikuji/omikuji_test.go b/kadai4/xlune/omikuji/omikuji_test.go new file mode 100644 index 0000000..b322f52 --- /dev/null +++ b/kadai4/xlune/omikuji/omikuji_test.go @@ -0,0 +1,50 @@ +package omikuji_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/xlune/dojo1/kadai4/xlune/omikuji" +) + +var handlerTests = []struct { + date string + fortune omikuji.Fortune +}{ + {"2017-01-01 00:00:00", omikuji.Daikichi}, + {"2017-01-01 23:59:59", omikuji.Daikichi}, + {"2017-01-02 00:00:00", omikuji.Daikichi}, + {"2017-01-02 23:59:59", omikuji.Daikichi}, + {"2017-01-03 00:00:00", omikuji.Daikichi}, + {"2017-01-03 23:59:59", omikuji.Daikichi}, + {"2018-04-01 01:23:45", omikuji.Chukichi}, + {"2019-08-08 22:23:45", omikuji.Kyo}, + {"2020-10-06 10:10:10", omikuji.Daikichi}, + {"2021-12-22 11:11:09", omikuji.Kichi}, +} + +func TestHandler(t *testing.T) { + for _, h := range handlerTests { + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/", nil) + q := r.URL.Query() + q.Add("date", h.date) + r.URL.RawQuery = q.Encode() + omikuji.Handler(w, r) + rw := w.Result() + defer rw.Body.Close() + if rw.StatusCode != http.StatusOK { + t.Fatal("unexpected status code") + } + var res omikuji.Result + dec := json.NewDecoder(rw.Body) + if err := dec.Decode(&res); err != nil { + t.Fatal("json decode error") + } + if res.Type != h.fortune { + t.Fatal("unexpected error") + } + } +}