From 57af4da0b1ab5b8696da9fe9c5e759dc8ff79e33 Mon Sep 17 00:00:00 2001 From: Inhere Date: Wed, 14 Jun 2023 10:12:49 +0800 Subject: [PATCH] :white_check_mark: test: fsutil - add more unit tests for fsutil and finder --- fsutil/find_test.go | 31 +++++-------- fsutil/finder/README.md | 4 +- fsutil/finder/elem.go | 2 +- fsutil/finder/finder.go | 5 +- fsutil/finder/finder_test.go | 1 + fsutil/finder/matcher.go | 84 +++++++++++++++++----------------- fsutil/finder/matchers.go | 2 +- fsutil/finder/matchers_test.go | 34 +++++++++++++- fsutil/fsutil_test.go | 11 +++++ fsutil/opwrite_test.go | 16 +++++++ 10 files changed, 122 insertions(+), 68 deletions(-) diff --git a/fsutil/find_test.go b/fsutil/find_test.go index 6fa759e9a..95be9ec7b 100644 --- a/fsutil/find_test.go +++ b/fsutil/find_test.go @@ -9,6 +9,7 @@ import ( "github.com/gookit/goutil/errorx" "github.com/gookit/goutil/fsutil" "github.com/gookit/goutil/testutil/assert" + "github.com/gookit/goutil/testutil/fakeobj" ) func TestSearchNameUp(t *testing.T) { @@ -28,30 +29,20 @@ func TestSearchNameUp(t *testing.T) { assert.Empty(t, p) } -type dirEnt struct { - typ fs.FileMode - isDir bool - name string -} - -func (d *dirEnt) Name() string { - return d.name -} - -func (d *dirEnt) IsDir() bool { - return d.isDir -} - -func (d *dirEnt) Type() fs.FileMode { - return d.typ -} +func TestGlobWithFunc(t *testing.T) { + var paths []string + err := fsutil.GlobWithFunc("testdata/*", func(fpath string) error { + paths = append(paths, fpath) + return nil + }) -func (d *dirEnt) Info() (fs.FileInfo, error) { - panic("implement me") + assert.NoErr(t, err) + assert.NotEmpty(t, paths) + assert.Contains(t, paths, "testdata/test.jpg") } func TestApplyFilters(t *testing.T) { - e1 := &dirEnt{name: "some-backup"} + e1 := &fakeobj.DirEntry{Nam: "some-backup"} f1 := fsutil.ExcludeSuffix("-backup") assert.False(t, f1("", e1)) diff --git a/fsutil/finder/README.md b/fsutil/finder/README.md index 1fe5af564..d695ae5e0 100644 --- a/fsutil/finder/README.md +++ b/fsutil/finder/README.md @@ -2,7 +2,9 @@ [![GoDoc](https://godoc.org/github.com/goutil/fsutil/finder?status.svg)](https://godoc.org/github.com/goutil/fsutil/finder) -`finder` provide a finding tool for find files or dirs, and with some built-in matchers. +`finder` Provides a simple and convenient filedir lookup function, +supports filtering, excluding, matching, ignoring, etc. +and with some commonly built-in matchers. ## Usage diff --git a/fsutil/finder/elem.go b/fsutil/finder/elem.go index 752b2bbb6..3edb3de70 100644 --- a/fsutil/finder/elem.go +++ b/fsutil/finder/elem.go @@ -9,7 +9,7 @@ import ( // Elem of find file/dir path result type Elem interface { fs.DirEntry - // Path get file/dir path. eg: "/path/to/file.go" + // Path get file/dir full path. eg: "/path/to/file.go" Path() string // Info get file info. like fs.DirEntry.Info(), but will cache result. Info() (fs.FileInfo, error) diff --git a/fsutil/finder/finder.go b/fsutil/finder/finder.go index 29f4e3523..02cf72769 100644 --- a/fsutil/finder/finder.go +++ b/fsutil/finder/finder.go @@ -1,5 +1,6 @@ -// Package finder provide a finding tool for find files or dirs, -// and with some built-in matchers. +// Package finder Provides a simple and convenient filedir lookup function, +// supports filtering, excluding, matching, ignoring, etc. +// and with some commonly built-in matchers. package finder import ( diff --git a/fsutil/finder/finder_test.go b/fsutil/finder/finder_test.go index fd9fc417e..79cb0a29b 100644 --- a/fsutil/finder/finder_test.go +++ b/fsutil/finder/finder_test.go @@ -25,6 +25,7 @@ func TestFinder_findFile(t *testing.T) { assert.Nil(t, f.Err()) assert.NotEmpty(t, f.String()) + assert.NotEmpty(t, f.Config()) assert.Eq(t, 0, f.CacheNum()) // find paths diff --git a/fsutil/finder/matcher.go b/fsutil/finder/matcher.go index 1daed89e3..eb4dc83cf 100644 --- a/fsutil/finder/matcher.go +++ b/fsutil/finder/matcher.go @@ -22,24 +22,24 @@ func (fn MatcherFunc) Apply(elem Elem) bool { // ------------------ Multi matcher wrapper ------------------ -// MultiFilter wrapper for multi matchers -type MultiFilter struct { - Before Matcher - Filters []Matcher +// MultiMatcher wrapper for multi matchers +type MultiMatcher struct { + Before Matcher + Matchers []Matcher } // Add matchers -func (mf *MultiFilter) Add(fls ...Matcher) { - mf.Filters = append(mf.Filters, fls...) +func (mf *MultiMatcher) Add(fls ...Matcher) { + mf.Matchers = append(mf.Matchers, fls...) } -// Apply check file path. return False will filter this file. -func (mf *MultiFilter) Apply(el Elem) bool { +// Apply check file path is match. +func (mf *MultiMatcher) Apply(el Elem) bool { if mf.Before != nil && !mf.Before.Apply(el) { return false } - for _, fl := range mf.Filters { + for _, fl := range mf.Matchers { if !fl.Apply(el) { return false } @@ -47,49 +47,49 @@ func (mf *MultiFilter) Apply(el Elem) bool { return true } -// NewDirFilters create a new dir matchers -func NewDirFilters(fls ...Matcher) *MultiFilter { - return &MultiFilter{ - Before: MatchDir, - Filters: fls, +// NewDirMatchers create a new dir matchers +func NewDirMatchers(fls ...Matcher) *MultiMatcher { + return &MultiMatcher{ + Before: MatchDir, + Matchers: fls, } } -// NewFileFilters create a new dir matchers -func NewFileFilters(fls ...Matcher) *MultiFilter { - return &MultiFilter{ - Before: MatchFile, - Filters: fls, +// NewFileMatchers create a new dir matchers +func NewFileMatchers(fls ...Matcher) *MultiMatcher { + return &MultiMatcher{ + Before: MatchFile, + Matchers: fls, } } // ------------------ Body Matcher ------------------ -// BodyFilter for filter file contents. -type BodyFilter interface { - Apply(filePath string, buf *bytes.Buffer) bool +// BodyMatcher for match file contents. +type BodyMatcher interface { + Apply(filePath string, body *bytes.Buffer) bool } -// BodyMatcherFunc for filter file contents. -type BodyMatcherFunc func(filePath string, buf *bytes.Buffer) bool +// BodyMatcherFunc for match file contents. +type BodyMatcherFunc func(filePath string, body *bytes.Buffer) bool -// Apply for filter file contents. -func (fn BodyMatcherFunc) Apply(filePath string, buf *bytes.Buffer) bool { - return fn(filePath, buf) +// Apply for match file contents. +func (fn BodyMatcherFunc) Apply(filePath string, body *bytes.Buffer) bool { + return fn(filePath, body) } -// BodyFilters multi body matchers as Matcher -type BodyFilters struct { - Filters []BodyFilter +// BodyMatchers multi body matchers as Matcher +type BodyMatchers struct { + Matchers []BodyMatcher } -// NewBodyFilters create a new body matchers +// NewBodyMatchers create a new body matchers // // Usage: // -// bf := finder.NewBodyFilters( +// bf := finder.NewBodyMatchers( // finder.BodyMatcherFunc(func(filePath string, buf *bytes.Buffer) bool { -// // filter file contents +// // match file contents // return true // }), // ) @@ -98,19 +98,19 @@ type BodyFilters struct { // for el := range es { // fmt.Println(el.Path()) // } -func NewBodyFilters(fls ...BodyFilter) *BodyFilters { - return &BodyFilters{ - Filters: fls, +func NewBodyMatchers(fls ...BodyMatcher) *BodyMatchers { + return &BodyMatchers{ + Matchers: fls, } } -// AddFilter add matchers -func (mf *BodyFilters) AddFilter(fls ...BodyFilter) { - mf.Filters = append(mf.Filters, fls...) +// AddMatcher add matchers +func (mf *BodyMatchers) AddMatcher(fls ...BodyMatcher) { + mf.Matchers = append(mf.Matchers, fls...) } -// Apply check file path. return False will filter this file. -func (mf *BodyFilters) Apply(el Elem) bool { +// Apply check file contents is match. +func (mf *BodyMatchers) Apply(el Elem) bool { if el.IsDir() { return false } @@ -130,7 +130,7 @@ func (mf *BodyFilters) Apply(el Elem) bool { file.Close() // apply matchers - for _, fl := range mf.Filters { + for _, fl := range mf.Matchers { if !fl.Apply(el.Path(), buf) { return false } diff --git a/fsutil/finder/matchers.go b/fsutil/finder/matchers.go index 4d408a96c..fc17975f3 100644 --- a/fsutil/finder/matchers.go +++ b/fsutil/finder/matchers.go @@ -136,7 +136,7 @@ func MatchSuffixes(suffixes []string) MatcherFunc { // // f := NewFinder('path/to/dir') // f.Add(MatchPath("need/path")) -func MatchPath(subPaths []string) MatcherFunc { return MatchPaths(subPaths) } +func MatchPath(subPaths ...string) MatcherFunc { return MatchPaths(subPaths) } // MatchPaths match file/dir by given sub paths. func MatchPaths(subPaths []string) MatcherFunc { diff --git a/fsutil/finder/matchers_test.go b/fsutil/finder/matchers_test.go index f123c2c68..061104433 100644 --- a/fsutil/finder/matchers_test.go +++ b/fsutil/finder/matchers_test.go @@ -12,8 +12,29 @@ func newMockElem(fp string, isDir ...bool) finder.Elem { return finder.NewElem(fp, testutil.NewDirEnt(fp, isDir...)) } -func TestFilters_simple(t *testing.T) { +func TestMultiMatcher(t *testing.T) { + mf := finder.NewDirMatchers(finder.MatchPath("sub/path")) + assert.NotEmpty(t, mf) + + mf.Add(finder.MatchName("dir")) + + el := newMockElem("/some/sub/path/dir", true) + assert.True(t, mf.Apply(el)) + + mf = finder.NewFileMatchers(finder.MatchPrefix("some_")) + assert.NotEmpty(t, mf) + mf.Add( + finder.GlobMatch("*_file.go"), + finder.NameLike("some%"), + ) + + el = newMockElem("/some/sub/path/some_file.go") + assert.True(t, mf.Apply(el)) +} + +func TestMatchers_simple(t *testing.T) { el := newMockElem("path/some.txt") + el1 := newMockElem("path/some_file.txt") fn := finder.MatcherFunc(func(el finder.Elem) bool { return false }) @@ -37,6 +58,17 @@ func TestFilters_simple(t *testing.T) { assert.True(t, fn(el)) fn = finder.MatchSuffix("not-exist.txt") assert.False(t, fn(el)) + + // MatchPrefix + fn = finder.MatchPrefix("some_") + assert.False(t, fn(el)) + assert.True(t, fn(el1)) + + // MatchPath + fn = finder.MatchPath("path/some") + assert.True(t, fn(el)) + fn = finder.MatchPath("not-exist/path") + assert.False(t, fn(el)) } func TestRegexMatch(t *testing.T) { diff --git a/fsutil/fsutil_test.go b/fsutil/fsutil_test.go index 51aaf91fe..07626bb99 100644 --- a/fsutil/fsutil_test.go +++ b/fsutil/fsutil_test.go @@ -2,12 +2,23 @@ package fsutil_test import ( "bytes" + "io/fs" "testing" + "github.com/gookit/goutil/basefn" "github.com/gookit/goutil/fsutil" "github.com/gookit/goutil/testutil/assert" ) +func TestMain(m *testing.M) { + err := fsutil.RemoveSub("./testdata", func(fPath string, ent fs.DirEntry) bool { + return fsutil.PathMatch(ent.Name(), "*.txt") + }) + basefn.MustOK(err) + + m.Run() +} + func TestMimeType(t *testing.T) { assert.Eq(t, "", fsutil.MimeType("")) assert.Eq(t, "", fsutil.MimeType("not-exist")) diff --git a/fsutil/opwrite_test.go b/fsutil/opwrite_test.go index e4d425fbd..9794a80f2 100644 --- a/fsutil/opwrite_test.go +++ b/fsutil/opwrite_test.go @@ -24,4 +24,20 @@ func TestMustCopyFile(t *testing.T) { str, err := fsutil.ReadStringOrErr(dstPath) assert.NoErr(t, err) assert.Eq(t, "hello", str) + + assert.NoErr(t, fsutil.RmFileIfExist(srcPath)) + assert.NoErr(t, fsutil.RmIfExist(srcPath)) // repeat delete +} + +func TestWriteFile(t *testing.T) { + tempFile := "./testdata/write-file.txt" + + err := fsutil.WriteFile(tempFile, []byte("hello\ngolang"), 0644) + assert.NoErr(t, err) + assert.Eq(t, []byte("hello\ngolang"), fsutil.MustReadFile(tempFile)) + + // write invalid data + assert.Panics(t, func() { + _ = fsutil.WriteFile(tempFile, []string{"hello"}, 0644) + }) }