Skip to content

segakazzz / 課題4 #26

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
2 changes: 2 additions & 0 deletions kadai4/segakazzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
cmd/omkj
39 changes: 39 additions & 0 deletions kadai4/segakazzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#【TRY】おみくじAPI
## おみくじAPIを作ってみよう
- JSON形式でおみくじの結果を返す
- 正月(1/1-1/3)だけ大吉にする
- ハンドラのテストを書いてみる

## 回答
### 実行方法
~~~
$ cd cmd
$ go build -o omkj main.go
$ ./omkj
Server is running with port 8080👍
~~~
上記実行後任意のブラウザでアクセスすると以下のような結果が帰ってくる
~~~
{
"time": "2020-07-26T22:54:31.541464+09:00",
"dice": 1,
"result": "凶"
}
~~~

### 処理説明補足
- 以前作成した[Try]おみくじプログラムを作ろうを応用しました。
- テストパッケージをomikuji_testとして作成しました。(課題2は同じパッケージ内で行った)
- テストでは勉強のため、一部のテストをStandard Library提供の関数をMockして実行しました。

~~~
$ cd omikuji
$ go test --cover --coverprofile=coverprofile.out
Server is starting with port 8000 👍
PASS
coverage: 97.6% of statements
ok github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji 0.016s
~~~

## 感想
- APIの作成自体はすんなり終わりましたが、テストコードの作成にかなり苦戦しました
10 changes: 10 additions & 0 deletions kadai4/segakazzz/cmd/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/gopherdojo/dojo8/kadai4/segakazzz/cmd

go 1.14

replace github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji => ../omikuji

require (
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji v0.0.0-00010101000000-000000000000 // indirect
github.com/pkg/errors v0.9.1 // indirect
)
2 changes: 2 additions & 0 deletions kadai4/segakazzz/cmd/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
24 changes: 24 additions & 0 deletions kadai4/segakazzz/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"flag"
"fmt"
"github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji"
"os"
)

var port int

func init() {
flag.IntVar(&port, "p", 8080, "Port Number to serve http")
}

func main() {
flag.Parse()
err := omikuji.Run(port)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
os.Exit(0)
}
27 changes: 27 additions & 0 deletions kadai4/segakazzz/omikuji/coverprofile.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
mode: set
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:33.28,35.2 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:37.74,39.16 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:43.2,44.16 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:47.2,48.13 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:39.16,42.3 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:44.16,46.3 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:51.26,56.16 5 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:59.2,59.12 1 0
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:56.16,58.3 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:62.38,66.2 3 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:68.50,69.11 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:70.9,71.20 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:72.12,73.20 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:74.12,75.23 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:76.9,77.23 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:78.10,79.48 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:83.38,86.26 3 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:91.2,92.12 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:86.26,88.3 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:88.8,90.3 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:95.45,97.16 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:100.2,100.16 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:97.16,99.3 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:103.44,105.26 2 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:108.2,108.14 1 1
github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji/omikuji.go:105.26,107.3 1 1
44 changes: 44 additions & 0 deletions kadai4/segakazzz/omikuji/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package omikuji

import (
"fmt"
"time"
)

var NewOmikuji = newOmikuji
var OmikujiHandler = (*Omikuji).omikujiHandler
var ThrowOneToSix = (*Omikuji).throwOneToSix
var IntToStr = (*Omikuji).intToStr
var IsNewYearHoliday = (*Omikuji).isNewYearHoliday
var GenJson = (*Omikuji).genJson
var TryOmikuji = (*Omikuji).tryOmikuji

var StdStdMethods = StdMethods

var ErrStdMethods = StdLibProvider{
JsonMarshal: func(v interface{}) ([]byte, error){
return nil, fmt.Errorf("json.marshal dummy error...")
},
}

var MockStdMethods = StdLibProvider{
RandIntn:func(i int) int {
return 5
},
}

var MockHoliday = StdLibProvider{
TimeNow: func () time.Time {
return time.Date(2020, time.January, 1, 10,23,30,9, time.UTC)
},
}

var MockNotHoliday = StdLibProvider{
TimeNow: func () time.Time {
return time.Date(2020, time.March, 1, 10,23,30,9, time.UTC)
},
RandIntn:func(i int) int {
return 5
},
}

5 changes: 5 additions & 0 deletions kadai4/segakazzz/omikuji/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/gopherdojo/dojo8/kadai4/segakazzz/omikuji

go 1.14

require github.com/pkg/errors v0.9.1
2 changes: 2 additions & 0 deletions kadai4/segakazzz/omikuji/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
109 changes: 109 additions & 0 deletions kadai4/segakazzz/omikuji/omikuji.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package omikuji

import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
"math/rand"
"net/http"
"strconv"
"time"
)

type Omikuji struct {
DateTime time.Time `json:"time"`
Dice int `json:"dice"`
Result string `json:"result"`
}

type StdLibProvider struct {
JsonMarshal func(v interface{}) ([]byte, error)
RandIntn func(int) int
TimeNow func() time.Time
HttpListenAndServe func (addr string, handler http.Handler) error
}

var StdMethods = StdLibProvider{
JsonMarshal: json.Marshal,
RandIntn: rand.Intn,
TimeNow: time.Now,
HttpListenAndServe: http.ListenAndServe,
}

func newOmikuji() *Omikuji {
return &Omikuji{}
}

func (o *Omikuji) omikujiHandler(w http.ResponseWriter, r *http.Request) {
err := o.tryOmikuji()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
js, err := o.genJson()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
w.Header().Set("Content-Type", "application/json")
w.Write(js)
}

func Run(port int) error {
o := newOmikuji()
http.HandleFunc("/", o.omikujiHandler)
fmt.Println("Server is starting with port " +strconv.Itoa(port), "👍")
err := StdMethods.HttpListenAndServe(":" + strconv.Itoa(port), nil)
if err != nil {
return errors.Wrapf(err, "Error in Run()\n")
}
return nil
}

func (o *Omikuji)throwOneToSix() int {
rand.Seed(o.DateTime.UnixNano())
i := StdMethods.RandIntn(6)
return i + 1
}

func (o *Omikuji)intToStr(n int) (string, error) {
switch n {
case 1:
return "凶", nil
case 2, 3:
return "吉", nil
case 4, 5:
return "中吉", nil
case 6:
return "大吉", nil
default:
return "", fmt.Errorf("invalid number %d", n)
}
}

func (o *Omikuji) tryOmikuji() error {
var err error
o.DateTime = StdMethods.TimeNow()
if !o.isNewYearHoliday(){
o.Dice = o.throwOneToSix()
} else {
o.Dice = 6
}
o.Result, err = o.intToStr(o.Dice)
return err
}

func (o *Omikuji) genJson() ([]byte, error) {
js, err := StdMethods.JsonMarshal(o)
if err != nil {
return nil, err
}
return js, nil
}

func (o *Omikuji) isNewYearHoliday () bool {
_, m, d := o.DateTime.Date()
if int(m) == 1 && d <= 3{
return true
}
return false
}
Loading