Skip to content
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

Kadai2 Hiroya-W #85

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7dffa53
:tada: Initial Commit
Hiroya-W Oct 1, 2021
f1d7d93
:sparkles: flagをparse出来るようにした
Hiroya-W Oct 2, 2021
b203fd9
:rotating_light: コマンド実行時のテストを追加
Hiroya-W Oct 2, 2021
eb8dff2
:sparkles: Converter を作成
Hiroya-W Oct 3, 2021
9e7137b
:rotating_light: test-deps ターゲットを追加
Hiroya-W Oct 3, 2021
922ee67
:recycle: Test のためにEncoderとDecoderを別々に持つように修正
Hiroya-W Oct 3, 2021
093ae2b
:pencil2: TIFFに修正
Hiroya-W Oct 3, 2021
29a4c14
:sparkles: GetFilesメソッドを作成
Hiroya-W Oct 3, 2021
7542412
:recycle: Encoder, Decoderがターゲットとなる拡張子を持つように変更
Hiroya-W Oct 3, 2021
bf1dfd8
:bug: inputTypeとoutputTypeが逆になっていたのを修正
Hiroya-W Oct 4, 2021
96ae654
:rotating_light: GetFilesで収集したファイルの数のテストを用意
Hiroya-W Oct 4, 2021
1dc45b8
:sparkles: Converterメソッドを実装
Hiroya-W Oct 4, 2021
63a940f
:wrench: テストデータの生成スクリプトを修正
Hiroya-W Oct 4, 2021
f9de113
:rotating_light: テストケースの修正
Hiroya-W Oct 4, 2021
babc6bc
:bug: 同名ファイルへ同時にアクセスすることがある
Hiroya-W Oct 4, 2021
00cef6f
:books: ドキュメントを書いた
Hiroya-W Oct 5, 2021
664c11a
:wastebasket: 不要なファイルを削除
Hiroya-W Oct 5, 2021
376860b
:+1: fix Makefile
Hiroya-W Oct 5, 2021
cdaa967
:recycle: Lintエラーの修正
Hiroya-W Oct 5, 2021
92c7e52
:recycle: 不要なメンバの削除
Hiroya-W Oct 5, 2021
8fa06af
:bug: Fix Module path
Hiroya-W Oct 5, 2021
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 kadai2/hiroya-w/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# binaries
bin/

# coverage outputs
coverage.out
57 changes: 57 additions & 0 deletions kadai2/hiroya-w/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
NAME := imgconv
VERSION := $(gobump show -r)
REVISION := $(shell git rev-parse --short HEAD)
LDFLAGS := "-X main.revision=$(REVISION)"

## Install dependencies
.PHONY: deps
deps:
go get -v -d

## Setup
.PHONY: devel-deps
devel-deps: devel-deps
go install honnef.co/go/tools/cmd/staticcheck@latest
go install github.com/kisielk/errcheck@latest
go install github.com/x-motemen/gobump/cmd/gobump@latest
go install github.com/Songmu/make2help/cmd/make2help@latest

## Run tests
.PHONY: test
test: deps
go test -v -race -cover -coverprofile=coverage.out ./...

## Generate testdatas
.PHONY: test-deps
test-deps:
cd _tools && sh gen_testdata.sh ../testdata

## Show coverage
.PHONY: cover
cover:
go tool cover -html=coverage.out

## Lint
.PHONY: lint
lint: deps
go vet ./...
staticcheck ./...
errcheck -ignore 'fmt:[FS]?[Pp]rint*' ./...

## build binaries
bin/%: cmd/%/main.go deps
go build -ldflags $(LDFLAGS) -o $@ $<

## build binary
.PHONY: build
build: bin/imgconv

## show go documention
.PHONY: doc
doc:
godoc -http=:8080

## Show help
.PHONY: help
help:
@make2help $(MAKEFILE_LIST)
64 changes: 64 additions & 0 deletions kadai2/hiroya-w/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 課題2

## テストを書いてみよう

- [x] テストのしやすさを考えてリファクタリングしてみる
- [x] テストのカバレッジを取ってみる
- [x] テーブル駆動テストを行う
- [ ] テストヘルパーを作ってみる

今回のテストで、どの部分にテストヘルパーを利用出来るのかがわからなかった。他の方のPRを参考に眺めてみようと思う。
Goでオブジェクト指向をしようとしてハマるやつをやりかけてしまっているように感じたので、もう少しGoらしい書き方を勉強してもいいなと思った。

## usage

```
.bin/imgconv -h
Usage of .bin/imgconv:
-input-type string
input type[jpg|jpeg|png|gif] (default "jpg")
-output-type string
output type[jpg|jpeg|png|gif] (default "png")
```

基本的なコマンドは `Makefile` で利用できます。

### build

ビルドに必要なパッケージを取得します。

```
make devel-deps
```

ビルドすると `bin` フォルダに `imgconv` のバイナリが生成されます。

```
make build
```

### test

`testdata` にテスト用の画像を生成します。
その後、 `make test` でテストを実行します。

```
make test-deps
make test
```

### coverage

テストの実行後、カバレッジを表示します。

```
make cover
```

### document

ドキュメントを表示します。

