// TestFS tests a file system implementation. // It walks the entire tree of files in fsys, // opening and checking that each file behaves correctly. // It also checks that the file system contains at least the expected files. // As a special case, if no expected files are listed, fsys must be empty. // Otherwise, fsys must contain at least the listed files; it can also contain others. // The contents of fsys must not change concurrently with TestFS. // // If TestFS finds any misbehaviors, it returns either the first error or a // list of errors. Use [errors.Is] or [errors.As] to inspect. // // Typical usage inside a test is: // // if err := fstest.TestFS(myFS, "file/that/should/be/present"); err != nil { // t.Fatal(err) // } func TestFS(fsys fs.FS, expected ...string) error { … } func testFS(fsys fs.FS, expected ...string) error { … } type fsTester … // errorf adds an error to the list of errors. func (t *fsTester) errorf(format string, args ...any) { … } func (t *fsTester) openDir(dir string) fs.ReadDirFile { … } // checkDir checks the directory dir, which is expected to exist // (it is either the root or was found in a directory listing with IsDir true). func (t *fsTester) checkDir(dir string) { … } // formatEntry formats an fs.DirEntry into a string for error messages and comparison. func formatEntry(entry fs.DirEntry) string { … } // formatInfoEntry formats an fs.FileInfo into a string like the result of formatEntry, for error messages and comparison. func formatInfoEntry(info fs.FileInfo) string { … } // formatInfo formats an fs.FileInfo into a string for error messages and comparison. func formatInfo(info fs.FileInfo) string { … } // checkGlob checks that various glob patterns work if the file system implements GlobFS. func (t *fsTester) checkGlob(dir string, list []fs.DirEntry) { … } // checkStat checks that a direct stat of path matches entry, // which was found in the parent's directory listing. func (t *fsTester) checkStat(path string, entry fs.DirEntry) { … } // checkDirList checks that two directory lists contain the same files and file info. // The order of the lists need not match. func (t *fsTester) checkDirList(dir, desc string, list1, list2 []fs.DirEntry) { … } // checkFile checks that basic file reading works correctly. func (t *fsTester) checkFile(file string) { … } func (t *fsTester) checkFileRead(file, desc string, data1, data2 []byte) { … } // checkBadPath checks that various invalid forms of file's name cannot be opened using t.fsys.Open. func (t *fsTester) checkOpen(file string) { … } // checkBadPath checks that various invalid forms of file's name cannot be opened using open. func (t *fsTester) checkBadPath(file string, desc string, open func(string) error) { … }