launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #15146
[Merge] lp:~jtv/gomaasapi/test-json-serialization into lp:gomaasapi
Jeroen T. Vermeulen has proposed merging lp:~jtv/gomaasapi/test-json-serialization into lp:gomaasapi.
Commit message:
Move JSON serializers for JSONObject and MAASObject into jsonobject.go and maasobject.go, respectively, and test them properly.
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~jtv/gomaasapi/test-json-serialization/+merge/147860
--
https://code.launchpad.net/~jtv/gomaasapi/test-json-serialization/+merge/147860
Your team MAAS Maintainers is requested to review the proposed merge of lp:~jtv/gomaasapi/test-json-serialization into lp:gomaasapi.
=== modified file 'jsonobject.go'
--- jsonobject.go 2013-02-11 12:29:23 +0000
+++ jsonobject.go 2013-02-12 09:14:22 +0000
@@ -81,6 +81,18 @@
return errors.New(msg)
}
+// MarshalJSON tells the standard json package how to serialize a JSONObject
+// back to JSON.
+func (obj JSONObject) MarshalJSON() ([]byte, error) {
+ if obj.IsNil() {
+ return json.Marshal(nil)
+ }
+ return json.Marshal(obj.value)
+}
+
+// With MarshalJSON, JSONObject implements json.Marshaler.
+var _ json.Marshaler = (*JSONObject)(nil)
+
func (obj JSONObject) IsNil() bool {
return obj.value == nil
}
=== modified file 'jsonobject_test.go'
--- jsonobject_test.go 2013-02-12 05:42:32 +0000
+++ jsonobject_test.go 2013-02-12 09:14:22 +0000
@@ -4,6 +4,8 @@
package gomaasapi
import (
+ "encoding/json"
+ "fmt"
. "launchpad.net/gocheck"
)
@@ -258,3 +260,114 @@
_, err = obj.GetArray()
c.Check(err, NotNil)
}
+
+func (suite *JSONObjectSuite) TestNilSerializesToJSON(c *C) {
+ output, err := json.Marshal(maasify(Client{}, nil))
+ c.Assert(err, IsNil)
+ c.Check(output, DeepEquals, []byte("null"))
+}
+
+func (suite *JSONObjectSuite) TestStringSerializesToJSON(c *C) {
+ text := "Text wrapped in JSON"
+ output, err := json.Marshal(maasify(Client{}, text))
+ c.Assert(err, IsNil)
+ c.Check(output, DeepEquals, []byte(fmt.Sprintf(`"%s"`, text)))
+}
+
+func (suite *JSONObjectSuite) TestStringIsEscapedInJSON(c *C) {
+ text := `\"Quote,\" \\backslash, and \'apostrophe\'.`
+ output, err := json.Marshal(maasify(Client{}, text))
+ c.Assert(err, IsNil)
+ var deserialized string
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized, Equals, text)
+}
+
+func (suite *JSONObjectSuite) TestFloat64SerializesToJSON(c *C) {
+ number := 3.1415926535
+ output, err := json.Marshal(maasify(Client{}, number))
+ c.Assert(err, IsNil)
+ var deserialized float64
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized, Equals, number)
+}
+
+func (suite *JSONObjectSuite) TestEmptyMapSerializesToJSON(c *C) {
+ mp := map[string]interface{}{}
+ output, err := json.Marshal(maasify(Client{}, mp))
+ c.Assert(err, IsNil)
+ var deserialized interface{}
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized.(map[string]interface{}), DeepEquals, mp)
+}
+
+func (suite *JSONObjectSuite) TestMapSerializesToJSON(c *C) {
+ // Sample data: counting in Japanese.
+ mp := map[string]interface{}{"one": "ichi", "two": "nii", "three": "san"}
+ output, err := json.Marshal(maasify(Client{}, mp))
+ c.Assert(err, IsNil)
+ var deserialized interface{}
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized.(map[string]interface{}), DeepEquals, mp)
+}
+
+func (suite *JSONObjectSuite) TestEmptyArraySerializesToJSON(c *C) {
+ arr := []interface{}{}
+ output, err := json.Marshal(maasify(Client{}, arr))
+ c.Assert(err, IsNil)
+ var deserialized interface{}
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ // The deserialized value is a slice, and it contains no elements.
+ // Can't do a regular comparison here because at least in the current
+ // json implementation, an empty list deserializes as a nil slice,
+ // not as an empty slice!
+ // (It doesn't work that way for maps though, for some reason).
+ c.Check(len(deserialized.([]interface{})), Equals, len(arr))
+}
+
+func (suite *JSONObjectSuite) TestArrayOfStringsSerializesToJSON(c *C) {
+ value := "item"
+ output, err := json.Marshal(maasify(Client{}, []interface{}{value}))
+ c.Assert(err, IsNil)
+ var deserialized []string
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized, DeepEquals, []string{value})
+}
+
+func (suite *JSONObjectSuite) TestArrayOfNumbersSerializesToJSON(c *C) {
+ value := 9.0
+ output, err := json.Marshal(maasify(Client{}, []interface{}{value}))
+ c.Assert(err, IsNil)
+ var deserialized []float64
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized, DeepEquals, []float64{value})
+}
+
+func (suite *JSONObjectSuite) TestArrayPreservesOrderInJSON(c *C) {
+ // Sample data: counting in Korean.
+ arr := []interface{}{"jong", "il", "ee", "sam"}
+ output, err := json.Marshal(maasify(Client{}, arr))
+ c.Assert(err, IsNil)
+
+ var deserialized []interface{}
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized, DeepEquals, arr)
+}
+
+func (suite *JSONObjectSuite) TestBoolSerializesToJSON(c *C) {
+ f, err := json.Marshal(maasify(Client{}, false))
+ c.Assert(err, IsNil)
+ t, err := json.Marshal(maasify(Client{}, true))
+ c.Assert(err, IsNil)
+
+ c.Check(f, DeepEquals, []byte("false"))
+ c.Check(t, DeepEquals, []byte("true"))
+}
=== modified file 'maasobject.go'
--- maasobject.go 2013-02-11 12:15:14 +0000
+++ maasobject.go 2013-02-12 09:14:22 +0000
@@ -4,6 +4,7 @@
package gomaasapi
import (
+ "encoding/json"
"errors"
"fmt"
"net/url"
@@ -33,6 +34,20 @@
return obj
}
+// MarshalJSON tells the standard json package how to serialize a MAASObject.
+func (obj MAASObject) MarshalJSON() ([]byte, error) {
+ return json.Marshal(obj.GetMap())
+}
+
+// With MarshalJSON, MAASObject implements json.Marshaler.
+var _ json.Marshaler = (*MAASObject)(nil)
+
+func marshalNode(node MAASObject) string {
+ res, _ := json.Marshal(node)
+ return string(res)
+
+}
+
var noResourceURI = errors.New("not a MAAS object: no 'resource_uri' key")
// extractURI obtains the "resource_uri" string from a JSONObject map.
=== modified file 'maasobject_test.go'
--- maasobject_test.go 2013-02-11 12:15:14 +0000
+++ maasobject_test.go 2013-02-12 09:14:22 +0000
@@ -4,6 +4,7 @@
package gomaasapi
import (
+ "encoding/json"
"fmt"
. "launchpad.net/gocheck"
"math/rand"
@@ -144,3 +145,20 @@
c.Check(err, IsNil)
c.Check(value, Equals, fieldValue)
}
+
+func (suite *MAASObjectSuite) TestSerializesToJSON(c *C) {
+ attrs := map[string]interface{}{
+ resourceURI: "http://maas.example.com/",
+ "counter": 5.0,
+ "active": true,
+ "macs": map[string]interface{}{"eth0": "AA:BB:CC:DD:EE:FF"},
+ }
+ obj := maasify(Client{}, attrs)
+ output, err := json.Marshal(obj)
+ c.Assert(err, IsNil)
+
+ var deserialized map[string]interface{}
+ err = json.Unmarshal(output, &deserialized)
+ c.Assert(err, IsNil)
+ c.Check(deserialized, DeepEquals, attrs)
+}
=== modified file 'testservice.go'
--- testservice.go 2013-02-12 05:47:33 +0000
+++ testservice.go 2013-02-12 09:14:22 +0000
@@ -180,31 +180,6 @@
}
}
-// MarshalJSON tells the standard json package how to serialize a JSONObject.
-func (obj JSONObject) MarshalJSON() ([]byte, error) {
- if obj.IsNil() {
- return json.Marshal(nil)
- }
- return json.Marshal(obj.value)
-}
-
-// With MarshalJSON, JSONObject implements json.Marshaler.
-var _ json.Marshaler = (*JSONObject)(nil)
-
-// MarshalJSON tells the standard json package how to serialize a MAASObject.
-func (obj MAASObject) MarshalJSON() ([]byte, error) {
- return json.Marshal(obj.GetMap())
-}
-
-// With MarshalJSON, MAASObject implements json.Marshaler.
-var _ json.Marshaler = (*MAASObject)(nil)
-
-func marshalNode(node MAASObject) string {
- res, _ := json.Marshal(node)
- return string(res)
-
-}
-
// nodeHandler handles requests for '/api/<version>/nodes/<system_id>/'.
func nodeHandler(server *TestServer, w http.ResponseWriter, r *http.Request, systemId string, operation string) {
node, ok := server.nodes[systemId]