github.com/kevinklinger/open_terraform@v1.3.6/noninternal/backend/unparsed_value_test.go (about)

     1  package backend
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/google/go-cmp/cmp"
     8  	"github.com/hashicorp/hcl/v2"
     9  	"github.com/zclconf/go-cty/cty"
    10  
    11  	"github.com/kevinklinger/open_terraform/noninternal/configs"
    12  	"github.com/kevinklinger/open_terraform/noninternal/terraform"
    13  	"github.com/kevinklinger/open_terraform/noninternal/tfdiags"
    14  )
    15  
    16  func TestUnparsedValue(t *testing.T) {
    17  	vv := map[string]UnparsedVariableValue{
    18  		"undeclared0": testUnparsedVariableValue("0"),
    19  		"undeclared1": testUnparsedVariableValue("1"),
    20  		"undeclared2": testUnparsedVariableValue("2"),
    21  		"undeclared3": testUnparsedVariableValue("3"),
    22  		"undeclared4": testUnparsedVariableValue("4"),
    23  		"declared1":   testUnparsedVariableValue("5"),
    24  	}
    25  	decls := map[string]*configs.Variable{
    26  		"declared1": {
    27  			Name:           "declared1",
    28  			Type:           cty.String,
    29  			ConstraintType: cty.String,
    30  			ParsingMode:    configs.VariableParseLiteral,
    31  			DeclRange: hcl.Range{
    32  				Filename: "fake.tf",
    33  				Start:    hcl.Pos{Line: 2, Column: 1, Byte: 0},
    34  				End:      hcl.Pos{Line: 2, Column: 1, Byte: 0},
    35  			},
    36  		},
    37  		"missing1": {
    38  			Name:           "missing1",
    39  			Type:           cty.String,
    40  			ConstraintType: cty.String,
    41  			ParsingMode:    configs.VariableParseLiteral,
    42  			DeclRange: hcl.Range{
    43  				Filename: "fake.tf",
    44  				Start:    hcl.Pos{Line: 3, Column: 1, Byte: 0},
    45  				End:      hcl.Pos{Line: 3, Column: 1, Byte: 0},
    46  			},
    47  		},
    48  		"missing2": {
    49  			Name:           "missing1",
    50  			Type:           cty.String,
    51  			ConstraintType: cty.String,
    52  			ParsingMode:    configs.VariableParseLiteral,
    53  			Default:        cty.StringVal("default for missing2"),
    54  			DeclRange: hcl.Range{
    55  				Filename: "fake.tf",
    56  				Start:    hcl.Pos{Line: 4, Column: 1, Byte: 0},
    57  				End:      hcl.Pos{Line: 4, Column: 1, Byte: 0},
    58  			},
    59  		},
    60  	}
    61  
    62  	const undeclSingular = `Value for undeclared variable`
    63  	const undeclPlural = `Values for undeclared variables`
    64  
    65  	t.Run("ParseDeclaredVariableValues", func(t *testing.T) {
    66  		gotVals, diags := ParseDeclaredVariableValues(vv, decls)
    67  
    68  		if got, want := len(diags), 0; got != want {
    69  			t.Fatalf("wrong number of diagnostics %d; want %d", got, want)
    70  		}
    71  
    72  		wantVals := terraform.InputValues{
    73  			"declared1": {
    74  				Value:      cty.StringVal("5"),
    75  				SourceType: terraform.ValueFromNamedFile,
    76  				SourceRange: tfdiags.SourceRange{
    77  					Filename: "fake.tfvars",
    78  					Start:    tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
    79  					End:      tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
    80  				},
    81  			},
    82  		}
    83  
    84  		if diff := cmp.Diff(wantVals, gotVals, cmp.Comparer(cty.Value.RawEquals)); diff != "" {
    85  			t.Errorf("wrong result\n%s", diff)
    86  		}
    87  	})
    88  
    89  	t.Run("ParseUndeclaredVariableValues", func(t *testing.T) {
    90  		gotVals, diags := ParseUndeclaredVariableValues(vv, decls)
    91  
    92  		if got, want := len(diags), 3; got != want {
    93  			t.Fatalf("wrong number of diagnostics %d; want %d", got, want)
    94  		}
    95  
    96  		if got, want := diags[0].Description().Summary, undeclSingular; got != want {
    97  			t.Errorf("wrong summary for diagnostic 0\ngot:  %s\nwant: %s", got, want)
    98  		}
    99  
   100  		if got, want := diags[1].Description().Summary, undeclSingular; got != want {
   101  			t.Errorf("wrong summary for diagnostic 1\ngot:  %s\nwant: %s", got, want)
   102  		}
   103  
   104  		if got, want := diags[2].Description().Summary, undeclPlural; got != want {
   105  			t.Errorf("wrong summary for diagnostic 2\ngot:  %s\nwant: %s", got, want)
   106  		}
   107  
   108  		wantVals := terraform.InputValues{
   109  			"undeclared0": {
   110  				Value:      cty.StringVal("0"),
   111  				SourceType: terraform.ValueFromNamedFile,
   112  				SourceRange: tfdiags.SourceRange{
   113  					Filename: "fake.tfvars",
   114  					Start:    tfdiags.SourcePos{Line: 1, Column: 1},
   115  					End:      tfdiags.SourcePos{Line: 1, Column: 1},
   116  				},
   117  			},
   118  			"undeclared1": {
   119  				Value:      cty.StringVal("1"),
   120  				SourceType: terraform.ValueFromNamedFile,
   121  				SourceRange: tfdiags.SourceRange{
   122  					Filename: "fake.tfvars",
   123  					Start:    tfdiags.SourcePos{Line: 1, Column: 1},
   124  					End:      tfdiags.SourcePos{Line: 1, Column: 1},
   125  				},
   126  			},
   127  			"undeclared2": {
   128  				Value:      cty.StringVal("2"),
   129  				SourceType: terraform.ValueFromNamedFile,
   130  				SourceRange: tfdiags.SourceRange{
   131  					Filename: "fake.tfvars",
   132  					Start:    tfdiags.SourcePos{Line: 1, Column: 1},
   133  					End:      tfdiags.SourcePos{Line: 1, Column: 1},
   134  				},
   135  			},
   136  			"undeclared3": {
   137  				Value:      cty.StringVal("3"),
   138  				SourceType: terraform.ValueFromNamedFile,
   139  				SourceRange: tfdiags.SourceRange{
   140  					Filename: "fake.tfvars",
   141  					Start:    tfdiags.SourcePos{Line: 1, Column: 1},
   142  					End:      tfdiags.SourcePos{Line: 1, Column: 1},
   143  				},
   144  			},
   145  			"undeclared4": {
   146  				Value:      cty.StringVal("4"),
   147  				SourceType: terraform.ValueFromNamedFile,
   148  				SourceRange: tfdiags.SourceRange{
   149  					Filename: "fake.tfvars",
   150  					Start:    tfdiags.SourcePos{Line: 1, Column: 1},
   151  					End:      tfdiags.SourcePos{Line: 1, Column: 1},
   152  				},
   153  			},
   154  		}
   155  		if diff := cmp.Diff(wantVals, gotVals, cmp.Comparer(cty.Value.RawEquals)); diff != "" {
   156  			t.Errorf("wrong result\n%s", diff)
   157  		}
   158  	})
   159  
   160  	t.Run("ParseVariableValues", func(t *testing.T) {
   161  		gotVals, diags := ParseVariableValues(vv, decls)
   162  		for _, diag := range diags {
   163  			t.Logf("%s: %s", diag.Description().Summary, diag.Description().Detail)
   164  		}
   165  		if got, want := len(diags), 4; got != want {
   166  			t.Fatalf("wrong number of diagnostics %d; want %d", got, want)
   167  		}
   168  
   169  		const missingRequired = `No value for required variable`
   170  
   171  		if got, want := diags[0].Description().Summary, undeclSingular; got != want {
   172  			t.Errorf("wrong summary for diagnostic 0\ngot:  %s\nwant: %s", got, want)
   173  		}
   174  		if got, want := diags[1].Description().Summary, undeclSingular; got != want {
   175  			t.Errorf("wrong summary for diagnostic 1\ngot:  %s\nwant: %s", got, want)
   176  		}
   177  		if got, want := diags[2].Description().Summary, undeclPlural; got != want {
   178  			t.Errorf("wrong summary for diagnostic 2\ngot:  %s\nwant: %s", got, want)
   179  		}
   180  		if got, want := diags[2].Description().Detail, "3 other variable(s)"; !strings.Contains(got, want) {
   181  			t.Errorf("wrong detail for diagnostic 2\ngot:  %s\nmust contain: %s", got, want)
   182  		}
   183  		if got, want := diags[3].Description().Summary, missingRequired; got != want {
   184  			t.Errorf("wrong summary for diagnostic 3\ngot:  %s\nwant: %s", got, want)
   185  		}
   186  
   187  		wantVals := terraform.InputValues{
   188  			"declared1": {
   189  				Value:      cty.StringVal("5"),
   190  				SourceType: terraform.ValueFromNamedFile,
   191  				SourceRange: tfdiags.SourceRange{
   192  					Filename: "fake.tfvars",
   193  					Start:    tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
   194  					End:      tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
   195  				},
   196  			},
   197  			"missing1": {
   198  				Value:      cty.DynamicVal,
   199  				SourceType: terraform.ValueFromConfig,
   200  				SourceRange: tfdiags.SourceRange{
   201  					Filename: "fake.tf",
   202  					Start:    tfdiags.SourcePos{Line: 3, Column: 1, Byte: 0},
   203  					End:      tfdiags.SourcePos{Line: 3, Column: 1, Byte: 0},
   204  				},
   205  			},
   206  			"missing2": {
   207  				Value:      cty.NilVal, // Terraform Core handles substituting the default
   208  				SourceType: terraform.ValueFromConfig,
   209  				SourceRange: tfdiags.SourceRange{
   210  					Filename: "fake.tf",
   211  					Start:    tfdiags.SourcePos{Line: 4, Column: 1, Byte: 0},
   212  					End:      tfdiags.SourcePos{Line: 4, Column: 1, Byte: 0},
   213  				},
   214  			},
   215  		}
   216  		if diff := cmp.Diff(wantVals, gotVals, cmp.Comparer(cty.Value.RawEquals)); diff != "" {
   217  			t.Errorf("wrong result\n%s", diff)
   218  		}
   219  	})
   220  }
   221  
   222  type testUnparsedVariableValue string
   223  
   224  func (v testUnparsedVariableValue) ParseVariableValue(mode configs.VariableParsingMode) (*terraform.InputValue, tfdiags.Diagnostics) {
   225  	return &terraform.InputValue{
   226  		Value:      cty.StringVal(string(v)),
   227  		SourceType: terraform.ValueFromNamedFile,
   228  		SourceRange: tfdiags.SourceRange{
   229  			Filename: "fake.tfvars",
   230  			Start:    tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
   231  			End:      tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
   232  		},
   233  	}, nil
   234  }