github.com/glycerine/zebrapack@v4.1.1-0.20181107023619-e955d028f9bf+incompatible/parse/getast_test.go (about)

     1  package parse
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  
     8  	cv "github.com/glycerine/goconvey/convey"
     9  	"github.com/glycerine/zebrapack/cfg"
    10  	"testing"
    11  )
    12  
    13  func Test001DuplicateOrMissingGapZidFieldsNotAllowed(t *testing.T) {
    14  
    15  	cv.Convey("duplicate zid fields and sequences of zid fields with gaps are detected and forbidden", t, func() {
    16  
    17  		fmt.Printf("\n  duplicate zid not allowed\n")
    18  		s := "\npackage fred\n\n" +
    19  			"type Flint struct {\n" +
    20  			"   Barney string `zid:\"0\"`\n" +
    21  			"   Wilma  string `zid:\"0\"`\n" +
    22  			"}\n"
    23  		cv.So(testCode(s, nil), cv.ShouldNotBeNil)
    24  
    25  		fmt.Printf("\n  zid must start at 0\n")
    26  		s = "\npackage fred\n\n" +
    27  			"type Flint struct {\n" +
    28  			"   Barney string `zid:\"1\"`\n" +
    29  			"   Wilma  string `zid:\"2\"`\n" +
    30  			"}\n"
    31  		cv.So(testCode(s, nil), cv.ShouldNotBeNil)
    32  
    33  		fmt.Printf("\n  negative zid mean skipped fields\n")
    34  		s = "\npackage fred\n\n" +
    35  			"type Flint struct {\n" +
    36  			"   Barney string `zid:\"0\"`\n" +
    37  			"   Wilma  string `zid:\"-1\"`\n" +
    38  			"}\n"
    39  		cv.So(testCode(s, nil), cv.ShouldBeNil)
    40  
    41  		fmt.Printf("\n  0, 1 should be fine and not error\n")
    42  		s = "\npackage fred\n\n" +
    43  			"type Flint struct {\n" +
    44  			"   Barney string `zid:\"0\"`\n" +
    45  			"   Wilma  string `zid:\"1\"`\n" +
    46  			"}\n"
    47  		cv.So(testCode(s, nil), cv.ShouldBeNil)
    48  
    49  		fmt.Printf("\n  empty struct{} values should be allowed without error\n")
    50  		s = "package p; type Flint struct {}"
    51  		cv.So(testCode(s, nil), cv.ShouldBeNil)
    52  
    53  		fmt.Printf("\n  struct{} with zid should be allowed and count in the zid sequence\n")
    54  		s = "package hoo; type S2 struct {A struct{} `zid:\"0\"`;B string   `zid:\"1\"`;}"
    55  		cv.So(testCode(s, nil), cv.ShouldBeNil)
    56  
    57  		fmt.Printf("\n  can't have one zid on 2 fields\n")
    58  		s = "package hoo; type S2 struct {A string `zid:\"0\"`; " +
    59  			"B, C string   `zid:\"1\"`;}" // multiple fields, one zid.
    60  		cv.So(testCode(s, nil), cv.ShouldNotBeNil)
    61  
    62  		fmt.Printf("\n  can't have one zid on 3 fields\n")
    63  		s = "package hoo; type S2 struct {A string `zid:\"0\"`; " +
    64  			"B, C, D string   `zid:\"1\"`;}" // multiple fields, one zid.
    65  		cv.So(testCode(s, nil), cv.ShouldNotBeNil)
    66  
    67  		fmt.Printf("\n  both tag name and Go name available in schema\n")
    68  		s = "package h; type S struct {Alfonzo string `zid:\"0\" msg:\"alpha\"`}"
    69  		var o [500]byte
    70  		cv.So(testCode(s, o[:]), cv.ShouldBeNil)
    71  		so := string(o[:])
    72  		//fmt.Printf("so=%v\n", so)
    73  		cv.So(so, cv.ShouldContainSubstring, `"FieldGoName": "Alfonzo"`)
    74  		cv.So(so, cv.ShouldContainSubstring, `"FieldTagName": "alpha"`)
    75  	})
    76  }
    77  
    78  func Test002EmptyStructsNotMarshalled(t *testing.T) {
    79  
    80  	cv.Convey("skipped fields (e.g. struct{} empty values) shouldn't be marshalled", t, func() {
    81  
    82  		s := "\npackage fred\n\n" +
    83  			"type Flint struct {\n" +
    84  			"   Barney string `zid:\"0\"`\n" +
    85  			"   Wilma  string `zid:\"1\"`\n" +
    86  			"   Skiperoo  func()   \n" +
    87  			"   Skiperoo2  struct{}   \n" +
    88  			"}\n"
    89  		cv.So(testCode(s, nil), cv.ShouldBeNil)
    90  	})
    91  }
    92  
    93  // testCode is a helper for checking for parsing errors
    94  func testCode(code string, out []byte) error {
    95  	// struct{} fields should still count in their zid
    96  	gofile, err := ioutil.TempFile(".", "tmp-test-001")
    97  	panicOn(err)
    98  	ofile := gofile.Name() + ".out"
    99  
   100  	fmt.Fprintf(gofile, code)
   101  	gofile.Close()
   102  
   103  	fmt.Printf("\n in file '%s', checking:\n%v\n", gofile.Name(),
   104  		code)
   105  
   106  	cfg := cfg.ZebraConfig{
   107  		Out:        ofile,
   108  		GoFile:     gofile.Name(),
   109  		Encode:     true,
   110  		Marshal:    true,
   111  		Tests:      true,
   112  		Unexported: false,
   113  	}
   114  	fileSet, err := File(&cfg)
   115  	if len(out) > 0 {
   116  		if len(fileSet.Identities) > 0 {
   117  			err := fileSet.SaveMsgpackFile(gofile.Name(), ofile)
   118  			if err != nil {
   119  				panic(err)
   120  			}
   121  		}
   122  		o, err := ioutil.ReadFile(ofile + ".json")
   123  		if err != nil {
   124  			panic(err)
   125  		}
   126  		copy(out, o)
   127  	}
   128  	os.Remove(gofile.Name())
   129  	os.Remove(ofile)
   130  	os.Remove(ofile + ".json")
   131  	return err
   132  }