@@ -2,144 +2,196 @@ package registry
22
33import (
44 "bytes"
5- "encoding/json"
6- "strings"
75 "testing"
86
97 "github.com/docker/cli/cli/command/formatter"
10- "github.com/docker/cli/internal/test"
118 registrytypes "github.com/docker/docker/api/types/registry"
129 "gotest.tools/v3/assert"
1310 is "gotest.tools/v3/assert/cmp"
1411 "gotest.tools/v3/golden"
1512)
1613
1714func TestSearchContext (t * testing.T ) {
18- name := "nginx"
19- starCount := 5000
20-
2115 var ctx searchContext
2216 cases := []struct {
2317 searchCtx searchContext
2418 expValue string
2519 call func () string
2620 }{
27- {searchContext {
28- s : registrytypes.SearchResult {Name : name },
29- }, name , ctx .Name },
30- {searchContext {
31- s : registrytypes.SearchResult {StarCount : starCount },
32- }, "5000" , ctx .StarCount },
33- {searchContext {
34- s : registrytypes.SearchResult {IsOfficial : true },
35- }, "[OK]" , ctx .IsOfficial },
36- {searchContext {
37- s : registrytypes.SearchResult {IsOfficial : false },
38- }, "" , ctx .IsOfficial },
39- {searchContext {
40- s : registrytypes.SearchResult {IsAutomated : true }, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).
41- }, "[OK]" , ctx .IsAutomated },
42- {searchContext {
43- s : registrytypes.SearchResult {},
44- }, "" , ctx .IsAutomated },
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:staticcheck // ignore SA1019 (IsAutomated is deprecated).
51+ },
52+ expValue : "[OK]" ,
53+ call : ctx .IsAutomated ,
54+ },
55+ {
56+ searchCtx : searchContext {
57+ s : registrytypes.SearchResult {},
58+ },
59+ call : ctx .IsAutomated ,
60+ },
4561 }
4662
4763 for _ , c := range cases {
4864 ctx = c .searchCtx
4965 v := c .call ()
50- if strings .Contains (v , "," ) {
51- test .CompareMultipleValues (t , v , c .expValue )
52- } else if v != c .expValue {
53- t .Fatalf ("Expected %s, was %s\n " , c .expValue , v )
54- }
66+ assert .Check (t , is .Equal (v , c .expValue ))
5567 }
5668}
5769
5870func TestSearchContextDescription (t * testing.T ) {
59- shortDescription := "Official build of Nginx."
60- longDescription := "Automated Nginx reverse proxy for docker containers"
61- descriptionWReturns := "Automated\n Nginx reverse\r proxy\r for docker\n containers"
71+ const (
72+ shortDescription = "Official build of Nginx."
73+ longDescription = "Automated Nginx reverse proxy for docker containers"
74+ descriptionWReturns = "Automated\n Nginx reverse\r proxy\r for docker\n containers"
75+ )
6276
6377 var ctx searchContext
6478 cases := []struct {
6579 searchCtx searchContext
6680 expValue string
6781 call func () string
6882 }{
69- {searchContext {
70- s : registrytypes.SearchResult {Description : shortDescription },
71- trunc : true ,
72- }, shortDescription , ctx .Description },
73- {searchContext {
74- s : registrytypes.SearchResult {Description : shortDescription },
75- trunc : false ,
76- }, shortDescription , ctx .Description },
77- {searchContext {
78- s : registrytypes.SearchResult {Description : longDescription },
79- trunc : false ,
80- }, longDescription , ctx .Description },
81- {searchContext {
82- s : registrytypes.SearchResult {Description : longDescription },
83- trunc : true ,
84- }, formatter .Ellipsis (longDescription , 45 ), ctx .Description },
85- {searchContext {
86- s : registrytypes.SearchResult {Description : descriptionWReturns },
87- trunc : false ,
88- }, longDescription , ctx .Description },
89- {searchContext {
90- s : registrytypes.SearchResult {Description : descriptionWReturns },
91- trunc : true ,
92- }, formatter .Ellipsis (longDescription , 45 ), ctx .Description },
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+ },
93131 }
94132
95133 for _ , c := range cases {
96134 ctx = c .searchCtx
97135 v := c .call ()
98- if strings .Contains (v , "," ) {
99- test .CompareMultipleValues (t , v , c .expValue )
100- } else if v != c .expValue {
101- t .Fatalf ("Expected %s, was %s\n " , c .expValue , v )
102- }
136+ assert .Check (t , is .Equal (v , c .expValue ))
103137 }
104138}
105139
106140func TestSearchContextWrite (t * testing.T ) {
107141 cases := []struct {
108- context formatter.Context
109- expected string
142+ doc string
143+ format formatter.Format
144+ expected string
145+ expectedErr string
110146 }{
111- // Errors
112147 {
113- formatter.Context {Format : "{{InvalidFunction}}" },
114- `template parsing error: template: :1: function "InvalidFunction" not defined` ,
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+ ` ,
115163 },
116164 {
117- formatter.Context {Format : "{{nil}}" },
118- `template parsing error: template: :1:2: executing "" at <nil>: nil is not a command` ,
165+ doc : "JSON format, single field" ,
166+ format : "{{json .Name}}" ,
167+ expected : `"result1"
168+ "result2"
169+ ` ,
119170 },
120- // Table format
121171 {
122- formatter.Context {Format : NewSearchFormat ("table" )},
123- string (golden .Get (t , "search-context-write-table.golden" )),
172+ doc : "Table format" ,
173+ format : NewSearchFormat ("table" ),
174+ expected : string (golden .Get (t , "search-context-write-table.golden" )),
124175 },
125176 {
126- formatter.Context {Format : NewSearchFormat ("table {{.Name}}" )},
127- `NAME
177+ doc : "Table format, single column" ,
178+ format : NewSearchFormat ("table {{.Name}}" ),
179+ expected : `NAME
128180result1
129181result2
130182` ,
131183 },
132- // Custom Format
133184 {
134- formatter.Context {Format : NewSearchFormat ("{{.Name}}" )},
135- `result1
185+ doc : "Custom format, single field" ,
186+ format : NewSearchFormat ("{{.Name}}" ),
187+ expected : `result1
136188result2
137189` ,
138190 },
139- // Custom Format with CreatedAt
140191 {
141- formatter.Context {Format : NewSearchFormat ("{{.Name}} {{.StarCount}}" )},
142- `result1 5000
192+ doc : "Custom Format, two columns" ,
193+ format : NewSearchFormat ("{{.Name}} {{.StarCount}}" ),
194+ expected : `result1 5000
143195result2 5
144196` ,
145197 },
@@ -152,61 +204,15 @@ result2 5
152204
153205 for _ , tc := range cases {
154206 tc := tc
155- t .Run (string ( tc .context . Format ) , func (t * testing.T ) {
207+ t .Run (tc .doc , func (t * testing.T ) {
156208 var out bytes.Buffer
157- tc .context .Output = & out
158-
159- err := SearchWrite (tc .context , results )
160- if err != nil {
161- assert .Error (t , err , tc .expected )
209+ err := SearchWrite (formatter.Context {Format : tc .format , Output : & out }, results )
210+ if tc .expectedErr != "" {
211+ assert .Check (t , is .Error (err , tc .expectedErr ))
162212 } else {
163- assert .Equal (t , out . String (), tc . expected )
213+ assert .Check (t , err )
164214 }
215+ assert .Check (t , is .Equal (out .String (), tc .expected ))
165216 })
166217 }
167218}
168-
169- func TestSearchContextWriteJSON (t * testing.T ) {
170- results := []registrytypes.SearchResult {
171- {Name : "result1" , Description : "Official build" , StarCount : 5000 , IsOfficial : true },
172- {Name : "result2" , Description : "Not official" , StarCount : 5 , IsOfficial : false , IsAutomated : true }, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).
173- }
174- expectedJSONs := []map [string ]interface {}{
175- {"Name" : "result1" , "Description" : "Official build" , "StarCount" : "5000" , "IsOfficial" : "true" , "IsAutomated" : "false" },
176- {"Name" : "result2" , "Description" : "Not official" , "StarCount" : "5" , "IsOfficial" : "false" , "IsAutomated" : "true" },
177- }
178-
179- out := bytes .NewBufferString ("" )
180- err := SearchWrite (formatter.Context {Format : "{{json .}}" , Output : out }, results )
181- if err != nil {
182- t .Fatal (err )
183- }
184- for i , line := range strings .Split (strings .TrimSpace (out .String ()), "\n " ) {
185- t .Logf ("Output: line %d: %s" , i , line )
186- var m map [string ]interface {}
187- if err := json .Unmarshal ([]byte (line ), & m ); err != nil {
188- t .Fatal (err )
189- }
190- assert .Check (t , is .DeepEqual (m , expectedJSONs [i ]))
191- }
192- }
193-
194- func TestSearchContextWriteJSONField (t * testing.T ) {
195- results := []registrytypes.SearchResult {
196- {Name : "result1" , Description : "Official build" , StarCount : 5000 , IsOfficial : true },
197- {Name : "result2" , Description : "Not official" , StarCount : 5 , IsOfficial : false , IsAutomated : true }, //nolint:staticcheck // ignore SA1019 (IsAutomated is deprecated).
198- }
199- out := bytes .NewBufferString ("" )
200- err := SearchWrite (formatter.Context {Format : "{{json .Name}}" , Output : out }, results )
201- if err != nil {
202- t .Fatal (err )
203- }
204- for i , line := range strings .Split (strings .TrimSpace (out .String ()), "\n " ) {
205- t .Logf ("Output: line %d: %s" , i , line )
206- var s string
207- if err := json .Unmarshal ([]byte (line ), & s ); err != nil {
208- t .Fatal (err )
209- }
210- assert .Check (t , is .Equal (s , results [i ].Name ))
211- }
212- }
0 commit comments