github.com/chrislusf/greenpack@v3.7.1-0.20170911073826-ad5bd10b7c47+incompatible/gen/testgen.go (about) 1 package gen 2 3 import ( 4 "github.com/glycerine/greenpack/cfg" 5 "io" 6 "text/template" 7 ) 8 9 var ( 10 marshalTestTempl = template.New("MarshalTest") 11 encodeTestTempl = template.New("EncodeTest") 12 ) 13 14 // TODO(philhofer): 15 // for simplicity's sake, right now 16 // we can only generate tests for types 17 // that can be initialized with the 18 // "Type{}" syntax. 19 // we should support all the types. 20 21 func mtest(w io.Writer, cfg *cfg.GreenConfig) *mtestGen { 22 return &mtestGen{w: w, cfg: cfg} 23 } 24 25 type mtestGen struct { 26 passes 27 w io.Writer 28 cfg *cfg.GreenConfig 29 } 30 31 func (m *mtestGen) MethodPrefix() string { 32 return m.cfg.MethodPrefix 33 } 34 35 func (m *mtestGen) Execute(p Elem) error { 36 p = m.applyall(p) 37 if p != nil && IsPrintable(p) { 38 switch p.(type) { 39 case *Struct, *Array, *Slice, *Map: 40 p.SetHasMethodPrefix(m) 41 return marshalTestTempl.Execute(m.w, p) 42 } 43 } 44 return nil 45 } 46 47 func (m *mtestGen) Method() Method { return marshaltest } 48 49 type etestGen struct { 50 passes 51 w io.Writer 52 cfg *cfg.GreenConfig 53 } 54 55 func etest(w io.Writer, cfg *cfg.GreenConfig) *etestGen { 56 return &etestGen{w: w, cfg: cfg} 57 } 58 59 func (e *etestGen) MethodPrefix() string { 60 return e.cfg.MethodPrefix 61 } 62 63 func (e *etestGen) Execute(p Elem) error { 64 p = e.applyall(p) 65 if p != nil && IsPrintable(p) { 66 switch p.(type) { 67 case *Struct, *Array, *Slice, *Map: 68 p.SetHasMethodPrefix(e) 69 return encodeTestTempl.Execute(e.w, p) 70 } 71 } 72 return nil 73 } 74 75 func (e *etestGen) Method() Method { return encodetest } 76 77 func init() { 78 template.Must(marshalTestTempl.Parse(`func TestMarshalUnmarshal{{.TypeName}}(t *testing.T) { 79 v := {{.TypeName}}{} 80 bts, err := v.{{.MethodPrefix}}MarshalMsg(nil) 81 if err != nil { 82 t.Fatal(err) 83 } 84 left, err := v.{{.MethodPrefix}}UnmarshalMsg(bts) 85 if err != nil { 86 t.Fatal(err) 87 } 88 if len(left) > 0 { 89 t.Errorf("%d bytes left over after {{.MethodPrefix}}UnmarshalMsg(): %q", len(left), left) 90 } 91 92 left, err = msgp.Skip(bts) 93 if err != nil { 94 t.Fatal(err) 95 } 96 if len(left) > 0 { 97 t.Errorf("%d bytes left over after Skip(): %q", len(left), left) 98 } 99 } 100 101 func BenchmarkMarshalMsg{{.TypeName}}(b *testing.B) { 102 v := {{.TypeName}}{} 103 b.ReportAllocs() 104 b.ResetTimer() 105 for i:=0; i<b.N; i++ { 106 v.{{.MethodPrefix}}MarshalMsg(nil) 107 } 108 } 109 110 func BenchmarkAppendMsg{{.TypeName}}(b *testing.B) { 111 v := {{.TypeName}}{} 112 bts := make([]byte, 0, v.{{.MethodPrefix}}Msgsize()) 113 bts, _ = v.{{.MethodPrefix}}MarshalMsg(bts[0:0]) 114 b.SetBytes(int64(len(bts))) 115 b.ReportAllocs() 116 b.ResetTimer() 117 for i:=0; i<b.N; i++ { 118 bts, _ = v.{{.MethodPrefix}}MarshalMsg(bts[0:0]) 119 } 120 } 121 122 func BenchmarkUnmarshal{{.TypeName}}(b *testing.B) { 123 v := {{.TypeName}}{} 124 bts, _ := v.{{.MethodPrefix}}MarshalMsg(nil) 125 b.ReportAllocs() 126 b.SetBytes(int64(len(bts))) 127 b.ResetTimer() 128 for i:=0; i<b.N; i++ { 129 _, err := v.{{.MethodPrefix}}UnmarshalMsg(bts) 130 if err != nil { 131 b.Fatal(err) 132 } 133 } 134 } 135 136 `)) 137 138 template.Must(encodeTestTempl.Parse(`func TestEncodeDecode{{.TypeName}}(t *testing.T) { 139 v := {{.TypeName}}{} 140 var buf bytes.Buffer 141 msgp.Encode(&buf, &v) 142 143 m := v.{{.MethodPrefix}}Msgsize() 144 if buf.Len() > m { 145 t.Logf("WARNING: {{.MethodPrefix}}Msgsize() for %v is inaccurate", v) 146 } 147 148 vn := {{.TypeName}}{} 149 err := msgp.Decode(&buf, &vn) 150 if err != nil { 151 t.Error(err) 152 } 153 154 buf.Reset() 155 msgp.Encode(&buf, &v) 156 err = msgp.NewReader(&buf).Skip() 157 if err != nil { 158 t.Error(err) 159 } 160 } 161 162 func BenchmarkEncode{{.TypeName}}(b *testing.B) { 163 v := {{.TypeName}}{} 164 var buf bytes.Buffer 165 msgp.Encode(&buf, &v) 166 b.SetBytes(int64(buf.Len())) 167 en := msgp.NewWriter(msgp.Nowhere) 168 b.ReportAllocs() 169 b.ResetTimer() 170 for i:=0; i<b.N; i++ { 171 v.{{.MethodPrefix}}EncodeMsg(en) 172 } 173 en.Flush() 174 } 175 176 func BenchmarkDecode{{.TypeName}}(b *testing.B) { 177 v := {{.TypeName}}{} 178 var buf bytes.Buffer 179 msgp.Encode(&buf, &v) 180 b.SetBytes(int64(buf.Len())) 181 rd := msgp.NewEndlessReader(buf.Bytes(), b) 182 dc := msgp.NewReader(rd) 183 b.ReportAllocs() 184 b.ResetTimer() 185 for i:=0; i<b.N; i++ { 186 err := v.{{.MethodPrefix}}DecodeMsg(dc) 187 if err != nil { 188 b.Fatal(err) 189 } 190 } 191 } 192 193 `)) 194 195 }