gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit e8c027b91d4e878ae583167832500ebd5f3b4217
parent 7ccc975d96d5fddcb7dc679fcc867b55c1bbf079
Author: francoispqt <francois@parquet.ninja>
Date:   Sat,  5 May 2018 02:54:50 +0800

add tests and add DecodeObjectFunc type

Diffstat:
Mdecode_object.go | 20++++++++++++++++++++
Mdecode_object_test.go | 25+++++++++++++++++++++++++
Mdecode_string.go | 2+-
Mdecode_string_test.go | 32++++++++++++++++++++++++++++++++
Mencode_object.go | 4++--
Mencode_stream_test.go | 6++++++
Mexamples/http-json/main.go | 8+++++---
7 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/decode_object.go b/decode_object.go @@ -217,3 +217,23 @@ func (dec *Decoder) skipData() error { } return InvalidJSONError("Invalid JSON") } + +// DecodeObjectFunc is a custom func type implementating UnarshaleObject. +// Use it to cast a func(*Decoder) to Unmarshal an object. +// +// str := "" +// dec := gojay.NewDecoder(io.Reader) +// dec.DecodeObject(gojay.DecodeObjectFunc(func(dec *gojay.Decoder, k string) error { +// return dec.AddString(&str) +// })) +type DecodeObjectFunc func(*Decoder, string) error + +// UnmarshalObject implements UnarshalerObject. +func (f DecodeObjectFunc) UnmarshalObject(dec *Decoder, k string) error { + return f(dec, k) +} + +// NKeys implements UnarshalerObject. +func (f DecodeObjectFunc) NKeys() int { + return 0 +} diff --git a/decode_object_test.go b/decode_object_test.go @@ -381,6 +381,31 @@ func TestDecoderObjectDecoderAPIReadCloser(t *testing.T) { assert.Len(t, m, 5, "len of m should be 5") } +func TestDecoderObjectDecoderAPIFuncReadCloser(t *testing.T) { + readCloser := ReadCloser{ + json: []byte(`{ + "test": "string", + "test2": "string", + "test3": "string", + "test4": "string", + "test5": "string", + }`), + } + m := myMap(make(map[string]string)) + dec := NewDecoder(&readCloser) + err := dec.DecodeObject(DecodeObjectFunc(func(dec *Decoder, k string) error { + str := "" + err := dec.AddString(&str) + if err != nil { + return err + } + m[k] = str + return nil + })) + assert.Nil(t, err, "err should be nil") + assert.Len(t, m, 5, "len of m should be 5") +} + func TestDecoderObjectDecoderInvalidJSONError(t *testing.T) { v := &TestObj{} dec := NewDecoder(strings.NewReader(`{"err:}`)) diff --git a/decode_string.go b/decode_string.go @@ -154,7 +154,7 @@ func (dec *Decoder) skipEscapedString() error { } } } - return nil + return InvalidJSONError("Invalid JSON") } func (dec *Decoder) skipString() error { diff --git a/decode_string_test.go b/decode_string_test.go @@ -70,3 +70,35 @@ func TestDecoderStringPoolError(t *testing.T) { _ = dec.DecodeString(&result) assert.True(t, false, "should not be called as decoder should have panicked") } + +func TestDecoderSkipEscapedStringError(t *testing.T) { + dec := NewDecoder(strings.NewReader(``)) + defer dec.Release() + err := dec.skipEscapedString() + assert.NotNil(t, err, "Err must be nil") + assert.IsType(t, InvalidJSONError(""), err, "err must be of type InvalidJSONError") +} + +func TestDecoderSkipEscapedStringError2(t *testing.T) { + dec := NewDecoder(strings.NewReader(`\"`)) + defer dec.Release() + err := dec.skipEscapedString() + assert.NotNil(t, err, "Err must be nil") + assert.IsType(t, InvalidJSONError(""), err, "err must be of type InvalidJSONError") +} + +func TestDecoderSkipEscapedStringError3(t *testing.T) { + dec := NewDecoder(strings.NewReader(`invalid`)) + defer dec.Release() + err := dec.skipEscapedString() + assert.NotNil(t, err, "Err must be nil") + assert.IsType(t, InvalidJSONError(""), err, "err must be of type InvalidJSONError") +} + +func TestDecoderSkipStringError(t *testing.T) { + dec := NewDecoder(strings.NewReader(`invalid`)) + defer dec.Release() + err := dec.skipString() + assert.NotNil(t, err, "Err must be nil") + assert.IsType(t, InvalidJSONError(""), err, "err must be of type InvalidJSONError") +} diff --git a/encode_object.go b/encode_object.go @@ -120,10 +120,10 @@ func (enc *Encoder) AddObjectKeyOmitEmpty(key string, value MarshalerObject) { } // EncodeObjectFunc is a custom func type implementating MarshaleObject. -// Use it to cast a func(*Encoder) to Marshal and object. +// Use it to cast a func(*Encoder) to Marshal an object. // // enc := gojay.NewEncoder(io.Writer) -// enc.EncoderObject(gojay.EncodeObjectFunc(func(enc *gojay.Encoder) { +// enc.EncodeObject(gojay.EncodeObjectFunc(func(enc *gojay.Encoder) { // enc.AddStringKey("hello", "world") // })) type EncodeObjectFunc func(*Encoder) diff --git a/encode_stream_test.go b/encode_stream_test.go @@ -321,6 +321,12 @@ func TestEncodeStream(t *testing.T) { assert.Equal(t, now, d, "deadline should be the one just set") }) + t.Run("encoder-deadline-unset", func(t *testing.T) { + enc := Stream.NewEncoder(os.Stdout) + d, _ := enc.Deadline() + assert.Equal(t, time.Time{}, d, "deadline should be the one just set") + }) + // just for coverage t.Run("encoder-context-value", func(t *testing.T) { enc := Stream.NewEncoder(os.Stdout) diff --git a/examples/http-json/main.go b/examples/http-json/main.go @@ -55,9 +55,11 @@ func home(w http.ResponseWriter, r *http.Request) { enc := gojay.BorrowEncoder(w) defer enc.Release() err = enc.Encode(m) - i, err := w.Write([]byte(err.Error())) - if err != nil || i == 0 { - panic(err) + if err != nil { + i, err := w.Write([]byte(err.Error())) + if err != nil || i == 0 { + panic(err) + } } return }