Repository: cli/cli
File: pkg/cmd/root/extension_test.go (Go)

Code before:
				return nil, nil
			}

			return &update.ReleaseInfo{
				Version: tt.extLatestVersion,
				URL:     tt.extURL,
			}, nil
		}

		cmd := root.NewCmdExtension(ios, em, ext, checkFunc)

		_, 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")
		}
	}
}

func TestNewCmdExtension_UpdateCheckIsNonblocking(t *testing.T) {
	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 "1.0.0"
		},
		IsPinnedFunc: func() bool {
			return false
		},
		LatestVersionFunc: func() string {
			return "2.0.0"
		},
		NameFunc: func() string {
			return "major-update"
		},
		UpdateAvailableFunc: func() bool {
			return true
		},
		URLFunc: func() string {
			return "https//github.com/dne/major-update"
		},

Review comment (suggestion):
I think this might be a slight improvement:

```go
func TestNewCmdExtension_UpdateCheckIsNonblocking(t *testing.T) {
	ios, _, _, _ := 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 "1.0.0"
		},
		IsPinnedFunc: func() bool {
			return false
		},
		LatestVersionFunc: func() string {
			return "2.0.0"
		},
		NameFunc: func() string {
			return "major-update"
		},
		UpdateAvailableFunc: func() bool {
			return true
		},
		URLFunc: func() string {
			return "https//github.com/dne/major-update"
		},
	}

	checkFunc := func(em extensions.ExtensionManager, ext extensions.Extension) (*update.ReleaseInfo, error) {
		// This function runs in the background as a goroutine while the extension is dispatched.
		// Testing whether the extension cobra command is non-blocking for extension update check,
		// this function will cause goroutine to sleep for a sufficiently long time before panicking.
		// The idea is that the test will conclude because the dispatch function completes immediately
		// and exits before the check update function completes.
		time.Sleep(30 * time.Second)
		return nil, fmt.Errorf("update check should not have completed")
	}

	cmd := root.NewCmdExtension(ios, em, ext, checkFunc)

	completed := make(chan struct{})
	go func() {
		_, err := cmd.ExecuteC()
		require.NoError(t, err)
		close(completed)
	}()

	select {
	case <-completed:
		// Expected behavior
	case <-time.After(1 * time.Second):
		t.Fatal("extension update check should have exited")
	}
}
```

Code after:

		checkFunc := func(em extensions.ExtensionManager, ext extensions.Extension) (*update.ReleaseInfo, error) {
			if !tt.extUpdateAvailable {
				return nil, nil
			}

			return &update.ReleaseInfo{
				Version: tt.extLatestVersion,
				URL:     tt.extURL,
			}, nil
		}

		cmd := root.NewCmdExtension(ios, em, ext, checkFunc)

		_, 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")
		}
	}
}

func TestNewCmdExtension_UpdateCheckIsNonblocking(t *testing.T) {
	ios, _, _, _ := 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 "1.0.0"
		},
		IsPinnedFunc: func() bool {
			return false
		},
		LatestVersionFunc: func() string {
			return "2.0.0"
		},
		NameFunc: func() string {
			return "major-update"
		},
		UpdateAvailableFunc: func() bool {
			return true
		},