github.com/thajeztah/cli@v0.0.0-20240223162942-dc6bfac81a8b/cli/command/plugin/formatter_test.go (about) 1 // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: 2 //go:build go1.19 3 4 package plugin 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "strings" 10 "testing" 11 12 "github.com/docker/cli/cli/command/formatter" 13 "github.com/docker/cli/internal/test" 14 "github.com/docker/docker/api/types" 15 "github.com/docker/docker/pkg/stringid" 16 "gotest.tools/v3/assert" 17 is "gotest.tools/v3/assert/cmp" 18 ) 19 20 func TestPluginContext(t *testing.T) { 21 pluginID := stringid.GenerateRandomID() 22 23 var ctx pluginContext 24 cases := []struct { 25 pluginCtx pluginContext 26 expValue string 27 call func() string 28 }{ 29 {pluginContext{ 30 p: types.Plugin{ID: pluginID}, 31 trunc: false, 32 }, pluginID, ctx.ID}, 33 {pluginContext{ 34 p: types.Plugin{ID: pluginID}, 35 trunc: true, 36 }, stringid.TruncateID(pluginID), ctx.ID}, 37 {pluginContext{ 38 p: types.Plugin{Name: "plugin_name"}, 39 }, "plugin_name", ctx.Name}, 40 {pluginContext{ 41 p: types.Plugin{Config: types.PluginConfig{Description: "plugin_description"}}, 42 }, "plugin_description", ctx.Description}, 43 } 44 45 for _, c := range cases { 46 ctx = c.pluginCtx 47 v := c.call() 48 if strings.Contains(v, ",") { 49 test.CompareMultipleValues(t, v, c.expValue) 50 } else if v != c.expValue { 51 t.Fatalf("Expected %s, was %s\n", c.expValue, v) 52 } 53 } 54 } 55 56 func TestPluginContextWrite(t *testing.T) { 57 cases := []struct { 58 context formatter.Context 59 expected string 60 }{ 61 // Errors 62 { 63 formatter.Context{Format: "{{InvalidFunction}}"}, 64 `template parsing error: template: :1: function "InvalidFunction" not defined`, 65 }, 66 { 67 formatter.Context{Format: "{{nil}}"}, 68 `template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`, 69 }, 70 // Table format 71 { 72 formatter.Context{Format: NewFormat("table", false)}, 73 `ID NAME DESCRIPTION ENABLED 74 pluginID1 foobar_baz description 1 true 75 pluginID2 foobar_bar description 2 false 76 `, 77 }, 78 { 79 formatter.Context{Format: NewFormat("table", true)}, 80 `pluginID1 81 pluginID2 82 `, 83 }, 84 { 85 formatter.Context{Format: NewFormat("table {{.Name}}", false)}, 86 `NAME 87 foobar_baz 88 foobar_bar 89 `, 90 }, 91 { 92 formatter.Context{Format: NewFormat("table {{.Name}}", true)}, 93 `NAME 94 foobar_baz 95 foobar_bar 96 `, 97 }, 98 // Raw Format 99 { 100 formatter.Context{Format: NewFormat("raw", false)}, 101 `plugin_id: pluginID1 102 name: foobar_baz 103 description: description 1 104 enabled: true 105 106 plugin_id: pluginID2 107 name: foobar_bar 108 description: description 2 109 enabled: false 110 111 `, 112 }, 113 { 114 formatter.Context{Format: NewFormat("raw", true)}, 115 `plugin_id: pluginID1 116 plugin_id: pluginID2 117 `, 118 }, 119 // Custom Format 120 { 121 formatter.Context{Format: NewFormat("{{.Name}}", false)}, 122 `foobar_baz 123 foobar_bar 124 `, 125 }, 126 } 127 128 plugins := []*types.Plugin{ 129 {ID: "pluginID1", Name: "foobar_baz", Config: types.PluginConfig{Description: "description 1"}, Enabled: true}, 130 {ID: "pluginID2", Name: "foobar_bar", Config: types.PluginConfig{Description: "description 2"}, Enabled: false}, 131 } 132 133 for _, tc := range cases { 134 tc := tc 135 t.Run(string(tc.context.Format), func(t *testing.T) { 136 var out bytes.Buffer 137 tc.context.Output = &out 138 139 err := FormatWrite(tc.context, plugins) 140 if err != nil { 141 assert.Error(t, err, tc.expected) 142 } else { 143 assert.Equal(t, out.String(), tc.expected) 144 } 145 }) 146 } 147 } 148 149 func TestPluginContextWriteJSON(t *testing.T) { 150 plugins := []*types.Plugin{ 151 {ID: "pluginID1", Name: "foobar_baz"}, 152 {ID: "pluginID2", Name: "foobar_bar"}, 153 } 154 expectedJSONs := []map[string]any{ 155 {"Description": "", "Enabled": false, "ID": "pluginID1", "Name": "foobar_baz", "PluginReference": ""}, 156 {"Description": "", "Enabled": false, "ID": "pluginID2", "Name": "foobar_bar", "PluginReference": ""}, 157 } 158 159 out := bytes.NewBufferString("") 160 err := FormatWrite(formatter.Context{Format: "{{json .}}", Output: out}, plugins) 161 if err != nil { 162 t.Fatal(err) 163 } 164 for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { 165 var m map[string]any 166 if err := json.Unmarshal([]byte(line), &m); err != nil { 167 t.Fatal(err) 168 } 169 assert.Check(t, is.DeepEqual(expectedJSONs[i], m)) 170 } 171 } 172 173 func TestPluginContextWriteJSONField(t *testing.T) { 174 plugins := []*types.Plugin{ 175 {ID: "pluginID1", Name: "foobar_baz"}, 176 {ID: "pluginID2", Name: "foobar_bar"}, 177 } 178 out := bytes.NewBufferString("") 179 err := FormatWrite(formatter.Context{Format: "{{json .ID}}", Output: out}, plugins) 180 if err != nil { 181 t.Fatal(err) 182 } 183 for i, line := range strings.Split(strings.TrimSpace(out.String()), "\n") { 184 var s string 185 if err := json.Unmarshal([]byte(line), &s); err != nil { 186 t.Fatal(err) 187 } 188 assert.Check(t, is.Equal(plugins[i].ID, s)) 189 } 190 }