github.com/xeptore/docker-cli@v20.10.14+incompatible/cli/command/registry/formatter_search_test.go (about) 1 package registry 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "strings" 7 "testing" 8 9 "github.com/docker/cli/cli/command/formatter" 10 "github.com/docker/cli/internal/test" 11 registrytypes "github.com/docker/docker/api/types/registry" 12 "gotest.tools/v3/assert" 13 is "gotest.tools/v3/assert/cmp" 14 "gotest.tools/v3/golden" 15 ) 16 17 func TestSearchContext(t *testing.T) { 18 name := "nginx" 19 starCount := 5000 20 21 var ctx searchContext 22 cases := []struct { 23 searchCtx searchContext 24 expValue string 25 call func() string 26 }{ 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}, 41 }, "[OK]", ctx.IsAutomated}, 42 {searchContext{ 43 s: registrytypes.SearchResult{IsAutomated: false}, 44 }, "", ctx.IsAutomated}, 45 } 46 47 for _, c := range cases { 48 ctx = c.searchCtx 49 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 } 55 } 56 } 57 58 func TestSearchContextDescription(t *testing.T) { 59 shortDescription := "Official build of Nginx." 60 longDescription := "Automated Nginx reverse proxy for docker containers" 61 descriptionWReturns := "Automated\nNginx reverse\rproxy\rfor docker\ncontainers" 62 63 var ctx searchContext 64 cases := []struct { 65 searchCtx searchContext 66 expValue string 67 call func() string 68 }{ 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}, 93 } 94 95 for _, c := range cases { 96 ctx = c.searchCtx 97 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 } 103 } 104 } 105 106 func TestSearchContextWrite(t *testing.T) { 107 cases := []struct { 108 context formatter.Context 109 expected string 110 }{ 111 112 // Errors 113 { 114 formatter.Context{Format: "{{InvalidFunction}}"}, 115 `Template parsing error: template: :1: function "InvalidFunction" not defined 116 `, 117 }, 118 { 119 formatter.Context{Format: "{{nil}}"}, 120 `Template parsing error: template: :1:2: executing "" at <nil>: nil is not a command 121 `, 122 }, 123 // Table format 124 { 125 formatter.Context{Format: NewSearchFormat("table")}, 126 string(golden.Get(t, "search-context-write-table.golden")), 127 }, 128 { 129 formatter.Context{Format: NewSearchFormat("table {{.Name}}")}, 130 `NAME 131 result1 132 result2 133 `, 134 }, 135 // Custom Format 136 { 137 formatter.Context{Format: NewSearchFormat("{{.Name}}")}, 138 `result1 139 result2 140 `, 141 }, 142 // Custom Format with CreatedAt 143 { 144 formatter.Context{Format: NewSearchFormat("{{.Name}} {{.StarCount}}")}, 145 `result1 5000 146 result2 5 147 `, 148 }, 149 } 150 151 results := []registrytypes.SearchResult{ 152 {Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true, IsAutomated: false}, 153 {Name: "result2", Description: "Not official", StarCount: 5, IsOfficial: false, IsAutomated: true}, 154 } 155 156 for _, tc := range cases { 157 tc := tc 158 t.Run(string(tc.context.Format), func(t *testing.T) { 159 var out bytes.Buffer 160 tc.context.Output = &out 161 162 err := SearchWrite(tc.context, results) 163 if err != nil { 164 assert.Error(t, err, tc.expected) 165 } else { 166 assert.Equal(t, out.String(), tc.expected) 167 } 168 }) 169 } 170 } 171 172 func TestSearchContextWriteJSON(t *testing.T) { 173 results := []registrytypes.SearchResult{ 174 {Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true, IsAutomated: false}, 175 {Name: "result2", Description: "Not official", StarCount: 5, IsOfficial: false, IsAutomated: true}, 176 } 177 expectedJSONs := []map[string]interface{}{ 178 {"Name": "result1", "Description": "Official build", "StarCount": "5000", "IsOfficial": "true", "IsAutomated": "false"}, 179 {"Name": "result2", "Description": "Not official", "StarCount": "5", "IsOfficial": "false", "IsAutomated": "true"}, 180 } 181 182 out := bytes.NewBufferString("") 183 err := SearchWrite(formatter.Context{Format: "{{json .}}", Output: out}, results) 184 if err != nil { 185 t.Fatal(err) 186 } 187 for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { 188 t.Logf("Output: line %d: %s", i, line) 189 var m map[string]interface{} 190 if err := json.Unmarshal([]byte(line), &m); err != nil { 191 t.Fatal(err) 192 } 193 assert.Check(t, is.DeepEqual(m, expectedJSONs[i])) 194 } 195 } 196 197 func TestSearchContextWriteJSONField(t *testing.T) { 198 results := []registrytypes.SearchResult{ 199 {Name: "result1", Description: "Official build", StarCount: 5000, IsOfficial: true, IsAutomated: false}, 200 {Name: "result2", Description: "Not official", StarCount: 5, IsOfficial: false, IsAutomated: true}, 201 } 202 out := bytes.NewBufferString("") 203 err := SearchWrite(formatter.Context{Format: "{{json .Name}}", Output: out}, results) 204 if err != nil { 205 t.Fatal(err) 206 } 207 for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { 208 t.Logf("Output: line %d: %s", i, line) 209 var s string 210 if err := json.Unmarshal([]byte(line), &s); err != nil { 211 t.Fatal(err) 212 } 213 assert.Check(t, is.Equal(s, results[i].Name)) 214 } 215 }