github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/release/view/view_test.go (about) 1 package view 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "net/http" 8 "testing" 9 "time" 10 11 "github.com/MakeNowJust/heredoc" 12 "github.com/ungtb10d/cli/v2/internal/ghrepo" 13 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 14 "github.com/ungtb10d/cli/v2/pkg/httpmock" 15 "github.com/ungtb10d/cli/v2/pkg/iostreams" 16 "github.com/google/shlex" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func Test_NewCmdView(t *testing.T) { 22 tests := []struct { 23 name string 24 args string 25 isTTY bool 26 want ViewOptions 27 wantErr string 28 }{ 29 { 30 name: "version argument", 31 args: "v1.2.3", 32 isTTY: true, 33 want: ViewOptions{ 34 TagName: "v1.2.3", 35 WebMode: false, 36 }, 37 }, 38 { 39 name: "no arguments", 40 args: "", 41 isTTY: true, 42 want: ViewOptions{ 43 TagName: "", 44 WebMode: false, 45 }, 46 }, 47 { 48 name: "web mode", 49 args: "-w", 50 isTTY: true, 51 want: ViewOptions{ 52 TagName: "", 53 WebMode: true, 54 }, 55 }, 56 } 57 for _, tt := range tests { 58 t.Run(tt.name, func(t *testing.T) { 59 ios, _, _, _ := iostreams.Test() 60 ios.SetStdoutTTY(tt.isTTY) 61 ios.SetStdinTTY(tt.isTTY) 62 ios.SetStderrTTY(tt.isTTY) 63 64 f := &cmdutil.Factory{ 65 IOStreams: ios, 66 } 67 68 var opts *ViewOptions 69 cmd := NewCmdView(f, func(o *ViewOptions) error { 70 opts = o 71 return nil 72 }) 73 cmd.PersistentFlags().StringP("repo", "R", "", "") 74 75 argv, err := shlex.Split(tt.args) 76 require.NoError(t, err) 77 cmd.SetArgs(argv) 78 79 cmd.SetIn(&bytes.Buffer{}) 80 cmd.SetOut(io.Discard) 81 cmd.SetErr(io.Discard) 82 83 _, err = cmd.ExecuteC() 84 if tt.wantErr != "" { 85 require.EqualError(t, err, tt.wantErr) 86 return 87 } else { 88 require.NoError(t, err) 89 } 90 91 assert.Equal(t, tt.want.TagName, opts.TagName) 92 assert.Equal(t, tt.want.WebMode, opts.WebMode) 93 }) 94 } 95 } 96 97 func Test_viewRun(t *testing.T) { 98 oneHourAgo := time.Now().Add(time.Duration(-24) * time.Hour) 99 frozenTime, err := time.Parse(time.RFC3339, "2020-08-31T15:44:24+02:00") 100 require.NoError(t, err) 101 102 tests := []struct { 103 name string 104 isTTY bool 105 releaseBody string 106 releasedAt time.Time 107 opts ViewOptions 108 wantErr string 109 wantStdout string 110 wantStderr string 111 }{ 112 { 113 name: "view specific release", 114 isTTY: true, 115 releaseBody: `* Fixed bugs\n`, 116 releasedAt: oneHourAgo, 117 opts: ViewOptions{ 118 TagName: "v1.2.3", 119 }, 120 wantStdout: heredoc.Doc(` 121 v1.2.3 122 MonaLisa released this about 1 day ago 123 124 125 • Fixed bugs 126 127 128 Assets 129 windows.zip 12 B 130 linux.tgz 34 B 131 132 View on GitHub: https://github.com/OWNER/REPO/releases/tags/v1.2.3 133 `), 134 wantStderr: ``, 135 }, 136 { 137 name: "view latest release", 138 isTTY: true, 139 releaseBody: `* Fixed bugs\n`, 140 releasedAt: oneHourAgo, 141 opts: ViewOptions{ 142 TagName: "", 143 }, 144 wantStdout: heredoc.Doc(` 145 v1.2.3 146 MonaLisa released this about 1 day ago 147 148 149 • Fixed bugs 150 151 152 Assets 153 windows.zip 12 B 154 linux.tgz 34 B 155 156 View on GitHub: https://github.com/OWNER/REPO/releases/tags/v1.2.3 157 `), 158 wantStderr: ``, 159 }, 160 { 161 name: "view machine-readable", 162 isTTY: false, 163 releaseBody: `* Fixed bugs\n`, 164 releasedAt: frozenTime, 165 opts: ViewOptions{ 166 TagName: "v1.2.3", 167 }, 168 wantStdout: heredoc.Doc(` 169 title: 170 tag: v1.2.3 171 draft: false 172 prerelease: false 173 author: MonaLisa 174 created: 2020-08-31T15:44:24+02:00 175 published: 2020-08-31T15:44:24+02:00 176 url: https://github.com/OWNER/REPO/releases/tags/v1.2.3 177 asset: windows.zip 178 asset: linux.tgz 179 -- 180 * Fixed bugs 181 `), 182 wantStderr: ``, 183 }, 184 { 185 name: "view machine-readable but body has no ending newline", 186 isTTY: false, 187 releaseBody: `* Fixed bugs`, 188 releasedAt: frozenTime, 189 opts: ViewOptions{ 190 TagName: "v1.2.3", 191 }, 192 wantStdout: heredoc.Doc(` 193 title: 194 tag: v1.2.3 195 draft: false 196 prerelease: false 197 author: MonaLisa 198 created: 2020-08-31T15:44:24+02:00 199 published: 2020-08-31T15:44:24+02:00 200 url: https://github.com/OWNER/REPO/releases/tags/v1.2.3 201 asset: windows.zip 202 asset: linux.tgz 203 -- 204 * Fixed bugs 205 `), 206 wantStderr: ``, 207 }, 208 } 209 for _, tt := range tests { 210 t.Run(tt.name, func(t *testing.T) { 211 ios, _, stdout, stderr := iostreams.Test() 212 ios.SetStdoutTTY(tt.isTTY) 213 ios.SetStdinTTY(tt.isTTY) 214 ios.SetStderrTTY(tt.isTTY) 215 216 path := "repos/OWNER/REPO/releases/tags/v1.2.3" 217 if tt.opts.TagName == "" { 218 path = "repos/OWNER/REPO/releases/latest" 219 } 220 221 fakeHTTP := &httpmock.Registry{} 222 fakeHTTP.Register(httpmock.REST("GET", path), httpmock.StringResponse(fmt.Sprintf(`{ 223 "tag_name": "v1.2.3", 224 "draft": false, 225 "author": { "login": "MonaLisa" }, 226 "body": "%[2]s", 227 "created_at": "%[1]s", 228 "published_at": "%[1]s", 229 "html_url": "https://github.com/OWNER/REPO/releases/tags/v1.2.3", 230 "assets": [ 231 { "name": "windows.zip", "size": 12 }, 232 { "name": "linux.tgz", "size": 34 } 233 ] 234 }`, tt.releasedAt.Format(time.RFC3339), tt.releaseBody))) 235 236 tt.opts.IO = ios 237 tt.opts.HttpClient = func() (*http.Client, error) { 238 return &http.Client{Transport: fakeHTTP}, nil 239 } 240 tt.opts.BaseRepo = func() (ghrepo.Interface, error) { 241 return ghrepo.FromFullName("OWNER/REPO") 242 } 243 244 err := viewRun(&tt.opts) 245 if tt.wantErr != "" { 246 require.EqualError(t, err, tt.wantErr) 247 return 248 } else { 249 require.NoError(t, err) 250 } 251 252 assert.Equal(t, tt.wantStdout, stdout.String()) 253 assert.Equal(t, tt.wantStderr, stderr.String()) 254 }) 255 } 256 } 257 258 func Test_humanFileSize(t *testing.T) { 259 tests := []struct { 260 name string 261 size int64 262 want string 263 }{ 264 { 265 name: "min bytes", 266 size: 1, 267 want: "1 B", 268 }, 269 { 270 name: "max bytes", 271 size: 1023, 272 want: "1023 B", 273 }, 274 { 275 name: "min kibibytes", 276 size: 1024, 277 want: "1.00 KiB", 278 }, 279 { 280 name: "max kibibytes", 281 size: 1024*1024 - 1, 282 want: "1023.99 KiB", 283 }, 284 { 285 name: "min mibibytes", 286 size: 1024 * 1024, 287 want: "1.00 MiB", 288 }, 289 { 290 name: "fractional mibibytes", 291 size: 1024*1024*12 + 1024*350, 292 want: "12.34 MiB", 293 }, 294 { 295 name: "max mibibytes", 296 size: 1024*1024*1024 - 1, 297 want: "1023.99 MiB", 298 }, 299 { 300 name: "min gibibytes", 301 size: 1024 * 1024 * 1024, 302 want: "1.00 GiB", 303 }, 304 { 305 name: "fractional gibibytes", 306 size: 1024 * 1024 * 1024 * 1.5, 307 want: "1.50 GiB", 308 }, 309 } 310 for _, tt := range tests { 311 t.Run(tt.name, func(t *testing.T) { 312 if got := humanFileSize(tt.size); got != tt.want { 313 t.Errorf("humanFileSize() = %v, want %v", got, tt.want) 314 } 315 }) 316 } 317 }