-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
IsRequired
validators to list
, set
, and object
validators…
… for Blocks (#107) * add `listvalidator` and diag helper * renamed to is_required * add set validator * added object validator * renamed to block * added examples and removed line in comment
- Loading branch information
1 parent
f5056ff
commit f27f636
Showing
10 changed files
with
443 additions
and
0 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
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,41 @@ | ||
package listvalidator | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
) | ||
|
||
var _ validator.List = isRequiredValidator{} | ||
|
||
// isRequiredValidator validates that a list has a configuration value. | ||
type isRequiredValidator struct{} | ||
|
||
// Description describes the validation in plain text formatting. | ||
func (v isRequiredValidator) Description(_ context.Context) string { | ||
return "must have a configuration value as the provider has marked it as required" | ||
} | ||
|
||
// MarkdownDescription describes the validation in Markdown formatting. | ||
func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { | ||
return v.Description(ctx) | ||
} | ||
|
||
// Validate performs the validation. | ||
func (v isRequiredValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { | ||
if req.ConfigValue.IsNull() { | ||
resp.Diagnostics.Append(validatordiag.InvalidBlockDiagnostic( | ||
req.Path, | ||
v.Description(ctx), | ||
)) | ||
} | ||
} | ||
|
||
// IsRequired returns a validator which ensures that any configured list has a value (not null). | ||
// | ||
// This validator is equivalent to the `Required` field on attributes and is only | ||
// practical for use with `schema.ListNestedBlock` | ||
func IsRequired() validator.List { | ||
return isRequiredValidator{} | ||
} |
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,28 @@ | ||
package listvalidator_test | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
) | ||
|
||
func ExampleIsRequired() { | ||
// Used within a Schema method of a DataSource, Provider, or Resource | ||
_ = schema.Schema{ | ||
Blocks: map[string]schema.Block{ | ||
"example_block": schema.ListNestedBlock{ | ||
Validators: []validator.List{ | ||
// Validate this block has a value (not null). | ||
listvalidator.IsRequired(), | ||
}, | ||
NestedObject: schema.NestedBlockObject{ | ||
Attributes: map[string]schema.Attribute{ | ||
"example_string_attribute": schema.StringAttribute{ | ||
Required: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} |
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,73 @@ | ||
package listvalidator_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" | ||
"github.com/hashicorp/terraform-plugin-framework/attr" | ||
"github.com/hashicorp/terraform-plugin-framework/path" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
func TestIsRequiredValidator(t *testing.T) { | ||
t.Parallel() | ||
|
||
type testCase struct { | ||
val types.List | ||
expectError bool | ||
} | ||
tests := map[string]testCase{ | ||
"List null": { | ||
val: types.ListNull( | ||
types.StringType, | ||
), | ||
expectError: true, | ||
}, | ||
"List unknown": { | ||
val: types.ListUnknown( | ||
types.StringType, | ||
), | ||
expectError: false, | ||
}, | ||
"List empty": { | ||
val: types.ListValueMust( | ||
types.StringType, | ||
[]attr.Value{}, | ||
), | ||
expectError: false, | ||
}, | ||
"List with elements": { | ||
val: types.ListValueMust( | ||
types.StringType, | ||
[]attr.Value{ | ||
types.StringValue("first"), | ||
}, | ||
), | ||
expectError: false, | ||
}, | ||
} | ||
|
||
for name, test := range tests { | ||
name, test := name, test | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
request := validator.ListRequest{ | ||
Path: path.Root("test"), | ||
PathExpression: path.MatchRoot("test"), | ||
ConfigValue: test.val, | ||
} | ||
response := validator.ListResponse{} | ||
listvalidator.IsRequired().ValidateList(context.TODO(), request, &response) | ||
|
||
if !response.Diagnostics.HasError() && test.expectError { | ||
t.Fatal("expected error, got no error") | ||
} | ||
|
||
if response.Diagnostics.HasError() && !test.expectError { | ||
t.Fatalf("got unexpected error: %s", response.Diagnostics) | ||
} | ||
}) | ||
} | ||
} |
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,41 @@ | ||
package objectvalidator | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
) | ||
|
||
var _ validator.Object = isRequiredValidator{} | ||
|
||
// isRequiredValidator validates that an object has a configuration value. | ||
type isRequiredValidator struct{} | ||
|
||
// Description describes the validation in plain text formatting. | ||
func (v isRequiredValidator) Description(_ context.Context) string { | ||
return "must have a configuration value as the provider has marked it as required" | ||
} | ||
|
||
// MarkdownDescription describes the validation in Markdown formatting. | ||
func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { | ||
return v.Description(ctx) | ||
} | ||
|
||
// Validate performs the validation. | ||
func (v isRequiredValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { | ||
if req.ConfigValue.IsNull() { | ||
resp.Diagnostics.Append(validatordiag.InvalidBlockDiagnostic( | ||
req.Path, | ||
v.Description(ctx), | ||
)) | ||
} | ||
} | ||
|
||
// IsRequired returns a validator which ensures that any configured object has a value (not null). | ||
// | ||
// This validator is equivalent to the `Required` field on attributes and is only | ||
// practical for use with `schema.SingleNestedBlock` | ||
func IsRequired() validator.Object { | ||
return isRequiredValidator{} | ||
} |
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,26 @@ | ||
package objectvalidator_test | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
) | ||
|
||
func ExampleIsRequired() { | ||
// Used within a Schema method of a DataSource, Provider, or Resource | ||
_ = schema.Schema{ | ||
Blocks: map[string]schema.Block{ | ||
"example_block": schema.SingleNestedBlock{ | ||
Validators: []validator.Object{ | ||
// Validate this block has a value (not null). | ||
objectvalidator.IsRequired(), | ||
}, | ||
Attributes: map[string]schema.Attribute{ | ||
"example_string_attribute": schema.StringAttribute{ | ||
Required: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} |
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 @@ | ||
package objectvalidator_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" | ||
"github.com/hashicorp/terraform-plugin-framework/attr" | ||
"github.com/hashicorp/terraform-plugin-framework/path" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
func TestIsRequiredValidator(t *testing.T) { | ||
t.Parallel() | ||
|
||
type testCase struct { | ||
val types.Object | ||
expectError bool | ||
} | ||
tests := map[string]testCase{ | ||
"Object null": { | ||
val: types.ObjectNull( | ||
map[string]attr.Type{ | ||
"field1": types.StringType, | ||
}, | ||
), | ||
expectError: true, | ||
}, | ||
"Object unknown": { | ||
val: types.ObjectUnknown( | ||
map[string]attr.Type{ | ||
"field1": types.StringType, | ||
}, | ||
), | ||
expectError: false, | ||
}, | ||
"Object empty": { | ||
val: types.ObjectValueMust( | ||
map[string]attr.Type{ | ||
"field1": types.StringType, | ||
}, | ||
map[string]attr.Value{ | ||
"field1": types.StringNull(), | ||
}, | ||
), | ||
expectError: false, | ||
}, | ||
"Object with elements": { | ||
val: types.ObjectValueMust( | ||
map[string]attr.Type{ | ||
"field1": types.StringType, | ||
}, | ||
map[string]attr.Value{ | ||
"field1": types.StringValue("value1"), | ||
}, | ||
), | ||
expectError: false, | ||
}, | ||
} | ||
|
||
for name, test := range tests { | ||
name, test := name, test | ||
t.Run(name, func(t *testing.T) { | ||
t.Parallel() | ||
request := validator.ObjectRequest{ | ||
Path: path.Root("test"), | ||
PathExpression: path.MatchRoot("test"), | ||
ConfigValue: test.val, | ||
} | ||
response := validator.ObjectResponse{} | ||
objectvalidator.IsRequired().ValidateObject(context.TODO(), request, &response) | ||
|
||
if !response.Diagnostics.HasError() && test.expectError { | ||
t.Fatal("expected error, got no error") | ||
} | ||
|
||
if response.Diagnostics.HasError() && !test.expectError { | ||
t.Fatalf("got unexpected error: %s", response.Diagnostics) | ||
} | ||
}) | ||
} | ||
} |
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,41 @@ | ||
package setvalidator | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
) | ||
|
||
var _ validator.Set = isRequiredValidator{} | ||
|
||
// isRequiredValidator validates that a set has a configuration value. | ||
type isRequiredValidator struct{} | ||
|
||
// Description describes the validation in plain text formatting. | ||
func (v isRequiredValidator) Description(_ context.Context) string { | ||
return "must have a configuration value as the provider has marked it as required" | ||
} | ||
|
||
// MarkdownDescription describes the validation in Markdown formatting. | ||
func (v isRequiredValidator) MarkdownDescription(ctx context.Context) string { | ||
return v.Description(ctx) | ||
} | ||
|
||
// Validate performs the validation. | ||
func (v isRequiredValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { | ||
if req.ConfigValue.IsNull() { | ||
resp.Diagnostics.Append(validatordiag.InvalidBlockDiagnostic( | ||
req.Path, | ||
v.Description(ctx), | ||
)) | ||
} | ||
} | ||
|
||
// IsRequired returns a validator which ensures that any configured set has a value (not null). | ||
// | ||
// This validator is equivalent to the `Required` field on attributes and is only | ||
// practical for use with `schema.SetNestedBlock` | ||
func IsRequired() validator.Set { | ||
return isRequiredValidator{} | ||
} |
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,28 @@ | ||
package setvalidator_test | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
) | ||
|
||
func ExampleIsRequired() { | ||
// Used within a Schema method of a DataSource, Provider, or Resource | ||
_ = schema.Schema{ | ||
Blocks: map[string]schema.Block{ | ||
"example_block": schema.SetNestedBlock{ | ||
Validators: []validator.Set{ | ||
// Validate this block has a value (not null). | ||
setvalidator.IsRequired(), | ||
}, | ||
NestedObject: schema.NestedBlockObject{ | ||
Attributes: map[string]schema.Attribute{ | ||
"example_string_attribute": schema.StringAttribute{ | ||
Required: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} |
Oops, something went wrong.