This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / engine / manifest_test.go
3.6 kB 112 lines
1package engine 2 3import ( 4 "strings" 5 "testing" 6) 7 8type testManifest struct { 9 Image string `yaml:"image"` 10 Registry map[string]any `yaml:"registry"` 11 Dependencies []string `yaml:"dependencies"` 12 Nested map[string][]string `yaml:"nested"` 13 Steps []struct { 14 Name string `yaml:"name"` 15 } `yaml:"steps"` 16} 17 18func TestDescribeManifestError(t *testing.T) { 19 cases := []struct { 20 name string 21 raw string 22 want []string // substrings the message must contain 23 }{ 24 { 25 name: "map field written as list", 26 raw: "registry:\n - nixpkgs: github:nixos/nixpkgs\n", 27 want: []string{"registry", "a mapping", "a list"}, 28 }, 29 { 30 name: "list field written as scalar", 31 raw: "dependencies: bun\n", 32 want: []string{"dependencies", "a list", "a scalar value"}, 33 }, 34 { 35 name: "scalar field written as mapping", 36 raw: "image:\n name: nixos\n", 37 want: []string{"image", "a scalar value", "a mapping"}, 38 }, 39 { 40 name: "nested map value mis-shaped", 41 raw: "nested:\n foo: bar\n", // foo should be a list of strings 42 want: []string{"nested.foo", "a list", "a scalar value"}, 43 }, 44 { 45 name: "field inside a list element mis-shaped", 46 raw: "steps:\n - name:\n x: y\n", // steps[0].name should be a scalar 47 want: []string{"steps[0].name", "a scalar value", "a mapping"}, 48 }, 49 { 50 name: "unknown top-level field (typo)", 51 raw: "dependancies:\n - bun\n", 52 want: []string{"unknown field", "dependancies"}, 53 }, 54 { 55 name: "unknown field inside a list element", 56 raw: "steps:\n - name: x\n cmd: y\n", // it's `command`, not `cmd` 57 want: []string{"unknown field", "steps[0].cmd"}, 58 }, 59 { 60 // `name` (filename-sourced, yaml:"-") must be tolerated so the real 61 // typo `registre` on a later line is the thing that surfaces. 62 name: "tolerated name does not mask a later typo", 63 raw: "name: mill\nengine: microvm\nregistre:\n - x: y\n", 64 want: []string{"unknown field", "registre"}, 65 }, 66 } 67 for _, tc := range cases { 68 t.Run(tc.name, func(t *testing.T) { 69 err := DescribeManifestError(tc.raw, testManifest{}) 70 if err == nil { 71 t.Fatalf("expected an error, got nil") 72 } 73 for _, w := range tc.want { 74 if !strings.Contains(err.Error(), w) { 75 t.Errorf("error %q missing %q", err, w) 76 } 77 } 78 }) 79 } 80} 81 82func TestDescribeManifestErrorNoFalsePositives(t *testing.T) { 83 cases := []string{ 84 // well-formed manifest 85 "image: nixos\nregistry:\n nixpkgs: github:nixos/nixpkgs\ndependencies:\n - bun\n", 86 // empty value is harmless, not a mismatch 87 "image: nixos\nregistry:\n", 88 // generic workflow keys live in the same doc and aren't engine fields, 89 // but must not be flagged as unknown at the root 90 "engine: microvm\nwhen:\n - event: [push]\nclone:\n skip: true\nimage: nixos\n", 91 // `any` map values accept any shape, including nested lists/maps 92 "registry:\n k:\n - a\n - b\n", 93 // well-formed nested map-of-lists 94 "nested:\n foo:\n - a\n - b\n", 95 // user-defined map keys are data, never flagged as unknown fields 96 "nested:\n any-package-name:\n - a\n", 97 } 98 for _, raw := range cases { 99 if err := DescribeManifestError(raw, testManifest{}); err != nil { 100 t.Errorf("DescribeManifestError(%q) = %v, want nil", raw, err) 101 } 102 } 103} 104 105func TestDescribeManifestErrorPointerSchema(t *testing.T) { 106 // nixery passes a pointer to an anonymous struct 107 schema := &testManifest{} 108 err := DescribeManifestError("nested: oops\n", schema) 109 if err == nil || !strings.Contains(err.Error(), "nested") { 110 t.Fatalf("expected an error naming `nested`, got %v", err) 111 } 112}