github.com/jimmyfrasche/autoreadme@v0.0.0-20240504231658-aacd7e11c8ba/autoreadme_test.go (about) 1 package main 2 3 import ( 4 "context" 5 "io/fs" 6 "os" 7 "path/filepath" 8 "testing" 9 10 "golang.org/x/tools/txtar" 11 ) 12 13 var join = filepath.Join 14 15 func mkdirp(t *testing.T, path ...string) { 16 t.Helper() 17 if err := os.MkdirAll(join(path...), 0777); err != nil { 18 t.Fatal(err) 19 } 20 } 21 22 func writeFile(t *testing.T, data []byte, path ...string) { 23 t.Helper() 24 if err := os.WriteFile(join(path...), data, 0666); err != nil { 25 t.Fatal(err) 26 } 27 } 28 29 func cd(t *testing.T, path ...string) { 30 t.Helper() 31 if err := os.Chdir(join(path...)); err != nil { 32 t.Fatalf("failed to cd: %s", err) 33 } 34 } 35 36 // See testdata/README.md for instructions on how to add additional test cases. 37 func TestAutoreadme(t *testing.T) { 38 // cd back to the original directory when we're done 39 originalDir, err := os.Getwd() 40 if err != nil { 41 t.Fatal(err) 42 } 43 t.Cleanup(func() { 44 os.Chdir(originalDir) 45 }) 46 47 // switch out the default template for one specialized for testing 48 src, err := readFile(join("testdata", "test.template")) 49 if err != nil { 50 t.Fatalf("reading testdata/test.template: %s", err) 51 } 52 originalSrc := defaultTemplateSrc 53 defaultTemplateSrc = string(src) 54 t.Cleanup(func() { 55 defaultTemplateSrc = originalSrc 56 }) 57 58 // use testdata/*.txtar files to build out scenarios for us to test 59 cases, err := filepath.Glob(join("testdata", "*.txtar")) 60 if err != nil { 61 t.Fatalf("getting testdata/*.txtar files: %s", err) 62 } 63 for _, c := range cases { 64 name := filepath.Base(c) 65 name = name[:len(name)-len(".txtar")] 66 67 t.Run(name, func(t *testing.T) { 68 cd(t, originalDir) 69 70 arc, err := txtar.ParseFile(c) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 tmp := t.TempDir() 76 cd(t, tmp) 77 78 // always create a .git/ directory at the root 79 // to avoid having to specify it in every single test case 80 mkdirp(t, ".git") 81 82 // write out the archive in tmp 83 for _, file := range arc.Files { 84 name := filepath.FromSlash(file.Name) 85 dir := filepath.Dir(name) 86 if dir != "" { 87 mkdirp(t, dir) 88 } 89 writeFile(t, file.Data, name) 90 } 91 92 // do the thing 93 if err = Main(context.Background()); err != nil { 94 t.Fatalf("running autoreadme: %s", err) 95 } 96 97 // collect all generated README.md and README.md.expect contents, keyed by location 98 expect := map[string]string{} 99 got := map[string]string{} 100 err = filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error { 101 if err != nil { 102 return err 103 } 104 if d.IsDir() { 105 return nil 106 } 107 name := d.Name() 108 switch name { 109 default: 110 return nil 111 case "README.md", "README.md.expect": 112 } 113 bs, err := readFile(path) 114 if err != nil { 115 return err 116 } 117 contents := string(bs) 118 path = filepath.Dir(path) 119 if name == "README.md.expect" { 120 expect[path] = contents 121 } else { 122 got[path] = contents 123 } 124 return nil 125 }) 126 if err != nil { 127 t.Fatal(err) 128 } 129 130 for k, v := range expect { 131 if _, ok := got[k]; !ok { 132 t.Errorf("README.md.expect with no README.md at %s\n %s", k, v) 133 } 134 } 135 for k, v := range got { 136 v2, ok := expect[k] 137 if !ok { 138 t.Errorf("README.md without README.md.expect at %s:\n%s", k, v) 139 } else if v != v2 { 140 t.Errorf("README.md difference at %s:\nGOT:\n%s\nEXPECTED:\n%s", k, v, v2) 141 } 142 } 143 }) 144 } 145 }