Skip to content

Kadai4 akuchii #56

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions kadai4/akuchii/fortune/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package fortune

func (f Fortune) GetFortuneList() []string {
return fortuneList
}
78 changes: 78 additions & 0 deletions kadai4/akuchii/fortune/fortune.go
Original file line number Diff line number Diff line change
@@ -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())
}
72 changes: 72 additions & 0 deletions kadai4/akuchii/fortune/fortune_test.go
Original file line number Diff line number Diff line change
@@ -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())
}
}
}
23 changes: 23 additions & 0 deletions kadai4/akuchii/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +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(fmt.Sprintf(":%d", port), nil)
}