Skip to content

Commit

Permalink
add parameters and schema
Browse files Browse the repository at this point in the history
  • Loading branch information
Reuven committed Jan 24, 2024
1 parent 3f532a6 commit e736a4d
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 99 deletions.
2 changes: 2 additions & 0 deletions data/simple4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ paths:
parameters:
- name: a
in: query
schema:
type: integer
responses:
200:
description: OK
Expand Down
19 changes: 19 additions & 0 deletions data/simple5.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
info:
title: Tufin
version: 1.0.0
openapi: 3.0.3
paths:
/api/test:
get:
parameters:
- name: a
in: query
schema:
type: string
responses:
200:
description: OK
post:
responses:
201:
description: OK
19 changes: 1 addition & 18 deletions delta/delta.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ func Get(asymmetric bool, diffReport *diff.Diff) float64 {
return 0
}

deltaEndpoints := getEndpointsDelta(asymmetric, diffReport.EndpointsDiff)

return weightedAverage(deltaEndpoints)
return getEndpointsDelta(asymmetric, diffReport.EndpointsDiff)
}

func ratio(asymmetric bool, added int, deleted int, modifiedDelta float64, all int) float64 {
Expand All @@ -23,18 +21,3 @@ func ratio(asymmetric bool, added int, deleted int, modifiedDelta float64, all i

return (float64(added+deleted) + modifiedDelta) / float64(all)
}

type WeightedDelta struct {
delta float64
weight int
}

func weightedAverage(weightedDeltas ...WeightedDelta) float64 {
dividend := 0.0
divisor := 0
for _, weightedDelta := range weightedDeltas {
dividend += weightedDelta.delta
divisor += weightedDelta.weight
}
return dividend / float64(divisor)
}
180 changes: 122 additions & 58 deletions delta/delta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,146 @@ import (
)

func TestEmpty(t *testing.T) {
loader := openapi3.NewLoader()
s1, err := loader.LoadFromFile("../data/empty.yaml")
require.NoError(t, err)

d, err := diff.Get(diff.NewConfig(), s1, s1)
require.NoError(t, err)
d := &diff.Diff{}
require.Equal(t, 0.0, delta.Get(false, d))
}

func TestEndpointAdded(t *testing.T) {
loader := openapi3.NewLoader()
s1, err := loader.LoadFromFile("../data/simple1.yaml")
require.NoError(t, err)

s2, err := loader.LoadFromFile("../data/simple3.yaml")
require.NoError(t, err)
d := &diff.Diff{
EndpointsDiff: &diff.EndpointsDiff{
Added: diff.Endpoints{
diff.Endpoint{
Method: "GET",
Path: "/test",
},
},
Unchanged: diff.Endpoints{
diff.Endpoint{
Method: "POST",
Path: "/test",
},
},
},
}

d, err := diff.Get(diff.NewConfig(), s1, s2)
require.NoError(t, err)
require.Equal(t, 0.5, delta.Get(false, d))
}

func TestEndpointDeletedAsym(t *testing.T) {
loader := openapi3.NewLoader()
s1, err := loader.LoadFromFile("../data/simple3.yaml")
require.NoError(t, err)

s2, err := loader.LoadFromFile("../data/simple1.yaml")
require.NoError(t, err)
d := &diff.Diff{
EndpointsDiff: &diff.EndpointsDiff{
Deleted: diff.Endpoints{
diff.Endpoint{
Method: "GET",
Path: "/test",
},
},
Unchanged: diff.Endpoints{
diff.Endpoint{
Method: "POST",
Path: "/test",
},
},
},
}

d, err := diff.Get(diff.NewConfig(), s1, s2)
require.NoError(t, err)
require.Equal(t, 0.5, delta.Get(true, d))
}

func TestEndpointAddedAndDeleted(t *testing.T) {
loader := openapi3.NewLoader()
s1, err := loader.LoadFromFile("../data/simple1.yaml")
require.NoError(t, err)

s2, err := loader.LoadFromFile("../data/simple2.yaml")
require.NoError(t, err)
d := &diff.Diff{
EndpointsDiff: &diff.EndpointsDiff{
Added: diff.Endpoints{
diff.Endpoint{
Method: "GET",
Path: "/test",
},
},
Deleted: diff.Endpoints{
diff.Endpoint{
Method: "POST",
Path: "/test",
},
},
},
}

d, err := diff.Get(diff.NewConfig(), s1, s2)
require.NoError(t, err)
require.Equal(t, 1.0, delta.Get(false, d))
}

func TestParameters(t *testing.T) {
d := &diff.Diff{
EndpointsDiff: &diff.EndpointsDiff{
Modified: diff.ModifiedEndpoints{
diff.Endpoint{
Method: "GET",
Path: "/test",
}: &diff.MethodDiff{
ParametersDiff: &diff.ParametersDiffByLocation{
Deleted: diff.ParamNamesByLocation{
"query": utils.StringList{"a"},
},
},
},
},
},
}

require.Equal(t, 0.5, delta.Get(true, d))
}

func TestResponses(t *testing.T) {
d := &diff.Diff{
EndpointsDiff: &diff.EndpointsDiff{
Modified: diff.ModifiedEndpoints{
diff.Endpoint{
Method: "GET",
Path: "/test",
}: &diff.MethodDiff{
ResponsesDiff: &diff.ResponsesDiff{
Added: utils.StringList{"201"},
Deleted: utils.StringList{"200"},
},
},
},
},
}

require.Equal(t, 0.5, delta.Get(false, d))
}

func TestSchema(t *testing.T) {
d := &diff.Diff{
EndpointsDiff: &diff.EndpointsDiff{
Modified: diff.ModifiedEndpoints{
diff.Endpoint{
Method: "GET",
Path: "/test",
}: &diff.MethodDiff{
ParametersDiff: &diff.ParametersDiffByLocation{
Modified: diff.ParamDiffByLocation{
"query": diff.ParamDiffs{
"a": &diff.ParameterDiff{
SchemaDiff: &diff.SchemaDiff{
TypeDiff: &diff.ValueDiff{
From: "integer",
To: "string",
},
},
},
},
},
},
},
},
},
}

require.Equal(t, 0.25, delta.Get(false, d))
}

func TestSymmetric(t *testing.T) {
specs := utils.StringList{"../data/simple.yaml", "../data/simple1.yaml", "../data/simple2.yaml", "../data/simple3.yaml", "../data/simple4.yaml"}
specs := utils.StringList{"../data/simple.yaml", "../data/simple1.yaml", "../data/simple2.yaml", "../data/simple3.yaml", "../data/simple4.yaml", "../data/simple5.yaml"}
specPairs := specs.CartesianProduct(specs)

loader := openapi3.NewLoader()
Expand All @@ -82,7 +172,7 @@ func TestSymmetric(t *testing.T) {
}

func TestAsymmetric(t *testing.T) {
specs := utils.StringList{"../data/simple.yaml", "../data/simple1.yaml", "../data/simple2.yaml", "../data/simple3.yaml", "../data/simple4.yaml"}
specs := utils.StringList{"../data/simple.yaml", "../data/simple1.yaml", "../data/simple2.yaml", "../data/simple3.yaml", "../data/simple4.yaml", "../data/simple5.yaml"}
specPairs := specs.CartesianProduct(specs)

loader := openapi3.NewLoader()
Expand All @@ -106,29 +196,3 @@ func TestAsymmetric(t *testing.T) {
require.Equal(t, asymmetric1+asymmetric2, symmetric, pair)
}
}

func TestParameters(t *testing.T) {
loader := openapi3.NewLoader()
s1, err := loader.LoadFromFile("../data/simple4.yaml")
require.NoError(t, err)

s2, err := loader.LoadFromFile("../data/simple3.yaml")
require.NoError(t, err)

d, err := diff.Get(diff.NewConfig(), s1, s2)
require.NoError(t, err)
require.Equal(t, 0.25, delta.Get(true, d))
}

func TestResponses(t *testing.T) {
loader := openapi3.NewLoader()
s1, err := loader.LoadFromFile("../data/simple2.yaml")
require.NoError(t, err)

s2, err := loader.LoadFromFile("../data/simple4.yaml")
require.NoError(t, err)

d, err := diff.Get(diff.NewConfig(), s1, s2)
require.NoError(t, err)
require.Equal(t, 0.0625, delta.Get(true, d))
}
19 changes: 9 additions & 10 deletions delta/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"github.com/tufin/oasdiff/diff"
)

func getEndpointsDelta(asymmetric bool, d *diff.EndpointsDiff) WeightedDelta {
func getEndpointsDelta(asymmetric bool, d *diff.EndpointsDiff) float64 {
if d.Empty() {
return WeightedDelta{}
return 0
}

added := len(d.Added)
Expand All @@ -17,18 +17,17 @@ func getEndpointsDelta(asymmetric bool, d *diff.EndpointsDiff) WeightedDelta {

modifiedDelta := coefficient * getModifiedEndpointsDelta(asymmetric, d.Modified)

return WeightedDelta{
delta: ratio(asymmetric, added, deleted, modifiedDelta, all),
weight: 1,
}
return ratio(asymmetric, added, deleted, modifiedDelta, all)
}

func getModifiedEndpointsDelta(asymmetric bool, d diff.ModifiedEndpoints) float64 {
result := 0.0
weightedDeltas := make([]*WeightedDelta, len(d))
i := 0
for _, methodDiff := range d {
result += getModifiedEndpointDelta(asymmetric, methodDiff)
weightedDeltas[i] = NewWeightedDelta(getModifiedEndpointDelta(asymmetric, methodDiff), 1)
i++
}
return result
return weightedAverage(weightedDeltas)
}

func getModifiedEndpointDelta(asymmetric bool, d *diff.MethodDiff) float64 {
Expand All @@ -40,5 +39,5 @@ func getModifiedEndpointDelta(asymmetric bool, d *diff.MethodDiff) float64 {
paramsDelta := getParametersDelta(asymmetric, d.ParametersDiff)
responsesDelta := getResponsesDelta(asymmetric, d.ResponsesDiff)

return weightedAverage(paramsDelta, responsesDelta)
return weightedAverage([]*WeightedDelta{paramsDelta, responsesDelta})
}
36 changes: 29 additions & 7 deletions delta/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"github.com/tufin/oasdiff/diff"
)

func getParametersDelta(asymmetric bool, d *diff.ParametersDiffByLocation) WeightedDelta {
func getParametersDelta(asymmetric bool, d *diff.ParametersDiffByLocation) *WeightedDelta {
if d.Empty() {
return WeightedDelta{}
return &WeightedDelta{}
}

added := d.Added.Len()
Expand All @@ -15,11 +15,33 @@ func getParametersDelta(asymmetric bool, d *diff.ParametersDiffByLocation) Weigh
unchanged := d.Unchanged.Len()
all := added + deleted + modified + unchanged

// TODO: drill down into modified
modifiedDelta := coefficient * float64(modified)
modifiedDelta := coefficient * getModifiedParametersDelta(asymmetric, d.Modified)

return WeightedDelta{
delta: ratio(asymmetric, added, deleted, modifiedDelta, all),
weight: all,
return NewWeightedDelta(
ratio(asymmetric, added, deleted, modifiedDelta, all),
all,
)
}

func getModifiedParametersDelta(asymmetric bool, d diff.ParamDiffByLocation) float64 {
weightedDeltas := make([]*WeightedDelta, len(d))
i := 0
for _, paramsDiff := range d {
for _, parameterDiff := range paramsDiff {
weightedDeltas[i] = NewWeightedDelta(getModifiedParameterDelta(asymmetric, parameterDiff), 1)
i++
}
}
return weightedAverage(weightedDeltas)
}

func getModifiedParameterDelta(asymmetric bool, d *diff.ParameterDiff) float64 {
if d.Empty() {
return 0.0
}

// TODO: consider additional elements of ParameterDiff
schemaDelta := getSchemaDelta(asymmetric, d.SchemaDiff)

return schemaDelta
}
9 changes: 3 additions & 6 deletions delta/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"github.com/tufin/oasdiff/diff"
)

func getResponsesDelta(asymmetric bool, d *diff.ResponsesDiff) WeightedDelta {
func getResponsesDelta(asymmetric bool, d *diff.ResponsesDiff) *WeightedDelta {
if d.Empty() {
return WeightedDelta{}
return &WeightedDelta{}
}

added := d.Added.Len()
Expand All @@ -18,8 +18,5 @@ func getResponsesDelta(asymmetric bool, d *diff.ResponsesDiff) WeightedDelta {
// TODO: drill down into modified
modifiedDelta := coefficient * float64(modified)

return WeightedDelta{
delta: ratio(asymmetric, added, deleted, modifiedDelta, all),
weight: all,
}
return NewWeightedDelta(ratio(asymmetric, added, deleted, modifiedDelta, all), all)
}
Loading

0 comments on commit e736a4d

Please sign in to comment.