Test extension command update behaviors
This commit expands upon the previous work by creating tests around extension command execution and how various extension update scenarios are handled. Along the way, the logic handling formatting update messaging has been switched to use `ColorScheme` in order to honor color behavior flags.
This commit is contained in:
parent
47d77bd51b
commit
ddf7287ab8
2 changed files with 165 additions and 15 deletions
|
|
@ -5,10 +5,10 @@ import (
|
|||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cli/cli/v2/pkg/extensions"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/mgutz/ansi"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -24,8 +24,8 @@ type extensionReleaseInfo struct {
|
|||
}
|
||||
|
||||
func NewCmdExtension(io *iostreams.IOStreams, em extensions.ExtensionManager, ext extensions.Extension) *cobra.Command {
|
||||
// Setup channel containing information about potential latest release info
|
||||
updateMessageChan := make(chan *extensionReleaseInfo)
|
||||
cs := io.ColorScheme()
|
||||
|
||||
return &cobra.Command{
|
||||
Use: ext.Name(),
|
||||
|
|
@ -56,20 +56,24 @@ func NewCmdExtension(io *iostreams.IOStreams, em extensions.ExtensionManager, ex
|
|||
},
|
||||
// PostRun handles communicating extension release information if found
|
||||
PostRun: func(c *cobra.Command, args []string) {
|
||||
releaseInfo := <-updateMessageChan
|
||||
if releaseInfo != nil {
|
||||
stderr := io.ErrOut
|
||||
fmt.Fprintf(stderr, "\n\n%s %s → %s\n",
|
||||
ansi.Color(fmt.Sprintf("A new release of %s is available:", ext.Name()), "yellow"),
|
||||
ansi.Color(strings.TrimPrefix(releaseInfo.CurrentVersion, "v"), "cyan"),
|
||||
ansi.Color(strings.TrimPrefix(releaseInfo.LatestVersion, "v"), "cyan"))
|
||||
if releaseInfo.Pinned {
|
||||
fmt.Fprintf(stderr, "To upgrade, run: gh extension upgrade %s --force\n", ext.Name())
|
||||
} else {
|
||||
fmt.Fprintf(stderr, "To upgrade, run: gh extension upgrade %s\n", ext.Name())
|
||||
select {
|
||||
case releaseInfo := <-updateMessageChan:
|
||||
if releaseInfo != nil {
|
||||
stderr := io.ErrOut
|
||||
fmt.Fprintf(stderr, "\n\n%s %s → %s\n",
|
||||
cs.Yellowf("A new release of %s is available:", ext.Name()),
|
||||
cs.Cyan(strings.TrimPrefix(releaseInfo.CurrentVersion, "v")),
|
||||
cs.Cyan(strings.TrimPrefix(releaseInfo.LatestVersion, "v")))
|
||||
if releaseInfo.Pinned {
|
||||
fmt.Fprintf(stderr, "To upgrade, run: gh extension upgrade %s --force\n", ext.Name())
|
||||
} else {
|
||||
fmt.Fprintf(stderr, "To upgrade, run: gh extension upgrade %s\n", ext.Name())
|
||||
}
|
||||
fmt.Fprintf(stderr, "%s\n\n",
|
||||
cs.Yellow(releaseInfo.URL))
|
||||
}
|
||||
fmt.Fprintf(stderr, "%s\n\n",
|
||||
ansi.Color(releaseInfo.URL, "yellow"))
|
||||
case <-time.After(3 * time.Second):
|
||||
// Bail on checking for new extension update as its taking too long
|
||||
}
|
||||
},
|
||||
GroupID: "extension",
|
||||
|
|
|
|||
146
pkg/cmd/root/extension_test.go
Normal file
146
pkg/cmd/root/extension_test.go
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
package root_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/pkg/cmd/root"
|
||||
"github.com/cli/cli/v2/pkg/extensions"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewCmdExtension_Updates(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
extCurrentVersion string
|
||||
extIsPinned bool
|
||||
extLatestVersion string
|
||||
extName string
|
||||
extUpdateAvailable bool
|
||||
extURL string
|
||||
wantStderr string
|
||||
}{
|
||||
{
|
||||
name: "no update available",
|
||||
extName: "no-update",
|
||||
extUpdateAvailable: false,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "1.0.0",
|
||||
},
|
||||
{
|
||||
name: "major update",
|
||||
extName: "major-update",
|
||||
extUpdateAvailable: true,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "2.0.0",
|
||||
wantStderr: heredoc.Doc(`
|
||||
A new release of major-update is available: 1.0.0 → 2.0.0
|
||||
To upgrade, run: gh extension upgrade major-update
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "major update, pinned",
|
||||
extName: "major-update",
|
||||
extUpdateAvailable: true,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "2.0.0",
|
||||
extIsPinned: true,
|
||||
wantStderr: heredoc.Doc(`
|
||||
A new release of major-update is available: 1.0.0 → 2.0.0
|
||||
To upgrade, run: gh extension upgrade major-update --force
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "minor update",
|
||||
extName: "minor-update",
|
||||
extUpdateAvailable: true,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "1.1.0",
|
||||
wantStderr: heredoc.Doc(`
|
||||
A new release of minor-update is available: 1.0.0 → 1.1.0
|
||||
To upgrade, run: gh extension upgrade minor-update
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "minor update, pinned",
|
||||
extName: "minor-update",
|
||||
extUpdateAvailable: true,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "1.1.0",
|
||||
extIsPinned: true,
|
||||
wantStderr: heredoc.Doc(`
|
||||
A new release of minor-update is available: 1.0.0 → 1.1.0
|
||||
To upgrade, run: gh extension upgrade minor-update --force
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "patch update",
|
||||
extName: "patch-update",
|
||||
extUpdateAvailable: true,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "1.0.1",
|
||||
wantStderr: heredoc.Doc(`
|
||||
A new release of patch-update is available: 1.0.0 → 1.0.1
|
||||
To upgrade, run: gh extension upgrade patch-update
|
||||
`),
|
||||
},
|
||||
{
|
||||
name: "patch update, pinned",
|
||||
extName: "patch-update",
|
||||
extUpdateAvailable: true,
|
||||
extCurrentVersion: "1.0.0",
|
||||
extLatestVersion: "1.0.1",
|
||||
extIsPinned: true,
|
||||
wantStderr: heredoc.Doc(`
|
||||
A new release of patch-update is available: 1.0.0 → 1.0.1
|
||||
To upgrade, run: gh extension upgrade patch-update --force
|
||||
`),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
ios, _, _, stderr := iostreams.Test()
|
||||
|
||||
em := &extensions.ExtensionManagerMock{
|
||||
DispatchFunc: func(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (bool, error) {
|
||||
// Assume extension executed / dispatched without problems as test is focused on upgrade checking.
|
||||
return true, nil
|
||||
},
|
||||
}
|
||||
|
||||
ext := &extensions.ExtensionMock{
|
||||
CurrentVersionFunc: func() string {
|
||||
return tt.extCurrentVersion
|
||||
},
|
||||
IsPinnedFunc: func() bool {
|
||||
return tt.extIsPinned
|
||||
},
|
||||
LatestVersionFunc: func() string {
|
||||
return tt.extLatestVersion
|
||||
},
|
||||
NameFunc: func() string {
|
||||
return tt.extName
|
||||
},
|
||||
UpdateAvailableFunc: func() bool {
|
||||
return tt.extUpdateAvailable
|
||||
},
|
||||
URLFunc: func() string {
|
||||
return tt.extURL
|
||||
},
|
||||
}
|
||||
|
||||
cmd := root.NewCmdExtension(ios, em, ext)
|
||||
|
||||
_, err := cmd.ExecuteC()
|
||||
require.NoError(t, err)
|
||||
|
||||
if tt.wantStderr == "" {
|
||||
assert.Emptyf(t, stderr.String(), "executing extension command should output nothing to stderr")
|
||||
} else {
|
||||
assert.Containsf(t, stderr.String(), tt.wantStderr, "executing extension command should output message about upgrade to stderr")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue