github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/test/init_test.go (about) 1 package test 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "reflect" 11 "strings" 12 "testing" 13 ) 14 15 var ( 16 baseDir = filepath.Join(".", "testdata") 17 walletTestDir = filepath.Join(baseDir, "wallet_tests") 18 chainTestDir = filepath.Join(baseDir, "chain_tests") 19 txTestDir = filepath.Join(baseDir, "tx_tests") 20 ) 21 22 func readJSON(reader io.Reader, value interface{}) error { 23 data, err := ioutil.ReadAll(reader) 24 if err != nil { 25 return fmt.Errorf("error reading JSON file: %v", err) 26 } 27 if err = json.Unmarshal(data, &value); err != nil { 28 if syntaxerr, ok := err.(*json.SyntaxError); ok { 29 line := findLine(data, syntaxerr.Offset) 30 return fmt.Errorf("JSON syntax error at line %v: %v", line, err) 31 } 32 return err 33 } 34 return nil 35 } 36 37 func readJSONFile(fn string, value interface{}) error { 38 file, err := os.Open(fn) 39 if err != nil { 40 return err 41 } 42 defer file.Close() 43 44 if err := readJSON(file, value); err != nil { 45 return fmt.Errorf("%s in file %s", err.Error(), fn) 46 } 47 return nil 48 } 49 50 // findLine returns the line number for the given offset into data. 51 func findLine(data []byte, offset int64) (line int) { 52 line = 1 53 for i, r := range string(data) { 54 if int64(i) >= offset { 55 return 56 } 57 if r == '\n' { 58 line++ 59 } 60 } 61 return 62 } 63 64 // walk invokes its runTest argument for all subtests in the given directory. 65 // 66 // runTest should be a function of type func(t *testing.T, name string, x <TestType>), 67 // where TestType is the type of the test contained in test files. 68 func walk(t *testing.T, dir string, runTest interface{}) { 69 // Walk the directory. 70 dirinfo, err := os.Stat(dir) 71 if os.IsNotExist(err) || !dirinfo.IsDir() { 72 fmt.Fprintf(os.Stderr, "can't find test files in %s\n", dir) 73 t.Skip("missing test files") 74 } 75 err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { 76 name := filepath.ToSlash(strings.TrimPrefix(path, dir+string(filepath.Separator))) 77 if info.IsDir() { 78 return nil 79 } 80 if filepath.Ext(path) == ".json" { 81 t.Run(name, func(t *testing.T) { runTestFile(t, path, name, runTest) }) 82 } 83 return nil 84 }) 85 if err != nil { 86 t.Fatal(err) 87 } 88 } 89 90 func runTestFile(t *testing.T, path, name string, runTest interface{}) { 91 m := makeMapFromTestFunc(runTest) 92 if err := readJSONFile(path, m.Addr().Interface()); err != nil { 93 t.Fatal(err) 94 } 95 runTestFunc(runTest, t, name, m) 96 } 97 98 func makeMapFromTestFunc(f interface{}) reflect.Value { 99 stringT := reflect.TypeOf("") 100 testingT := reflect.TypeOf((*testing.T)(nil)) 101 ftyp := reflect.TypeOf(f) 102 if ftyp.Kind() != reflect.Func || ftyp.NumIn() != 3 || ftyp.NumOut() != 0 || ftyp.In(0) != testingT || ftyp.In(1) != stringT { 103 panic(fmt.Sprintf("bad test function type: want func(*testing.T, string, <TestType>), have %s", ftyp)) 104 } 105 testType := ftyp.In(2) 106 mp := reflect.New(testType) 107 return mp.Elem() 108 } 109 110 func runTestFunc(runTest interface{}, t *testing.T, name string, m reflect.Value) { 111 reflect.ValueOf(runTest).Call([]reflect.Value{ 112 reflect.ValueOf(t), 113 reflect.ValueOf(name), 114 m, 115 }) 116 }