github.com/blend/go-sdk@v1.20220411.3/env/parse_test.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package env
     9  
    10  import (
    11  	"testing"
    12  
    13  	"github.com/blend/go-sdk/assert"
    14  )
    15  
    16  func TestDelimitedString(t *testing.T) {
    17  	assert := assert.New(t)
    18  	testVars := make(Vars)
    19  	testVars["var_1"] = "val_1"
    20  	res := testVars.DelimitedString(PairDelimiterSemicolon)
    21  	groundTruth := `"var_1"="val_1"`
    22  	assert.Equal(groundTruth, res)
    23  
    24  	// Now try with multiple key-val pairs
    25  	testVars["var_2"] = "val_2"
    26  	res = testVars.DelimitedString(PairDelimiterSemicolon)
    27  	groundTruths := []string{`"var_1"="val_1";"var_2"="val_2"`, `"var_2"="val_2";"var_1"="val_1"`}
    28  	t.Log(res)
    29  	assert.True(matchOne(res, groundTruths...))
    30  }
    31  
    32  func TestParseGoodInputs(t *testing.T) {
    33  	assert := assert.New(t)
    34  
    35  	// Empty string, which is valid
    36  	input := ""
    37  	res, err := ParsePairDelimiter(input, PairDelimiterSemicolon)
    38  	assert.Equal(nil, err)
    39  
    40  	groundTruth := make(Vars)
    41  	assert.Equal(groundTruth, res)
    42  
    43  	// Single valid key-val pair
    44  	input = "var_1=val_1;"
    45  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
    46  	assert.Equal(nil, err)
    47  
    48  	groundTruth = make(Vars)
    49  	groundTruth["var_1"] = "val_1"
    50  	assert.Equal(groundTruth, res)
    51  
    52  	// Single valid key-val pair with no trailing delimiter
    53  	input = "var_1=val_1"
    54  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
    55  	assert.Equal(nil, err)
    56  
    57  	groundTruth = make(Vars)
    58  	groundTruth["var_1"] = "val_1"
    59  	assert.Equal(groundTruth, res)
    60  
    61  	// Two valid key-val pairs
    62  	input = "var_1=val_1;var_2=val_2;"
    63  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
    64  	assert.Equal(nil, err)
    65  
    66  	groundTruth = make(Vars)
    67  	groundTruth["var_1"] = "val_1"
    68  	groundTruth["var_2"] = "val_2"
    69  	assert.Equal(groundTruth, res)
    70  
    71  	// Two valid key-val pairs with arbitrary whitespace
    72  	input = " var_1   = val_1 ;  var_2 =    val_2; "
    73  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
    74  	assert.Equal(nil, err)
    75  	groundTruth = make(Vars)
    76  	groundTruth["var_1"] = "val_1"
    77  	groundTruth["var_2"] = "val_2"
    78  	assert.Equal(groundTruth, res)
    79  
    80  	// Two valid key-val pairs with a quoted string and arbitrary whitespace
    81  	input = "var_1 = val_1; var_2 = \" val_2 \";"
    82  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
    83  	assert.Equal(nil, err)
    84  
    85  	groundTruth = make(Vars)
    86  	groundTruth["var_1"] = "val_1"
    87  	groundTruth["var_2"] = " val_2 "
    88  	assert.Equal(groundTruth, res)
    89  
    90  	// Two valid key-val pairs with a quoted string and arbitrary whitespace
    91  	// and no trailing separator
    92  	input = `var_1 = val_1; var_2 = " val_2 "`
    93  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
    94  	assert.Equal(nil, err)
    95  
    96  	groundTruth = make(Vars)
    97  	groundTruth["var_1"] = "val_1"
    98  	groundTruth["var_2"] = " val_2 "
    99  	assert.Equal(groundTruth, res)
   100  
   101  	// Two valid key-val pairs with an escaped quote and arbitrary whitespace
   102  	// and no trailing separator
   103  	input = `  var_1     = val_1  ; var_2 =   \" val_2  `
   104  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   105  	assert.Equal(nil, err)
   106  
   107  	groundTruth = make(Vars)
   108  	groundTruth["var_1"] = "val_1"
   109  	groundTruth["var_2"] = `"val_2`
   110  	assert.Equal(groundTruth, res)
   111  
   112  	// Two valid key-val pairs with an escaped quote and arbitrary whitespace
   113  	// and no trailing separator
   114  	input = `var_1 = \=val_1; var_2 = \" val_2 \;  `
   115  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   116  	assert.Equal(nil, err)
   117  
   118  	groundTruth = make(Vars)
   119  	groundTruth["var_1"] = "=val_1"
   120  	groundTruth["var_2"] = `"val_2;`
   121  	assert.Equal(groundTruth, res)
   122  
   123  	// two valid key-val pairs where both the key and value for each pair is
   124  	// enclosed in quotes
   125  	input = `"var_1"="val_1";"var_2"="val_2";`
   126  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   127  	assert.Equal(nil, err)
   128  
   129  	groundTruth = make(Vars)
   130  	groundTruth["var_1"] = "val_1"
   131  	groundTruth["var_2"] = "val_2"
   132  	assert.Equal(groundTruth, res)
   133  
   134  	// A valid key-val pair consisting of a single quote inside a quoted block
   135  	input = `var_1 = "\""`
   136  	res, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   137  	assert.Equal(nil, err)
   138  
   139  	groundTruth = make(Vars)
   140  	groundTruth["var_1"] = `"`
   141  	assert.Equal(groundTruth, res)
   142  }
   143  
   144  func TestParseBadInputs(t *testing.T) {
   145  	assert := assert.New(t)
   146  
   147  	input := "="
   148  	_, err := ParsePairDelimiter(input, PairDelimiterSemicolon)
   149  	assert.NotEqual(nil, err)
   150  
   151  	input = ";"
   152  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   153  	assert.NotEqual(nil, err)
   154  
   155  	input = `\;`
   156  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   157  	assert.NotEqual(nil, err)
   158  
   159  	input = "=;"
   160  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   161  	assert.NotEqual(nil, err)
   162  
   163  	input = "=some_val;"
   164  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   165  	assert.NotEqual(nil, err)
   166  
   167  	input = ";=some_val;"
   168  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   169  	assert.NotEqual(nil, err)
   170  
   171  	input = `;\=some_val;`
   172  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   173  	assert.NotEqual(nil, err)
   174  
   175  	input = "some"
   176  	res, err := ParsePairDelimiter(input, PairDelimiterSemicolon)
   177  	t.Log(res)
   178  	assert.NotEqual(nil, err)
   179  
   180  	input = `some\=val`
   181  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   182  	assert.NotEqual(nil, err)
   183  
   184  	input = `key = "`
   185  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   186  	assert.NotEqual(nil, err)
   187  
   188  	input = `key "= "`
   189  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   190  	assert.NotEqual(nil, err)
   191  
   192  	input = `key \"= "`
   193  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   194  	assert.NotEqual(nil, err)
   195  
   196  	input = `key "= \""`
   197  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   198  	assert.NotEqual(nil, err)
   199  
   200  	input = `var_1 = =val_1; var_2 = \" val_2 \;  `
   201  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   202  	assert.NotEqual(nil, err)
   203  
   204  	input = `var_1 \= val_1; var_2 = " val_2 ";`
   205  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   206  	assert.NotEqual(nil, err)
   207  
   208  	input = `var_1 = val_1; var_2 = \" val_2 ";`
   209  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   210  	assert.NotEqual(nil, err)
   211  
   212  	input = `var_1 = =val_1; var_1 = \" val_2 \;  `
   213  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   214  	assert.NotEqual(nil, err)
   215  
   216  	input = `var_1 \= val_1; var_1 = " val_2 ";`
   217  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   218  	assert.NotEqual(nil, err)
   219  
   220  	input = `var_1 = val_1; var_1 = \" val_2 ";`
   221  	_, err = ParsePairDelimiter(input, PairDelimiterSemicolon)
   222  	assert.NotEqual(nil, err)
   223  }
   224  
   225  // TestParseAndBack is an integration test to sanity check that our
   226  // serialization/deserialization methods are at least consistent with each
   227  // other
   228  func TestParseAndBack(t *testing.T) {
   229  	assert := assert.New(t)
   230  	delimiter := PairDelimiterSemicolon
   231  
   232  	// Single valid key-val pair
   233  	groundTruth := make(Vars)
   234  	groundTruth["var_1"] = "val_1"
   235  	serialized := groundTruth.DelimitedString(delimiter)
   236  	res, err := ParsePairDelimiter(serialized, PairDelimiterSemicolon)
   237  	assert.Equal(nil, err)
   238  	assert.Equal(groundTruth, res)
   239  
   240  	// Single valid key-val pair with no trailing delimiter
   241  	groundTruth = make(Vars)
   242  	groundTruth["var_1"] = "val_1"
   243  	groundTruth["var_2"] = "val_2"
   244  	serialized = groundTruth.DelimitedString(delimiter)
   245  	res, _ = ParsePairDelimiter(serialized, PairDelimiterSemicolon)
   246  	assert.Equal(groundTruth, res)
   247  
   248  	// Single valid key-val pair with no trailing delimiter
   249  	groundTruth = make(Vars)
   250  	groundTruth[`"`] = "val_1"
   251  	groundTruth[`=`] = "val_2"
   252  	serialized = groundTruth.DelimitedString(delimiter)
   253  	res, _ = ParsePairDelimiter(serialized, PairDelimiterSemicolon)
   254  	assert.Equal(groundTruth, res)
   255  
   256  	// More special characters
   257  	groundTruth = make(Vars)
   258  	groundTruth[`\"`] = "val_1"
   259  	groundTruth[`=`] = "val_2"
   260  	serialized = groundTruth.DelimitedString(delimiter)
   261  	res, _ = ParsePairDelimiter(serialized, PairDelimiterSemicolon)
   262  	assert.Equal(groundTruth, res)
   263  
   264  	groundTruth = make(Vars)
   265  	groundTruth[`"val_1"="val_2";`] = `"what;a\tricky=value!`
   266  	groundTruth[`=`] = "val_2"
   267  	serialized = groundTruth.DelimitedString(delimiter)
   268  	res, _ = ParsePairDelimiter(serialized, PairDelimiterSemicolon)
   269  	assert.Equal(groundTruth, res)
   270  }
   271  
   272  func TestEscapeString(t *testing.T) {
   273  	assert := assert.New(t)
   274  
   275  	// no escapes
   276  	input := "some test string"
   277  	expected := "some test string"
   278  	res := escapeString(input, PairDelimiterSemicolon)
   279  	assert.Equal(expected, res)
   280  
   281  	input = `some \test string`
   282  	expected = `some \\test string`
   283  	res = escapeString(input, PairDelimiterSemicolon)
   284  	assert.Equal(expected, res)
   285  
   286  	input = `some \=test string`
   287  	expected = `some \\\=test string`
   288  	res = escapeString(input, PairDelimiterSemicolon)
   289  	assert.Equal(expected, res)
   290  
   291  	input = `test; string`
   292  	expected = `test\; string`
   293  	res = escapeString(input, PairDelimiterSemicolon)
   294  	assert.Equal(expected, res)
   295  
   296  	input = `test; " string`
   297  	expected = `test\; \" string`
   298  	res = escapeString(input, PairDelimiterSemicolon)
   299  	assert.Equal(expected, res)
   300  }
   301  
   302  // matchOne checks to see if the input string is an exact match of a number of
   303  // candidate ground truths
   304  func matchOne(input string, groundTruths ...string) bool {
   305  	for _, groundTruth := range groundTruths {
   306  		if groundTruth == input {
   307  			return true
   308  		}
   309  	}
   310  	return false
   311  }