diff --git a/kadai4/README.md b/kadai4/README.md new file mode 100644 index 0000000..5cb4f64 --- /dev/null +++ b/kadai4/README.md @@ -0,0 +1,8 @@ +## Usage + +``` +$ go build omikuji.go +$ ./omokuji +``` + +上記を実行するとWebサーバが立ち上がるので、localhost:8080にアクセスしてください。 \ No newline at end of file diff --git a/kadai4/fortune/debug.test b/kadai4/fortune/debug.test new file mode 100755 index 0000000..00605bd Binary files /dev/null and b/kadai4/fortune/debug.test differ diff --git a/kadai4/fortune/fortune.go b/kadai4/fortune/fortune.go new file mode 100644 index 0000000..3d8d6b0 --- /dev/null +++ b/kadai4/fortune/fortune.go @@ -0,0 +1,50 @@ +package fortune + +import ( + "math/rand" + "time" +) + +var fortuneList = []string{"大吉", "中吉", "小吉", "吉", "末吉", "凶", "大凶"} + +// Fortune はおみくじの構造体です +type Fortune struct { + Content string `json:"content"` +} + +// FortuneSelector はおみくじ選択処理を行う構造体です +type FortuneSelector struct { + Qlock Qlock +} + +// DefaultQlock はGetCurrenttimeで普通に現在時刻を返す時計です +type DefaultQlock struct{} + +// GetCurrentTime は現在時刻を返す関数です +func (d DefaultQlock) GetCurrentTime() time.Time { + return time.Now() +} + +// Qlock は時計のインターフェースです +type Qlock interface { + GetCurrentTime() time.Time +} + +// SelectFortune はおみくじリストの中からひとつ選んでFortuneオブジェクトを返す関数です +func (f FortuneSelector) SelectFortune() Fortune { + t := f.Qlock.GetCurrentTime() + if t.Month() == 1 && (1 <= t.Day() && t.Day() <= 3) { + return f.selectFortuneOnlyDaikichi() + } + return f.selectFortuneRandom() +} + +func (f FortuneSelector) selectFortuneOnlyDaikichi() Fortune { + return Fortune{Content: "大吉"} +} + +func (f FortuneSelector) selectFortuneRandom() Fortune { + rand.Seed(time.Now().UnixNano()) + content := fortuneList[rand.Int()%len(fortuneList)] + return Fortune{Content: content} +} diff --git a/kadai4/fortune/fortune_test.go b/kadai4/fortune/fortune_test.go new file mode 100644 index 0000000..5343f2d --- /dev/null +++ b/kadai4/fortune/fortune_test.go @@ -0,0 +1,51 @@ +package fortune + +import ( + "testing" + "time" +) + +func TestSelectFortuneDefault(t *testing.T) { + var dq DefaultQlock + fs := FortuneSelector{Qlock: dq} + f := fs.SelectFortune() + + var fortuneList = []string{"大吉", "中吉", "小吉", "吉", "末吉", "凶", "大凶"} + exists := false + for _, v := range fortuneList { + if v == f.Content { + exists = true + break + } + } + if exists == false { + t.Fatalf("unexpected f.Content: %s", f.Content) + } +} + +type ManualQlock struct { + Time time.Time +} + +func (d ManualQlock) GetCurrentTime() time.Time { + return d.Time +} + +func TestSelectFortuneNewYear(t *testing.T) { + + timeList := []time.Time{ + time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), + time.Date(2000, time.January, 2, 12, 0, 0, 0, time.UTC), + time.Date(2000, time.January, 3, 23, 59, 0, 0, time.UTC), + } + + for _, ti := range timeList { + mq := ManualQlock{Time: ti} + fs := FortuneSelector{Qlock: mq} + f := fs.SelectFortune() + + if f.Content != "大吉" { + t.Fatalf("unexpected f.Content when: %s", ti) + } + } +} diff --git a/kadai4/omikuji.go b/kadai4/omikuji.go new file mode 100644 index 0000000..c34fd02 --- /dev/null +++ b/kadai4/omikuji.go @@ -0,0 +1,30 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "net/http" + + "github.com/gopherdojo/dojo2/kadai4/fortune" +) + +func handler(w http.ResponseWriter, r *http.Request) { + var dq fortune.DefaultQlock + fs := fortune.FortuneSelector{Qlock: dq} + f := fs.SelectFortune() + + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + if err := enc.Encode(f); err != nil { + log.Fatal(err) + } + fmt.Fprint(w, buf.String()) +} + +func main() { + fmt.Println("Web Server Starting...") + http.HandleFunc("/", handler) + http.ListenAndServe(":8080", nil) +} diff --git a/kadai4/omikuji_test.go b/kadai4/omikuji_test.go new file mode 100644 index 0000000..c121d1f --- /dev/null +++ b/kadai4/omikuji_test.go @@ -0,0 +1,42 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gopherdojo/dojo2/kadai4/fortune" +) + +func TestHandler(t *testing.T) { + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/", nil) + 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") + } + f := fortune.Fortune{} + if err := json.Unmarshal(b, &f); err != nil { + t.Fatal("failed json unmarshal") + } + // fortuneListのうちどれかが返ってきていればOK + var fortuneList = []string{"大吉", "中吉", "小吉", "吉", "末吉", "凶", "大凶"} + exists := false + for _, v := range fortuneList { + if v == f.Content { + exists = true + break + } + } + if exists == false { + t.Fatalf("unexpected f.Content: %s", f.Content) + } +}