Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
osamingo committed Jul 5, 2021
0 parents commit 1a1ac37
Show file tree
Hide file tree
Showing 33 changed files with 2,424 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# local database file
.sqlite3/*
!.sqlite3/.gitkeep
Empty file added .sqlite3/.gitkeep
Empty file.
26 changes: 26 additions & 0 deletions _test/sta1/sta1_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package sta1_test

import (
"bytes"
"os/exec"
"regexp"
"testing"
)

func TestStation1(t *testing.T) {
t.Parallel()

cmd := exec.Command("go", "version")
w := bytes.NewBuffer(nil)
cmd.Stdout = w

if err := cmd.Run(); err != nil {
t.Error("エラーが発生しました", err)
return
}

if !regexp.MustCompile(`go\sversion\sgo1\.\d+\.\d+\s.+/.+`).Match(w.Bytes()) {
t.Error("go version の実行結果に問題があります")
return
}
}
50 changes: 50 additions & 0 deletions _test/sta10/sta10_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package sta10_test

import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"testing"
)

func TestStation10(t *testing.T) {
t.Parallel()

fset := token.NewFileSet()

f, err := parser.ParseFile(fset, "../../model/error.go", nil, 0)
if err != nil {
t.Error("エラーが発生しました", err)
return
}

config := &types.Config{
Importer: importer.Default(),
}

pkg, err := config.Check("model", fset, []*ast.File{f}, nil)
if err != nil {
t.Error("エラーが発生しました", err)
return
}

obj := pkg.Scope().Lookup("ErrNotFound")
if obj == nil {
t.Error("ErrNotFound がみつかりません")
return
}

_, ok := obj.Type().(*types.Named)
if !ok {
t.Error("ErrNotFound 型が見つかりません")
return
}

typ := obj.Type()
errInterface := types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
if !types.Implements(typ, errInterface) && !types.Implements(types.NewPointer(typ), errInterface) {
t.Error("ErrNotFound に error interface が実装されていません")
}
}
98 changes: 98 additions & 0 deletions _test/sta11/sta11_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package sta11_test

import (
"reflect"
"testing"

"github.com/TechBowl-japan/go-stations/model"
)

func TestStation11(t *testing.T) {
t.Parallel()

testcases := map[string]struct {
Target interface{}
FieldName string
WantKinds []reflect.Kind
WantTypes []reflect.Type
JSONTagValue string
}{
"UpdateTODORequest has ID field": {
Target: model.UpdateTODORequest{},
FieldName: "ID",
WantKinds: []reflect.Kind{reflect.Int, reflect.Uint, reflect.Int8, reflect.Uint8, reflect.Int16,
reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64},
JSONTagValue: "id",
},
"UpdateTODORequest has Subject field": {
Target: model.UpdateTODORequest{},
FieldName: "Subject",
WantKinds: []reflect.Kind{reflect.String},
JSONTagValue: "subject",
},
"UpdateTODORequest has Description field": {
Target: model.UpdateTODORequest{},
FieldName: "Description",
WantKinds: []reflect.Kind{reflect.String},
JSONTagValue: "description",
},
"UpdateTODOResponse has TODO field": {
Target: model.UpdateTODOResponse{},
FieldName: "TODO",
WantKinds: []reflect.Kind{reflect.Struct, reflect.Ptr},
WantTypes: []reflect.Type{reflect.TypeOf(model.TODO{}), reflect.TypeOf(&model.TODO{})},
JSONTagValue: "todo",
},
}

for name, tc := range testcases {
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()

tp := reflect.TypeOf(tc.Target)
f, ok := tp.FieldByName(tc.FieldName)
if !ok {
t.Error(tc.FieldName + " field がみつかりません")
return
}

notFound := true
for _, k := range tc.WantKinds {
if f.Type.Kind() == k {
notFound = false
break
}
}
if notFound {
t.Errorf(tc.FieldName+" が期待している kind ではありません, got = %s, want = %s", f.Type.Kind(), tc.WantKinds)
return
}

if tc.WantTypes != nil {
notFound = true
for _, et := range tc.WantTypes {
if f.Type == et {
notFound = false
break
}
}
if notFound {
t.Errorf(tc.FieldName+" が期待している Type ではありません, got = %s, want = %s", f.Type, tc.WantTypes)
return
}
}

v, ok := f.Tag.Lookup("json")
if !ok {
t.Error("json tag が見つかりません")
return
}

if v != tc.JSONTagValue {
t.Errorf("json tag の内容が期待している内容ではありません, got = %s, want = %s", v, tc.JSONTagValue)
return
}
})
}
}
116 changes: 116 additions & 0 deletions _test/sta12/sta12_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package sta12_test

import (
"context"
"errors"
"os"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/mattn/go-sqlite3"

"github.com/TechBowl-japan/go-stations/db"
"github.com/TechBowl-japan/go-stations/model"
"github.com/TechBowl-japan/go-stations/service"
)

func TestStation12(t *testing.T) {
t.Parallel()

dbpath := "./temp_test.db"
d, err := db.NewDB(dbpath)
if err != nil {
t.Error("エラーが発生しました", err)
return
}

t.Cleanup(func() {
if err := d.Close(); err != nil {
t.Error("エラーが発生しました", err)
return
}
})

t.Cleanup(func() {
if err := os.Remove(dbpath); err != nil {
t.Error("エラーが発生しました", err)
return
}
})

stmt, err := d.Prepare(`INSERT INTO todos(subject) VALUES(?)`)
if err != nil {
t.Error("エラーが発生しました", err)
return
}
t.Cleanup(func() {
if err := stmt.Close(); err != nil {
t.Error("エラーが発生しました", err)
return
}
})

_, err = stmt.Exec("todo subject")
if err != nil {
t.Error(err)
return
}

testcases := map[string]struct {
ID int64
Subject string
Description string
WantError error
}{
"ID is empty": {
WantError: &model.ErrNotFound{},
},
"Subject is empty": {
ID: 1,
WantError: sqlite3.ErrConstraint,
},
"Description is empty": {
ID: 1,
Subject: "todo subject 1",
},
"Have not empty arguments": {
ID: 1,
Subject: "todo subject 2",
Description: "todo description 2",
},
}

for name, tc := range testcases {
tc := tc
t.Run(name, func(t *testing.T) {
svc := service.NewTODOService(d)
got, err := svc.UpdateTODO(context.Background(), tc.ID, tc.Subject, tc.Description)
switch tc.WantError {
case nil:
if err != nil {
t.Error("エラーが発生しました", err)
return
}
default:
if !errors.As(err, &tc.WantError) {
t.Errorf("期待していないエラーの Type です, got = %t, want = %+v", err, tc.WantError)
return
}
return
}

want := &model.TODO{
ID: tc.ID,
Subject: tc.Subject,
Description: tc.Description,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
if diff := cmp.Diff(got, want, cmpopts.EquateApproxTime(time.Second)); diff != "" {
t.Error("期待していない値です\n", diff)
}
})
}
}
Loading

0 comments on commit 1a1ac37

Please sign in to comment.