|
| 1 | +package cli |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "strings" |
| 6 | + "testing" |
| 7 | +) |
| 8 | + |
| 9 | +// fakeLister answers ListContainers from a map of "sorted,label,filter" -> ids. |
| 10 | +type fakeLister struct{ byFilter map[string][]string } |
| 11 | + |
| 12 | +func (f *fakeLister) ListContainers(_ context.Context, _ bool, labels []string) ([]string, error) { |
| 13 | + return f.byFilter[strings.Join(labels, "|")], nil |
| 14 | +} |
| 15 | + |
| 16 | +func TestResolveContainerID(t *testing.T) { |
| 17 | + const ( |
| 18 | + ws = "/proj" |
| 19 | + cfgA = "/proj/.devcontainer/a/devcontainer.json" |
| 20 | + cfgB = "/proj/.devcontainer/b/devcontainer.json" |
| 21 | + local = "devcontainer.local_folder=/proj" |
| 22 | + ) |
| 23 | + key := func(labels ...string) string { return strings.Join(labels, "|") } |
| 24 | + |
| 25 | + t.Run("config_file disambiguates multiple configs", func(t *testing.T) { |
| 26 | + f := &fakeLister{byFilter: map[string][]string{ |
| 27 | + key(local, "devcontainer.config_file="+cfgA): {"idA"}, |
| 28 | + key(local, "devcontainer.config_file="+cfgB): {"idB"}, |
| 29 | + key(local): {"idA", "idB"}, // both share local_folder |
| 30 | + }} |
| 31 | + if got := resolveContainerID(context.Background(), f, ws, cfgB, nil); got != "idB" { |
| 32 | + t.Errorf("cfgB -> %q, want idB", got) |
| 33 | + } |
| 34 | + if got := resolveContainerID(context.Background(), f, ws, cfgA, nil); got != "idA" { |
| 35 | + t.Errorf("cfgA -> %q, want idA", got) |
| 36 | + } |
| 37 | + }) |
| 38 | + |
| 39 | + t.Run("falls back to local_folder for legacy container (no config_file match)", func(t *testing.T) { |
| 40 | + f := &fakeLister{byFilter: map[string][]string{ |
| 41 | + key(local): {"legacy"}, // no config_file-filtered entry |
| 42 | + }} |
| 43 | + if got := resolveContainerID(context.Background(), f, ws, cfgA, nil); got != "legacy" { |
| 44 | + t.Errorf("-> %q, want legacy (fallback)", got) |
| 45 | + } |
| 46 | + }) |
| 47 | + |
| 48 | + t.Run("explicit id-labels win", func(t *testing.T) { |
| 49 | + f := &fakeLister{byFilter: map[string][]string{ |
| 50 | + key("x=y"): {"bylabel"}, |
| 51 | + key(local): {"byfolder"}, |
| 52 | + }} |
| 53 | + if got := resolveContainerID(context.Background(), f, ws, cfgA, []string{"x=y"}); got != "bylabel" { |
| 54 | + t.Errorf("-> %q, want bylabel", got) |
| 55 | + } |
| 56 | + }) |
| 57 | + |
| 58 | + t.Run("no match", func(t *testing.T) { |
| 59 | + if got := resolveContainerID(context.Background(), &fakeLister{}, ws, cfgA, nil); got != "" { |
| 60 | + t.Errorf("-> %q, want empty", got) |
| 61 | + } |
| 62 | + }) |
| 63 | +} |
0 commit comments