diff --git a/kadai1/nagaa052/.gitignore b/kadai1/nagaa052/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/kadai1/nagaa052/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/kadai1/nagaa052/Makefile b/kadai1/nagaa052/Makefile new file mode 100644 index 0000000..9ceaecf --- /dev/null +++ b/kadai1/nagaa052/Makefile @@ -0,0 +1,21 @@ +NAME := gocon + +GO ?= go +BUILD_DIR=./build +BINARY ?= $(BUILD_DIR)/$(NAME) + +.PHONY: all +all: clean test build + +.PHONY: test +test: + $(GO) test -v ./... + +.PHONY: clean +clean: + $(GO) clean + rm -f $(BINARY) + +.PHONY: build +build: + $(GO) build -o $(BINARY) -v diff --git a/kadai1/nagaa052/README.md b/kadai1/nagaa052/README.md new file mode 100644 index 0000000..f1dfbad --- /dev/null +++ b/kadai1/nagaa052/README.md @@ -0,0 +1,20 @@ +gocon +=== +image convert command by golang + +### Usage + +``` +Usage: + gocon [option] +Options: + -d string + Convert output directory. (default "out") + -f string + Convert image format. The input format is [In]:[Out]. image is jpeg|png. (default "jpeg:png") +``` + +#### Example +``` +$ gocon -f jpeg:png -d output image/jpegs +``` diff --git a/kadai1/nagaa052/go.mod b/kadai1/nagaa052/go.mod new file mode 100644 index 0000000..fe5d747 --- /dev/null +++ b/kadai1/nagaa052/go.mod @@ -0,0 +1 @@ +module github.com/gopherdojo/dojo5/kadai1/nagaa052 diff --git a/kadai1/nagaa052/internal/gocon/format.go b/kadai1/nagaa052/internal/gocon/format.go new file mode 100644 index 0000000..c0bf5fc --- /dev/null +++ b/kadai1/nagaa052/internal/gocon/format.go @@ -0,0 +1,34 @@ +package gocon + +import "fmt" + +// ImgFormat is a convertible image format. +type ImgFormat string + +const ( + JPEG ImgFormat = "jpeg" + PNG ImgFormat = "png" +) + +// String is converted to string type and returned. +func (i *ImgFormat) String() string { + return string(*i) +} + +// GetExtentions returns the extension of the target format. +func (i *ImgFormat) GetExtentions() ([]string, error) { + if !i.Exist() { + return nil, fmt.Errorf("Format that does not exist is an error") + } + + if *i == JPEG { + return []string{".jpeg", ".jpg"}, nil + } + + return []string{"." + string(*i)}, nil +} + +// Exist examines available formats. +func (i *ImgFormat) Exist() bool { + return *i == JPEG || *i == PNG +} diff --git a/kadai1/nagaa052/internal/gocon/format_test.go b/kadai1/nagaa052/internal/gocon/format_test.go new file mode 100644 index 0000000..8af539c --- /dev/null +++ b/kadai1/nagaa052/internal/gocon/format_test.go @@ -0,0 +1,60 @@ +package gocon_test + +import ( + "fmt" + "testing" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/internal/gocon" +) + +func TestGetExtentions(t *testing.T) { + errMessage := ` + Incorrect extension. + expected: %s + actual: %s + ` + + cases := []struct { + name string + format string + expected []string + isError bool + }{ + { + name: "success test", + format: "jpeg", + expected: []string{".jpeg", ".jpg"}, + isError: false, + }, + { + name: "format does not exist", + format: "hogehoge", + expected: []string{".hogehoge"}, + isError: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + i := gocon.ImgFormat(c.format) + actual, err := i.GetExtentions() + if c.isError { + if err == nil { + t.Error(err) + } + } else { + if err != nil { + t.Error(err) + } + + if len(actual) <= 0 { + t.Error(fmt.Sprintf(errMessage, c.expected, actual)) + } + + if c.expected[0] != actual[0] { + t.Error(fmt.Sprintf(errMessage, c.expected, actual)) + } + } + }) + } +} diff --git a/kadai1/nagaa052/internal/gocon/gocon.go b/kadai1/nagaa052/internal/gocon/gocon.go new file mode 100644 index 0000000..2656375 --- /dev/null +++ b/kadai1/nagaa052/internal/gocon/gocon.go @@ -0,0 +1,145 @@ +/* +Provides the ability to perform image conversion with gocon. +*/ +package gocon + +import ( + "fmt" + "io" + "os" + "path/filepath" + "strings" + "sync" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/pkg/convert" + "github.com/gopherdojo/dojo5/kadai1/nagaa052/pkg/search" +) + +const ( + ExitOK = iota + ExitError +) + +const ( + SuccessConvertFileMessageFmt string = "convert file : %s\n" +) + +type gocon struct { + SrcDir string + Options + outStream, errStream io.Writer +} + +// Options is a specifiable option. Default is DefaultOptions. +type Options struct { + FromFormat ImgFormat + ToFormat ImgFormat + DestDir string +} + +// DefaultOptions is the default value of Options. +var DefaultOptions = Options{ + FromFormat: JPEG, + ToFormat: PNG, + DestDir: "out", +} + +// New is Generate a new gocon. +func New(srcDir string, opt Options, outStream, errStream io.Writer) (*gocon, error) { + if srcDir == "" { + return nil, fmt.Errorf("target path is required") + } + + srcDir, err := filepath.Abs(srcDir) + if err != nil { + return nil, fmt.Errorf("Invalid directory specification") + } + + if _, err := os.Stat(srcDir); err != nil { + return nil, err + } + + if opt.FromFormat == "" { + opt.FromFormat = DefaultOptions.FromFormat + } + + if opt.ToFormat == "" { + opt.ToFormat = DefaultOptions.ToFormat + } + + if opt.DestDir == "" { + opt.DestDir = DefaultOptions.DestDir + } + + opt.DestDir, err = filepath.Abs(opt.DestDir) + if err != nil { + return nil, fmt.Errorf("Invalid directory specification") + } + + return &gocon{ + SrcDir: srcDir, + Options: opt, + outStream: outStream, + errStream: errStream, + }, nil +} + +// Run is executes gocon. +func (gc *gocon) Run() int { + + wg := &sync.WaitGroup{} + chw := make(chan string) + defer close(chw) + + ext, err := gc.FromFormat.GetExtentions() + if err != nil { + fmt.Fprintf(gc.errStream, "%+v\n", err) + return ExitError + } + + err = search.WalkWithExtHandle(gc.SrcDir, ext, + func(srcImgPath string, info os.FileInfo, err error) { + if err != nil { + fmt.Fprintf(gc.errStream, "%+v\n", err) + return + } + + wg.Add(1) + go func() { + defer wg.Done() + destFilePath, err := gc.convert(srcImgPath, info) + if err != nil { + fmt.Fprintf(gc.errStream, "%+v\n", err) + return + } + + fmt.Fprintf(gc.outStream, SuccessConvertFileMessageFmt, destFilePath) + }() + }) + if err != nil { + fmt.Fprintf(gc.errStream, "%+v\n", err) + return ExitError + } + + wg.Wait() + return ExitOK +} + +func (gc *gocon) convert(srcImgPath string, info os.FileInfo) (string, error) { + srcImgDir := strings.Replace(srcImgPath, "/"+info.Name(), "", -1) + destDir := strings.Replace(srcImgDir, gc.SrcDir, gc.DestDir, -1) + + con, err := convert.New(srcImgPath, destDir) + if err != nil { + return "", err + } + + switch gc.ToFormat { + case JPEG: + return con.ToJpeg(&convert.JpegOptions{}) + case PNG: + return con.ToPng() + default: + return "", fmt.Errorf("There is no convertible format") + } +} diff --git a/kadai1/nagaa052/internal/gocon/gocon_test.go b/kadai1/nagaa052/internal/gocon/gocon_test.go new file mode 100644 index 0000000..4daba29 --- /dev/null +++ b/kadai1/nagaa052/internal/gocon/gocon_test.go @@ -0,0 +1,82 @@ +package gocon_test + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/internal/gocon" +) + +func TestRun(t *testing.T) { + errMessage := ` + It was not converted properly. + Error: %v + ` + streamErrMessage := ` + Convert Error. + %v + ` + + srcDir, err := filepath.Abs(filepath.Join("testdata", t.Name())) + if err != nil { + t.Error(err) + } + destDir, err := filepath.Abs("out") + if err != nil { + t.Error(err) + } + + cases := []struct { + name string + options gocon.Options + expected int + isError bool + }{ + { + name: "Success Test", + options: gocon.Options{ + FromFormat: gocon.JPEG, + ToFormat: gocon.PNG, + DestDir: destDir, + }, + expected: gocon.ExitOK, + isError: false, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + outStream, errStream := new(bytes.Buffer), new(bytes.Buffer) + g, err := gocon.New(srcDir, c.options, outStream, errStream) + if !c.isError && err != nil { + t.Error(fmt.Sprintf("gocon make error : %+v", err)) + } + + actual := g.Run() + + if _, err := os.Stat(destDir); err == nil { + if err := os.RemoveAll(destDir); err != nil { + fmt.Println(err) + } + } + + if c.expected != actual { + t.Error(fmt.Sprintf(errMessage, c.expected, actual)) + } + + if errStream.String() != "" { + t.Error(fmt.Sprintf(streamErrMessage, errStream.String())) + } + + messageFmt := strings.Replace(gocon.SuccessConvertFileMessageFmt, "\n", "", -1) + expectedMessage := fmt.Sprintf(messageFmt, destDir) + if !strings.Contains(outStream.String(), expectedMessage) { + t.Error("Conversion failed") + } + }) + } +} diff --git a/kadai1/nagaa052/internal/gocon/testdata/TestRun/1.jpg b/kadai1/nagaa052/internal/gocon/testdata/TestRun/1.jpg new file mode 100644 index 0000000..81aa02b Binary files /dev/null and b/kadai1/nagaa052/internal/gocon/testdata/TestRun/1.jpg differ diff --git a/kadai1/nagaa052/internal/gocon/testdata/TestRun/dirA/1.jpg b/kadai1/nagaa052/internal/gocon/testdata/TestRun/dirA/1.jpg new file mode 100644 index 0000000..81aa02b Binary files /dev/null and b/kadai1/nagaa052/internal/gocon/testdata/TestRun/dirA/1.jpg differ diff --git a/kadai1/nagaa052/main.go b/kadai1/nagaa052/main.go new file mode 100644 index 0000000..df6f111 --- /dev/null +++ b/kadai1/nagaa052/main.go @@ -0,0 +1,83 @@ +package main + +import ( + "flag" + "fmt" + "io" + "os" + "strings" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/internal/gocon" +) + +var imageFormat string +var destDir string +var outStream io.Writer = os.Stdout +var errStream io.Writer = os.Stderr + +func init() { + flag.StringVar(&imageFormat, + "f", + gocon.DefaultOptions.FromFormat.String()+":"+gocon.DefaultOptions.ToFormat.String(), + "Convert image format. The input format is [In]:[Out].") + flag.StringVar(&destDir, + "d", + gocon.DefaultOptions.DestDir, + "Destination directory.") +} + +func main() { + + flag.Usage = usage + flag.Parse() + + if opt, err := parseOptions(); err != nil { + fmt.Printf("%s\n", err.Error()) + usage() + } else { + for _, srcDir := range flag.Args() { + gc, err := gocon.New(srcDir, *opt, outStream, errStream) + if err != nil { + fmt.Printf("%v\n", err.Error()) + os.Exit(1) + } + + os.Exit(gc.Run()) + } + } +} + +func parseOptions() (*gocon.Options, error) { + format := strings.Split(imageFormat, ":") + + if len(format) != 2 { + return nil, fmt.Errorf("invalid format") + } + + from := gocon.ImgFormat(format[0]) + to := gocon.ImgFormat(format[1]) + + if !from.Exist() || !to.Exist() { + return nil, fmt.Errorf("Format that does not exist is an error") + } + + if from == to { + return nil, fmt.Errorf("The same format specification is an error") + } + + return &gocon.Options{ + FromFormat: from, + ToFormat: to, + DestDir: destDir, + }, nil +} + +func usage() { + fmt.Fprintf(os.Stderr, ` +gocon is a tool for ... +Usage: + gocon [option] +Options: +`) + flag.PrintDefaults() +} diff --git a/kadai1/nagaa052/main_test.go b/kadai1/nagaa052/main_test.go new file mode 100644 index 0000000..d487089 --- /dev/null +++ b/kadai1/nagaa052/main_test.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/internal/gocon" +) + +func TestParseOptions(t *testing.T) { + + cases := []struct { + name string + expectedFrom string + expectedTo string + isError bool + }{ + { + name: "Parse success", + expectedFrom: "png", + expectedTo: "jpeg", + isError: false, + }, + { + name: "The same format specification is an error", + expectedFrom: "jpeg", + expectedTo: "jpeg", + isError: true, + }, + { + name: "Format that does not exist is an error", + expectedFrom: "png", + expectedTo: "jpeggg", + isError: true, + }, + } + + errMessage := ` + Expected and actual are different. + expected: %v + actual: %v + ` + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + imageFormat = fmt.Sprintf("%s:%s", c.expectedFrom, c.expectedTo) + opt, err := parseOptions() + + if c.isError { + if err == nil { + t.Errorf("No error occurred. Test : %s", c.name) + } + } else { + if opt.FromFormat != gocon.ImgFormat(c.expectedFrom) { + t.Error(fmt.Sprintf(errMessage, gocon.ImgFormat(c.expectedFrom), opt.FromFormat)) + } + if opt.ToFormat != gocon.ImgFormat(c.expectedTo) { + t.Error(fmt.Sprintf(errMessage, gocon.ImgFormat(c.expectedTo), opt.ToFormat)) + } + } + }) + } +} diff --git a/kadai1/nagaa052/pkg/convert/convert.go b/kadai1/nagaa052/pkg/convert/convert.go new file mode 100644 index 0000000..4eb7462 --- /dev/null +++ b/kadai1/nagaa052/pkg/convert/convert.go @@ -0,0 +1,101 @@ +/* +Package 'convert' provides image conversion +*/ +package convert + +import ( + "image" + "image/jpeg" + "image/png" + "os" + "path/filepath" + "strings" +) + +// Convert is a structure required for conversion +type Convert struct { + SrcPath string + FileName string + DestDir string +} + +// New generates and returns a new Convert. +// An error is returned if the original directory for image conversion does not exist. +func New(srcPath string, destDir string) (*Convert, error) { + stat, err := os.Stat(srcPath) + if err != nil { + return nil, err + } + + return &Convert{ + SrcPath: srcPath, + FileName: stat.Name(), + DestDir: destDir, + }, nil +} + +// JpegOptions is an option to convert Jpeg +type JpegOptions jpeg.Options + +// ToJpeg does Jpeg conversion. You can specify conversion options with JpegOptions. +func (c *Convert) ToJpeg(opt *JpegOptions) (string, error) { + + image, outFilePath, err := c.convertPreProcessing(".jpeg") + if err != nil { + return "", err + } + + f, err := os.OpenFile(outFilePath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0755) + if err != nil { + return "", err + } + defer f.Close() + + jo := jpeg.Options(*opt) + return outFilePath, jpeg.Encode(f, *image, &jo) +} + +// ToPng does Png conversion +func (c *Convert) ToPng() (string, error) { + + image, outFilePath, err := c.convertPreProcessing(".png") + if err != nil { + return "", err + } + + f, err := os.OpenFile(outFilePath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0755) + if err != nil { + return "", err + } + + return outFilePath, png.Encode(f, *image) +} + +func (c *Convert) convertPreProcessing(ext string) (*image.Image, string, error) { + file, err := os.Open(c.SrcPath) + if err != nil { + return nil, "", err + } + defer file.Close() + + image, _, err := image.Decode(file) + if err != nil { + return nil, "", err + } + + _, err = os.Stat(c.DestDir) + if err != nil { + if err := os.MkdirAll(c.DestDir, 0777); err != nil { + return nil, "", err + } + } + + outFilePath := filepath.Join(c.DestDir, replaceExt(c.FileName, ext)) + + return &image, outFilePath, nil +} + +func replaceExt(filePath, to string) string { + ext := filepath.Ext(filePath) + return strings.Replace(filePath, ext, to, -1) +} diff --git a/kadai1/nagaa052/pkg/convert/convert_test.go b/kadai1/nagaa052/pkg/convert/convert_test.go new file mode 100644 index 0000000..8ff1804 --- /dev/null +++ b/kadai1/nagaa052/pkg/convert/convert_test.go @@ -0,0 +1,128 @@ +package convert_test + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/pkg/convert" +) + +func TestToJpeg(t *testing.T) { + errMessage := ` + Expected and actual are different. + expected: %v + actual: %v + ` + + srcBase, err := filepath.Abs(filepath.Join("testdata", t.Name())) + if err != nil { + t.Error(err) + } + + destDir := filepath.Join(srcBase, "out") + + cases := []struct { + name string + srcPath string + expected string + isError bool + }{ + { + name: "Success Test", + srcPath: filepath.Join(srcBase, "1.png"), + expected: filepath.Join(destDir, "1.jpeg"), + isError: false, + }, + { + name: "Not an image file", + srcPath: filepath.Join(srcBase, "2.png"), + expected: "", + isError: true, + }, + { + name: "Error if DestDir already exists", + srcPath: filepath.Join(srcBase, "1.png"), + expected: "", + isError: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + con, err := convert.New(c.srcPath, destDir) + if err != nil { + t.Error(err) + } + + actual, err := con.ToJpeg(&convert.JpegOptions{}) + if c.isError { + if err == nil { + t.Errorf("No error occurred. Test : %s", c.name) + } + } else if actual != c.expected { + t.Error(fmt.Sprintf(errMessage, c.expected, actual)) + } + }) + } + + if _, err := os.Stat(destDir); err == nil { + if err := os.RemoveAll(destDir); err != nil { + fmt.Println(err) + } + } +} + +func TestToPng(t *testing.T) { + errMessage := ` + Expected and actual are different. + expected: %v + actual: %v + ` + + sourceBase, err := filepath.Abs(filepath.Join("testdata", t.Name())) + if err != nil { + t.Error(err) + } + + outDir := filepath.Join(sourceBase, "out") + + cases := []struct { + sourcePath string + expected string + isError bool + }{ + { + sourcePath: filepath.Join(sourceBase, "1.jpg"), + expected: filepath.Join(outDir, "1.png"), + isError: false, + }, + { + sourcePath: filepath.Join(sourceBase, "1.jpg"), + expected: "", + isError: true, + }, + } + for _, c := range cases { + con, err := convert.New(c.sourcePath, outDir) + if err != nil { + t.Error(err) + } + + actual, err := con.ToPng() + if c.isError && err == nil { + t.Error(err) + } + + if actual != c.expected { + t.Error(fmt.Sprintf(errMessage, c.expected, actual)) + } + } + + if _, err := os.Stat(outDir); err == nil { + if err := os.RemoveAll(outDir); err != nil { + fmt.Println(err) + } + } +} diff --git a/kadai1/nagaa052/pkg/convert/testdata/TestToJpeg/1.png b/kadai1/nagaa052/pkg/convert/testdata/TestToJpeg/1.png new file mode 100644 index 0000000..1cebe40 Binary files /dev/null and b/kadai1/nagaa052/pkg/convert/testdata/TestToJpeg/1.png differ diff --git a/kadai1/nagaa052/pkg/convert/testdata/TestToJpeg/2.png b/kadai1/nagaa052/pkg/convert/testdata/TestToJpeg/2.png new file mode 100644 index 0000000..5adcd3d --- /dev/null +++ b/kadai1/nagaa052/pkg/convert/testdata/TestToJpeg/2.png @@ -0,0 +1 @@ +This is a text file. diff --git a/kadai1/nagaa052/pkg/convert/testdata/TestToPng/1.jpg b/kadai1/nagaa052/pkg/convert/testdata/TestToPng/1.jpg new file mode 100644 index 0000000..81aa02b Binary files /dev/null and b/kadai1/nagaa052/pkg/convert/testdata/TestToPng/1.jpg differ diff --git a/kadai1/nagaa052/pkg/search/search.go b/kadai1/nagaa052/pkg/search/search.go new file mode 100644 index 0000000..3f303c7 --- /dev/null +++ b/kadai1/nagaa052/pkg/search/search.go @@ -0,0 +1,29 @@ +/* +Package 'search' provides file search function +*/ +package search + +import ( + "os" + "path/filepath" +) + +// WalkWithExtHandle searches the target directory recursively for files with matching extensions. +// If a matching file is found, the handle function is called. +func WalkWithExtHandle(dir string, ext []string, handle func(string, os.FileInfo, error)) error { + return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if contains(ext, filepath.Ext(path)) { + handle(path, info, err) + } + return nil + }) +} + +func contains(s []string, e string) bool { + for _, v := range s { + if e == v { + return true + } + } + return false +} diff --git a/kadai1/nagaa052/pkg/search/search_test.go b/kadai1/nagaa052/pkg/search/search_test.go new file mode 100644 index 0000000..66fa8fb --- /dev/null +++ b/kadai1/nagaa052/pkg/search/search_test.go @@ -0,0 +1,40 @@ +package search_test + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/gopherdojo/dojo5/kadai1/nagaa052/pkg/search" +) + +func TestWalk(t *testing.T) { + errMessage := ` + The quantity found is different. + expected: %d + actual: %d + ` + cases := []struct { + name string + ext []string + expected int + }{ + {name: "search jpg", ext: []string{".jpg"}, expected: 4}, + {name: "search png", ext: []string{".png"}, expected: 2}, + {name: "search jpg and png", ext: []string{".jpg", ".png"}, expected: 6}, + } + + path := filepath.Join("testdata", t.Name()) + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + actual := 0 + search.WalkWithExtHandle(path, c.ext, func(path string, info os.FileInfo, err error) { + actual++ + }) + if c.expected != actual { + t.Error(fmt.Sprintf(errMessage, c.expected, actual)) + } + }) + } +} diff --git a/kadai1/nagaa052/pkg/search/testdata/TestWalk/1.jpg b/kadai1/nagaa052/pkg/search/testdata/TestWalk/1.jpg new file mode 100644 index 0000000..81aa02b Binary files /dev/null and b/kadai1/nagaa052/pkg/search/testdata/TestWalk/1.jpg differ diff --git a/kadai1/nagaa052/pkg/search/testdata/TestWalk/2.jpg b/kadai1/nagaa052/pkg/search/testdata/TestWalk/2.jpg new file mode 100644 index 0000000..be5b07a Binary files /dev/null and b/kadai1/nagaa052/pkg/search/testdata/TestWalk/2.jpg differ diff --git a/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/1.png b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/1.png new file mode 100644 index 0000000..1cebe40 Binary files /dev/null and b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/1.png differ diff --git a/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/3.jpg b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/3.jpg new file mode 100644 index 0000000..d61a2f5 Binary files /dev/null and b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/3.jpg differ diff --git a/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/dirB/2.png b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/dirB/2.png new file mode 100644 index 0000000..56db80f Binary files /dev/null and b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/dirB/2.png differ diff --git a/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/dirB/4.jpg b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/dirB/4.jpg new file mode 100644 index 0000000..6b71675 Binary files /dev/null and b/kadai1/nagaa052/pkg/search/testdata/TestWalk/dirA/dirB/4.jpg differ