From 47fbc0165b90b98b294da76a606379af3c5f02ca Mon Sep 17 00:00:00 2001 From: atsang Date: Fri, 24 Aug 2018 09:28:22 -0700 Subject: [PATCH] dashboards: Add Yaxis.AutoMin, YAxis.AutoMax, and custom Unmarshal (#167) * Add Yaxis.AutoMin, YAxis.AutoMax, and custom Unmarshal * Add in the AutoMin and AutoMax fields for the Yaxis struct so we can work around the times when datadog's API returns a string when we expect a float64. * Add a custom UnmarshalJSON for Yaxis to utilize the new AutoMin and AutoMax fields. * Update custom Yaxis UnmarshalJSON and add unittests --- dashboards.go | 49 +++++++++++++++++++++++++++-- dashboards_test.go | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 dashboards_test.go diff --git a/dashboards.go b/dashboards.go index 552b85d..c09508e 100644 --- a/dashboards.go +++ b/dashboards.go @@ -52,9 +52,52 @@ type GraphEvent struct { } type Yaxis struct { - Min *float64 `json:"min,omitempty"` - Max *float64 `json:"max,omitempty"` - Scale *string `json:"scale,omitempty"` + Min *float64 `json:"min,omitempty"` + AutoMin bool `json:"-"` + Max *float64 `json:"max,omitempty"` + AutoMax bool `json:"-"` + Scale *string `json:"scale,omitempty"` +} + +// UnmarshalJSON is a Custom Unmarshal for Yaxis.Min/Yaxis.Max. If the datadog API +// returns "auto" for min or max, then we should set Yaxis.min or Yaxis.max to nil, +// respectively. +func (y *Yaxis) UnmarshalJSON(data []byte) error { + type Alias Yaxis + wrapper := &struct { + Min *json.Number `json:"min,omitempty"` + Max *json.Number `json:"max,omitempty"` + *Alias + }{ + Alias: (*Alias)(y), + } + + if err := json.Unmarshal(data, &wrapper); err != nil { + return err + } + + if wrapper.Min != nil && *wrapper.Min == "auto" { + y.AutoMin = true + y.Min = nil + } else { + f, err := wrapper.Min.Float64() + if err != nil { + return err + } + y.Min = &f + } + + if wrapper.Max != nil && *wrapper.Max == "auto" { + y.AutoMax = true + y.Max = nil + } else { + f, err := wrapper.Max.Float64() + if err != nil { + return err + } + y.Max = &f + } + return nil } type Style struct { diff --git a/dashboards_test.go b/dashboards_test.go new file mode 100644 index 0000000..8ad9414 --- /dev/null +++ b/dashboards_test.go @@ -0,0 +1,77 @@ +package datadog + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +type Alias Yaxis + +type YAxisTestSuite struct { + suite.Suite + yJSON []byte + yMarshalledJSON []byte + y Yaxis + yAutoMinMaxJSON []byte + yAutoMinMaxMarshalledJSON []byte + yAutoMinMax Yaxis +} + +func (suite *YAxisTestSuite) SetupTest() { + // Custom Y.Min, Y.Max + suite.yJSON = []byte(`{"min":0,"max":1,"scale":"linear"}`) + suite.yMarshalledJSON = suite.yJSON + yMinFloat := float64(0) + yMaxFloat := float64(1) + yScale := "linear" + suite.y = Yaxis{ + Min: &yMinFloat, + AutoMin: false, + Max: &yMaxFloat, + AutoMax: false, + Scale: &yScale, + } + // Auto Y.Min, Y.Max + suite.yAutoMinMaxJSON = []byte(`{"min":"auto","max":"auto","scale":"linear"}`) + suite.yAutoMinMaxMarshalledJSON = []byte(`{"scale":"linear"}`) + suite.yAutoMinMax = Yaxis{ + Min: nil, + AutoMin: true, + Max: nil, + AutoMax: true, + Scale: &yScale, + } +} + +func (suite *YAxisTestSuite) TestYAxisJSONMarshalCustomMinMax() { + jsonData, err := json.Marshal(suite.y) + assert.Nil(suite.T(), err) + assert.Equal(suite.T(), suite.yMarshalledJSON, jsonData) +} + +func (suite *YAxisTestSuite) TestYAxisJSONUnmarshalCustomMinMax() { + var res Yaxis + err := json.Unmarshal(suite.yJSON, &res) + assert.Nil(suite.T(), err) + assert.Equal(suite.T(), suite.y, res) +} + +func (suite *YAxisTestSuite) TestYAxisJSONMarshalAutoMinMax() { + jsonData, err := json.Marshal(suite.yAutoMinMax) + assert.Nil(suite.T(), err) + assert.Equal(suite.T(), suite.yAutoMinMaxMarshalledJSON, jsonData) +} + +func (suite *YAxisTestSuite) TestYAxisJSONUnmarshalAutoMinMax() { + var res Yaxis + err := json.Unmarshal(suite.yAutoMinMaxJSON, &res) + assert.Nil(suite.T(), err) + assert.Equal(suite.T(), suite.yAutoMinMax, res) +} + +func TestYAxisTestSuite(t *testing.T) { + suite.Run(t, new(YAxisTestSuite)) +}