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  }