Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

geojson: null json into non-pointer Feature/FeatureCollection will set them to empty #145

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions geojson/feature.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package geojson

import (
"bytes"
"fmt"

"github.com/paulmach/orb"
Expand Down Expand Up @@ -79,6 +80,11 @@ func UnmarshalFeature(data []byte) (*Feature, error) {
// UnmarshalJSON handles the correct unmarshalling of the data
// into the orb.Geometry types.
func (f *Feature) UnmarshalJSON(data []byte) error {
if bytes.Equal(data, []byte(`null`)) {
*f = Feature{}
return nil
}

doc := &featureDoc{}
err := unmarshalJSON(data, &doc)
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions geojson/feature_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ json.Unmarshaler interfaces as well as helper functions such as
package geojson

import (
"bytes"
"fmt"

"go.mongodb.org/mongo-driver/bson"
Expand Down Expand Up @@ -85,6 +86,11 @@ func newFeatureCollectionDoc(fc FeatureCollection) map[string]interface{} {
// UnmarshalJSON decodes the data into a GeoJSON feature collection.
// Extra/foreign members will be put into the `ExtraMembers` attribute.
func (fc *FeatureCollection) UnmarshalJSON(data []byte) error {
if bytes.Equal(data, []byte(`null`)) {
*fc = FeatureCollection{}
return nil
}

tmp := make(map[string]nocopyRawMessage, 4)

err := unmarshalJSON(data, &tmp)
Expand Down
34 changes: 34 additions & 0 deletions geojson/feature_collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,40 @@ func TestFeatureCollectionMarshalJSON(t *testing.T) {
}
}

func TestFeatureCollectionMarshalJSON_null(t *testing.T) {
t.Run("pointer", func(t *testing.T) {
type S struct {
GeoJSON *FeatureCollection `json:"geojson"`
}

var s S
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
if err != nil {
t.Fatalf("unmarshal error: %v", err)
}

if s.GeoJSON != nil {
t.Errorf("should be nil, got: %v", s)
}
})

t.Run("non-pointer", func(t *testing.T) {
type S struct {
GeoJSON FeatureCollection `json:"geojson"`
}

var s S
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
if err != nil {
t.Fatalf("unmarshal error: %v", err)
}

if !reflect.DeepEqual(s.GeoJSON, FeatureCollection{}) {
t.Errorf("should be empty, got: %v", s)
}
})
}

func TestFeatureCollectionMarshal(t *testing.T) {
fc := NewFeatureCollection()
fc.Features = nil
Expand Down
35 changes: 35 additions & 0 deletions geojson/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"io/ioutil"
"reflect"
"strings"
"testing"

Expand Down Expand Up @@ -201,6 +202,40 @@ func TestUnmarshalFeature_missingGeometry(t *testing.T) {
})
}

func TestFeatureMarshalJSON_null(t *testing.T) {
t.Run("pointer", func(t *testing.T) {
type S struct {
GeoJSON *Feature `json:"geojson"`
}

var s S
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
if err != nil {
t.Fatalf("unmarshal error: %v", err)
}

if s.GeoJSON != nil {
t.Errorf("should be nil, got: %v", s)
}
})

t.Run("non-pointer", func(t *testing.T) {
type S struct {
GeoJSON Feature `json:"geojson"`
}

var s S
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
if err != nil {
t.Fatalf("unmarshal error: %v", err)
}

if !reflect.DeepEqual(s.GeoJSON, Feature{}) {
t.Errorf("should be empty, got: %v", s)
}
})
}

func TestUnmarshalBSON_missingGeometry(t *testing.T) {
t.Run("missing geometry", func(t *testing.T) {
f := NewFeature(nil)
Expand Down
34 changes: 34 additions & 0 deletions geojson/geometry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,40 @@ func TestGeometryUnmarshal_errors(t *testing.T) {
}
}

func TestGeometryMarshalJSON_null(t *testing.T) {
t.Run("pointer", func(t *testing.T) {
type S struct {
GeoJSON *Geometry `json:"geojson"`
}

var s S
err := json.Unmarshal([]byte(`{"geojson": null}`), &s)
if err != nil {
t.Fatalf("unmarshal error: %v", err)
}

if s.GeoJSON != nil {
t.Errorf("should be nil, got: %v", s)
}
})

t.Run("feature with null geometry", func(t *testing.T) {
type S struct {
GeoJSON *Feature `json:"geojson"`
}

var s S
err := json.Unmarshal([]byte(`{"geojson": {"type":"Feature","geometry":null,"properties":null}}`), &s)
if err != nil {
t.Fatalf("unmarshal error: %v", err)
}

if s.GeoJSON.Geometry != nil {
t.Errorf("should be nil, got: %v", s)
}
})
}

func TestHelperTypes(t *testing.T) {
// This test makes sure the marshal-unmarshal loop does the same thing.
// The code and types here are complicated to avoid duplicate code.
Expand Down
Loading