```
make doc
```
6 changes: 6 additions & 0 deletions kadai2/hiroya-w/_tools/gen_testdata.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
DIR=${1:-.}

curl https://avatars.githubusercontent.com/hiroya-w -o $DIR/image_png.png
curl http://icb-lab.naist.jp/members/yoshi/ouec_lecture/image_recognition/image_files/lena.jpg -o $DIR/image_jpg.jpg
curl https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif -o $DIR/image_gif.gif
91 changes: 91 additions & 0 deletions kadai2/hiroya-w/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package imgconv

import (
"flag"
"fmt"
"io"
"os"
)

// CLI is the command line interface
type CLI struct {
OutStream, ErrStream io.Writer
}

// validateType validates the type of the image
func validateType(t string) error {
switch t {
case "jpg", "jpeg", "png", "gif":
return nil
default:
return fmt.Errorf("invalid type: %s", t)
}
}

// Run parses the command line arguments and runs the imgConv
func (cli *CLI) Run() int {
config := &Config{}
fs := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
fs.StringVar(&config.InputType, "input-type", "jpg", "input type[jpg|jpeg|png|gif]")
fs.StringVar(&config.OutputType, "output-type", "png", "output type[jpg|jpeg|png|gif]")
fs.SetOutput(cli.ErrStream)
fs.Usage = func() {
fmt.Fprintf(cli.ErrStream, "Usage: %s [options] DIRECTORY\n", "imgconv")
fs.PrintDefaults()
}

if err := fs.Parse(os.Args[1:]); err != nil {
fmt.Fprintf(cli.ErrStream, "Error parsing arguments: %s\n", err)
return 1
}

if err := validateType(config.InputType); err != nil {
fmt.Fprintf(cli.ErrStream, "invalid input type: %s\n", err)
return 1
}

if err := validateType(config.OutputType); err != nil {
fmt.Fprintf(cli.ErrStream, "invalid output type: %s\n", err)
return 1
}

if config.InputType == config.OutputType {
fmt.Fprintf(cli.ErrStream, "input type and output type must be different\n")
return 1
}

if fs.Arg(0) == "" {
fmt.Fprintf(cli.ErrStream, "directory is required\n")
return 1
}

config.Directory = fs.Arg(0)

dec, err := NewDecoder(config.InputType)
if err != nil {
fmt.Fprintf(cli.ErrStream, "failed to create decoder: %s\n", err)
return 1
}
enc, err := NewEncoder(config.OutputType)
if err != nil {
fmt.Fprintf(cli.ErrStream, "failed to create encoder: %s\n", err)
return 1
}
imgConv := &ImgConv{
Decoder: dec,
Encoder: enc,
TargetDir: config.Directory,
}
convertedFiles, err := imgConv.Run()
if err != nil {
fmt.Fprintf(cli.ErrStream, "failed to convert images: %s\n", err)
return 1
}

fmt.Fprintf(cli.OutStream, "converted %d files\n", len(convertedFiles))
for _, f := range convertedFiles {
fmt.Fprintf(cli.OutStream, "%s\n", f)
}

return 0
}
46 changes: 46 additions & 0 deletions kadai2/hiroya-w/cli_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package imgconv_test

import (
"bytes"
"fmt"
"os"
"strings"
"testing"

imgconv "github.com/Hiroya-W/gopherdojo-studyroom/kadai2/hiroya-w"
)

func TestCLI(t *testing.T) {
// t.Parallel()
tests := []struct {
options string
exitStatus int
want string
}{
{options: "", exitStatus: 1, want: "directory is required"},
{options: "-h", exitStatus: 1, want: "Usage"},
{options: "-input-type=bmp testdata", exitStatus: 1, want: "invalid input type:"},
{options: "-output-type=tiff testdata", exitStatus: 1, want: "invalid output type:"},
{options: "-input-type=jpg -output-type=jpg testdata", exitStatus: 1, want: "input type and output type must be different"},
{options: "testdata", exitStatus: 0, want: ""},
}

for _, test := range tests {
test := test
t.Run(fmt.Sprintf("Options:'%s'", test.options), func(t *testing.T) {
outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
cli := &imgconv.CLI{OutStream: outStream, ErrStream: errStream}

os.Args = append([]string{os.Args[0]}, strings.Split(test.options, " ")...)
exitStatus := cli.Run()

if exitStatus != test.exitStatus {
t.Errorf("exit status = %d, want %d", exitStatus, test.exitStatus)
}

if !strings.Contains(errStream.String(), test.want) {
t.Errorf("expected %q to eq %q", errStream.String(), test.want)
}
})
}
}
12 changes: 12 additions & 0 deletions kadai2/hiroya-w/cmd/imgconv/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import (
"os"

imgconv "github.com/Hiroya-W/gopherdojo-studyroom/kadai2/hiroya-w"
)

func main() {
cli := &imgconv.CLI{OutStream: os.Stdout, ErrStream: os.Stderr}
os.Exit(cli.Run())
}
3 changes: 3 additions & 0 deletions kadai2/hiroya-w/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/Hiroya-W/gopherdojo-studyroom/kadai2/hiroya-w

go 1.17
Empty file added kadai2/hiroya-w/go.sum
Empty file.
Loading