From ba6785a0367b2f3af46b0f57c6313ebaab838a1e Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 25 May 2022 12:54:14 -0400 Subject: [PATCH] Move shared type validation functions to separate source file and add unit testing Reference: https://github.com/hashicorp/terraform-plugin-framework-validators/pull/23#discussion_r881645421 --- float64validator/at_most.go | 20 ------- float64validator/type_validation.go | 27 +++++++++ float64validator/type_validation_test.go | 72 ++++++++++++++++++++++++ int64validator/at_most.go | 20 ------- int64validator/type_validation.go | 27 +++++++++ int64validator/type_validation_test.go | 72 ++++++++++++++++++++++++ stringvalidator/length_at_most.go | 20 ------- stringvalidator/type_validation.go | 27 +++++++++ stringvalidator/type_validation_test.go | 72 ++++++++++++++++++++++++ 9 files changed, 297 insertions(+), 60 deletions(-) create mode 100644 float64validator/type_validation.go create mode 100644 float64validator/type_validation_test.go create mode 100644 int64validator/type_validation.go create mode 100644 int64validator/type_validation_test.go create mode 100644 stringvalidator/type_validation.go create mode 100644 stringvalidator/type_validation_test.go diff --git a/float64validator/at_most.go b/float64validator/at_most.go index 72bc343a..79c41a11 100644 --- a/float64validator/at_most.go +++ b/float64validator/at_most.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/validatordiag" "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" ) var _ tfsdk.AttributeValidator = atMostValidator{} @@ -57,22 +56,3 @@ func AtMost(max float64) tfsdk.AttributeValidator { max: max, } } - -// validateFloat ensures that the request contains a Float64 value. -func validateFloat(ctx context.Context, request tfsdk.ValidateAttributeRequest, response *tfsdk.ValidateAttributeResponse) (float64, bool) { - var n types.Float64 - - diags := tfsdk.ValueAs(ctx, request.AttributeConfig, &n) - - if diags.HasError() { - response.Diagnostics = append(response.Diagnostics, diags...) - - return 0, false - } - - if n.Unknown || n.Null { - return 0, false - } - - return n.Value, true -} diff --git a/float64validator/type_validation.go b/float64validator/type_validation.go new file mode 100644 index 00000000..d4d99473 --- /dev/null +++ b/float64validator/type_validation.go @@ -0,0 +1,27 @@ +package float64validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// validateFloat ensures that the request contains a Float64 value. +func validateFloat(ctx context.Context, request tfsdk.ValidateAttributeRequest, response *tfsdk.ValidateAttributeResponse) (float64, bool) { + var n types.Float64 + + diags := tfsdk.ValueAs(ctx, request.AttributeConfig, &n) + + if diags.HasError() { + response.Diagnostics = append(response.Diagnostics, diags...) + + return 0, false + } + + if n.Unknown || n.Null { + return 0, false + } + + return n.Value, true +} diff --git a/float64validator/type_validation_test.go b/float64validator/type_validation_test.go new file mode 100644 index 00000000..e2e40415 --- /dev/null +++ b/float64validator/type_validation_test.go @@ -0,0 +1,72 @@ +package float64validator + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestValidateFloat(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + request tfsdk.ValidateAttributeRequest + expectedFloat64 float64 + expectedOk bool + }{ + "invalid-type": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Bool{Value: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedFloat64: 0.0, + expectedOk: false, + }, + "float64-null": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Float64{Null: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedFloat64: 0.0, + expectedOk: false, + }, + "float64-value": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Float64{Value: 1.2}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedFloat64: 1.2, + expectedOk: true, + }, + "float64-unknown": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Float64{Unknown: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedFloat64: 0.0, + expectedOk: false, + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + gotFloat64, gotOk := validateFloat(context.Background(), testCase.request, &tfsdk.ValidateAttributeResponse{}) + + if diff := cmp.Diff(gotFloat64, testCase.expectedFloat64); diff != "" { + t.Errorf("unexpected float64 difference: %s", diff) + } + + if diff := cmp.Diff(gotOk, testCase.expectedOk); diff != "" { + t.Errorf("unexpected ok difference: %s", diff) + } + }) + } +} diff --git a/int64validator/at_most.go b/int64validator/at_most.go index 5bb30761..6fe9954a 100644 --- a/int64validator/at_most.go +++ b/int64validator/at_most.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/validatordiag" "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" ) var _ tfsdk.AttributeValidator = atMostValidator{} @@ -57,22 +56,3 @@ func AtMost(max int64) tfsdk.AttributeValidator { max: max, } } - -// validateInt ensures that the request contains an Int64 value. -func validateInt(ctx context.Context, request tfsdk.ValidateAttributeRequest, response *tfsdk.ValidateAttributeResponse) (int64, bool) { - var n types.Int64 - - diags := tfsdk.ValueAs(ctx, request.AttributeConfig, &n) - - if diags.HasError() { - response.Diagnostics = append(response.Diagnostics, diags...) - - return 0, false - } - - if n.Unknown || n.Null { - return 0, false - } - - return n.Value, true -} diff --git a/int64validator/type_validation.go b/int64validator/type_validation.go new file mode 100644 index 00000000..a7b10b44 --- /dev/null +++ b/int64validator/type_validation.go @@ -0,0 +1,27 @@ +package int64validator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// validateInt ensures that the request contains an Int64 value. +func validateInt(ctx context.Context, request tfsdk.ValidateAttributeRequest, response *tfsdk.ValidateAttributeResponse) (int64, bool) { + var n types.Int64 + + diags := tfsdk.ValueAs(ctx, request.AttributeConfig, &n) + + if diags.HasError() { + response.Diagnostics = append(response.Diagnostics, diags...) + + return 0, false + } + + if n.Unknown || n.Null { + return 0, false + } + + return n.Value, true +} diff --git a/int64validator/type_validation_test.go b/int64validator/type_validation_test.go new file mode 100644 index 00000000..229b4954 --- /dev/null +++ b/int64validator/type_validation_test.go @@ -0,0 +1,72 @@ +package int64validator + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestValidateInt(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + request tfsdk.ValidateAttributeRequest + expectedInt64 int64 + expectedOk bool + }{ + "invalid-type": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Bool{Value: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedInt64: 0.0, + expectedOk: false, + }, + "int64-null": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Int64{Null: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedInt64: 0.0, + expectedOk: false, + }, + "int64-value": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Int64{Value: 123}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedInt64: 123, + expectedOk: true, + }, + "int64-unknown": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Int64{Unknown: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedInt64: 0.0, + expectedOk: false, + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + gotInt64, gotOk := validateInt(context.Background(), testCase.request, &tfsdk.ValidateAttributeResponse{}) + + if diff := cmp.Diff(gotInt64, testCase.expectedInt64); diff != "" { + t.Errorf("unexpected float64 difference: %s", diff) + } + + if diff := cmp.Diff(gotOk, testCase.expectedOk); diff != "" { + t.Errorf("unexpected ok difference: %s", diff) + } + }) + } +} diff --git a/stringvalidator/length_at_most.go b/stringvalidator/length_at_most.go index 6a7789c5..d9e8c28d 100644 --- a/stringvalidator/length_at_most.go +++ b/stringvalidator/length_at_most.go @@ -6,7 +6,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/validatordiag" "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" ) var _ tfsdk.AttributeValidator = lengthAtMostValidator{} @@ -61,22 +60,3 @@ func LengthAtMost(maxLength int) tfsdk.AttributeValidator { maxLength: maxLength, } } - -// validateString ensures that the request contains a String value. -func validateString(ctx context.Context, request tfsdk.ValidateAttributeRequest, response *tfsdk.ValidateAttributeResponse) (string, bool) { - var s types.String - - diags := tfsdk.ValueAs(ctx, request.AttributeConfig, &s) - - if diags.HasError() { - response.Diagnostics = append(response.Diagnostics, diags...) - - return "", false - } - - if s.Unknown || s.Null { - return "", false - } - - return s.Value, true -} diff --git a/stringvalidator/type_validation.go b/stringvalidator/type_validation.go new file mode 100644 index 00000000..2a0ec479 --- /dev/null +++ b/stringvalidator/type_validation.go @@ -0,0 +1,27 @@ +package stringvalidator + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// validateString ensures that the request contains a String value. +func validateString(ctx context.Context, request tfsdk.ValidateAttributeRequest, response *tfsdk.ValidateAttributeResponse) (string, bool) { + var s types.String + + diags := tfsdk.ValueAs(ctx, request.AttributeConfig, &s) + + if diags.HasError() { + response.Diagnostics = append(response.Diagnostics, diags...) + + return "", false + } + + if s.Unknown || s.Null { + return "", false + } + + return s.Value, true +} diff --git a/stringvalidator/type_validation_test.go b/stringvalidator/type_validation_test.go new file mode 100644 index 00000000..91e4c968 --- /dev/null +++ b/stringvalidator/type_validation_test.go @@ -0,0 +1,72 @@ +package stringvalidator + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestValidateString(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + request tfsdk.ValidateAttributeRequest + expectedString string + expectedOk bool + }{ + "invalid-type": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Bool{Value: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedString: "", + expectedOk: false, + }, + "string-null": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Int64{Null: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedString: "", + expectedOk: false, + }, + "string-value": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.String{Value: "test-value"}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedString: "test-value", + expectedOk: true, + }, + "string-unknown": { + request: tfsdk.ValidateAttributeRequest{ + AttributeConfig: types.Int64{Unknown: true}, + AttributePath: tftypes.NewAttributePath().WithAttributeName("test"), + }, + expectedString: "", + expectedOk: false, + }, + } + + for name, testCase := range testCases { + name, testCase := name, testCase + + t.Run(name, func(t *testing.T) { + t.Parallel() + + gotInt64, gotOk := validateString(context.Background(), testCase.request, &tfsdk.ValidateAttributeResponse{}) + + if diff := cmp.Diff(gotInt64, testCase.expectedString); diff != "" { + t.Errorf("unexpected float64 difference: %s", diff) + } + + if diff := cmp.Diff(gotOk, testCase.expectedOk); diff != "" { + t.Errorf("unexpected ok difference: %s", diff) + } + }) + } +}