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

Kadai3 1 sintan23 #77

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
Empty file added kadai2/sintan23/.gitkeep
Empty file.
37 changes: 37 additions & 0 deletions kadai2/sintan23/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
NAME := convertImage
VERSION := 0.0.1

SRC_PATH := ./src
SRC := $(SRC_PATH)/*.go
SRC_TEST := $(SRC_PATH)/convert
BIN_PATH := ./bin
OUTPUT_BIN := $(BIN_PATH)/$(NAME)

.PHONY: $(/bin/bash egrep -o ^[a-zA-Z_-]+: $(MAKEFILE_LIST) | sed 's/://')


all: test build

.PHONY: test
test:
## test
go test -v ${SRC_TEST} -coverprofile cover.out
go tool cover -func cover.out

.PHONY: build
build:
## build
mkdir -p $(BIN_PATH)
go build -o $(OUTPUT_BIN) $(SRC)
chmod 755 $(OUTPUT_BIN)

.PHONY: run
run:
## run
rm -f ./_data/jpg*.png
go run $(SRC)

.PHONY: clean
clean:
## clean
rm -rf $(BIN_PATH)/*
28 changes: 28 additions & 0 deletions kadai2/sintan23/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Gopher Dojo 3 - Kadai 2

# io.Readerとio.Writerについて調べてみよう

## 標準パッケージでどのように使われているか
* 標準パーケージに多く使われている。
* 入出力が必要なところは、ほとんどio.Readerとio.Writerを使っている。

## io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる
* 関数に渡す事により、入出力を抽象化している。
* ファイルやDBなど意識せず扱うことができる。
* 全体的に実装することにより、サービスによって挙動を変えることができる。
* テストする際にモックなどの実装がしやすくなる。

# テストを書いてみよう
* [convert_test.go]をご参照ください。

# テストのしやすさを考えてリファクタリングしてみる
* もっとできそうですが…取り急ぎUPします。

# テストのカバレッジを取ってみる
* make testで実行されるtestでカバレッジが表示されるようにしました。

# テーブル駆動テストを行う
* [convert_test.go]でテーブル駆動テストを実装しました。

# テストヘルパーを作ってみる
* [convert_test.go]でヘルパーが動作するように別関数にしてみました。
Binary file added kadai2/sintan23/_data/gif1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/sintan23/_data/jpg1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/sintan23/_data/jpg2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/sintan23/_data/jpg3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/sintan23/_data/png1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/sintan23/_data/png2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added kadai2/sintan23/bin/convertImage
Binary file not shown.
32 changes: 32 additions & 0 deletions kadai2/sintan23/cover.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
mode: set
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:46.31,50.34 3 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:66.2,66.15 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:50.34,51.16 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:51.16,54.14 2 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:54.14,58.5 3 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:59.9,62.4 2 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:66.15,68.3 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:71.54,74.9 2 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:79.2,81.12 2 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:75.49,76.28 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:84.51,90.2 4 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:92.42,97.2 3 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:99.31,107.27 5 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:117.2,117.14 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:107.27,115.3 3 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:120.36,121.27 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:121.27,122.10 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:128.3,128.47 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:123.31,124.16 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:125.35,126.20 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:132.25,134.2 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:136.23,138.2 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:140.35,142.2 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:144.28,146.2 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:148.33,150.2 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:152.26,154.2 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:157.24,158.16 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:158.16,160.3 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:163.25,164.11 1 1
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convert.go:164.11,166.3 1 0
gopher-dojo/dojo3/kadai2/sintan23/src/convert/convertToPng.go:9.63,21.2 6 1
167 changes: 167 additions & 0 deletions kadai2/sintan23/src/convert/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
ConvertImage
*/
package convert

import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"strconv"
"sync"
)

var (
toExt string
)

type Converter struct {
src string
toExt string
reader io.Reader
}

type Converters []Converter

var (
// デバックフラグ true:デバックコメント表示
DEBUG = false

// Goルーチンフラグ true:並列処理する
GOROUTINE = false

// ベースパス
basePath = ""

// デフォルト拡張子
baseExtension = ""

// フォルダから抽出する正規表現パターン
// (最後の/除去はGlobの方で実装済みだった)
basePattern = "/*."
)

func ConvertAll(toExt string) {
debug("- Convert From: " + getExtension() + " To: " + toExt)

var waitGroup sync.WaitGroup
for _, c := range getFileList() {
if GOROUTINE {
// goルーチン
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
err := c.Convert(toExt)
logErr(err)
}()
} else {
err := c.Convert(toExt)
logErr(err)
}
}

