Skip to content

kadai4-en-ken #32

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 6 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
20 changes: 20 additions & 0 deletions kadai4/en-ken/kadai4/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"time"
)

var GetFortune = getFortune
var Handler = handler

func SetNow(n func() time.Time) {
now = n
}

func SetFortunes(f []string) {
fortunes = f
}

func SetNewEncoder(n NewEncoder) {
newEncoder = n
}
29 changes: 29 additions & 0 deletions kadai4/en-ken/kadai4/fortune.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"math/rand"
"time"
)

// 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]

t := now()
if t.Month() == 1 {
if t.Day() >= 1 && t.Day() <= 3 {
f = "大吉"
}
}

return f
}
64 changes: 64 additions & 0 deletions kadai4/en-ken/kadai4/fortune_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}

}
45 changes: 45 additions & 0 deletions kadai4/en-ken/kadai4/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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() {
// For testing
newEncoder = func(w io.Writer) Encoder {
return json.NewEncoder(w)
}
}

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 := newEncoder(w)

resp := &struct {
Fortune string `json:"fortune"`
}{
Fortune: getFortune(),
}

if err := enc.Encode(resp); err != nil {
http.Error(w, "Server error", http.StatusInternalServerError)
}
}
79 changes: 79 additions & 0 deletions kadai4/en-ken/kadai4/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package main_test

import (
"encoding/json"
"fmt"
"io"
"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("Response error:%v", err)
}

var d data
if err = json.NewDecoder(res.Body).Decode(&d); err != nil {
t.Errorf("Data format error:%v", err)
}
}

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()
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)
}
}
14 changes: 14 additions & 0 deletions kadai4/en-ken/reame.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# 課題4

おみくじ API を作りましょう

- JSON形式でおみくじの結果を返す
- 正月 (1/1-1/3) だけ大吉にする
- ハンドラのテストを書いてみる

## 使い方

```go
go get github.com/gopherdojo/dojo6/kadai4/en-ken/kadai4
kadai4
```