diff --git a/cli/command/formatter/formatter.go b/cli/command/formatter/formatter.go index 10ada78f93..ab0ebdfdfd 100644 --- a/cli/command/formatter/formatter.go +++ b/cli/command/formatter/formatter.go @@ -16,8 +16,10 @@ const ( TableFormatKey = "table" RawFormatKey = "raw" PrettyFormatKey = "pretty" + JSONFormatKey = "json" DefaultQuietFormat = "{{.ID}}" + jsonFormat = "{{json .}}" ) // Format is the format string rendered using the Context @@ -28,6 +30,11 @@ func (f Format) IsTable() bool { return strings.HasPrefix(string(f), TableFormatKey) } +// IsJSON returns true if the format is the json format +func (f Format) IsJSON() bool { + return string(f) == JSONFormatKey +} + // Contains returns true if the format contains the substring func (f Format) Contains(sub string) bool { return strings.Contains(string(f), sub) @@ -50,10 +57,12 @@ type Context struct { func (c *Context) preFormat() { c.finalFormat = string(c.Format) - // TODO: handle this in the Format type - if c.Format.IsTable() { + switch { + case c.Format.IsTable(): c.finalFormat = c.finalFormat[len(TableFormatKey):] + case c.Format.IsJSON(): + c.finalFormat = jsonFormat } c.finalFormat = strings.Trim(c.finalFormat, " ") diff --git a/cli/command/formatter/formatter_test.go b/cli/command/formatter/formatter_test.go new file mode 100644 index 0000000000..0f7ca93442 --- /dev/null +++ b/cli/command/formatter/formatter_test.go @@ -0,0 +1,68 @@ +package formatter + +import ( + "bytes" + "testing" + + "gotest.tools/v3/assert" +) + +func TestFormat(t *testing.T) { + f := Format("json") + assert.Assert(t, f.IsJSON()) + assert.Assert(t, !f.IsTable()) + + f = Format("table") + assert.Assert(t, !f.IsJSON()) + assert.Assert(t, f.IsTable()) + + f = Format("other") + assert.Assert(t, !f.IsJSON()) + assert.Assert(t, !f.IsTable()) +} + +type fakeSubContext struct { + Name string +} + +func (f fakeSubContext) FullHeader() interface{} { + return map[string]string{"Name": "NAME"} +} + +func TestContext(t *testing.T) { + testCases := []struct { + name string + format string + expected string + }{ + { + name: "json format", + format: JSONFormatKey, + expected: `{"Name":"test"} +`, + }, + { + name: "table format", + format: `table {{.Name}}`, + expected: `NAME +test +`, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + buf := bytes.NewBuffer(nil) + ctx := Context{ + Format: Format(tc.format), + Output: buf, + } + subContext := fakeSubContext{Name: "test"} + subFormat := func(f func(sub SubContext) error) error { + return f(subContext) + } + err := ctx.Write(&subContext, subFormat) + assert.NilError(t, err) + assert.Equal(t, buf.String(), tc.expected) + }) + } +}