github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/io/fs/walk_test.go (about)

     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 fs_test
     6  
     7  import (
     8  	. "io/fs"
     9  	"io/ioutil"
    10  	"os"
    11  	pathpkg "path"
    12  	"testing"
    13  	"testing/fstest"
    14  )
    15  
    16  type Node struct {
    17  	name    string
    18  	entries []*Node // nil if the entry is a file
    19  	mark    int
    20  }
    21  
    22  var tree = &Node{
    23  	"testdata",
    24  	[]*Node{
    25  		{"a", nil, 0},
    26  		{"b", []*Node{}, 0},
    27  		{"c", nil, 0},
    28  		{
    29  			"d",
    30  			[]*Node{
    31  				{"x", nil, 0},
    32  				{"y", []*Node{}, 0},
    33  				{
    34  					"z",
    35  					[]*Node{
    36  						{"u", nil, 0},
    37  						{"v", nil, 0},
    38  					},
    39  					0,
    40  				},
    41  			},
    42  			0,
    43  		},
    44  	},
    45  	0,
    46  }
    47  
    48  func walkTree(n *Node, path string, f func(path string, n *Node)) {
    49  	f(path, n)
    50  	for _, e := range n.entries {
    51  		walkTree(e, pathpkg.Join(path, e.name), f)
    52  	}
    53  }
    54  
    55  func makeTree(t *testing.T) FS {
    56  	fsys := fstest.MapFS{}
    57  	walkTree(tree, tree.name, func(path string, n *Node) {
    58  		if n.entries == nil {
    59  			fsys[path] = &fstest.MapFile{}
    60  		} else {
    61  			fsys[path] = &fstest.MapFile{Mode: ModeDir}
    62  		}
    63  	})
    64  	return fsys
    65  }
    66  
    67  func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) }
    68  
    69  func checkMarks(t *testing.T, report bool) {
    70  	walkTree(tree, tree.name, func(path string, n *Node) {
    71  		if n.mark != 1 && report {
    72  			t.Errorf("node %s mark = %d; expected 1", path, n.mark)
    73  		}
    74  		n.mark = 0
    75  	})
    76  }
    77  
    78  // Assumes that each node name is unique. Good enough for a test.
    79  // If clear is true, any incoming error is cleared before return. The errors
    80  // are always accumulated, though.
    81  func mark(entry DirEntry, err error, errors *[]error, clear bool) error {
    82  	name := entry.Name()
    83  	walkTree(tree, tree.name, func(path string, n *Node) {
    84  		if n.name == name {
    85  			n.mark++
    86  		}
    87  	})
    88  	if err != nil {
    89  		*errors = append(*errors, err)
    90  		if clear {
    91  			return nil
    92  		}
    93  		return err
    94  	}
    95  	return nil
    96  }
    97  
    98  func TestWalkDir(t *testing.T) {
    99  	tmpDir, err := ioutil.TempDir("", "TestWalk")
   100  	if err != nil {
   101  		t.Fatal("creating temp dir:", err)
   102  	}
   103  	defer os.RemoveAll(tmpDir)
   104  
   105  	origDir, err := os.Getwd()
   106  	if err != nil {
   107  		t.Fatal("finding working dir:", err)
   108  	}
   109  	if err = os.Chdir(tmpDir); err != nil {
   110  		t.Fatal("entering temp dir:", err)
   111  	}
   112  	defer os.Chdir(origDir)
   113  
   114  	fsys := makeTree(t)
   115  	errors := make([]error, 0, 10)
   116  	clear := true
   117  	markFn := func(path string, entry DirEntry, err error) error {
   118  		return mark(entry, err, &errors, clear)
   119  	}
   120  	// Expect no errors.
   121  	err = WalkDir(fsys, ".", markFn)
   122  	if err != nil {
   123  		t.Fatalf("no error expected, found: %s", err)
   124  	}
   125  	if len(errors) != 0 {
   126  		t.Fatalf("unexpected errors: %s", errors)
   127  	}
   128  	checkMarks(t, true)
   129  }