github.com/thanhphan1147/cloudfoundry-cli@v7.1.0+incompatible/cf/terminal/table_test.go (about) 1 package terminal_test 2 3 import ( 4 "bytes" 5 "strings" 6 7 . "code.cloudfoundry.org/cli/cf/terminal" 8 . "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 ) 12 13 var _ = Describe("Table", func() { 14 var ( 15 outputs *bytes.Buffer 16 table *Table 17 ) 18 19 BeforeEach(func() { 20 outputs = &bytes.Buffer{} 21 table = NewTable([]string{"watashi", "no", "atama!"}) 22 }) 23 24 It("prints the header", func() { 25 table.PrintTo(outputs) 26 s := strings.Split(outputs.String(), "\n") 27 Expect(s).To(ContainSubstrings( 28 []string{"watashi", "no", "atama!"}, 29 )) 30 }) 31 32 Describe("REGRESSION: #117404629, having a space in one of the middle headers", func() { 33 BeforeEach(func() { 34 outputs = &bytes.Buffer{} 35 table = NewTable([]string{"watashi", "no ", "atama!"}) 36 }) 37 38 It("prints the table without error", func() { 39 err := table.PrintTo(outputs) 40 Expect(err).NotTo(HaveOccurred()) 41 42 s := strings.Split(outputs.String(), "\n") 43 Expect(s).To(ContainSubstrings( 44 []string{"watashi", "no", "atama!"}, 45 )) 46 }) 47 48 It("prints the table with the extra whitespace from the header stripped", func() { 49 err := table.PrintTo(outputs) 50 Expect(err).NotTo(HaveOccurred()) 51 52 s := strings.Split(outputs.String(), "\n") 53 Expect(s).To(ContainSubstrings( 54 []string{"watashi no atama!"}, 55 )) 56 }) 57 }) 58 59 It("prints format string literals as strings", func() { 60 table.Add("cloak %s", "and", "dagger") 61 table.PrintTo(outputs) 62 s := strings.Split(outputs.String(), "\n") 63 64 Expect(s).To(ContainSubstrings( 65 []string{"cloak %s", "and", "dagger"}, 66 )) 67 }) 68 69 It("prints all the rows you give it", func() { 70 table.Add("something", "and", "nothing") 71 table.PrintTo(outputs) 72 s := strings.Split(outputs.String(), "\n") 73 Expect(s).To(ContainSubstrings( 74 []string{"something", "and", "nothing"}, 75 )) 76 }) 77 78 Describe("adding rows to be printed later", func() { 79 It("prints them when you call Print()", func() { 80 table.Add("a", "b", "c") 81 table.Add("passed", "to", "print") 82 table.PrintTo(outputs) 83 s := strings.Split(outputs.String(), "\n") 84 85 Expect(s).To(ContainSubstrings( 86 []string{"a", "b", "c"}, 87 )) 88 }) 89 90 It("flushes previously added rows and then outputs passed rows", func() { 91 table.Add("a", "b", "c") 92 table.Add("passed", "to", "print") 93 table.PrintTo(outputs) 94 s := strings.Split(outputs.String(), "\n") 95 96 Expect(s).To(ContainSubstrings( 97 []string{"watashi", "no", "atama!"}, 98 []string{"a", "b", "c"}, 99 []string{"passed", "to", "print"}, 100 )) 101 }) 102 }) 103 104 It("prints a newline for the headers, and nothing for rows", func() { 105 table = NewTable([]string{}) 106 table.PrintTo(outputs) 107 108 Expect(outputs.String()).To(Equal("\n")) 109 }) 110 111 It("prints nothing with suppressed headers and no rows", func() { 112 table.NoHeaders() 113 table.PrintTo(outputs) 114 115 Expect(outputs.String()).To(BeEmpty()) 116 }) 117 118 It("does not print the header when suppressed", func() { 119 table.NoHeaders() 120 table.Add("cloak", "and", "dagger") 121 table.PrintTo(outputs) 122 s := strings.Split(outputs.String(), "\n") 123 124 Expect(s).To(Not(ContainSubstrings( 125 []string{"watashi", "no", "atama!"}, 126 ))) 127 Expect(s).To(ContainSubstrings( 128 []string{"cloak", "and", "dagger"}, 129 )) 130 }) 131 132 It("prints cell strings as specified by column transformers", func() { 133 table.Add("cloak", "and", "dagger") 134 table.SetTransformer(0, func(s string) string { 135 return "<<" + s + ">>" 136 }) 137 table.PrintTo(outputs) 138 s := strings.Split(outputs.String(), "\n") 139 140 Expect(s).To(ContainSubstrings( 141 []string{"<<cloak>>", "and", "dagger"}, 142 )) 143 Expect(s).To(Not(ContainSubstrings( 144 []string{"<<watashi>>"}, 145 ))) 146 }) 147 148 It("prints no more columns than headers", func() { 149 table.Add("something", "and", "nothing", "ignored") 150 table.PrintTo(outputs) 151 s := strings.Split(outputs.String(), "\n") 152 153 Expect(s).To(Not(ContainSubstrings( 154 []string{"ignored"}, 155 ))) 156 }) 157 158 It("avoids printing trailing whitespace for empty columns", func() { 159 table.Add("something", "and") 160 table.PrintTo(outputs) 161 s := strings.Split(outputs.String(), "\n") 162 163 Expect(s).To(ContainSubstrings( 164 []string{"watashi no atama!"}, 165 []string{"something and"}, 166 )) 167 }) 168 169 It("avoids printing trailing whitespace for whitespace columns", func() { 170 table.Add("something", " ") 171 table.PrintTo(outputs) 172 s := strings.Split(outputs.String(), "\n") 173 174 Expect(s).To(ContainSubstrings( 175 []string{"watashi no atama!"}, 176 []string{"something"}, 177 )) 178 }) 179 180 It("even avoids printing trailing whitespace for multi-line cells", func() { 181 table.Add("a", "b\nd", "\nc") 182 table.PrintTo(outputs) 183 s := strings.Split(outputs.String(), "\n") 184 185 Expect(s).To(ContainSubstrings( 186 []string{"watashi no atama!"}, 187 []string{"a b"}, 188 []string{" d c"}, 189 )) 190 }) 191 192 It("prints multi-line cells on separate physical lines", func() { 193 table.Add("a", "b\nd", "c") 194 table.PrintTo(outputs) 195 s := strings.Split(outputs.String(), "\n") 196 197 Expect(s).To(ContainSubstrings( 198 []string{"watashi no atama!"}, 199 []string{"a b c"}, 200 []string{" d"}, 201 )) 202 }) 203 204 Describe("aligning columns", func() { 205 It("aligns rows to the header when the header is longest", func() { 206 table.Add("a", "b", "c") 207 table.PrintTo(outputs) 208 s := strings.Split(outputs.String(), "\n") 209 210 Expect(s).To(ContainSubstrings( 211 []string{"watashi no atama!"}, 212 []string{"a b c"}, 213 )) 214 }) 215 216 It("aligns rows to the longest row provided", func() { 217 table.Add("x", "y", "z") 218 table.Add("something", "something", "darkside") 219 table.PrintTo(outputs) 220 s := strings.Split(outputs.String(), "\n") 221 222 Expect(s).To(ContainSubstrings( 223 []string{"watashi no atama!"}, 224 []string{"x y z"}, 225 []string{"something something darkside"}, 226 )) 227 }) 228 229 It("aligns rows to the longest row provided when there are multibyte characters present", func() { 230 table.Add("x", "ÿ", "z") 231 table.Add("something", "something", "darkside") 232 table.PrintTo(outputs) 233 s := strings.Split(outputs.String(), "\n") 234 235 Expect(s).To(ContainSubstrings( 236 []string{"watashi no atama!"}, 237 []string{"x ÿ z"}, 238 []string{"something something darkside"}, 239 )) 240 }) 241 242 It("supports multi-byte Japanese runes", func() { 243 table = NewTable([]string{"", "", "", "", "", ""}) 244 table.Add("名前", "要求された状態", "インスタンス", "メモリー", "ディスク", "URL") 245 table.Add("app-name", "stopped", "0/1", "1G", "1G", "app-name.example.com") 246 table.PrintTo(outputs) 247 s := strings.Split(outputs.String(), "\n") 248 249 Expect(s).To(ContainSubstrings( 250 []string{"名前 要求された状態 インスタンス メモリー ディスク URL"}, 251 []string{"app-name stopped 0/1 1G 1G app-name.example.com"}, 252 )) 253 }) 254 255 It("supports multi-byte French runes", func() { 256 table = NewTable([]string{"", "", "", "", "", ""}) 257 table.Add("nom", "état demandé", "instances", "mémoire", "disque", "adresses URL") 258 table.Add("app-name", "stopped", "0/1", "1G", "1G", "app-name.example.com") 259 table.PrintTo(outputs) 260 s := strings.Split(outputs.String(), "\n") 261 262 Expect(s).To(ContainSubstrings( 263 []string{"nom état demandé instances mémoire disque adresses URL"}, 264 []string{"app-name stopped 0/1 1G 1G app-name.example.com"}, 265 )) 266 }) 267 }) 268 })