// チャネルを待つ
if GOROUTINE {
waitGroup.Wait()
}
}

func (c Converter) Convert(toExt string) (err error) {
debug("-- Doing... " + filepath.Ext(c.src) + " → " + toExt)

switch {
case getExtension() == "jpg" && toExt == "png":
c.ConvertJpegToPng(toExt)
}

debug("--- Output: " + c.getFilename(toExt))

return err
}

func (c Converter) getFilename(ext string) string {
d, f := filepath.Split(c.src)
f = filepath.Base(f[:len(f)-len(filepath.Ext(f))])
path := filepath.Join(d, f+"."+ext)

return path
}

func Open(src string) (io.Reader, error) {
r, err := os.Open(src)
logErr(err)

return r, err
}

func getFileList() Converters {
var files Converters

debug("- Find Pattern: ", getPath()+getPattern())

list, err := filepath.Glob(getPath() + getPattern())
logErr(err)

for _, src := range list {
r, err := Open(src)
logErr(err)
files = append(files, Converter{
src,
toExt,
r,
})
}

return files
}

func SetOpts(opts map[string]bool) {
for k, flg := range opts {
switch {
case k == "debugFlg" && flg:
DEBUG = true
case k == "goroutineFlg" && flg:
GOROUTINE = true
}
debug("Option:", k, strconv.FormatBool(flg))
}
}

func SetPath(d *string) {
basePath = *d
}

func getPath() string {
return basePath
}

func SetExtension(fromExt string) {
baseExtension = fromExt
}

func getExtension() string {
return baseExtension
}

func SetPattern(pattern string) {
basePattern = pattern
}

func getPattern() string {
return basePattern + getExtension()
}

// Errorチェック
func logErr(err error) {
if err != nil {
log.Fatal(err)
}
}

func debug(m ...string) {
if DEBUG {
fmt.Printf("%+v\n", m)
}
}
21 changes: 21 additions & 0 deletions kadai2/sintan23/src/convert/convertToPng.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package convert

import (
"image/jpeg"
"image/png"
"os"
)

func (c Converter) ConvertJpegToPng(toExt string) (err error) {
img, err := jpeg.Decode(c.reader)
logErr(err)

// 空ファイル作成
out, err := os.Create(c.getFilename(toExt))
logErr(err)

// pngフォーマットで書き込み
err = png.Encode(out, img)

return err
}
104 changes: 104 additions & 0 deletions kadai2/sintan23/src/convert/convert_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
ConvertImage Test
*/
package convert

import (
"os"
"testing"
)

type Case = struct {
name string
src string
toExt string
}

func TestConvertAll(t *testing.T) {
var convertTests = []struct {
caseName string
toExt string
}{
{caseName: "Test Convert Jpg to Png 1", toExt: "png"},
{caseName: "Test Convert Jpg to Png 2", toExt: "png"},
}
for _, c := range convertTests {
t.Run(
c.caseName, func(t *testing.T) {
ConvertAll("png")
})
}
}

func TestConvert(t *testing.T) {
var convertTests = []Case{
{name: "Test Convert Jpg to Png", src: "../../_data/jpg1.jpg", toExt: "png"},
}

for _, tt := range convertTests {
testConvert(t, tt)
}
}

func testConvert(t *testing.T, c Case) {
t.Helper()

r, err := os.Open(c.src)
if err != nil {
t.Fatalf("Open error = %v", err)
}

ct := Converter{
c.src,
c.toExt,
r,
}

t.Run(c.name, func(t *testing.T) {
err := ct.Convert(ct.toExt)
if err != nil {
t.Errorf("Convert error = %v", err)
}
})
}

func TestConvertJpegToPng(t *testing.T) {
var convertTests = []struct {
caseName string
src string
toExt string
}{
{caseName: "Test ConvertJpegToPng", src: "../../_data/jpg1.jpg", toExt: "png"},
}

for _, c := range convertTests {
t.Run(
c.caseName, func(t *testing.T) {
r, err := Open(c.src)
logErr(err)
ct := Converter{
c.src,
c.toExt,
r,
}
ct.ConvertJpegToPng(c.toExt)
})
}
}

func TestLogErr(t *testing.T) {
var convertTests = []struct {
caseName string
src string
}{
{caseName: "Test Open+LogErr", src: "../../_data/jpg1.jpg"},
}

for _, c := range convertTests {
t.Run(
c.caseName, func(t *testing.T) {
_, err := Open(c.src)
logErr(err)
})
}
}
Loading