package main import ( "bytes" "encoding/json" "testing" ) // Every other JSON command emits an object, so a consumer can add fields // later without breaking. `effect --list` returned a bare array because the // EffectList wrapper it built was bypassed in favour of its slice. func TestEffectListEmitsAnObjectNotABareArray(t *testing.T) { var out, errOut bytes.Buffer cmd := NewEffectCmd() cmd.SetOut(&out) cmd.SetErr(&errOut) cmd.SetArgs([]string{"--list"}) if err := cmd.Execute(); err != nil { t.Fatalf("effect --list returned error: %v", err) } var parsed map[string][]struct { Zone string `json:"zone"` Effect string `json:"effect"` ID int `json:"id"` } if err := json.Unmarshal(out.Bytes(), &parsed); err != nil { t.Fatalf("effect --list output is not a JSON object: %v (output %q)", err, out.String()[:min(80, out.Len())]) } zones, ok := parsed["zones"] if !ok { t.Fatalf("output = %q, want a top-level \"zones\" key", out.String()[:min(80, out.Len())]) } if len(zones) == 0 { t.Fatal("zones is empty, want the full catalog") } // The catalog itself must not have changed shape. if zones[0].Zone == "" || zones[0].Effect == "" { t.Errorf("zones[0] = %+v, want zone, effect and id populated", zones[0]) } } func min(a, b int) int { if a < b { return a } return b }