...

Source file src/github.com/mailru/easyjson/tests/basic_test.go

Documentation: github.com/mailru/easyjson/tests

     1  package tests
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"net/http/httptest"
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/mailru/easyjson"
    11  	"github.com/mailru/easyjson/jwriter"
    12  )
    13  
    14  type testType interface {
    15  	json.Marshaler
    16  	json.Unmarshaler
    17  }
    18  
    19  var testCases = []struct {
    20  	Decoded testType
    21  	Encoded string
    22  }{
    23  	{&primitiveTypesValue, primitiveTypesString},
    24  	{&namedPrimitiveTypesValue, namedPrimitiveTypesString},
    25  	{&structsValue, structsString},
    26  	{&omitEmptyValue, omitEmptyString},
    27  	{&snakeStructValue, snakeStructString},
    28  	{&omitEmptyDefaultValue, omitEmptyDefaultString},
    29  	{&optsValue, optsString},
    30  	{&rawValue, rawString},
    31  	{&stdMarshalerValue, stdMarshalerString},
    32  	{&userMarshalerValue, userMarshalerString},
    33  	{&unexportedStructValue, unexportedStructString},
    34  	{&excludedFieldValue, excludedFieldString},
    35  	{&sliceValue, sliceString},
    36  	{&arrayValue, arrayString},
    37  	{&mapsValue, mapsString},
    38  	{&deepNestValue, deepNestString},
    39  	{&IntsValue, IntsString},
    40  	{&mapStringStringValue, mapStringStringString},
    41  	{&namedTypeValue, namedTypeValueString},
    42  	{&customMapKeyTypeValue, customMapKeyTypeValueString},
    43  	{&embeddedTypeValue, embeddedTypeValueString},
    44  	{&mapMyIntStringValue, mapMyIntStringValueString},
    45  	{&mapIntStringValue, mapIntStringValueString},
    46  	{&mapInt32StringValue, mapInt32StringValueString},
    47  	{&mapInt64StringValue, mapInt64StringValueString},
    48  	{&mapUintStringValue, mapUintStringValueString},
    49  	{&mapUint32StringValue, mapUint32StringValueString},
    50  	{&mapUint64StringValue, mapUint64StringValueString},
    51  	{&mapUintptrStringValue, mapUintptrStringValueString},
    52  	{&intKeyedMapStructValue, intKeyedMapStructValueString},
    53  	{&intArrayStructValue, intArrayStructValueString},
    54  	{&myUInt8SliceValue, myUInt8SliceString},
    55  	{&myUInt8ArrayValue, myUInt8ArrayString},
    56  	{&mapWithEncodingMarshaler, mapWithEncodingMarshalerString},
    57  	{&myGenDeclaredValue, myGenDeclaredString},
    58  	{&myGenDeclaredWithCommentValue, myGenDeclaredWithCommentString},
    59  	{&myTypeDeclaredValue, myTypeDeclaredString},
    60  	{&myTypeNotSkippedValue, myTypeNotSkippedString},
    61  	{&intern, internString},
    62  }
    63  
    64  func TestMarshal(t *testing.T) {
    65  	for i, test := range testCases {
    66  		data, err := test.Decoded.MarshalJSON()
    67  		if err != nil {
    68  			t.Errorf("[%d, %T] MarshalJSON() error: %v", i, test.Decoded, err)
    69  		}
    70  
    71  		got := string(data)
    72  		if got != test.Encoded {
    73  			t.Errorf("[%d, %T] MarshalJSON(): got \n%v\n\t\t want \n%v", i, test.Decoded, got, test.Encoded)
    74  		}
    75  	}
    76  }
    77  
    78  func TestUnmarshal(t *testing.T) {
    79  	for i, test := range testCases {
    80  		v1 := reflect.New(reflect.TypeOf(test.Decoded).Elem()).Interface()
    81  		v := v1.(testType)
    82  
    83  		err := v.UnmarshalJSON([]byte(test.Encoded))
    84  		if err != nil {
    85  			t.Errorf("[%d, %T] UnmarshalJSON() error: %v", i, test.Decoded, err)
    86  		}
    87  
    88  		if !reflect.DeepEqual(v, test.Decoded) {
    89  			t.Errorf("[%d, %T] UnmarshalJSON(): got \n%+v\n\t\t want \n%+v", i, test.Decoded, v, test.Decoded)
    90  		}
    91  	}
    92  }
    93  
    94  func TestRawMessageSTD(t *testing.T) {
    95  	type T struct {
    96  		F    easyjson.RawMessage
    97  		Fnil easyjson.RawMessage
    98  	}
    99  
   100  	val := T{F: easyjson.RawMessage([]byte(`"test"`))}
   101  	str := `{"F":"test","Fnil":null}`
   102  
   103  	data, err := json.Marshal(val)
   104  	if err != nil {
   105  		t.Errorf("json.Marshal() error: %v", err)
   106  	}
   107  	got := string(data)
   108  	if got != str {
   109  		t.Errorf("json.Marshal() = %v; want %v", got, str)
   110  	}
   111  
   112  	wantV := T{F: easyjson.RawMessage([]byte(`"test"`)), Fnil: easyjson.RawMessage([]byte("null"))}
   113  	var gotV T
   114  
   115  	err = json.Unmarshal([]byte(str), &gotV)
   116  	if err != nil {
   117  		t.Errorf("json.Unmarshal() error: %v", err)
   118  	}
   119  	if !reflect.DeepEqual(gotV, wantV) {
   120  		t.Errorf("json.Unmarshal() = %v; want %v", gotV, wantV)
   121  	}
   122  }
   123  
   124  func TestParseNull(t *testing.T) {
   125  	var got, want SubStruct
   126  	if err := easyjson.Unmarshal([]byte("null"), &got); err != nil {
   127  		t.Errorf("Unmarshal() error: %v", err)
   128  	}
   129  
   130  	if !reflect.DeepEqual(got, want) {
   131  		t.Errorf("Unmarshal() = %+v; want %+v", got, want)
   132  	}
   133  }
   134  
   135  var testSpecialCases = []struct {
   136  	EncodedString string
   137  	Value         string
   138  }{
   139  	{`"Username \u003cuser@example.com\u003e"`, `Username <user@example.com>`},
   140  	{`"Username\ufffd"`, "Username\xc5"},
   141  	{`"тестzтест"`, "тестzтест"},
   142  	{`"тест\ufffdтест"`, "тест\xc5тест"},
   143  	{`"绿茶"`, "绿茶"},
   144  	{`"绿\ufffd茶"`, "绿\xc5茶"},
   145  	{`"тест\u2028"`, "тест\xE2\x80\xA8"},
   146  	{`"\\\r\n\t\""`, "\\\r\n\t\""},
   147  	{`"text\\\""`, "text\\\""},
   148  	{`"ü"`, "ü"},
   149  }
   150  
   151  func TestSpecialCases(t *testing.T) {
   152  	for i, test := range testSpecialCases {
   153  		w := jwriter.Writer{}
   154  		w.String(test.Value)
   155  		got := string(w.Buffer.BuildBytes())
   156  		if got != test.EncodedString {
   157  			t.Errorf("[%d] Encoded() = %+v; want %+v", i, got, test.EncodedString)
   158  		}
   159  	}
   160  }
   161  
   162  func TestOverflowArray(t *testing.T) {
   163  	var a Arrays
   164  	err := easyjson.Unmarshal([]byte(arrayOverflowString), &a)
   165  	if err != nil {
   166  		t.Error(err)
   167  	}
   168  	if a != arrayValue {
   169  		t.Errorf("Unmarshal(%v) = %+v; want %+v", arrayOverflowString, a, arrayValue)
   170  	}
   171  }
   172  
   173  func TestUnderflowArray(t *testing.T) {
   174  	var a Arrays
   175  	err := easyjson.Unmarshal([]byte(arrayUnderflowString), &a)
   176  	if err != nil {
   177  		t.Error(err)
   178  	}
   179  	if a != arrayUnderflowValue {
   180  		t.Errorf("Unmarshal(%v) = %+v; want %+v", arrayUnderflowString, a, arrayUnderflowValue)
   181  	}
   182  }
   183  
   184  func TestEncodingFlags(t *testing.T) {
   185  	for i, test := range []struct {
   186  		Flags jwriter.Flags
   187  		In    easyjson.Marshaler
   188  		Want  string
   189  	}{
   190  		{0, EncodingFlagsTestMap{}, `{"F":null}`},
   191  		{0, EncodingFlagsTestSlice{}, `{"F":null}`},
   192  		{jwriter.NilMapAsEmpty, EncodingFlagsTestMap{}, `{"F":{}}`},
   193  		{jwriter.NilSliceAsEmpty, EncodingFlagsTestSlice{}, `{"F":[]}`},
   194  	} {
   195  		w := &jwriter.Writer{Flags: test.Flags}
   196  		test.In.MarshalEasyJSON(w)
   197  
   198  		data, err := w.BuildBytes()
   199  		if err != nil {
   200  			t.Errorf("[%v] easyjson.Marshal(%+v) error: %v", i, test.In, err)
   201  		}
   202  
   203  		v := string(data)
   204  		if v != test.Want {
   205  			t.Errorf("[%v] easyjson.Marshal(%+v) = %v; want %v", i, test.In, v, test.Want)
   206  		}
   207  	}
   208  
   209  }
   210  
   211  func TestNestedEasyJsonMarshal(t *testing.T) {
   212  	n := map[string]*NestedEasyMarshaler{
   213  		"Value":  {},
   214  		"Slice1": {},
   215  		"Slice2": {},
   216  		"Map1":   {},
   217  		"Map2":   {},
   218  	}
   219  
   220  	ni := NestedInterfaces{
   221  		Value: n["Value"],
   222  		Slice: []interface{}{n["Slice1"], n["Slice2"]},
   223  		Map:   map[string]interface{}{"1": n["Map1"], "2": n["Map2"]},
   224  	}
   225  	easyjson.Marshal(ni)
   226  
   227  	for k, v := range n {
   228  		if !v.EasilyMarshaled {
   229  			t.Errorf("Nested interface %s wasn't easily marshaled", k)
   230  		}
   231  	}
   232  }
   233  
   234  func TestNestedMarshaler(t *testing.T) {
   235  	s := NestedMarshaler{
   236  		Value: &StructWithMarshaler{
   237  			Value: 5,
   238  		},
   239  		Value2: 10,
   240  	}
   241  
   242  	data, err := s.MarshalJSON()
   243  	if err != nil {
   244  		t.Errorf("Can't marshal NestedMarshaler: %s", err)
   245  	}
   246  
   247  	s2 := NestedMarshaler {
   248  		Value: &StructWithMarshaler{},
   249  	}
   250  
   251  	err = s2.UnmarshalJSON(data)
   252  	if err != nil {
   253  		t.Errorf("Can't unmarshal NestedMarshaler: %s", err)
   254  	}
   255  
   256  	if !reflect.DeepEqual(s2, s) {
   257  		t.Errorf("easyjson.Unmarshal() = %#v; want %#v", s2, s)
   258  	}
   259  }
   260  
   261  func TestUnmarshalStructWithEmbeddedPtrStruct(t *testing.T) {
   262  	var s = StructWithInterface{Field2: &EmbeddedStruct{}}
   263  	var err error
   264  	err = easyjson.Unmarshal([]byte(structWithInterfaceString), &s)
   265  	if err != nil {
   266  		t.Errorf("easyjson.Unmarshal() error: %v", err)
   267  	}
   268  	if !reflect.DeepEqual(s, structWithInterfaceValueFilled) {
   269  		t.Errorf("easyjson.Unmarshal() = %#v; want %#v", s, structWithInterfaceValueFilled)
   270  	}
   271  }
   272  
   273  func TestDisallowUnknown(t *testing.T) {
   274  	var d DisallowUnknown
   275  	err := easyjson.Unmarshal([]byte(disallowUnknownString), &d)
   276  	if err == nil {
   277  		t.Error("want error, got nil")
   278  	}
   279  }
   280  
   281  var testNotGeneratedTypeCases = []interface{}{
   282  	TypeNotDeclared{},
   283  	TypeSkipped{},
   284  }
   285  
   286  func TestMethodsNoGenerated(t *testing.T) {
   287  	var ok bool
   288  	for i, instance := range testNotGeneratedTypeCases {
   289  		_, ok = instance.(json.Marshaler)
   290  		if ok {
   291  			t.Errorf("[%d, %T] Unexpected MarshalJSON()", i, instance)
   292  		}
   293  
   294  		_, ok = instance.(json.Unmarshaler)
   295  		if ok {
   296  			t.Errorf("[%d, %T] Unexpected Unmarshaler()", i, instance)
   297  		}
   298  	}
   299  }
   300  
   301  func TestNil(t *testing.T) {
   302  	var p *PrimitiveTypes
   303  
   304  	data, err := easyjson.Marshal(p)
   305  	if err != nil {
   306  		t.Errorf("easyjson.Marshal() error: %v", err)
   307  	}
   308  	if string(data) != "null" {
   309  		t.Errorf("Wanted null, got %q", string(data))
   310  	}
   311  
   312  	var b bytes.Buffer
   313  	if n, err := easyjson.MarshalToWriter(p, &b); err != nil || n != 4 {
   314  		t.Errorf("easyjson.MarshalToWriter() error: %v, written %d", err, n)
   315  	}
   316  
   317  	if s := b.String(); s != "null" {
   318  		t.Errorf("Wanted null, got %q", s)
   319  	}
   320  
   321  	w := httptest.NewRecorder()
   322  	started, written, err := easyjson.MarshalToHTTPResponseWriter(p, w)
   323  	if !started || written != 4 || err != nil {
   324  		t.Errorf("easyjson.MarshalToHTTPResponseWriter() error: %v, written %d, started %t",
   325  			err, written, started)
   326  	}
   327  
   328  	if s := w.Body.String(); s != "null" {
   329  		t.Errorf("Wanted null, got %q", s)
   330  	}
   331  }
   332  

View as plain text