-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding plan checks for
ExpectKnownValue
, ExpectKnownOutputValue
, …
…and `ExpectKnownOutputValueAtPath` (#248) * Add KnownValue interface and types (#243) * Add ExpectKnownValue plan check (#243) * Handling different permutations for equality checking of interface type and value, and known value type and value (#243) * Adding tests for missing resource, and attribute value null (#243) * Adding plan checks for known output value and known output value at path (#243) * Adding documentation (#243) * Adding changelog entries (#243) * Adding TerraformVersionChecks (#243) * Modifying to handle numerical values returned as json.Number for tfjson.Plan (#243) * Renaming known value constructors (#243) * Refactoring to Check interface (#243) * Linting (#243) * Modifying known value check error messages and tests (#243) * Updating tests for ExpectKnownValue, ExpectKnownOutputValue and ExpectKnownOutputValueAtPaath (#243) * Adding changelog entry to note the switch to using json.Number for numerical value representation in the plan (#243) * Remove reference to state checks (#243) * Moving concepts under title and removing reference to Framework types (#243) * Updating Go doc comments to clarify usage of partial equality and remove references to KnownValue interface (#243) * Modifying known-values.mdx page description (#243) * Restructuring and updating references to knownvalue.Check (#243) * Adding individual docs pages for each type of known value check (#243) * Removing references to num elements (#243) * Removing references to state (#243) * Adding docs page for custom known value checks (#243) * Fixing error message (#243) * Refactoring to accomodate custom known value checks in ExpectKnownValue, ExpectKnownOutputValue and ExpectKnownOutputValueAtPath (#243) * Apply suggestions from code review Co-authored-by: Brian Flad <[email protected]> * Unexporting types that implement known value check (#266) * Document usage of 512-bit precision in the number known value check (#266) * Adding attribute or output path to error message (#266) * Replacing alias in example code (#266) * Rename file (#266) * Renamed list, map, and set element length checks to <List|Map|Set>SizeExact (#243) * Removing ObjectAttributesExact (#243) * Renaming known value check types (#243) --------- Co-authored-by: Brian Flad <[email protected]>
- Loading branch information
1 parent
725d48a
commit 198c751
Showing
65 changed files
with
8,982 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: FEATURES | ||
body: 'plancheck: Added `ExpectKnownValue` plan check, which asserts that a given | ||
resource attribute has a defined type, and value' | ||
time: 2023-12-18T11:45:39.181954Z | ||
custom: | ||
Issue: "248" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: FEATURES | ||
body: 'plancheck: Added `ExpectKnownOutputValue` plan check, which asserts that a | ||
given output value has a defined type, and value' | ||
time: 2023-12-18T11:45:53.272412Z | ||
custom: | ||
Issue: "248" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: FEATURES | ||
body: 'plancheck: Added `ExpectKnownOutputValueAtPath` plan check, which asserts that | ||
a given output value at a specified path has a defined type, and value' | ||
time: 2023-12-18T11:46:11.58053Z | ||
custom: | ||
Issue: "248" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: FEATURES | ||
body: 'knownvalue: Introduced new `knownvalue` package which contains types for working | ||
with plan checks and state checks' | ||
time: 2023-12-18T11:47:39.059813Z | ||
custom: | ||
Issue: "248" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
kind: NOTES | ||
body: Numerical values in the plan are now represented as json.Number, not float64. | ||
Custom plan checks relying upon float64 representation may need altering | ||
time: 2024-01-04T08:38:41.645745Z | ||
custom: | ||
Issue: "248" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package knownvalue | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
) | ||
|
||
var _ Check = boolExact{} | ||
|
||
type boolExact struct { | ||
value bool | ||
} | ||
|
||
// CheckValue determines whether the passed value is of type bool, and | ||
// contains a matching bool value. | ||
func (v boolExact) CheckValue(other any) error { | ||
otherVal, ok := other.(bool) | ||
|
||
if !ok { | ||
return fmt.Errorf("expected bool value for BoolExact check, got: %T", other) | ||
} | ||
|
||
if otherVal != v.value { | ||
return fmt.Errorf("expected value %t for BoolExact check, got: %t", v.value, otherVal) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// String returns the string representation of the bool value. | ||
func (v boolExact) String() string { | ||
return strconv.FormatBool(v.value) | ||
} | ||
|
||
// BoolExact returns a Check for asserting equality between the | ||
// supplied bool and the value passed to the CheckValue method. | ||
func BoolExact(value bool) boolExact { | ||
return boolExact{ | ||
value: value, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package knownvalue_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/knownvalue" | ||
) | ||
|
||
func TestBoolValue_CheckValue(t *testing.T) { | ||
t.Parallel() | ||
|
||
testCases := map[string]struct { | ||
self knownvalue.Check | ||
other any | ||
expectedError error | ||
}{ | ||
"zero-nil": { | ||
self: knownvalue.BoolExact(false), | ||
expectedError: fmt.Errorf("expected bool value for BoolExact check, got: <nil>"), | ||
}, | ||
"zero-other": { | ||
self: knownvalue.BoolExact(false), | ||
other: false, // checking against the underlying value field zero-value | ||
}, | ||
"nil": { | ||
self: knownvalue.BoolExact(false), | ||
expectedError: fmt.Errorf("expected bool value for BoolExact check, got: <nil>"), | ||
}, | ||
"wrong-type": { | ||
self: knownvalue.BoolExact(true), | ||
other: 1.23, | ||
expectedError: fmt.Errorf("expected bool value for BoolExact check, got: float64"), | ||
}, | ||
"not-equal": { | ||
self: knownvalue.BoolExact(true), | ||
other: false, | ||
expectedError: fmt.Errorf("expected value true for BoolExact check, got: false"), | ||
}, | ||
"equal": { | ||
self: knownvalue.BoolExact(true), | ||
other: true, | ||
}, | ||
} | ||
|
||
for name, testCase := range testCases { | ||
name, testCase := name, testCase | ||
|
||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
got := testCase.self.CheckValue(testCase.other) | ||
|
||
if diff := cmp.Diff(got, testCase.expectedError, equateErrorMessage); diff != "" { | ||
t.Errorf("unexpected difference: %s", diff) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestBoolValue_String(t *testing.T) { | ||
t.Parallel() | ||
|
||
got := knownvalue.BoolExact(true).String() | ||
|
||
if diff := cmp.Diff(got, "true"); diff != "" { | ||
t.Errorf("unexpected difference: %s", diff) | ||
} | ||
} | ||
|
||
// equateErrorMessage reports errors to be equal if both are nil | ||
// or both have the same message. | ||
var equateErrorMessage = cmp.Comparer(func(x, y error) bool { | ||
if x == nil || y == nil { | ||
return x == nil && y == nil | ||
} | ||
return x.Error() == y.Error() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package knownvalue | ||
|
||
// Check defines an interface that is implemented to determine whether type and value match. Individual | ||
// implementations determine how the match is performed (e.g., exact match, partial match). | ||
type Check interface { | ||
// CheckValue should assert the given known value against any expectations. Use the error | ||
// return to signal unexpected values or implementation errors. | ||
CheckValue(value any) error | ||
// String should return a string representation of the type and value. | ||
String() string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
// Package knownvalue contains the known value interface, and types implementing the known value interface. | ||
package knownvalue |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package knownvalue | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strconv" | ||
) | ||
|
||
var _ Check = float64Exact{} | ||
|
||
type float64Exact struct { | ||
value float64 | ||
} | ||
|
||
// CheckValue determines whether the passed value is of type float64, and | ||
// contains a matching float64 value. | ||
func (v float64Exact) CheckValue(other any) error { | ||
jsonNum, ok := other.(json.Number) | ||
|
||
if !ok { | ||
return fmt.Errorf("expected json.Number value for Float64Exact check, got: %T", other) | ||
} | ||
|
||
otherVal, err := jsonNum.Float64() | ||
|
||
if err != nil { | ||
return fmt.Errorf("expected json.Number to be parseable as float64 value for Float64Exact check: %s", err) | ||
} | ||
|
||
if otherVal != v.value { | ||
return fmt.Errorf("expected value %s for Float64Exact check, got: %s", v.String(), strconv.FormatFloat(otherVal, 'f', -1, 64)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// String returns the string representation of the float64 value. | ||
func (v float64Exact) String() string { | ||
return strconv.FormatFloat(v.value, 'f', -1, 64) | ||
} | ||
|
||
// Float64Exact returns a Check for asserting equality between the | ||
// supplied float64 and the value passed to the CheckValue method. | ||
func Float64Exact(value float64) float64Exact { | ||
return float64Exact{ | ||
value: value, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package knownvalue_test | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/knownvalue" | ||
) | ||
|
||
func TestFloat64Value_CheckValue(t *testing.T) { | ||
t.Parallel() | ||
|
||
testCases := map[string]struct { | ||
self knownvalue.Check | ||
other any | ||
expectedError error | ||
}{ | ||
"zero-nil": { | ||
self: knownvalue.Float64Exact(0), | ||
expectedError: fmt.Errorf("expected json.Number value for Float64Exact check, got: <nil>"), | ||
}, | ||
"zero-other": { | ||
self: knownvalue.Float64Exact(0), | ||
other: json.Number("0.0"), // checking against the underlying value field zero-value | ||
}, | ||
"nil": { | ||
self: knownvalue.Float64Exact(1.234), | ||
expectedError: fmt.Errorf("expected json.Number value for Float64Exact check, got: <nil>"), | ||
}, | ||
"wrong-type": { | ||
self: knownvalue.Float64Exact(1.234), | ||
other: json.Number("str"), | ||
expectedError: fmt.Errorf("expected json.Number to be parseable as float64 value for Float64Exact check: strconv.ParseFloat: parsing \"str\": invalid syntax"), | ||
}, | ||
"not-equal": { | ||
self: knownvalue.Float64Exact(1.234), | ||
other: json.Number("4.321"), | ||
expectedError: fmt.Errorf("expected value 1.234 for Float64Exact check, got: 4.321"), | ||
}, | ||
"equal": { | ||
self: knownvalue.Float64Exact(1.234), | ||
other: json.Number("1.234"), | ||
}, | ||
} | ||
|
||
for name, testCase := range testCases { | ||
name, testCase := name, testCase | ||
|
||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
|
||
got := testCase.self.CheckValue(testCase.other) | ||
|
||
if diff := cmp.Diff(got, testCase.expectedError, equateErrorMessage); diff != "" { | ||
t.Errorf("unexpected difference: %s", diff) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestFloat64Value_String(t *testing.T) { | ||
t.Parallel() | ||
|
||
got := knownvalue.Float64Exact(1.234567890123e+09).String() | ||
|
||
if diff := cmp.Diff(got, "1234567890.123"); diff != "" { | ||
t.Errorf("unexpected difference: %s", diff) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package knownvalue | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strconv" | ||
) | ||
|
||
var _ Check = int64Exact{} | ||
|
||
type int64Exact struct { | ||
value int64 | ||
} | ||
|
||
// CheckValue determines whether the passed value is of type int64, and | ||
// contains a matching int64 value. | ||
func (v int64Exact) CheckValue(other any) error { | ||
jsonNum, ok := other.(json.Number) | ||
|
||
if !ok { | ||
return fmt.Errorf("expected json.Number value for Int64Exact check, got: %T", other) | ||
} | ||
|
||
otherVal, err := jsonNum.Int64() | ||
|
||
if err != nil { | ||
return fmt.Errorf("expected json.Number to be parseable as int64 value for Int64Exact check: %s", err) | ||
} | ||
|
||
if otherVal != v.value { | ||
return fmt.Errorf("expected value %d for Int64Exact check, got: %d", v.value, otherVal) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// String returns the string representation of the int64 value. | ||
func (v int64Exact) String() string { | ||
return strconv.FormatInt(v.value, 10) | ||
} | ||
|
||
// Int64Exact returns a Check for asserting equality between the | ||
// supplied int64 and the value passed to the CheckValue method. | ||
func Int64Exact(value int64) int64Exact { | ||
return int64Exact{ | ||
value: value, | ||
} | ||
} |
Oops, something went wrong.