github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/arguments/plan_test.go (about)

     1  package arguments
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/google/go-cmp/cmp"
     8  	"github.com/google/go-cmp/cmp/cmpopts"
     9  	"github.com/hashicorp/terraform/internal/addrs"
    10  	"github.com/hashicorp/terraform/internal/plans"
    11  )
    12  
    13  func TestParsePlan_basicValid(t *testing.T) {
    14  	testCases := map[string]struct {
    15  		args []string
    16  		want *Plan
    17  	}{
    18  		"defaults": {
    19  			nil,
    20  			&Plan{
    21  				DetailedExitCode: false,
    22  				InputEnabled:     true,
    23  				OutPath:          "",
    24  				ViewType:         ViewHuman,
    25  				State:            &State{Lock: true},
    26  				Vars:             &Vars{},
    27  				Operation: &Operation{
    28  					PlanMode:    plans.NormalMode,
    29  					Parallelism: 10,
    30  					Refresh:     true,
    31  				},
    32  			},
    33  		},
    34  		"setting all options": {
    35  			[]string{"-destroy", "-detailed-exitcode", "-input=false", "-out=saved.tfplan"},
    36  			&Plan{
    37  				DetailedExitCode: true,
    38  				InputEnabled:     false,
    39  				OutPath:          "saved.tfplan",
    40  				ViewType:         ViewHuman,
    41  				State:            &State{Lock: true},
    42  				Vars:             &Vars{},
    43  				Operation: &Operation{
    44  					PlanMode:    plans.DestroyMode,
    45  					Parallelism: 10,
    46  					Refresh:     true,
    47  				},
    48  			},
    49  		},
    50  		"JSON view disables input": {
    51  			[]string{"-json"},
    52  			&Plan{
    53  				DetailedExitCode: false,
    54  				InputEnabled:     false,
    55  				OutPath:          "",
    56  				ViewType:         ViewJSON,
    57  				State:            &State{Lock: true},
    58  				Vars:             &Vars{},
    59  				Operation: &Operation{
    60  					PlanMode:    plans.NormalMode,
    61  					Parallelism: 10,
    62  					Refresh:     true,
    63  				},
    64  			},
    65  		},
    66  	}
    67  
    68  	cmpOpts := cmpopts.IgnoreUnexported(Operation{}, Vars{}, State{})
    69  
    70  	for name, tc := range testCases {
    71  		t.Run(name, func(t *testing.T) {
    72  			got, diags := ParsePlan(tc.args)
    73  			if len(diags) > 0 {
    74  				t.Fatalf("unexpected diags: %v", diags)
    75  			}
    76  			if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" {
    77  				t.Errorf("unexpected result\n%s", diff)
    78  			}
    79  		})
    80  	}
    81  }
    82  
    83  func TestParsePlan_invalid(t *testing.T) {
    84  	got, diags := ParsePlan([]string{"-frob"})
    85  	if len(diags) == 0 {
    86  		t.Fatal("expected diags but got none")
    87  	}
    88  	if got, want := diags.Err().Error(), "flag provided but not defined"; !strings.Contains(got, want) {
    89  		t.Fatalf("wrong diags\n got: %s\nwant: %s", got, want)
    90  	}
    91  	if got.ViewType != ViewHuman {
    92  		t.Fatalf("wrong view type, got %#v, want %#v", got.ViewType, ViewHuman)
    93  	}
    94  }
    95  
    96  func TestParsePlan_tooManyArguments(t *testing.T) {
    97  	got, diags := ParsePlan([]string{"saved.tfplan"})
    98  	if len(diags) == 0 {
    99  		t.Fatal("expected diags but got none")
   100  	}
   101  	if got, want := diags.Err().Error(), "Too many command line arguments"; !strings.Contains(got, want) {
   102  		t.Fatalf("wrong diags\n got: %s\nwant: %s", got, want)
   103  	}
   104  	if got.ViewType != ViewHuman {
   105  		t.Fatalf("wrong view type, got %#v, want %#v", got.ViewType, ViewHuman)
   106  	}
   107  }
   108  
   109  func TestParsePlan_targets(t *testing.T) {
   110  	foobarbaz, _ := addrs.ParseTargetStr("foo_bar.baz")
   111  	boop, _ := addrs.ParseTargetStr("module.boop")
   112  	testCases := map[string]struct {
   113  		args    []string
   114  		want    []addrs.Targetable
   115  		wantErr string
   116  	}{
   117  		"no targets by default": {
   118  			args: nil,
   119  			want: nil,
   120  		},
   121  		"one target": {
   122  			args: []string{"-target=foo_bar.baz"},
   123  			want: []addrs.Targetable{foobarbaz.Subject},
   124  		},
   125  		"two targets": {
   126  			args: []string{"-target=foo_bar.baz", "-target", "module.boop"},
   127  			want: []addrs.Targetable{foobarbaz.Subject, boop.Subject},
   128  		},
   129  		"invalid traversal": {
   130  			args:    []string{"-target=foo."},
   131  			want:    nil,
   132  			wantErr: "Dot must be followed by attribute name",
   133  		},
   134  		"invalid target": {
   135  			args:    []string{"-target=data[0].foo"},
   136  			want:    nil,
   137  			wantErr: "A data source name is required",
   138  		},
   139  	}
   140  
   141  	for name, tc := range testCases {
   142  		t.Run(name, func(t *testing.T) {
   143  			got, diags := ParsePlan(tc.args)
   144  			if len(diags) > 0 {
   145  				if tc.wantErr == "" {
   146  					t.Fatalf("unexpected diags: %v", diags)
   147  				} else if got := diags.Err().Error(); !strings.Contains(got, tc.wantErr) {
   148  					t.Fatalf("wrong diags\n got: %s\nwant: %s", got, tc.wantErr)
   149  				}
   150  			}
   151  			if !cmp.Equal(got.Operation.Targets, tc.want) {
   152  				t.Fatalf("unexpected result\n%s", cmp.Diff(got.Operation.Targets, tc.want))
   153  			}
   154  		})
   155  	}
   156  }
   157  
   158  func TestParsePlan_vars(t *testing.T) {
   159  	testCases := map[string]struct {
   160  		args []string
   161  		want []FlagNameValue
   162  	}{
   163  		"no var flags by default": {
   164  			args: nil,
   165  			want: nil,
   166  		},
   167  		"one var": {
   168  			args: []string{"-var", "foo=bar"},
   169  			want: []FlagNameValue{
   170  				{Name: "-var", Value: "foo=bar"},
   171  			},
   172  		},
   173  		"one var-file": {
   174  			args: []string{"-var-file", "cool.tfvars"},
   175  			want: []FlagNameValue{
   176  				{Name: "-var-file", Value: "cool.tfvars"},
   177  			},
   178  		},
   179  		"ordering preserved": {
   180  			args: []string{
   181  				"-var", "foo=bar",
   182  				"-var-file", "cool.tfvars",
   183  				"-var", "boop=beep",
   184  			},
   185  			want: []FlagNameValue{
   186  				{Name: "-var", Value: "foo=bar"},
   187  				{Name: "-var-file", Value: "cool.tfvars"},
   188  				{Name: "-var", Value: "boop=beep"},
   189  			},
   190  		},
   191  	}
   192  
   193  	for name, tc := range testCases {
   194  		t.Run(name, func(t *testing.T) {
   195  			got, diags := ParsePlan(tc.args)
   196  			if len(diags) > 0 {
   197  				t.Fatalf("unexpected diags: %v", diags)
   198  			}
   199  			if vars := got.Vars.All(); !cmp.Equal(vars, tc.want) {
   200  				t.Fatalf("unexpected result\n%s", cmp.Diff(vars, tc.want))
   201  			}
   202  			if got, want := got.Vars.Empty(), len(tc.want) == 0; got != want {
   203  				t.Fatalf("expected Empty() to return %t, but was %t", want, got)
   204  			}
   205  		})
   206  	}
   207  }