| 
 | 1 | +package files  | 
 | 2 | + | 
 | 3 | +import (  | 
 | 4 | +	"fmt"  | 
 | 5 | +	"io/ioutil"  | 
 | 6 | +	"os"  | 
 | 7 | +	"path/filepath"  | 
 | 8 | +	"strings"  | 
 | 9 | +	"testing"  | 
 | 10 | +)  | 
 | 11 | + | 
 | 12 | +func isPathHidden(p string) bool {  | 
 | 13 | +	return strings.HasPrefix(p, ".") || strings.Contains(p, "/.")  | 
 | 14 | +}  | 
 | 15 | + | 
 | 16 | +func TestSerialFile(t *testing.T) {  | 
 | 17 | +	t.Run("Hidden", func(t *testing.T) { testSerialFile(t, true) })  | 
 | 18 | +	t.Run("NotHidden", func(t *testing.T) { testSerialFile(t, false) })  | 
 | 19 | +}  | 
 | 20 | + | 
 | 21 | +func testSerialFile(t *testing.T, hidden bool) {  | 
 | 22 | +	tmppath, err := ioutil.TempDir("", "files-test")  | 
 | 23 | +	if err != nil {  | 
 | 24 | +		t.Fatal(err)  | 
 | 25 | +	}  | 
 | 26 | +	defer os.RemoveAll(tmppath)  | 
 | 27 | + | 
 | 28 | +	expected := map[string]string{  | 
 | 29 | +		"1":      "Some text!\n",  | 
 | 30 | +		"2":      "beep",  | 
 | 31 | +		"3":      "",  | 
 | 32 | +		"4":      "boop",  | 
 | 33 | +		"5":      "",  | 
 | 34 | +		"5/a":    "foobar",  | 
 | 35 | +		".6":     "thing",  | 
 | 36 | +		"7":      "",  | 
 | 37 | +		"7/.foo": "bla",  | 
 | 38 | +		".8":     "",  | 
 | 39 | +		".8/foo": "bla",  | 
 | 40 | +	}  | 
 | 41 | + | 
 | 42 | +	for p, c := range expected {  | 
 | 43 | +		path := filepath.Join(tmppath, p)  | 
 | 44 | +		if c != "" {  | 
 | 45 | +			continue  | 
 | 46 | +		}  | 
 | 47 | +		if err := os.MkdirAll(path, 0777); err != nil {  | 
 | 48 | +			t.Fatal(err)  | 
 | 49 | +		}  | 
 | 50 | +	}  | 
 | 51 | + | 
 | 52 | +	for p, c := range expected {  | 
 | 53 | +		path := filepath.Join(tmppath, p)  | 
 | 54 | +		if c == "" {  | 
 | 55 | +			continue  | 
 | 56 | +		}  | 
 | 57 | +		if err := ioutil.WriteFile(path, []byte(c), 0666); err != nil {  | 
 | 58 | +			t.Fatal(err)  | 
 | 59 | +		}  | 
 | 60 | +	}  | 
 | 61 | + | 
 | 62 | +	stat, err := os.Stat(tmppath)  | 
 | 63 | +	if err != nil {  | 
 | 64 | +		t.Fatal(err)  | 
 | 65 | +	}  | 
 | 66 | + | 
 | 67 | +	sf, err := NewSerialFile(tmppath, hidden, stat)  | 
 | 68 | +	if err != nil {  | 
 | 69 | +		t.Fatal(err)  | 
 | 70 | +	}  | 
 | 71 | +	defer sf.Close()  | 
 | 72 | + | 
 | 73 | +	rootFound := false  | 
 | 74 | +	err = Walk(sf, func(path string, nd Node) error {  | 
 | 75 | +		defer nd.Close()  | 
 | 76 | + | 
 | 77 | +		// root node.  | 
 | 78 | +		if path == "" {  | 
 | 79 | +			if rootFound {  | 
 | 80 | +				return fmt.Errorf("found root twice")  | 
 | 81 | +			}  | 
 | 82 | +			if sf != nd {  | 
 | 83 | +				return fmt.Errorf("wrong root")  | 
 | 84 | +			}  | 
 | 85 | +			rootFound = true  | 
 | 86 | +			return nil  | 
 | 87 | +		}  | 
 | 88 | + | 
 | 89 | +		if !hidden && isPathHidden(path) {  | 
 | 90 | +			return fmt.Errorf("found a hidden file")  | 
 | 91 | +		}  | 
 | 92 | + | 
 | 93 | +		data, ok := expected[path]  | 
 | 94 | +		if !ok {  | 
 | 95 | +			return fmt.Errorf("expected something at %q", path)  | 
 | 96 | +		}  | 
 | 97 | +		delete(expected, path)  | 
 | 98 | + | 
 | 99 | +		switch nd := nd.(type) {  | 
 | 100 | +		case *Symlink:  | 
 | 101 | +			return fmt.Errorf("didn't expect a symlink")  | 
 | 102 | +		case Directory:  | 
 | 103 | +			if data != "" {  | 
 | 104 | +				return fmt.Errorf("expected a directory at %q", path)  | 
 | 105 | +			}  | 
 | 106 | +		case File:  | 
 | 107 | +			actual, err := ioutil.ReadAll(nd)  | 
 | 108 | +			if err != nil {  | 
 | 109 | +				return err  | 
 | 110 | +			}  | 
 | 111 | +			if string(actual) != data {  | 
 | 112 | +				return fmt.Errorf("expected %q, got %q", data, string(actual))  | 
 | 113 | +			}  | 
 | 114 | +		}  | 
 | 115 | +		return nil  | 
 | 116 | +	})  | 
 | 117 | +	if !rootFound {  | 
 | 118 | +		t.Fatal("didn't find the root")  | 
 | 119 | +	}  | 
 | 120 | +	for p := range expected {  | 
 | 121 | +		if !hidden && isPathHidden(p) {  | 
 | 122 | +			continue  | 
 | 123 | +		}  | 
 | 124 | +		t.Errorf("missed %q", p)  | 
 | 125 | +	}  | 
 | 126 | +}  | 
0 commit comments