diff --git a/what-changed/model/server.go b/what-changed/model/server.go new file mode 100644 index 0000000..805636a --- /dev/null +++ b/what-changed/model/server.go @@ -0,0 +1,67 @@ +// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley +// SPDX-License-Identifier: MIT + +package model + +import ( + "github.com/pb33f/libopenapi/datamodel/low" + "github.com/pb33f/libopenapi/datamodel/low/v3" +) + +type ServerChanges struct { + PropertyChanges + ServerVariableChanges map[string]*ServerVariableChanges +} + +func (s *ServerChanges) TotalChanges() int { + c := s.PropertyChanges.TotalChanges() + for k := range s.ServerVariableChanges { + c += s.ServerVariableChanges[k].TotalChanges() + } + return c +} + +func (s *ServerChanges) TotalBreakingChanges() int { + c := s.PropertyChanges.TotalBreakingChanges() + for k := range s.ServerVariableChanges { + c += s.ServerVariableChanges[k].TotalBreakingChanges() + } + return c +} + +func CompareServers(l, r *v3.Server) *ServerChanges { + if low.AreEqual(l, r) { + return nil + } + var changes []*Change + var props []*PropertyCheck + + // URL + props = append(props, &PropertyCheck{ + LeftNode: l.URL.ValueNode, + RightNode: r.URL.ValueNode, + Label: v3.URLLabel, + Changes: &changes, + Breaking: true, + Original: l, + New: r, + }) + // Description + props = append(props, &PropertyCheck{ + LeftNode: l.Description.ValueNode, + RightNode: r.Description.ValueNode, + Label: v3.DescriptionLabel, + Changes: &changes, + Breaking: false, + Original: l, + New: r, + }) + + CheckProperties(props) + sc := new(ServerChanges) + sc.Changes = changes + sc.ServerVariableChanges = CheckMapForChanges(l.Variables.Value, r.Variables.Value, + &changes, v3.VariablesLabel, CompareServerVariables) + + return sc +} diff --git a/what-changed/model/server_test.go b/what-changed/model/server_test.go new file mode 100644 index 0000000..68d5b4f --- /dev/null +++ b/what-changed/model/server_test.go @@ -0,0 +1,165 @@ +// Copyright 2022 Princess B33f Heavy Industries / Dave Shanley +// SPDX-License-Identifier: MIT + +package model + +import ( + "github.com/pb33f/libopenapi/datamodel/low" + v3 "github.com/pb33f/libopenapi/datamodel/low/v3" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "testing" +) + +func TestCompareServers(t *testing.T) { + + left := `url: https://pb33f.io +description: a server +variables: + thing: + enum: + - choccy + - biccy + default: choccy` + + right := `url: https://pb33f.io +description: a server +variables: + thing: + enum: + - choccy + - biccy + default: choccy` + + var lNode, rNode yaml.Node + _ = yaml.Unmarshal([]byte(left), &lNode) + _ = yaml.Unmarshal([]byte(right), &rNode) + + // create low level objects + var lDoc v3.Server + var rDoc v3.Server + _ = low.BuildModel(&lNode, &lDoc) + _ = low.BuildModel(&rNode, &rDoc) + _ = lDoc.Build(lNode.Content[0], nil) + _ = rDoc.Build(rNode.Content[0], nil) + + // compare. + extChanges := CompareServers(&lDoc, &rDoc) + assert.Nil(t, extChanges) +} + +func TestCompareServers_Modified(t *testing.T) { + + left := `url: https://pb33f.io +description: a server +variables: + thing: + enum: + - choccy + - biccy + default: choccy` + + right := `url: https://pb33f.io/hotness +description: a server that is not +variables: + thing: + enum: + - choccy + - biccy + default: biccy` + + var lNode, rNode yaml.Node + _ = yaml.Unmarshal([]byte(left), &lNode) + _ = yaml.Unmarshal([]byte(right), &rNode) + + // create low level objects + var lDoc v3.Server + var rDoc v3.Server + _ = low.BuildModel(&lNode, &lDoc) + _ = low.BuildModel(&rNode, &rDoc) + _ = lDoc.Build(lNode.Content[0], nil) + _ = rDoc.Build(rNode.Content[0], nil) + + // compare. + extChanges := CompareServers(&lDoc, &rDoc) + assert.Equal(t, 3, extChanges.TotalChanges()) + assert.Equal(t, 2, extChanges.TotalBreakingChanges()) +} + +func TestCompareServers_Added(t *testing.T) { + left := `url: https://pb33f.io +variables: + thing: + enum: + - choccy + - biccy + default: choccy` + + right := `url: https://pb33f.io +description: a server +variables: + thing: + enum: + - choccy + - biccy + - tea + default: choccy` + + var lNode, rNode yaml.Node + _ = yaml.Unmarshal([]byte(left), &lNode) + _ = yaml.Unmarshal([]byte(right), &rNode) + + // create low level objects + var lDoc v3.Server + var rDoc v3.Server + _ = low.BuildModel(&lNode, &lDoc) + _ = low.BuildModel(&rNode, &rDoc) + _ = lDoc.Build(lNode.Content[0], nil) + _ = rDoc.Build(rNode.Content[0], nil) + + // compare. + extChanges := CompareServers(&lDoc, &rDoc) + assert.Equal(t, 2, extChanges.TotalChanges()) + assert.Equal(t, 0, extChanges.TotalBreakingChanges()) + assert.Equal(t, PropertyAdded, extChanges.Changes[0].ChangeType) + assert.Equal(t, ObjectAdded, extChanges.ServerVariableChanges["thing"].Changes[0].ChangeType) +} + +func TestCompareServers_Removed(t *testing.T) { + left := `url: https://pb33f.io +variables: + thing: + enum: + - choccy + - biccy + default: choccy` + + right := `url: https://pb33f.io +description: a server +variables: + thing: + enum: + - choccy + - biccy + - tea + default: choccy` + + var lNode, rNode yaml.Node + _ = yaml.Unmarshal([]byte(left), &lNode) + _ = yaml.Unmarshal([]byte(right), &rNode) + + // create low level objects + var lDoc v3.Server + var rDoc v3.Server + _ = low.BuildModel(&lNode, &lDoc) + _ = low.BuildModel(&rNode, &rDoc) + _ = lDoc.Build(lNode.Content[0], nil) + _ = rDoc.Build(rNode.Content[0], nil) + + // compare. + extChanges := CompareServers(&rDoc, &lDoc) + assert.Equal(t, 2, extChanges.TotalChanges()) + assert.Equal(t, 1, extChanges.TotalBreakingChanges()) + assert.Equal(t, PropertyRemoved, extChanges.Changes[0].ChangeType) + assert.Equal(t, ObjectRemoved, extChanges.ServerVariableChanges["thing"].Changes[0].ChangeType) +} diff --git a/what-changed/model/server_variable_test.go b/what-changed/model/server_variable_test.go index da55fc4..e6b46f0 100644 --- a/what-changed/model/server_variable_test.go +++ b/what-changed/model/server_variable_test.go @@ -106,12 +106,12 @@ enum: func TestCompareServerVariables_Added(t *testing.T) { left := `description: hi -default: hello enum: - one - two` - right := `description: hi + right := `default: hello +description: hi enum: - one - two`