Skip to content

Commit 6e47a37

Browse files
committed
geojson: null json into non-pointer Feature/FeatureCollection will set them to empty
1 parent 8c80c61 commit 6e47a37

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

Diff for: geojson/feature.go

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package geojson
22

33
import (
4+
"bytes"
45
"fmt"
56

67
"github.com/paulmach/orb"
@@ -79,6 +80,11 @@ func UnmarshalFeature(data []byte) (*Feature, error) {
7980
// UnmarshalJSON handles the correct unmarshalling of the data
8081
// into the orb.Geometry types.
8182
func (f *Feature) UnmarshalJSON(data []byte) error {
83+
if bytes.Equal(data, []byte(`null`)) {
84+
*f = Feature{}
85+
return nil
86+
}
87+
8288
doc := &featureDoc{}
8389
err := unmarshalJSON(data, &doc)
8490
if err != nil {

Diff for: geojson/feature_collection.go

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ json.Unmarshaler interfaces as well as helper functions such as
77
package geojson
88

99
import (
10+
"bytes"
1011
"fmt"
1112

1213
"go.mongodb.org/mongo-driver/bson"
@@ -85,6 +86,11 @@ func newFeatureCollectionDoc(fc FeatureCollection) map[string]interface{} {
8586
// UnmarshalJSON decodes the data into a GeoJSON feature collection.
8687
// Extra/foreign members will be put into the `ExtraMembers` attribute.
8788
func (fc *FeatureCollection) UnmarshalJSON(data []byte) error {
89+
if bytes.Equal(data, []byte(`null`)) {
90+
*fc = FeatureCollection{}
91+
return nil
92+
}
93+
8894
tmp := make(map[string]nocopyRawMessage, 4)
8995

9096
err := unmarshalJSON(data, &tmp)

Diff for: geojson/feature_collection_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,40 @@ func TestFeatureCollectionMarshalJSON(t *testing.T) {
185185
}
186186
}
187187

188+
func TestFeatureCollectionMarshalJSON_null(t *testing.T) {
189+
t.Run("pointer", func(t *testing.T) {
190+
type S struct {
191+
GeoJSON *FeatureCollection `json:"geojson"`
192+
}
193+
194+
var s S
195+
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
196+
if err != nil {
197+
t.Fatalf("unmarshal error: %v", err)
198+
}
199+
200+
if s.GeoJSON != nil {
201+
t.Errorf("should be nil, got: %v", s)
202+
}
203+
})
204+
205+
t.Run("non-pointer", func(t *testing.T) {
206+
type S struct {
207+
GeoJSON FeatureCollection `json:"geojson"`
208+
}
209+
210+
var s S
211+
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
212+
if err != nil {
213+
t.Fatalf("unmarshal error: %v", err)
214+
}
215+
216+
if !reflect.DeepEqual(s.GeoJSON, FeatureCollection{}) {
217+
t.Errorf("should be empty, got: %v", s)
218+
}
219+
})
220+
}
221+
188222
func TestFeatureCollectionMarshal(t *testing.T) {
189223
fc := NewFeatureCollection()
190224
fc.Features = nil

Diff for: geojson/feature_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"encoding/json"
66
"io/ioutil"
7+
"reflect"
78
"strings"
89
"testing"
910

@@ -201,6 +202,40 @@ func TestUnmarshalFeature_missingGeometry(t *testing.T) {
201202
})
202203
}
203204

205+
func TestFeatureMarshalJSON_null(t *testing.T) {
206+
t.Run("pointer", func(t *testing.T) {
207+
type S struct {
208+
GeoJSON *Feature `json:"geojson"`
209+
}
210+
211+
var s S
212+
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
213+
if err != nil {
214+
t.Fatalf("unmarshal error: %v", err)
215+
}
216+
217+
if s.GeoJSON != nil {
218+
t.Errorf("should be nil, got: %v", s)
219+
}
220+
})
221+
222+
t.Run("non-pointer", func(t *testing.T) {
223+
type S struct {
224+
GeoJSON Feature `json:"geojson"`
225+
}
226+
227+
var s S
228+
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
229+
if err != nil {
230+
t.Fatalf("unmarshal error: %v", err)
231+
}
232+
233+
if !reflect.DeepEqual(s.GeoJSON, Feature{}) {
234+
t.Errorf("should be empty, got: %v", s)
235+
}
236+
})
237+
}
238+
204239
func TestUnmarshalBSON_missingGeometry(t *testing.T) {
205240
t.Run("missing geometry", func(t *testing.T) {
206241
f := NewFeature(nil)

Diff for: geojson/geometry_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,40 @@ func TestGeometryUnmarshal_errors(t *testing.T) {
237237
}
238238
}
239239

240+
func TestGeometryMarshalJSON_null(t *testing.T) {
241+
t.Run("pointer", func(t *testing.T) {
242+
type S struct {
243+
GeoJSON *Geometry `json:"geojson"`
244+
}
245+
246+
var s S
247+
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
248+
if err != nil {
249+
t.Fatalf("unmarshal error: %v", err)
250+
}
251+
252+
if s.GeoJSON != nil {
253+
t.Errorf("should be nil, got: %v", s)
254+
}
255+
})
256+
257+
t.Run("feature with null geometry", func(t *testing.T) {
258+
type S struct {
259+
GeoJSON *Feature `json:"geojson"`
260+
}
261+
262+
var s S
263+
err := json.Unmarshal([]byte(`{"geojson": {"type":"Feature","geometry":null,"properties":null}}`), &s)
264+
if err != nil {
265+
t.Fatalf("unmarshal error: %v", err)
266+
}
267+
268+
if s.GeoJSON.Geometry != nil {
269+
t.Errorf("should be nil, got: %v", s)
270+
}
271+
})
272+
}
273+
240274
func TestHelperTypes(t *testing.T) {
241275
// This test makes sure the marshal-unmarshal loop does the same thing.
242276
// The code and types here are complicated to avoid duplicate code.

0 commit comments

Comments
 (0)