Skip to content

Commit

Permalink
feat: add 'valid_json' function
Browse files Browse the repository at this point in the history
  • Loading branch information
bschaatsbergen committed Mar 16, 2024
1 parent fb4f2ec commit eaf3ca0
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
26 changes: 26 additions & 0 deletions docs/functions/valid_json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "valid_json function - assert"
subcategory: ""
description: |-
Checks whether a string is valid JSON
---

# function: valid_json





## Signature

<!-- signature generated by tfplugindocs -->
```text
valid_json(json string) bool
```

## Arguments

<!-- arguments generated by tfplugindocs -->
1. `json` (String) The JSON string to check

1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (p *AssertProvider) Functions(ctx context.Context) []func() function.Functi
NewNotEqualFunction,
NewTrueFunction,
NewFalseFunction,
NewValidJSONFunction,
}
}

Expand Down
66 changes: 66 additions & 0 deletions internal/provider/valid_json_function.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"encoding/json"

"github.com/hashicorp/terraform-plugin-framework/function"
)

var (
_ function.Function = ValidJSONFunction{}
)

func NewValidJSONFunction() function.Function {
return ValidJSONFunction{}
}

type ValidJSONFunction struct{}

func (r ValidJSONFunction) Metadata(_ context.Context, req function.MetadataRequest, resp *function.MetadataResponse) {
resp.Name = "valid_json"
}

func (r ValidJSONFunction) Definition(_ context.Context, _ function.DefinitionRequest, resp *function.DefinitionResponse) {
resp.Definition = function.Definition{
Summary: "Checks whether a string is valid JSON",
Parameters: []function.Parameter{
function.StringParameter{
AllowNullValue: false,
AllowUnknownValues: true,
Description: "The JSON string to check",
Name: "json",
},
},
Return: function.BoolReturn{},
}
}

func (r ValidJSONFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
var JSON *string

resp.Error = function.ConcatFuncErrors(req.Arguments.Get(ctx, &JSON))
if resp.Error != nil {
return
}

isValidJSON, err := isValidJSON(JSON)
if err != nil {
resp.Error = function.ConcatFuncErrors(resp.Error, function.NewFuncError(err.Error()))
return
}

resp.Error = function.ConcatFuncErrors(resp.Result.Set(ctx, isValidJSON))
}

func isValidJSON(JSON *string) (bool, error) {
var js map[string]interface{}
err := json.Unmarshal([]byte(*JSON), &js)
if err != nil {
return false, nil
}
return true, nil
}
66 changes: 66 additions & 0 deletions internal/provider/valid_json_function_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"testing"

"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

func TestValidJSONFunction_basic(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(version.Must(version.NewVersion("1.8.0-beta1"))),
},
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: `
locals {
json = jsonencode({
foo = "bar"
})
}
output "test" {
value = provider::assert::valid_json(local.json)
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckOutput("test", "true"),
),
},
},
})
}

func TestValidJSONFunction_multiline(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(version.Must(version.NewVersion("1.8.0-beta1"))),
},
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: `
locals {
json = <<EOF
{
"foo": "bar"
}
EOF
}
output "test" {
value = provider::assert::valid_json(local.json)
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckOutput("test", "true"),
),
},
},
})
}

0 comments on commit eaf3ca0

Please sign in to comment.