github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/cli/output/output_test.go (about) 1 package output 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "strings" 9 "testing" 10 11 "github.com/spf13/cobra" 12 "github.com/stretchr/testify/require" 13 "sigs.k8s.io/yaml" 14 15 "github.com/telepresenceio/telepresence/v2/pkg/client/cli/global" 16 ) 17 18 func TestWithOutput(t *testing.T) { 19 expectedREStdout := "re\n" 20 expectedREStderr := "re_stderr\n" 21 expectedName := "testing" 22 23 re := func(cmd *cobra.Command, args []string) error { 24 stdout := cmd.OutOrStdout() 25 stderr := cmd.ErrOrStderr() 26 fmt.Fprint(stdout, expectedREStdout) 27 fmt.Fprint(stderr, expectedREStderr) 28 return nil 29 } 30 31 newCmdWithBufs := func() (*cobra.Command, *strings.Builder, *strings.Builder) { 32 stdoutBuf := strings.Builder{} 33 stderrBuf := strings.Builder{} 34 cmd := cobra.Command{} 35 36 cmd.Use = expectedName 37 cmd.SetOut(&stdoutBuf) 38 cmd.SetErr(&stderrBuf) 39 cmd.SetContext(context.Background()) 40 cmd.RunE = re 41 42 cmd.PersistentFlags().String(global.FlagOutput, "default", "") 43 44 return &cmd, &stdoutBuf, &stderrBuf 45 } 46 47 t.Run("non-json output", func(t *testing.T) { 48 cmd, outBuf, errBuf := newCmdWithBufs() 49 _, _, err := Execute(cmd) 50 require.NoError(t, err) 51 52 require.Equal(t, expectedREStdout, outBuf.String(), "did not get expected stdout") 53 require.Equal(t, expectedREStderr, errBuf.String(), "did not get expected stderr") 54 }) 55 56 t.Run("json output no error", func(t *testing.T) { 57 cmd, outBuf, errBuf := newCmdWithBufs() 58 cmd.SetArgs([]string{"--output=json"}) 59 _, _, err := Execute(cmd) 60 require.NoError(t, err) 61 62 stdout := outBuf.String() 63 m := map[string]string{} 64 require.NoError(t, json.Unmarshal([]byte(stdout), &m), "did not get json as stdout, got: %s", stdout) 65 require.Equal(t, expectedREStdout, m["stdout"], "did not get expected stdout, got: %s", m["stdout"]) 66 require.Equal(t, expectedREStderr, m["stderr"], "did not get expected stderr, got: %s", m["stderr"]) 67 require.Equal(t, expectedName, m["cmd"], "did not get expected cmd name, got: %s", m["cmd"]) 68 69 stderr := errBuf.String() 70 require.Empty(t, stderr, "expected empty stderr, got: %s", stderr) 71 }) 72 73 t.Run("json output with error", func(t *testing.T) { 74 expectedErr := "ERROR" 75 cmd, outBuf, _ := newCmdWithBufs() 76 cmd.RunE = func(cmd *cobra.Command, args []string) error { 77 return errors.New(expectedErr) 78 } 79 cmd.SetArgs([]string{"--output=json"}) 80 _, _, err := Execute(cmd) 81 require.Error(t, err) 82 83 stdout := outBuf.String() 84 m := map[string]string{} 85 require.NoError(t, json.Unmarshal([]byte(stdout), &m), "did not get json as stdout, got: %s", stdout) 86 require.Equal(t, expectedErr, m["err"], "did not get expected err, got: %s", m["err"]) 87 }) 88 89 t.Run("yaml output with error", func(t *testing.T) { 90 expectedErr := "ERROR" 91 cmd, outBuf, _ := newCmdWithBufs() 92 cmd.RunE = func(cmd *cobra.Command, args []string) error { 93 return errors.New(expectedErr) 94 } 95 cmd.SetArgs([]string{"--output=yaml"}) 96 _, _, err := Execute(cmd) 97 require.Error(t, err) 98 99 stdout := outBuf.String() 100 m := map[string]string{} 101 require.NoError(t, yaml.Unmarshal([]byte(stdout), &m), "did not get yaml as stdout, got: %s", stdout) 102 require.Equal(t, expectedErr, m["err"], "did not get expected err, got: %s", m["err"]) 103 }) 104 105 t.Run("json output with native json", func(t *testing.T) { 106 expectedNativeJSONMap := map[string]float64{ 107 "a": 1, 108 } 109 cmd, outBuf, errBuf := newCmdWithBufs() 110 cmd.RunE = func(cmd *cobra.Command, args []string) error { 111 Object(cmd.Context(), expectedNativeJSONMap, false) 112 return nil 113 } 114 cmd.SetArgs([]string{"--output=json"}) 115 _, _, err := Execute(cmd) 116 require.NoError(t, err) 117 118 stdout := outBuf.String() 119 m := map[string]any{} 120 require.NoError(t, json.Unmarshal([]byte(stdout), &m), "did not get json as stdout, got: %s", stdout) 121 jsonOutputBytes, err := json.Marshal(m["stdout"]) 122 require.NoError(t, err, "did not get json stdout as expected") 123 expectedJSONOutputBytes, _ := json.Marshal(expectedNativeJSONMap) 124 125 require.Equal(t, expectedJSONOutputBytes, jsonOutputBytes, "did not get expected stdout json") 126 stderr := errBuf.String() 127 require.Empty(t, stderr, "expected empty stderr, got: %s", stderr) 128 }) 129 130 t.Run("json output with native json and other output", func(t *testing.T) { 131 expectedNativeJSONMap := map[string]float64{ 132 "a": 1, 133 } 134 cmd, _, _ := newCmdWithBufs() 135 cmd.RunE = func(cmd *cobra.Command, args []string) error { 136 Object(cmd.Context(), expectedNativeJSONMap, false) 137 fmt.Fprintln(cmd.OutOrStdout(), "hello") 138 return nil 139 } 140 cmd.SetArgs([]string{"--output=json"}) 141 require.Panics(t, func() { 142 _, _, _ = Execute(cmd) 143 }) 144 }) 145 146 t.Run("json output with other output and native json", func(t *testing.T) { 147 expectedNativeJSONMap := map[string]float64{ 148 "a": 1, 149 } 150 cmd, _, _ := newCmdWithBufs() 151 cmd.RunE = func(cmd *cobra.Command, args []string) error { 152 fmt.Fprintln(cmd.OutOrStdout(), "hello") 153 Object(cmd.Context(), expectedNativeJSONMap, false) 154 return nil 155 } 156 cmd.SetArgs([]string{"--output=json"}) 157 require.Panics(t, func() { 158 _, _, _ = Execute(cmd) 159 }) 160 }) 161 162 t.Run("json output with multiple native json", func(t *testing.T) { 163 expectedNativeJSONMap := map[string]float64{ 164 "a": 1, 165 } 166 cmd, _, _ := newCmdWithBufs() 167 cmd.RunE = func(cmd *cobra.Command, args []string) error { 168 Object(cmd.Context(), expectedNativeJSONMap, false) 169 Object(cmd.Context(), expectedNativeJSONMap, false) 170 return nil 171 } 172 cmd.SetArgs([]string{"--output=json"}) 173 require.Panics(t, func() { 174 _, _, _ = Execute(cmd) 175 }) 176 }) 177 178 t.Run("json output with overriding native json", func(t *testing.T) { 179 expectedNativeJSONMap := map[string]float64{ 180 "a": 1, 181 } 182 cmd, outBuf, _ := newCmdWithBufs() 183 cmd.RunE = func(cmd *cobra.Command, args []string) error { 184 Object(cmd.Context(), expectedNativeJSONMap, true) 185 return nil 186 } 187 cmd.SetArgs([]string{"--output=json"}) 188 _, _, err := Execute(cmd) 189 require.NoError(t, err) 190 191 stdout := outBuf.String() 192 m := map[string]any{} 193 require.NoError(t, json.Unmarshal([]byte(stdout), &m), "did not get json as stdout, got: %s", stdout) 194 require.Equal(t, 1.0, m["a"]) 195 }) 196 197 t.Run("json output with overriding native json and error", func(t *testing.T) { 198 expectedNativeMap := map[string]any{ 199 "a": 1.0, 200 } 201 cmd, outBuf, _ := newCmdWithBufs() 202 cmd.RunE = func(cmd *cobra.Command, args []string) error { 203 Object(cmd.Context(), expectedNativeMap, true) 204 return errors.New("this went south") 205 } 206 cmd.SetArgs([]string{"--output=json"}) 207 _, _, err := Execute(cmd) 208 require.Error(t, err) 209 210 stdout := outBuf.String() 211 m := map[string]any{} 212 require.NoError(t, json.Unmarshal([]byte(stdout), &m), "did not get json as stdout, got: %s", stdout) 213 require.Equal(t, m["stdout"], expectedNativeMap, "did not get expected stdout") 214 require.Empty(t, m["stderr"], "did not get empty stderr") 215 require.Equal(t, m["err"], "this went south") 216 }) 217 }