github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/registry/formatter_search_test.go (about)

     1  package registry
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/docker/cli/cli/command/formatter"
     8  	registrytypes "github.com/docker/docker/api/types/registry"
     9  	"gotest.tools/v3/assert"
    10  	is "gotest.tools/v3/assert/cmp"
    11  	"gotest.tools/v3/golden"
    12  )
    13  
    14  func TestSearchContext(t *testing.T) {
    15  	var ctx searchContext
    16  	cases := []struct {
    17  		searchCtx searchContext
    18  		expValue  string
    19  		call      func() string
    20  	}{
    21  		{
    22  			searchCtx: searchContext{
    23  				s: registrytypes.SearchResult{Name: "nginx"},
    24  			},
    25  			expValue: "nginx",
    26  			call:     ctx.Name,
    27  		},
    28  		{
    29  			searchCtx: searchContext{
    30  				s: registrytypes.SearchResult{StarCount: 5000},
    31  			},
    32  			expValue: "5000",
    33  			call:     ctx.StarCount,
    34  		},
    35  		{
    36  			searchCtx: searchContext{
    37  				s: registrytypes.SearchResult{IsOfficial: true},
    38  			},
    39  			expValue: "[OK]",
    40  			call:     ctx.IsOfficial,
    41  		},
    42  		{
    43  			searchCtx: searchContext{
    44  				s: registrytypes.SearchResult{IsOfficial: false},
    45  			},
    46  			call: ctx.IsOfficial,
    47  		},
    48  		{
    49  			searchCtx: searchContext{
    50  				s: registrytypes.SearchResult{IsAutomated: true}, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
    51  			},
    52  			expValue: "[OK]",
    53  			call:     ctx.IsAutomated, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
    54  		},
    55  		{
    56  			searchCtx: searchContext{
    57  				s: registrytypes.SearchResult{},
    58  			},
    59  			call: ctx.IsAutomated, //nolint:nolintlint,staticcheck // ignore SA1019 (IsAutomated is deprecated).
    60  		},
    61  	}
    62  
    63  	for _, c := range cases {
    64  		ctx = c.searchCtx
    65  		v := c.call()
    66  		assert.Check(t, is.Equal(v, c.expValue))
    67  	}
    68  }
    69  
    70  func TestSearchContextDescription(t *testing.T) {
    71  	const (
    72  		shortDescription    = "Official build of Nginx."
    73  		longDescription     = "Automated Nginx reverse proxy for docker containers"
    74  		descriptionWReturns = "Automated\nNginx reverse\rproxy\rfor docker\ncontainers"
    75  	)
    76  
    77  	var ctx searchContext
    78  	cases := []struct {
    79  		searchCtx searchContext
    80  		expValue  string
    81  		call      func() string
    82  	}{
    83  		{
    84  			searchCtx: searchContext{
    85  				s:     registrytypes.SearchResult{Description: shortDescription},
    86  				trunc: true,
    87  			},
    88  			expValue: shortDescription,
    89  			call:     ctx.Description,
    90  		},
    91  		{
    92  			searchCtx: searchContext{
    93  				s:     registrytypes.SearchResult{Description: shortDescription},
    94  				trunc: false,
    95  			},
    96  			expValue: shortDescription,
    97  			call:     ctx.Description,
    98  		},
    99  		{
   100  			searchCtx: searchContext{
   101  				s:     registrytypes.SearchResult{Description: longDescription},
   102  				trunc: false,
   103  			},
   104  			expValue: longDescription,
   105  			call:     ctx.Description,
   106  		},
   107  		{
   108  			searchCtx: searchContext{
   109  				s:     registrytypes.SearchResult{Description: longDescription},
   110  				trunc: true,
   111  			},
   112  			expValue: formatter.Ellipsis(longDescription, 45),
   113  			call:     ctx.Description,
   114  		},
   115  		{
   116  			searchCtx: searchContext{
   117  				s:     registrytypes.SearchResult{Description: descriptionWReturns},
   118  				trunc: false,
   119  			},
   120  			expValue: longDescription,
   121  			call:     ctx.Description,
   122  		},
   123  		{
   124  			searchCtx: searchContext{
   125  				s:     registrytypes.SearchResult{Description: descriptionWReturns},
   126  				trunc: true,
   127  			},
   128  			expValue: formatter.Ellipsis(longDescription, 45),
   129  			call:     ctx.Description,
   130  		},
   131  	}
   132  
   133  	for _, c := range cases {
   134  		ctx = c.searchCtx
   135  		v := c.call()
   136  		assert.Check(t, is.Equal(v, c.expValue))
   137  	}
   138  }
   139  
   140  func TestSearchContextWrite(t *testing.T) {
   141  	cases := []struct {
   142  		doc         string
   143  		format      formatter.Format
   144  		expected    string
   145  		expectedErr string
   146  	}{
   147  		{
   148  			doc:         "Errors",
   149  			format:      "{{InvalidFunction}}",
   150  			expectedErr: `template parsing error: template: :1: function "InvalidFunction" not defined`,
   151  		},
   152  		{
   153  			doc:         "Nil format",
   154  			format:      "{{nil}}",
   155  			expectedErr: `template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`,
   156  		},
   157  		{
   158  			doc:    "JSON format",
   159  			format: "{{json .}}",
   160  			expected: `{"Description":"Official build","IsAutomated":"false","IsOfficial":"true","Name":"result1","StarCount":"5000"}
   161  {"Description":"Not official","IsAutomated":"true","IsOfficial":"false","Name":"result2","StarCount":"5"}
   162  `,
   163  		},
   164  		{
   165  			doc:    "JSON format, single field",
   166  			format: "{{json .Name}}",
   167  			expected: `"result1"
   168  "result2"
   169  `,
   170  		},
   171  		{
   172  			doc:      "Table format",
   173  			format:   NewSearchFormat("table"),
   174  			expected: string(golden.Get(t, "search-context-write-table.golden")),
   175  		},
   176  		{
   177  			doc:    "Table format, single column",
   178  			format: NewSearchFormat("table {{.Name}}"),
   179  			expected: `NAME
   180  result1
   181  result2
   182  `,
   183  		},
   184  		{
   185  			doc:    "Custom format, single field",
   186  			format: NewSearchFormat("{{.Name}}"),
   187  			expected: `result1
   188  result2
   189  `,
   190  		},
   191  		{
   192  			doc:    "Custom Format, two columns",
   193  			format: NewSearchFormat("{{.Name}} {{.StarCount}}"),
   194  			expected: `result1 5000
   195  result2 5
   196  `,
   197  		},
   198  	}
   199  
   200  	results := []registrytypes.SearchResult{
   201  		{Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true},
   202  		{Name: "result2", Description: "Not official", StarCount: 5, IsAutomated: true},
   203  	}
   204  
   205  	for _, tc := range cases {
   206  		tc := tc
   207  		t.Run(tc.doc, func(t *testing.T) {
   208  			var out bytes.Buffer
   209  			err := SearchWrite(formatter.Context{Format: tc.format, Output: &out}, results)
   210  			if tc.expectedErr != "" {
   211  				assert.Check(t, is.Error(err, tc.expectedErr))
   212  			} else {
   213  				assert.Check(t, err)
   214  			}
   215  			assert.Check(t, is.Equal(out.String(), tc.expected))
   216  		})
   217  	}
   218  }