44 "bufio"
55 "bytes"
66 "encoding/json"
7+ "io"
78 "os"
89 "path/filepath"
910 "regexp"
@@ -31,35 +32,42 @@ type cmdTestCase struct {
3132 goldenFile string
3233 goldenRegex string
3334 goldenJson []jsonCheck // Use like this for array {"[0].compliant", false}
35+ goldenStdout string // expected stdout only (exact match, ignored when empty)
36+ goldenStderr string // expected stderr only (exact match, ignored when empty)
3437 wantError bool
3538 additionalConfig interface {}
3639}
3740
38- // executeCommandStdinC executes a command as a user would and return the output
39- // this creates a new kosli command that is run, but it cannot be used in other tests
40- // because newRootCmd overwrites the global options
41- func executeCommandC (cmd string ) (* cobra.Command , string , error ) {
41+ // executeCommandC executes a command as a user would and returns the output
42+ // split into combined, stdout-only, and stderr-only streams.
43+ // This creates a new kosli command that is run, but it cannot be used in other tests
44+ // because newRootCmd overwrites the global options.
45+ func executeCommandC (cmd string ) (* cobra.Command , string , string , string , error ) {
4246 args , err := shellwords .Parse (cmd )
4347 if err != nil {
44- return nil , "" , err
48+ return nil , "" , "" , "" , err
4549 }
4650
47- buf := new (bytes.Buffer )
51+ combinedBuf := new (bytes.Buffer )
52+ outBuf := new (bytes.Buffer )
53+ errBuf := new (bytes.Buffer )
4854
49- root , err := newRootCmd (buf , buf , args )
55+ outWriter := io .MultiWriter (outBuf , combinedBuf )
56+ errWriter := io .MultiWriter (errBuf , combinedBuf )
57+
58+ root , err := newRootCmd (outWriter , errWriter , args )
5059 if err != nil {
51- return nil , "" , err
60+ return nil , "" , "" , "" , err
5261 }
5362
5463 root .SilenceErrors = false
55- root .SetOut (buf )
56- root .SetErr (buf )
64+ root .SetOut (outWriter )
65+ root .SetErr (errWriter )
5766 root .SetArgs (args )
5867
5968 c , err := root .ExecuteC ()
60- output := buf .String ()
6169
62- return c , output , err
70+ return c , combinedBuf . String (), outBuf . String (), errBuf . String () , err
6371}
6472
6573// runTestCmd runs a table of cmd test cases
@@ -76,23 +84,33 @@ func runTestCmd(t *testing.T, tests []cmdTestCase) {
7684 t .Error ("golden and goldenPath cannot be set together" )
7785 }
7886 t .Logf ("running cmd: %s" , tt .cmd )
79- _ , out , err := executeCommandC (tt .cmd )
87+ _ , combined , stdout , stderr , err := executeCommandC (tt .cmd )
8088 if (err != nil ) != tt .wantError {
8189 t .Errorf ("error expectation not matched\n \n WANT error is: %t\n \n but GOT: '%v'" , tt .wantError , err )
8290 }
8391 if tt .golden != "" {
84- if ! bytes .Equal ([]byte (tt .golden ), []byte (out )) {
85- t .Errorf ("does not match golden\n \n WANT:\n '%s'\n \n GOT:\n '%s'\n " , tt .golden , out )
92+ if ! bytes .Equal ([]byte (tt .golden ), []byte (combined )) {
93+ t .Errorf ("does not match golden\n \n WANT:\n '%s'\n \n GOT:\n '%s'\n " , tt .golden , combined )
8694 }
8795 } else if tt .goldenFile != "" {
88- if err := compareAgainstFile ([]byte (out ), goldenPath (tt .goldenFile )); err != nil {
96+ if err := compareAgainstFile ([]byte (combined ), goldenPath (tt .goldenFile )); err != nil {
8997 t .Error (err )
9098 }
9199 } else if tt .goldenRegex != "" {
92- require .Regexp (t , tt .goldenRegex , out )
100+ require .Regexp (t , tt .goldenRegex , combined )
93101 } else if len (tt .goldenJson ) > 0 {
94102 for _ , check := range tt .goldenJson {
95- goldenJsonContains (t , out , check .Path , check .Want )
103+ goldenJsonContains (t , combined , check .Path , check .Want )
104+ }
105+ }
106+ if tt .goldenStdout != "" {
107+ if ! bytes .Equal ([]byte (tt .goldenStdout ), []byte (stdout )) {
108+ t .Errorf ("stdout does not match goldenStdout\n \n WANT:\n '%s'\n \n GOT:\n '%s'\n " , tt .goldenStdout , stdout )
109+ }
110+ }
111+ if tt .goldenStderr != "" {
112+ if ! bytes .Equal ([]byte (tt .goldenStderr ), []byte (stderr )) {
113+ t .Errorf ("stderr does not match goldenStderr\n \n WANT:\n '%s'\n \n GOT:\n '%s'\n " , tt .goldenStderr , stderr )
96114 }
97115 }
98116 })
0 commit comments