Repository: urfave/cli
Pull request #1191 (2020-10-02 10:45:53)

feature: Add a App.Reader that defaults to os.Stdin
<!--
  This template provides some ideas of things to include in your PR description.
  To start, try providing a short summary of your changes in the Title above.
  If a section of the PR template does not apply to this PR, then delete that section.
 -->

## What type of PR is this?

_(REQUIRED)_

- [ ] bug
- [ ] cleanup  
- [ ] documentation
- [x] feature

## What this PR does / why we need it:

_(REQUIRED)_

1. Add a new default Reader to the App for easy testing STDIN.
1. Adds tests for the above.

<!--
  What goal is this change working towards?
  Provide a bullet pointed summary of how each file was changed.
  Briefly explain any decisions you made with respect to the changes.
  Include anything here that you didn't include in *Release Notes*
  above, such as changes to CI or changes to internal methods.
-->

## Which issue(s) this PR fixes:

_(REQUIRED)_
<!--
If this PR fixes one of more issues, list them here.
One line each, like so:

Fixes #123
Fixes #39
-->

Closes: #1190

## Release Notes

_(REQUIRED)_
<!--
  If this PR makes user facing changes, please describe them here. This
  description will be copied into the release notes/changelog, whenever the
  next version is released. Keep this section short, and focus on high level
  changes.

  Put your text between the block. To omit notes, use NONE within the block.
-->

```release-note
Add a App.Reader that defaults to os.Stdin.
```



Patch:
diff --git a/app.go b/app.go
index 59bf68d..1767c0e 100644
--- a/app.go
+++ b/app.go
@@ -72,6 +72,8 @@ type App struct {
 	Authors []*Author
 	// Copyright of the binary if any
 	Copyright string
+	// Reader reader to write input to (useful for tests)
+	Reader io.Reader
 	// Writer writer to write output to
 	Writer io.Writer
 	// ErrWriter writes error output
@@ -117,6 +119,7 @@ func NewApp() *App {
 		BashComplete: DefaultAppComplete,
 		Action:       helpCommand.Action,
 		Compiled:     compileTime(),
+		Reader:       os.Stdin,
 		Writer:       os.Stdout,
 		ErrWriter:    os.Stderr,
 	}
@@ -160,6 +163,10 @@ func (a *App) Setup() {
 		a.Compiled = compileTime()
 	}
 
+	if a.Reader == nil {
+		a.Reader = os.Stdin
+	}
+
 	if a.Writer == nil {
 		a.Writer = os.Stdout
 	}


Test patch:
diff --git a/app_test.go b/app_test.go
index 6c95faa..57c850d 100644
--- a/app_test.go
+++ b/app_test.go
@@ -433,6 +433,12 @@ func TestApp_Command(t *testing.T) {
 	}
 }
 
+func TestApp_Setup_defaultsReader(t *testing.T) {
+	app := &App{}
+	app.Setup()
+	expect(t, app.Reader, os.Stdin)
+}
+
 func TestApp_Setup_defaultsWriter(t *testing.T) {
 	app := &App{}
 	app.Setup()
@@ -850,6 +856,15 @@ func TestApp_ParseSliceFlagsWithMissingValue(t *testing.T) {
 	}
 }
 
+func TestApp_DefaultStdin(t *testing.T) {
+	app := &App{}
+	app.Setup()
+
+	if app.Reader != os.Stdin {
+		t.Error("Default input reader not set.")
+	}
+}
+
 func TestApp_DefaultStdout(t *testing.T) {
 	app := &App{}
 	app.Setup()
@@ -859,6 +874,29 @@ func TestApp_DefaultStdout(t *testing.T) {
 	}
 }
 
+func TestApp_SetStdin(t *testing.T) {
+	buf := make([]byte, 12)
+
+	app := &App{
+		Name:   "test",
+		Reader: strings.NewReader("Hello World!"),
+		Action: func(c *Context) error {
+			_, err := c.App.Reader.Read(buf)
+			return err
+		},
+	}
+
+	err := app.Run([]string{"help"})
+
+	if err != nil {
+		t.Fatalf("Run error: %s", err)
+	}
+
+	if string(buf) != "Hello World!" {
+		t.Error("App did not read input from desired reader.")
+	}
+}
+
 func TestApp_SetStdout(t *testing.T) {
 	var w bytes.Buffer