github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/encoding/yaml_test.go (about) 1 package encoding 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 "github.com/tilt-dev/tilt/internal/testutils" 10 "github.com/tilt-dev/tilt/internal/tiltfile/io" 11 ) 12 13 func TestReadYAML(t *testing.T) { 14 f := newFixture(t) 15 16 var document = ` 17 key1: foo 18 key2: 19 key3: "bar" 20 key4: true 21 key5: 3 22 ` 23 f.File("options.yaml", document) 24 f.File("Tiltfile", ` 25 observed = read_yaml("options.yaml") 26 27 expected = { 28 'key1': 'foo', 29 'key2': { 30 'key3': 'bar', 31 'key4': True 32 }, 33 'key5': 3, 34 } 35 36 load('assert.tilt', 'assert') 37 assert.equals(expected, observed) 38 `) 39 40 result, err := f.ExecFile("Tiltfile") 41 if err != nil { 42 fmt.Println(f.PrintOutput()) 43 } 44 require.NoError(t, err) 45 46 rs, err := io.GetState(result) 47 require.NoError(t, err) 48 require.Contains(t, rs.Paths, f.JoinPath("options.yaml")) 49 } 50 51 func TestReadYAMLDefaultValue(t *testing.T) { 52 f := newFixture(t) 53 54 f.File("Tiltfile", ` 55 result = read_yaml("dne.yaml", "hello") 56 57 load('assert.tilt', 'assert') 58 assert.equals('hello', result) 59 `) 60 61 _, err := f.ExecFile("Tiltfile") 62 if err != nil { 63 fmt.Println(f.PrintOutput()) 64 } 65 require.NoError(t, err) 66 } 67 68 func TestReadYAMLStreamDefaultValue(t *testing.T) { 69 f := newFixture(t) 70 71 f.File("Tiltfile", ` 72 result = read_yaml_stream("dne.yaml", ["hello", "goodbye"]) 73 74 load('assert.tilt', 'assert') 75 assert.equals(['hello', 'goodbye'], result) 76 `) 77 78 _, err := f.ExecFile("Tiltfile") 79 if err != nil { 80 fmt.Println(f.PrintOutput()) 81 } 82 require.NoError(t, err) 83 } 84 85 func TestYAMLDoesNotExist(t *testing.T) { 86 f := newFixture(t) 87 88 f.File("Tiltfile", `result = read_yaml("dne.yaml")`) 89 result, err := f.ExecFile("Tiltfile") 90 require.Error(t, err) 91 require.Contains(t, err.Error(), "dne.yaml") 92 testutils.AssertIsNotExist(t, err) 93 94 rs, err := io.GetState(result) 95 require.NoError(t, err) 96 require.Contains(t, rs.Paths, f.JoinPath("dne.yaml")) 97 } 98 99 func TestMalformedYAML(t *testing.T) { 100 f := newFixture(t) 101 102 f.UseRealFS() 103 104 var document = ` 105 key1: foo 106 key2: 107 key3: "bar 108 key4: true 109 key5: 3 110 ` 111 f.File("options.yaml", document) 112 113 f.File("Tiltfile", `result = read_yaml("options.yaml")`) 114 result, err := f.ExecFile("Tiltfile") 115 require.Error(t, err) 116 require.Contains(t, err.Error(), "error parsing YAML from options.yaml: error converting YAML to JSON: yaml: line 7: found unexpected end of stream") 117 118 rs, err := io.GetState(result) 119 require.NoError(t, err) 120 require.Contains(t, rs.Paths, f.JoinPath("options.yaml")) 121 122 } 123 124 func TestDecodeYAMLDocument(t *testing.T) { 125 for _, blob := range []bool{false, true} { 126 t.Run(fmt.Sprintf("blob: %v", blob), func(t *testing.T) { 127 f := newFixture(t) 128 129 d := `'- "foo"\n- baz:\n - "bar"\n - ""\n - 1\n - 2'` 130 if blob { 131 d = fmt.Sprintf("blob(%s)", d) 132 } 133 d = fmt.Sprintf("observed = decode_yaml(%s)", d) 134 tf := d + ` 135 expected = [ 136 "foo", 137 { 138 "baz": [ "bar", "", 1, 2], 139 } 140 ] 141 142 load('assert.tilt', 'assert') 143 assert.equals(expected, observed) 144 ` 145 f.File("Tiltfile", tf) 146 147 _, err := f.ExecFile("Tiltfile") 148 if err != nil { 149 fmt.Println(f.PrintOutput()) 150 } 151 require.NoError(t, err) 152 }) 153 } 154 } 155 156 func TestDecodeYAMLEmptyString(t *testing.T) { 157 f := newFixture(t) 158 159 tf := ` 160 observed = decode_yaml('') 161 expected = None 162 163 load('assert.tilt', 'assert') 164 assert.equals(expected, observed) 165 ` 166 f.File("Tiltfile", tf) 167 168 _, err := f.ExecFile("Tiltfile") 169 if err != nil { 170 fmt.Println(f.PrintOutput()) 171 } 172 require.NoError(t, err) 173 } 174 175 const yamlStream = `- foo 176 - baz: 177 - bar 178 - "" 179 - 1 180 - 2 181 --- 182 quu: 183 - qux 184 - a: 185 - 3 186 ` 187 188 const yamlStreamAsStarlark = `[ 189 [ 190 "foo", 191 { 192 "baz": [ "bar", "", 1, 2], 193 } 194 ], 195 { 196 "quu": [ 197 "qux", 198 { 199 "a": [3], 200 } 201 ] 202 }, 203 ]` 204 205 func TestReadYAMLStream(t *testing.T) { 206 f := newFixture(t) 207 208 f.UseRealFS() 209 210 f.File("test.yaml", yamlStream) 211 d := "observed = read_yaml_stream('test.yaml')\n" 212 d += fmt.Sprintf("expected = %s\n", yamlStreamAsStarlark) 213 tf := d + ` 214 def test(): 215 if expected != observed: 216 print('expected: %s' % (expected)) 217 print('observed: %s' % (observed)) 218 fail() 219 220 test() 221 222 ` 223 f.File("Tiltfile", tf) 224 225 _, err := f.ExecFile("Tiltfile") 226 if err != nil { 227 fmt.Println(f.PrintOutput()) 228 } 229 require.NoError(t, err) 230 } 231 232 // call read_yaml on a stream, get an error 233 func TestReadYAMLUnexpectedStream(t *testing.T) { 234 f := newFixture(t) 235 236 f.UseRealFS() 237 238 f.File("test.yaml", yamlStream) 239 tf := "observed = read_yaml('test.yaml')\n" 240 f.File("Tiltfile", tf) 241 242 _, err := f.ExecFile("Tiltfile") 243 if err != nil { 244 fmt.Println(f.PrintOutput()) 245 } 246 require.Error(t, err) 247 require.Contains(t, err.Error(), "expected a yaml document but found a yaml stream") 248 } 249 250 func TestDecodeYAMLStream(t *testing.T) { 251 f := newFixture(t) 252 253 d := yamlStream 254 d = fmt.Sprintf("observed = decode_yaml_stream('''%s''')\n", d) 255 d += fmt.Sprintf("expected = %s\n", yamlStreamAsStarlark) 256 tf := d + ` 257 load('assert.tilt', 'assert') 258 assert.equals(expected, observed) 259 260 ` 261 f.File("Tiltfile", tf) 262 263 _, err := f.ExecFile("Tiltfile") 264 if err != nil { 265 fmt.Println(f.PrintOutput()) 266 } 267 require.NoError(t, err) 268 } 269 270 func TestDecodeYAMLStreamEmptyEntries(t *testing.T) { 271 f := newFixture(t) 272 273 yaml := `name: hello 274 --- 275 276 --- 277 name: goodbye 278 --- 279 280 ---` 281 d := fmt.Sprintf("observed = decode_yaml_stream('''%s''')\n", yaml) 282 tf := d + ` 283 load('assert.tilt', 'assert') 284 assert.equals(['hello', 'goodbye'], [r['name'] for r in observed]) 285 286 ` 287 f.File("Tiltfile", tf) 288 289 _, err := f.ExecFile("Tiltfile") 290 if err != nil { 291 fmt.Println(f.PrintOutput()) 292 } 293 require.NoError(t, err) 294 } 295 296 func TestDecodeYAMLUnexpectedStream(t *testing.T) { 297 f := newFixture(t) 298 299 tf := fmt.Sprintf("observed = decode_yaml('''%s''')\n", yamlStream) 300 f.File("Tiltfile", tf) 301 302 _, err := f.ExecFile("Tiltfile") 303 if err != nil { 304 fmt.Println(f.PrintOutput()) 305 } 306 require.Error(t, err) 307 require.Contains(t, err.Error(), "expected a yaml document but found a yaml stream") 308 } 309 310 func TestEncodeYAML(t *testing.T) { 311 f := newFixture(t) 312 313 f.File("Tiltfile", ` 314 expected = '''key1: foo 315 key2: 316 key3: bar 317 key4: true 318 key5: 3 319 key6: 320 - foo 321 - 7 322 key7: [] 323 ''' 324 observed = encode_yaml({ 325 'key1': 'foo', 326 'key2': { 327 'key3': 'bar', 328 'key4': True 329 }, 330 'key5': 3, 331 'key6': [ 332 'foo', 333 7, 334 ], 335 'key7': [] 336 }) 337 338 load('assert.tilt', 'assert') 339 assert.equals(expected, str(observed)) 340 `) 341 342 _, err := f.ExecFile("Tiltfile") 343 if err != nil { 344 fmt.Println(f.PrintOutput()) 345 } 346 require.NoError(t, err) 347 } 348 349 func TestEncodeYAMLStream(t *testing.T) { 350 f := newFixture(t) 351 352 tf := fmt.Sprintf("expected = '''%s'''\n", yamlStream) 353 tf += fmt.Sprintf("observed = encode_yaml_stream(%s)\n", yamlStreamAsStarlark) 354 tf += ` 355 load('assert.tilt', 'assert') 356 assert.equals(expected, str(observed)) 357 ` 358 359 f.File("Tiltfile", tf) 360 361 _, err := f.ExecFile("Tiltfile") 362 if err != nil { 363 fmt.Println(f.PrintOutput()) 364 } 365 require.NoError(t, err) 366 } 367 368 func TestEncodeYAMLNonStringMapKey(t *testing.T) { 369 f := newFixture(t) 370 371 f.File("Tiltfile", `encode_yaml({1: 'hello'})`) 372 373 _, err := f.ExecFile("Tiltfile") 374 require.Error(t, err) 375 require.Contains(t, err.Error(), "only string keys are supported in maps. found key '1' of type int64") 376 } 377 378 func TestEncodeYAMLNonYAMLable(t *testing.T) { 379 f := newFixture(t) 380 381 f.File("Tiltfile", ` 382 encode_yaml(blob('hello')) 383 `) 384 385 _, err := f.ExecFile("Tiltfile") 386 require.Error(t, err) 387 require.Contains(t, err.Error(), "unsupported type io.Blob") 388 } 389 390 func TestDecodeYAMLIntFloat(t *testing.T) { 391 f := newFixture(t) 392 f.File("Tiltfile", ` 393 yaml = '''--- 394 int: 42 395 float: 3.14 396 ''' 397 x = decode_yaml(yaml) 398 if repr(x["int"]) != "42": 399 fail('repr(int) value was not "42": ' + repr(x["int"])) 400 if repr(x["float"]) != "3.14": 401 fail('repr(float) value was not a "3.14": ' + repr(x["float"])) 402 `) 403 404 _, err := f.ExecFile("Tiltfile") 405 if err != nil { 406 fmt.Println(f.PrintOutput()) 407 } 408 require.NoError(t, err) 409 }