Files
docker-cli/cli/command/registry/formatter_search_test.go
Sebastiaan van Stijn 83371c2014 cli/command/registry: deprecate NewSearchFormat, SearchWrite
It's part of the presentation logic of the cli, and only used internally.
We can consider providing utilities for these, but better as part of
separate packages.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-08-21 15:25:25 +02:00

205 lines
4.6 KiB
Go

package registry
import (
"bytes"
"testing"
"github.com/docker/cli/cli/command/formatter"
registrytypes "github.com/moby/moby/api/types/registry"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
)
func TestSearchContext(t *testing.T) {
var ctx searchContext
cases := []struct {
searchCtx searchContext
expValue string
call func() string
}{
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Name: "nginx"},
},
expValue: "nginx",
call: ctx.Name,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{StarCount: 5000},
},
expValue: "5000",
call: ctx.StarCount,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{IsOfficial: true},
},
expValue: "[OK]",
call: ctx.IsOfficial,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{IsOfficial: false},
},
call: ctx.IsOfficial,
},
}
for _, c := range cases {
ctx = c.searchCtx
v := c.call()
assert.Check(t, is.Equal(v, c.expValue))
}
}
func TestSearchContextDescription(t *testing.T) {
const (
shortDescription = "Official build of Nginx."
longDescription = "Automated Nginx reverse proxy for docker containers"
descriptionWReturns = "Automated\nNginx reverse\rproxy\rfor docker\ncontainers"
)
var ctx searchContext
cases := []struct {
searchCtx searchContext
expValue string
call func() string
}{
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Description: shortDescription},
trunc: true,
},
expValue: shortDescription,
call: ctx.Description,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Description: shortDescription},
trunc: false,
},
expValue: shortDescription,
call: ctx.Description,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Description: longDescription},
trunc: false,
},
expValue: longDescription,
call: ctx.Description,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Description: longDescription},
trunc: true,
},
expValue: formatter.Ellipsis(longDescription, 45),
call: ctx.Description,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Description: descriptionWReturns},
trunc: false,
},
expValue: longDescription,
call: ctx.Description,
},
{
searchCtx: searchContext{
s: registrytypes.SearchResult{Description: descriptionWReturns},
trunc: true,
},
expValue: formatter.Ellipsis(longDescription, 45),
call: ctx.Description,
},
}
for _, c := range cases {
ctx = c.searchCtx
v := c.call()
assert.Check(t, is.Equal(v, c.expValue))
}
}
func TestSearchContextWrite(t *testing.T) {
cases := []struct {
doc string
format formatter.Format
expected string
expectedErr string
}{
{
doc: "Errors",
format: "{{InvalidFunction}}",
expectedErr: `template parsing error: template: :1: function "InvalidFunction" not defined`,
},
{
doc: "Nil format",
format: "{{nil}}",
expectedErr: `template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`,
},
{
doc: "JSON format",
format: "{{json .}}",
expected: `{"Description":"Official build","IsOfficial":"true","Name":"result1","StarCount":"5000"}
{"Description":"Not official","IsOfficial":"false","Name":"result2","StarCount":"5"}
`,
},
{
doc: "JSON format, single field",
format: "{{json .Name}}",
expected: `"result1"
"result2"
`,
},
{
doc: "Table format",
format: newFormat("table"),
expected: string(golden.Get(t, "search-context-write-table.golden")),
},
{
doc: "Table format, single column",
format: newFormat("table {{.Name}}"),
expected: `NAME
result1
result2
`,
},
{
doc: "Custom format, single field",
format: newFormat("{{.Name}}"),
expected: `result1
result2
`,
},
{
doc: "Custom Format, two columns",
format: newFormat("{{.Name}} {{.StarCount}}"),
expected: `result1 5000
result2 5
`,
},
}
results := []registrytypes.SearchResult{
{Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true},
{Name: "result2", Description: "Not official", StarCount: 5},
}
for _, tc := range cases {
t.Run(tc.doc, func(t *testing.T) {
var out bytes.Buffer
err := formatWrite(formatter.Context{Format: tc.format, Output: &out}, results)
if tc.expectedErr != "" {
assert.Check(t, is.Error(err, tc.expectedErr))
} else {
assert.Check(t, err)
}
assert.Check(t, is.Equal(out.String(), tc.expected))
})
}
}