fstest.MapFS ReadDir does not set name field for entry.Name()

237 views
Skip to first unread message

Kalen Krempely

unread,
Mar 23, 2022, 5:01:28 PM3/23/22
to golang-nuts
I am trying to use fstest.MapFS to help with testing, but I noticed the mapfs implementation of ReadDir does not set the name field which is quite problematic as I rely on that in my code.

Example Test Code:
t.Run("some test", func(t *testing.T) {
   fs := fstest.MapFS{
      "/some/long/test/path_hi_there": {Mode: fs.ModeDir},
   }

   err := VerifyDir(fs, "/some/long/test/path_hi_there")
   if err != nil {
      fmt.Println("unexpected error %+v", err)
   }
})

Snippet of Code:
func VerifyDir(fsys fs.FS, dir string) error {
   entries, err := fs.ReadDir(fsys, ".")
   if err != nil {
      return err
   }

   for _, entry := range entries {
      if !entry.IsDir() {
         continue
      }
     
      fmt.Println("expected entry.Name() to not be empty:", entry.Name())
      path := filepath.Join(dir, entry.Name())
      // do stuff with path...
   }

   return nil
}

Any ideas around this? Any practical examples of using fstest.MapFS to learn from?

Ian Lance Taylor

unread,
Mar 23, 2022, 5:12:24 PM3/23/22
to Kalen Krempely, golang-nuts
As far as I can tell testing.MapFS.ReadDir does return values for
which the Name method returns a non-empty string. Can you show a
complete, stand-alone, program that demonstrates the problem you are
describing? Thanks.

Note that in normal use the strings used as names when initialization
a testing.MapFS should not start with a slash. See
https://pkg.go.dev/io/fs#ValidPath.

Ian

Kalen Krempely

unread,
Apr 2, 2022, 5:46:11 PM4/2/22
to golang-nuts
Thanks Ian for the reply!

1) I think I figured out what was going on. Basically, I need to pass the root path to my verifyDir function and just have the fstest.MapFS contain the sub elements, rather than the full paths.

That is, the example test code needs to be:

t.Run("some test", func(t *testing.T) {
   fs := fstest.MapFS{
      "test/path_hi_there": {Mode: fs.ModeDir},
   }

   err := VerifyDir(fs, "/some/long")

   if err != nil {
      fmt.Println("unexpected error %+v", err)
   }
})


2) As a follow up question I find it weird that VerifyDir needs to take in both a filesystem and the root path. (ie: `VerifyDir(fsys fs.FS, dir string)`) That is, the calling code will be something like VerifyDir(os.DirFS("/some/path"), "/some/path"), where /some/path is passed in twice essentially since there is no way to get the path from fs.FS. Is this common? Or am I miss understanding something?

Ian Lance Taylor

unread,
Apr 2, 2022, 10:10:02 PM4/2/22
to Kalen Krempely, golang-nuts
On Sat, Apr 2, 2022 at 2:46 PM Kalen Krempely <kal...@gmail.com> wrote:
>
> 2) As a follow up question I find it weird that VerifyDir needs to take in both a filesystem and the root path. (ie: `VerifyDir(fsys fs.FS, dir string)`) That is, the calling code will be something like VerifyDir(os.DirFS("/some/path"), "/some/path"), where /some/path is passed in twice essentially since there is no way to get the path from fs.FS. Is this common? Or am I miss understanding something?

That is correct: there is no way to get the path from fs.FS. In
general, an fs.FS can be anything that looks like a file system, such
as a zip file; it need not have a path at all.

Ian
Reply all
Reply to author
Forward
0 new messages