From 156a76c301077d6a77be843558d24f104f877f17 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 17 Mar 2025 17:59:44 -0400 Subject: [PATCH 1/2] issue #451 fix --- knownvalue/object.go | 42 ++++++++++++++++++++++++++--------- knownvalue/object_test.go | 46 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/knownvalue/object.go b/knownvalue/object.go index 87eabfb63..e15c03928 100644 --- a/knownvalue/object.go +++ b/knownvalue/object.go @@ -5,6 +5,8 @@ package knownvalue import ( "fmt" + "maps" + "slices" "sort" ) @@ -24,18 +26,14 @@ func (v objectExact) CheckValue(other any) error { } if len(otherVal) != len(v.value) { - expectedAttributes := "attributes" - actualAttributes := "attributes" - - if len(v.value) == 1 { - expectedAttributes = "attribute" - } - - if len(otherVal) == 1 { - actualAttributes = "attribute" + deltaMsg := "" + if len(otherVal) > len(v.value) { + deltaMsg = createDeltaString(otherVal, v.value, "actual value has extra attribute(s): ") + } else { + deltaMsg = createDeltaString(v.value, otherVal, "actual value is missing attribute(s): ") } - return fmt.Errorf("expected %d %s for ObjectExact check, got %d %s", len(v.value), expectedAttributes, len(otherVal), actualAttributes) + return fmt.Errorf("expected %d attribute(s) for ObjectExact check, got %d attribute(s): %s", len(v.value), len(otherVal), deltaMsg) } var keys []string @@ -92,3 +90,27 @@ func ObjectExact(value map[string]Check) objectExact { value: value, } } + +// createDeltaString prints the map keys that are present in mapA and not present in mapB +func createDeltaString[T any, V any](mapA map[string]T, mapB map[string]V, msgPrefix string) string { + deltaMsg := "" + + deltaMap := make(map[string]T, len(mapA)) + maps.Copy(deltaMap, mapA) + for key := range mapB { + delete(deltaMap, key) + } + + deltaKeys := slices.Sorted(maps.Keys(deltaMap)) + + for i, k := range deltaKeys { + if i == 0 { + deltaMsg += msgPrefix + } else if i != 0 { + deltaMsg += ", " + } + deltaMsg += fmt.Sprintf("%q", k) + } + + return deltaMsg +} diff --git a/knownvalue/object_test.go b/knownvalue/object_test.go index 0c3d0be64..173aba0ae 100644 --- a/knownvalue/object_test.go +++ b/knownvalue/object_test.go @@ -53,9 +53,9 @@ func TestObjectValue_CheckValue(t *testing.T) { "three": knownvalue.Float64Exact(7.89), }), other: map[string]any{}, - expectedError: fmt.Errorf("expected 3 attributes for ObjectExact check, got 0 attributes"), + expectedError: fmt.Errorf("expected 3 attribute(s) for ObjectExact check, got 0 attribute(s): actual value is missing attribute(s): \"one\", \"three\", \"two\""), }, - "wrong-length": { + "missing-one-attribute": { self: knownvalue.ObjectExact(map[string]knownvalue.Check{ "one": knownvalue.Float64Exact(1.23), "two": knownvalue.Float64Exact(4.56), @@ -65,7 +65,47 @@ func TestObjectValue_CheckValue(t *testing.T) { "one": json.Number("1.23"), "two": json.Number("4.56"), }, - expectedError: fmt.Errorf("expected 3 attributes for ObjectExact check, got 2 attributes"), + expectedError: fmt.Errorf("expected 3 attribute(s) for ObjectExact check, got 2 attribute(s): actual value is missing attribute(s): \"three\""), + }, + "missing-multiple-attributes": { + self: knownvalue.ObjectExact(map[string]knownvalue.Check{ + "one": knownvalue.Float64Exact(1.23), + "two": knownvalue.Float64Exact(4.56), + "three": knownvalue.Float64Exact(7.89), + "four": knownvalue.Float64Exact(0.12), + "five": knownvalue.Float64Exact(3.45), + }), + other: map[string]any{ + "one": json.Number("1.23"), + "two": json.Number("4.56"), + }, + expectedError: fmt.Errorf("expected 5 attribute(s) for ObjectExact check, got 2 attribute(s): actual value is missing attribute(s): \"five\", \"four\", \"three\""), + }, + "extra-one-attribute": { + self: knownvalue.ObjectExact(map[string]knownvalue.Check{ + "one": knownvalue.Float64Exact(1.23), + "two": knownvalue.Float64Exact(4.56), + }), + other: map[string]any{ + "one": json.Number("1.23"), + "two": json.Number("4.56"), + "three": json.Number("7.89"), + }, + expectedError: fmt.Errorf("expected 2 attribute(s) for ObjectExact check, got 3 attribute(s): actual value has extra attribute(s): \"three\""), + }, + "extra-multiple-attributes": { + self: knownvalue.ObjectExact(map[string]knownvalue.Check{ + "one": knownvalue.Float64Exact(1.23), + "two": knownvalue.Float64Exact(4.56), + }), + other: map[string]any{ + "one": json.Number("1.23"), + "two": json.Number("4.56"), + "three": json.Number("7.89"), + "four": json.Number("0.12"), + "five": json.Number("3.45"), + }, + expectedError: fmt.Errorf("expected 2 attribute(s) for ObjectExact check, got 5 attribute(s): actual value has extra attribute(s): \"five\", \"four\", \"three\""), }, "not-equal": { self: knownvalue.ObjectExact(map[string]knownvalue.Check{ From 1b73f3fd000f17c555040dfd829dc32c381bba90 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 17 Mar 2025 18:28:15 -0400 Subject: [PATCH 2/2] add changelog --- .changes/unreleased/ENHANCEMENTS-20250317-182730.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/unreleased/ENHANCEMENTS-20250317-182730.yaml diff --git a/.changes/unreleased/ENHANCEMENTS-20250317-182730.yaml b/.changes/unreleased/ENHANCEMENTS-20250317-182730.yaml new file mode 100644 index 000000000..e74d6d433 --- /dev/null +++ b/.changes/unreleased/ENHANCEMENTS-20250317-182730.yaml @@ -0,0 +1,5 @@ +kind: ENHANCEMENTS +body: 'knownvalue: Updated the `ObjectExact` error message to report extra/missing attributes from the actual object.' +time: 2025-03-17T18:27:30.206493-04:00 +custom: + Issue: "451"