github.com/jmigpin/editor@v1.6.0/util/testutil/txtar.go (about) 1 package testutil 2 3 import ( 4 "bytes" 5 "fmt" 6 "path/filepath" 7 "testing" 8 9 "github.com/jmigpin/editor/util/pathutil" 10 "golang.org/x/tools/txtar" 11 ) 12 13 func ParseTxtar(src []byte, filename string) *Archive { 14 tar := txtar.Parse(src) 15 16 ar := &Archive{} 17 ar.Filename = filename 18 ar.Tar = tar 19 20 line := countLines(tar.Comment) 21 for _, f := range tar.Files { 22 line++ // file header line 23 ar.Lines = append(ar.Lines, line) 24 line += countLines(f.Data) 25 } 26 return ar 27 } 28 29 //---------- 30 31 type Archive struct { 32 Tar *txtar.Archive 33 Filename string // for errors 34 Lines []int // Tar.Files[] line position in src 35 } 36 37 func (ar *Archive) Error(err error, i int) error { 38 return fmt.Errorf("%s:%d: %w", ar.Filename, ar.Lines[i]+1, err) 39 } 40 41 //---------- 42 //---------- 43 //---------- 44 45 func RunArchive2(t *testing.T, ar *Archive, 46 fn func(t2 *testing.T, name string, input, output []byte) error, 47 ) { 48 RunArchive(t, ar, []string{".in", ".out"}, 49 func(t2 *testing.T, name string, data [][]byte) error { 50 return fn(t2, name, data[0], data[1]) 51 }, 52 ) 53 } 54 55 // Expects n files named in filesExts args 56 func RunArchive(t *testing.T, ar *Archive, filesExts []string, 57 fn func(t2 *testing.T, name string, datas [][]byte) error, 58 ) { 59 // map files 60 fm := map[string]txtar.File{} 61 for _, file := range ar.Tar.Files { 62 if _, ok := fm[file.Name]; ok { 63 t.Fatalf("file already defined: %v", file.Name) 64 } 65 fm[file.Name] = file 66 } 67 68 for fi, file := range ar.Tar.Files { 69 // get data 70 datas := [][]byte{} 71 for i := 0; i < len(filesExts); i++ { 72 ext := filesExts[i] 73 fname := pathutil.ReplaceExt(file.Name, ext) 74 75 // run only files that match the first ext 76 if i == 0 { 77 if fname != file.Name { 78 break 79 } 80 } 81 82 f, ok := fm[fname] 83 if !ok { 84 // show warning only for files after first 85 if i > 0 { 86 t.Logf("warning: missing %q for %v", ext, file.Name) 87 } 88 break 89 } 90 datas = append(datas, f.Data) 91 } 92 if len(datas) != len(filesExts) { 93 continue 94 } 95 96 name := filepath.Base(file.Name) 97 ok2 := t.Run(name, func(t2 *testing.T) { 98 t2.Logf("run name: %v", name) 99 err := fn(t2, name, datas) 100 if err != nil { 101 t2.Fatal(ar.Error(err, fi)) 102 } 103 }) 104 if !ok2 { 105 break // stop on first failed test 106 } 107 } 108 } 109 110 //---------- 111 //---------- 112 //---------- 113 114 func countLines(b []byte) int { 115 return bytes.Count(b, []byte("\n")) 116 }