github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/compose/interpolation/interpolation_test.go (about) 1 package interpolation 2 3 import ( 4 "testing" 5 6 "strconv" 7 8 "gotest.tools/v3/assert" 9 is "gotest.tools/v3/assert/cmp" 10 "gotest.tools/v3/env" 11 ) 12 13 var defaults = map[string]string{ 14 "USER": "jenny", 15 "FOO": "bar", 16 "count": "5", 17 } 18 19 func defaultMapping(name string) (string, bool) { 20 val, ok := defaults[name] 21 return val, ok 22 } 23 24 func TestInterpolate(t *testing.T) { 25 services := map[string]interface{}{ 26 "servicea": map[string]interface{}{ 27 "image": "example:${USER}", 28 "volumes": []interface{}{"$FOO:/target"}, 29 "logging": map[string]interface{}{ 30 "driver": "${FOO}", 31 "options": map[string]interface{}{ 32 "user": "$USER", 33 }, 34 }, 35 }, 36 } 37 expected := map[string]interface{}{ 38 "servicea": map[string]interface{}{ 39 "image": "example:jenny", 40 "volumes": []interface{}{"bar:/target"}, 41 "logging": map[string]interface{}{ 42 "driver": "bar", 43 "options": map[string]interface{}{ 44 "user": "jenny", 45 }, 46 }, 47 }, 48 } 49 result, err := Interpolate(services, Options{LookupValue: defaultMapping}) 50 assert.NilError(t, err) 51 assert.Check(t, is.DeepEqual(expected, result)) 52 } 53 54 func TestInvalidInterpolation(t *testing.T) { 55 services := map[string]interface{}{ 56 "servicea": map[string]interface{}{ 57 "image": "${", 58 }, 59 } 60 _, err := Interpolate(services, Options{LookupValue: defaultMapping}) 61 assert.Error(t, err, `invalid interpolation format for servicea.image: "${". You may need to escape any $ with another $.`) 62 } 63 64 func TestInterpolateWithDefaults(t *testing.T) { 65 defer env.Patch(t, "FOO", "BARZ")() 66 67 config := map[string]interface{}{ 68 "networks": map[string]interface{}{ 69 "foo": "thing_${FOO}", 70 }, 71 } 72 expected := map[string]interface{}{ 73 "networks": map[string]interface{}{ 74 "foo": "thing_BARZ", 75 }, 76 } 77 result, err := Interpolate(config, Options{}) 78 assert.NilError(t, err) 79 assert.Check(t, is.DeepEqual(expected, result)) 80 } 81 82 func TestInterpolateWithCast(t *testing.T) { 83 config := map[string]interface{}{ 84 "foo": map[string]interface{}{ 85 "replicas": "$count", 86 }, 87 } 88 toInt := func(value string) (interface{}, error) { 89 return strconv.Atoi(value) 90 } 91 result, err := Interpolate(config, Options{ 92 LookupValue: defaultMapping, 93 TypeCastMapping: map[Path]Cast{NewPath(PathMatchAll, "replicas"): toInt}, 94 }) 95 assert.NilError(t, err) 96 expected := map[string]interface{}{ 97 "foo": map[string]interface{}{ 98 "replicas": 5, 99 }, 100 } 101 assert.Check(t, is.DeepEqual(expected, result)) 102 } 103 104 func TestPathMatches(t *testing.T) { 105 var testcases = []struct { 106 doc string 107 path Path 108 pattern Path 109 expected bool 110 }{ 111 { 112 doc: "pattern too short", 113 path: NewPath("one", "two", "three"), 114 pattern: NewPath("one", "two"), 115 }, 116 { 117 doc: "pattern too long", 118 path: NewPath("one", "two"), 119 pattern: NewPath("one", "two", "three"), 120 }, 121 { 122 doc: "pattern mismatch", 123 path: NewPath("one", "three", "two"), 124 pattern: NewPath("one", "two", "three"), 125 }, 126 { 127 doc: "pattern mismatch with match-all part", 128 path: NewPath("one", "three", "two"), 129 pattern: NewPath(PathMatchAll, "two", "three"), 130 }, 131 { 132 doc: "pattern match with match-all part", 133 path: NewPath("one", "two", "three"), 134 pattern: NewPath("one", "*", "three"), 135 expected: true, 136 }, 137 { 138 doc: "pattern match", 139 path: NewPath("one", "two", "three"), 140 pattern: NewPath("one", "two", "three"), 141 expected: true, 142 }, 143 } 144 for _, testcase := range testcases { 145 assert.Check(t, is.Equal(testcase.expected, testcase.path.matches(testcase.pattern))) 146 } 147 }