github.com/posener/terraform@v0.11.0-beta1.0.20171103235147-645df36af025/helper/validation/validation_test.go (about)

     1  package validation
     2  
     3  import (
     4  	"regexp"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  )
     9  
    10  type testCase struct {
    11  	val         interface{}
    12  	f           schema.SchemaValidateFunc
    13  	expectedErr *regexp.Regexp
    14  }
    15  
    16  func TestValidationIntBetween(t *testing.T) {
    17  	runTestCases(t, []testCase{
    18  		{
    19  			val: 1,
    20  			f:   IntBetween(1, 1),
    21  		},
    22  		{
    23  			val: 1,
    24  			f:   IntBetween(0, 2),
    25  		},
    26  		{
    27  			val:         1,
    28  			f:           IntBetween(2, 3),
    29  			expectedErr: regexp.MustCompile("expected [\\w]+ to be in the range \\(2 - 3\\), got 1"),
    30  		},
    31  		{
    32  			val:         "1",
    33  			f:           IntBetween(2, 3),
    34  			expectedErr: regexp.MustCompile("expected type of [\\w]+ to be int"),
    35  		},
    36  	})
    37  }
    38  
    39  func TestValidationIntAtLeast(t *testing.T) {
    40  	runTestCases(t, []testCase{
    41  		{
    42  			val: 1,
    43  			f:   IntAtLeast(1),
    44  		},
    45  		{
    46  			val: 1,
    47  			f:   IntAtLeast(0),
    48  		},
    49  		{
    50  			val:         1,
    51  			f:           IntAtLeast(2),
    52  			expectedErr: regexp.MustCompile("expected [\\w]+ to be at least \\(2\\), got 1"),
    53  		},
    54  		{
    55  			val:         "1",
    56  			f:           IntAtLeast(2),
    57  			expectedErr: regexp.MustCompile("expected type of [\\w]+ to be int"),
    58  		},
    59  	})
    60  }
    61  
    62  func TestValidationIntAtMost(t *testing.T) {
    63  	runTestCases(t, []testCase{
    64  		{
    65  			val: 1,
    66  			f:   IntAtMost(1),
    67  		},
    68  		{
    69  			val: 1,
    70  			f:   IntAtMost(2),
    71  		},
    72  		{
    73  			val:         1,
    74  			f:           IntAtMost(0),
    75  			expectedErr: regexp.MustCompile("expected [\\w]+ to be at most \\(0\\), got 1"),
    76  		},
    77  		{
    78  			val:         "1",
    79  			f:           IntAtMost(0),
    80  			expectedErr: regexp.MustCompile("expected type of [\\w]+ to be int"),
    81  		},
    82  	})
    83  }
    84  
    85  func TestValidationStringInSlice(t *testing.T) {
    86  	runTestCases(t, []testCase{
    87  		{
    88  			val: "ValidValue",
    89  			f:   StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false),
    90  		},
    91  		// ignore case
    92  		{
    93  			val: "VALIDVALUE",
    94  			f:   StringInSlice([]string{"ValidValue", "AnotherValidValue"}, true),
    95  		},
    96  		{
    97  			val:         "VALIDVALUE",
    98  			f:           StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false),
    99  			expectedErr: regexp.MustCompile("expected [\\w]+ to be one of \\[ValidValue AnotherValidValue\\], got VALIDVALUE"),
   100  		},
   101  		{
   102  			val:         "InvalidValue",
   103  			f:           StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false),
   104  			expectedErr: regexp.MustCompile("expected [\\w]+ to be one of \\[ValidValue AnotherValidValue\\], got InvalidValue"),
   105  		},
   106  		{
   107  			val:         1,
   108  			f:           StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false),
   109  			expectedErr: regexp.MustCompile("expected type of [\\w]+ to be string"),
   110  		},
   111  	})
   112  }
   113  
   114  func TestValidationRegexp(t *testing.T) {
   115  	runTestCases(t, []testCase{
   116  		{
   117  			val: ".*foo.*",
   118  			f:   ValidateRegexp,
   119  		},
   120  		{
   121  			val:         "foo(bar",
   122  			f:           ValidateRegexp,
   123  			expectedErr: regexp.MustCompile(regexp.QuoteMeta("error parsing regexp: missing closing ): `foo(bar`")),
   124  		},
   125  	})
   126  }
   127  
   128  func TestValidateJsonString(t *testing.T) {
   129  	type testCases struct {
   130  		Value    string
   131  		ErrCount int
   132  	}
   133  
   134  	invalidCases := []testCases{
   135  		{
   136  			Value:    `{0:"1"}`,
   137  			ErrCount: 1,
   138  		},
   139  		{
   140  			Value:    `{'abc':1}`,
   141  			ErrCount: 1,
   142  		},
   143  		{
   144  			Value:    `{"def":}`,
   145  			ErrCount: 1,
   146  		},
   147  		{
   148  			Value:    `{"xyz":[}}`,
   149  			ErrCount: 1,
   150  		},
   151  	}
   152  
   153  	for _, tc := range invalidCases {
   154  		_, errors := ValidateJsonString(tc.Value, "json")
   155  		if len(errors) != tc.ErrCount {
   156  			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
   157  		}
   158  	}
   159  
   160  	validCases := []testCases{
   161  		{
   162  			Value:    ``,
   163  			ErrCount: 0,
   164  		},
   165  		{
   166  			Value:    `{}`,
   167  			ErrCount: 0,
   168  		},
   169  		{
   170  			Value:    `{"abc":["1","2"]}`,
   171  			ErrCount: 0,
   172  		},
   173  	}
   174  
   175  	for _, tc := range validCases {
   176  		_, errors := ValidateJsonString(tc.Value, "json")
   177  		if len(errors) != tc.ErrCount {
   178  			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
   179  		}
   180  	}
   181  }
   182  
   183  func TestValidateListUniqueStrings(t *testing.T) {
   184  	runTestCases(t, []testCase{
   185  		{
   186  			val: []interface{}{"foo", "bar"},
   187  			f:   ValidateListUniqueStrings,
   188  		},
   189  		{
   190  			val:         []interface{}{"foo", "bar", "foo"},
   191  			f:           ValidateListUniqueStrings,
   192  			expectedErr: regexp.MustCompile("duplicate entry - foo"),
   193  		},
   194  		{
   195  			val:         []interface{}{"foo", "bar", "foo", "baz", "bar"},
   196  			f:           ValidateListUniqueStrings,
   197  			expectedErr: regexp.MustCompile("duplicate entry - (?:foo|bar)"),
   198  		},
   199  	})
   200  }
   201  
   202  func TestValidationNoZeroValues(t *testing.T) {
   203  	runTestCases(t, []testCase{
   204  		{
   205  			val: "foo",
   206  			f:   NoZeroValues,
   207  		},
   208  		{
   209  			val: 1,
   210  			f:   NoZeroValues,
   211  		},
   212  		{
   213  			val: float64(1),
   214  			f:   NoZeroValues,
   215  		},
   216  		{
   217  			val:         "",
   218  			f:           NoZeroValues,
   219  			expectedErr: regexp.MustCompile("must not be empty"),
   220  		},
   221  		{
   222  			val:         0,
   223  			f:           NoZeroValues,
   224  			expectedErr: regexp.MustCompile("must not be zero"),
   225  		},
   226  		{
   227  			val:         float64(0),
   228  			f:           NoZeroValues,
   229  			expectedErr: regexp.MustCompile("must not be zero"),
   230  		},
   231  	})
   232  }
   233  
   234  func runTestCases(t *testing.T, cases []testCase) {
   235  	matchErr := func(errs []error, r *regexp.Regexp) bool {
   236  		// err must match one provided
   237  		for _, err := range errs {
   238  			if r.MatchString(err.Error()) {
   239  				return true
   240  			}
   241  		}
   242  
   243  		return false
   244  	}
   245  
   246  	for i, tc := range cases {
   247  		_, errs := tc.f(tc.val, "test_property")
   248  
   249  		if len(errs) == 0 && tc.expectedErr == nil {
   250  			continue
   251  		}
   252  
   253  		if len(errs) != 0 && tc.expectedErr == nil {
   254  			t.Fatalf("expected test case %d to produce no errors, got %v", i, errs)
   255  		}
   256  
   257  		if !matchErr(errs, tc.expectedErr) {
   258  			t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs)
   259  		}
   260  	}
   261  }