Source file src/testing/fstest/mapfs_test.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fstest
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"io/fs"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  func TestMapFS(t *testing.T) {
    17  	m := MapFS{
    18  		"hello":             {Data: []byte("hello, world\n")},
    19  		"fortune/k/ken.txt": {Data: []byte("If a program is too slow, it must have a loop.\n")},
    20  	}
    21  	if err := TestFS(m, "hello", "fortune", "fortune/k", "fortune/k/ken.txt"); err != nil {
    22  		t.Fatal(err)
    23  	}
    24  }
    25  
    26  func TestMapFSChmodDot(t *testing.T) {
    27  	m := MapFS{
    28  		"a/b.txt": &MapFile{Mode: 0666},
    29  		".":       &MapFile{Mode: 0777 | fs.ModeDir},
    30  	}
    31  	buf := new(strings.Builder)
    32  	fs.WalkDir(m, ".", func(path string, d fs.DirEntry, err error) error {
    33  		fi, err := d.Info()
    34  		if err != nil {
    35  			return err
    36  		}
    37  		fmt.Fprintf(buf, "%s: %v\n", path, fi.Mode())
    38  		return nil
    39  	})
    40  	want := `
    41  .: drwxrwxrwx
    42  a: dr-xr-xr-x
    43  a/b.txt: -rw-rw-rw-
    44  `[1:]
    45  	got := buf.String()
    46  	if want != got {
    47  		t.Errorf("MapFS modes want:\n%s\ngot:\n%s\n", want, got)
    48  	}
    49  }
    50  
    51  func TestMapFSFileInfoName(t *testing.T) {
    52  	m := MapFS{
    53  		"path/to/b.txt": &MapFile{},
    54  	}
    55  	info, _ := m.Stat("path/to/b.txt")
    56  	want := "b.txt"
    57  	got := info.Name()
    58  	if want != got {
    59  		t.Errorf("MapFS FileInfo.Name want:\n%s\ngot:\n%s\n", want, got)
    60  	}
    61  }
    62  
    63  func TestMapFSSymlink(t *testing.T) {
    64  	const fileContent = "If a program is too slow, it must have a loop.\n"
    65  	m := MapFS{
    66  		"fortune/k/ken.txt": {Data: []byte(fileContent)},
    67  		"dirlink":           {Data: []byte("fortune/k"), Mode: fs.ModeSymlink},
    68  		"linklink":          {Data: []byte("dirlink"), Mode: fs.ModeSymlink},
    69  		"ken.txt":           {Data: []byte("dirlink/ken.txt"), Mode: fs.ModeSymlink},
    70  	}
    71  	if err := TestFS(m, "fortune/k/ken.txt", "dirlink", "ken.txt", "linklink"); err != nil {
    72  		t.Error(err)
    73  	}
    74  
    75  	gotData, err := fs.ReadFile(m, "ken.txt")
    76  	if string(gotData) != fileContent || err != nil {
    77  		t.Errorf("fs.ReadFile(m, \"ken.txt\") = %q, %v; want %q, <nil>", gotData, err, fileContent)
    78  	}
    79  	gotLink, err := fs.ReadLink(m, "dirlink")
    80  	if want := "fortune/k"; gotLink != want || err != nil {
    81  		t.Errorf("fs.ReadLink(m, \"dirlink\") = %q, %v; want %q, <nil>", gotLink, err, fileContent)
    82  	}
    83  	gotInfo, err := fs.Lstat(m, "dirlink")
    84  	if err != nil {
    85  		t.Errorf("fs.Lstat(m, \"dirlink\") = _, %v; want _, <nil>", err)
    86  	} else {
    87  		if got, want := gotInfo.Name(), "dirlink"; got != want {
    88  			t.Errorf("fs.Lstat(m, \"dirlink\").Name() = %q; want %q", got, want)
    89  		}
    90  		if got, want := gotInfo.Mode(), fs.ModeSymlink; got != want {
    91  			t.Errorf("fs.Lstat(m, \"dirlink\").Mode() = %v; want %v", got, want)
    92  		}
    93  	}
    94  	gotInfo, err = fs.Stat(m, "dirlink")
    95  	if err != nil {
    96  		t.Errorf("fs.Stat(m, \"dirlink\") = _, %v; want _, <nil>", err)
    97  	} else {
    98  		if got, want := gotInfo.Name(), "dirlink"; got != want {
    99  			t.Errorf("fs.Stat(m, \"dirlink\").Name() = %q; want %q", got, want)
   100  		}
   101  		if got, want := gotInfo.Mode(), fs.ModeDir|0555; got != want {
   102  			t.Errorf("fs.Stat(m, \"dirlink\").Mode() = %v; want %v", got, want)
   103  		}
   104  	}
   105  	gotInfo, err = fs.Lstat(m, "linklink")
   106  	if err != nil {
   107  		t.Errorf("fs.Lstat(m, \"linklink\") = _, %v; want _, <nil>", err)
   108  	} else {
   109  		if got, want := gotInfo.Name(), "linklink"; got != want {
   110  			t.Errorf("fs.Lstat(m, \"linklink\").Name() = %q; want %q", got, want)
   111  		}
   112  		if got, want := gotInfo.Mode(), fs.ModeSymlink; got != want {
   113  			t.Errorf("fs.Lstat(m, \"linklink\").Mode() = %v; want %v", got, want)
   114  		}
   115  	}
   116  	gotInfo, err = fs.Stat(m, "linklink")
   117  	if err != nil {
   118  		t.Errorf("fs.Stat(m, \"linklink\") = _, %v; want _, <nil>", err)
   119  	} else {
   120  		if got, want := gotInfo.Name(), "linklink"; got != want {
   121  			t.Errorf("fs.Stat(m, \"linklink\").Name() = %q; want %q", got, want)
   122  		}
   123  		if got, want := gotInfo.Mode(), fs.ModeDir|0555; got != want {
   124  			t.Errorf("fs.Stat(m, \"linklink\").Mode() = %v; want %v", got, want)
   125  		}
   126  	}
   127  }
   128  
   129  func TestMapFSReadAt(t *testing.T) {
   130  	const fileContent = "hello, world\n"
   131  	m := MapFS{
   132  		"hello": {Data: []byte(fileContent)},
   133  	}
   134  	f, err := m.Open("hello")
   135  	if err != nil {
   136  		t.Error(err)
   137  	}
   138  	r, ok := f.(io.ReaderAt)
   139  	if !ok {
   140  		t.Errorf("Open file does not implement io.ReaderAt")
   141  	}
   142  	buf := make([]byte, 1)
   143  
   144  	n, err := r.ReadAt(buf, 0)
   145  	if n != 1 || err != nil {
   146  		t.Errorf("ReadAt(buf, 0) = %d, %v; want 1, <nil>", n, err)
   147  	}
   148  
   149  	n, err = r.ReadAt(buf, int64(len(fileContent)))
   150  	if n != 0 || err != io.EOF {
   151  		t.Errorf("ReadAt(buf, len(fileContent)) = %d, %v; want 0, io.EOF", n, err)
   152  	}
   153  
   154  	n, err = r.ReadAt(buf, int64(len(fileContent)+1))
   155  	if n != 0 || err != io.EOF {
   156  		t.Errorf("ReadAt(buf, len(fileContent)+1) = %d, %v; want 0, io.EOF", n, err)
   157  	}
   158  }
   159  
   160  func TestMapFSSeek(t *testing.T) {
   161  	m := MapFS{
   162  		"hello": {Data: []byte("hello, world\n")},
   163  	}
   164  	f, err := m.Open("hello")
   165  	if err != nil {
   166  		t.Error(err)
   167  	}
   168  	defer f.Close()
   169  	s := f.(io.Seeker)
   170  	_, err = s.Seek(0, io.SeekEnd+5)
   171  	if err == nil {
   172  		t.Errorf("Seek: expected error for invalid whence")
   173  	}
   174  	if !errors.Is(err, fs.ErrInvalid) {
   175  		t.Errorf("Seek: expected fs.ErrInvalid, got %v", err)
   176  	}
   177  }
   178  

View as plain text