diff --git a/cmd/kn/main_test.go b/cmd/kn/main_test.go index c41ba3cfec..278573788a 100644 --- a/cmd/kn/main_test.go +++ b/cmd/kn/main_test.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" "gotest.tools/assert" - "knative.dev/client/pkg/kn/commands" + "knative.dev/client/lib/test" "knative.dev/client/pkg/kn/root" "knative.dev/client/pkg/util" ) @@ -243,7 +243,7 @@ func TestRunWithError(t *testing.T) { }, } for _, d := range data { - capture := commands.CaptureOutput(t) + capture := test.CaptureOutput(t) printError(errors.New(d.given)) stdOut, errOut := capture.Close() @@ -261,7 +261,7 @@ func TestRun(t *testing.T) { os.Args = oldArgs })() - capture := commands.CaptureOutput(t) + capture := test.CaptureOutput(t) err := run(os.Args[1:]) out, _ := capture.Close() diff --git a/lib/test/capture_output.go b/lib/test/capture_output.go new file mode 100644 index 0000000000..b70ba7dd42 --- /dev/null +++ b/lib/test/capture_output.go @@ -0,0 +1,77 @@ +// Copyright 2020 The Knative Authors + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// OutputCapture allows to capture any text written to standard out or standard error +// which is especially useful during testing. +// +// Call it like: +// +// capture := CaptureOutput(t) +// doSomeActionThatWritesToStdOutAndStdErr() +// stdOut, stdErr := capture.Close() +// +// CaptureOutpu() and capture.Close() should always come in pairs as Close() also +// restores the old streams +package test + +import ( + "io/ioutil" + "os" + "testing" + + "gotest.tools/assert" +) + +type OutputCapture struct { + outRead, outWrite *os.File + errorRead, errorWrite *os.File + t *testing.T + + oldStdout *os.File + oldStderr *os.File +} + +// CaptureOutput sets up standard our and standard error to capture any +// output which +func CaptureOutput(t *testing.T) OutputCapture { + ret := OutputCapture{ + oldStdout: os.Stdout, + oldStderr: os.Stderr, + t: t, + } + var err error + ret.outRead, ret.outWrite, err = os.Pipe() + assert.NilError(t, err) + os.Stdout = ret.outWrite + ret.errorRead, ret.errorWrite, err = os.Pipe() + assert.NilError(t, err) + os.Stderr = ret.errorWrite + return ret +} + +// Close return the output collected and restores the original standard out and error streams +// (i.e. those that were present before the call to CaptureOutput). +func (c OutputCapture) Close() (string, string) { + err := c.outWrite.Close() + assert.NilError(c.t, err) + err = c.errorWrite.Close() + assert.NilError(c.t, err) + outOutput, err := ioutil.ReadAll(c.outRead) + assert.NilError(c.t, err) + errOutput, err := ioutil.ReadAll(c.errorRead) + assert.NilError(c.t, err) + os.Stdout = c.oldStdout + os.Stderr = c.oldStderr + return string(outOutput), string(errOutput) +} diff --git a/pkg/kn/commands/completion/completion_test.go b/pkg/kn/commands/completion/completion_test.go index 7ca71708fb..122447b23c 100644 --- a/pkg/kn/commands/completion/completion_test.go +++ b/pkg/kn/commands/completion/completion_test.go @@ -17,6 +17,7 @@ package completion import ( "testing" + "knative.dev/client/lib/test" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/util" @@ -35,7 +36,7 @@ func TestCompletionUsage(t *testing.T) { func TestCompletionGeneration(t *testing.T) { for _, shell := range []string{"bash", "zsh"} { completionCmd := NewCompletionCommand(&commands.KnParams{}) - c := commands.CaptureOutput(t) + c := test.CaptureOutput(t) err := completionCmd.RunE(&cobra.Command{}, []string{shell}) assert.NilError(t, err) stdOut, stdErr := c.Close() diff --git a/pkg/kn/commands/testing_helper.go b/pkg/kn/commands/testing_helper.go index 4c8d2c76b9..5e8b36bce4 100644 --- a/pkg/kn/commands/testing_helper.go +++ b/pkg/kn/commands/testing_helper.go @@ -16,12 +16,9 @@ package commands import ( "bytes" - "io/ioutil" "os" - "testing" "github.com/spf13/cobra" - "gotest.tools/assert" "k8s.io/apimachinery/pkg/runtime" clienttesting "k8s.io/client-go/testing" servingv1fake "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1/fake" @@ -93,46 +90,6 @@ func CreateDynamicTestKnCommand(cmd *cobra.Command, knParams *KnParams, objects } -type OutputCapture struct { - outRead, outWrite *os.File - errorRead, errorWrite *os.File - t *testing.T - - oldStdout *os.File - oldStderr *os.File -} - -func CaptureOutput(t *testing.T) OutputCapture { - ret := OutputCapture{ - oldStdout: os.Stdout, - oldStderr: os.Stderr, - t: t, - } - var err error - ret.outRead, ret.outWrite, err = os.Pipe() - assert.NilError(t, err) - os.Stdout = ret.outWrite - ret.errorRead, ret.errorWrite, err = os.Pipe() - assert.NilError(t, err) - os.Stderr = ret.errorWrite - return ret -} - -// CaptureOutput collects the current content of os.Stdout -func (c OutputCapture) Close() (string, string) { - err := c.outWrite.Close() - assert.NilError(c.t, err) - err = c.errorWrite.Close() - assert.NilError(c.t, err) - outOutput, err := ioutil.ReadAll(c.outRead) - assert.NilError(c.t, err) - errOutput, err := ioutil.ReadAll(c.errorRead) - assert.NilError(c.t, err) - os.Stdout = c.oldStdout - os.Stderr = c.oldStderr - return string(outOutput), string(errOutput) -} - // NewTestCommand can be used by tes func NewTestCommand(subCommand *cobra.Command, params *KnParams) *cobra.Command { rootCmd := &cobra.Command{ diff --git a/pkg/kn/commands/testing_helper_test.go b/pkg/kn/commands/testing_helper_test.go index fea84d3a78..b9b109b770 100644 --- a/pkg/kn/commands/testing_helper_test.go +++ b/pkg/kn/commands/testing_helper_test.go @@ -20,6 +20,8 @@ import ( "github.com/spf13/cobra" "gotest.tools/assert" + + "knative.dev/client/lib/test" ) func TestCreateTestKnCommand(t *testing.T) { @@ -56,7 +58,7 @@ func TestCreateDynamicTestKnCommand(t *testing.T) { } func TestCaptureStdout(t *testing.T) { - c := CaptureOutput(t) + c := test.CaptureOutput(t) fmt.Print("Hello World !") stdOut, stdErr := c.Close() assert.Equal(t, stdErr, "") diff --git a/pkg/templates/command_groups_test.go b/pkg/templates/command_groups_test.go index 400d778513..011241a447 100644 --- a/pkg/templates/command_groups_test.go +++ b/pkg/templates/command_groups_test.go @@ -21,7 +21,7 @@ import ( "github.com/spf13/cobra" "gotest.tools/assert" - "knative.dev/client/pkg/kn/commands" + "knative.dev/client/lib/test" "knative.dev/client/pkg/util" ) @@ -54,14 +54,14 @@ func TestSetUsage(t *testing.T) { assert.Assert(t, cmd.DisableFlagsInUseLine) } - capture := commands.CaptureOutput(t) + capture := test.CaptureOutput(t) err := (rootCmd.UsageFunc())(rootCmd) assert.NilError(t, err) stdOut, stdErr := capture.Close() assert.Equal(t, stdErr, "") assert.Assert(t, util.ContainsAll(stdOut, "header-1", "header-2")) - capture = commands.CaptureOutput(t) + capture = test.CaptureOutput(t) (rootCmd.HelpFunc())(rootCmd, nil) stdOut, stdErr = capture.Close() assert.Equal(t, stdErr, "") diff --git a/pkg/templates/template_engine_test.go b/pkg/templates/template_engine_test.go index b1ee05dfcc..2ce0b13c5d 100644 --- a/pkg/templates/template_engine_test.go +++ b/pkg/templates/template_engine_test.go @@ -23,7 +23,7 @@ import ( "github.com/spf13/cobra" "gotest.tools/assert" - "knative.dev/client/pkg/kn/commands" + "knative.dev/client/lib/test" "knative.dev/client/pkg/util" ) @@ -60,7 +60,7 @@ func TestUsageFunc(t *testing.T) { }, } for _, d := range data { - capture := commands.CaptureOutput(t) + capture := test.CaptureOutput(t) err := (engine.usageFunc())(d.cmd) assert.NilError(t, err) stdOut, stdErr := capture.Close() @@ -91,7 +91,7 @@ func TestHelpFunc(t *testing.T) { }, } for _, d := range data { - capture := commands.CaptureOutput(t) + capture := test.CaptureOutput(t) (engine.helpFunc())(d.cmd, []string{}) stdOut, stdErr := capture.Close() @@ -103,7 +103,7 @@ func TestHelpFunc(t *testing.T) { func TestOptionsFunc(t *testing.T) { rootCmd, _ := newTemplateEngine() subCmd := rootCmd.Commands()[0] - capture := commands.CaptureOutput(t) + capture := test.CaptureOutput(t) err := NewGlobalOptionsFunc()(subCmd) assert.NilError(t, err) stdOut, stdErr := capture.Close()