github.com/arunkumar7540/cli@v6.45.0+incompatible/command/flag/path_test.go (about) 1 package flag_test 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 9 . "code.cloudfoundry.org/cli/command/flag" 10 flags "github.com/jessevdk/go-flags" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 ) 14 15 var _ = Describe("path types", func() { 16 var ( 17 currentDir string 18 tempDir string 19 ) 20 21 BeforeEach(func() { 22 var err error 23 currentDir, err = os.Getwd() 24 Expect(err).ToNot(HaveOccurred()) 25 26 tempDir, err = ioutil.TempDir("", "") 27 Expect(err).ToNot(HaveOccurred()) 28 29 err = os.Chdir(tempDir) 30 Expect(err).ToNot(HaveOccurred()) 31 32 for _, filename := range []string{"abc", "abd", "~abd", "tfg", "ABCD"} { 33 err = ioutil.WriteFile(filename, []byte{}, 0400) 34 Expect(err).ToNot(HaveOccurred()) 35 } 36 37 for _, dir := range []string{"~add", "add", "aee"} { 38 err := os.Mkdir(dir, 0700) 39 Expect(err).ToNot(HaveOccurred()) 40 } 41 }) 42 43 AfterEach(func() { 44 err := os.Chdir(currentDir) 45 Expect(err).ToNot(HaveOccurred()) 46 err = os.RemoveAll(tempDir) 47 Expect(err).ToNot(HaveOccurred()) 48 }) 49 50 Describe("Path", func() { 51 var path Path 52 53 Describe("Complete", func() { 54 When("the prefix is empty", func() { 55 It("returns all files and directories", func() { 56 matches := path.Complete("") 57 Expect(matches).To(ConsistOf( 58 flags.Completion{Item: "abc"}, 59 flags.Completion{Item: "abd"}, 60 flags.Completion{Item: fmt.Sprintf("~add%c", os.PathSeparator)}, 61 flags.Completion{Item: "~abd"}, 62 flags.Completion{Item: fmt.Sprintf("add%c", os.PathSeparator)}, 63 flags.Completion{Item: fmt.Sprintf("aee%c", os.PathSeparator)}, 64 flags.Completion{Item: "tfg"}, 65 flags.Completion{Item: "ABCD"}, 66 )) 67 }) 68 }) 69 70 When("the prefix is not empty", func() { 71 When("there are matching paths", func() { 72 It("returns the matching paths", func() { 73 matches := path.Complete("a") 74 Expect(matches).To(ConsistOf( 75 flags.Completion{Item: "abc"}, 76 flags.Completion{Item: "abd"}, 77 flags.Completion{Item: fmt.Sprintf("add%c", os.PathSeparator)}, 78 flags.Completion{Item: fmt.Sprintf("aee%c", os.PathSeparator)}, 79 )) 80 }) 81 82 It("is case sensitive", func() { 83 matches := path.Complete("A") 84 Expect(matches).To(ConsistOf( 85 flags.Completion{Item: "ABCD"}, 86 )) 87 }) 88 89 It("finds files starting with '~'", func() { 90 matches := path.Complete("~") 91 Expect(matches).To(ConsistOf( 92 flags.Completion{Item: "~abd"}, 93 flags.Completion{Item: fmt.Sprintf("~add%c", os.PathSeparator)}, 94 )) 95 }) 96 }) 97 98 When("there are no matching paths", func() { 99 It("returns no matches", func() { 100 Expect(path.Complete("z")).To(BeEmpty()) 101 }) 102 }) 103 }) 104 105 When("the prefix is ~/", func() { 106 var prevHome string 107 108 BeforeEach(func() { 109 prevHome = os.Getenv("HOME") 110 }) 111 112 AfterEach(func() { 113 os.Setenv("HOME", prevHome) 114 }) 115 116 When("$HOME is set", func() { 117 var ( 118 tempDir string 119 err error 120 ) 121 122 BeforeEach(func() { 123 tempDir, err = ioutil.TempDir("", "") 124 Expect(err).ToNot(HaveOccurred()) 125 os.Setenv("HOME", tempDir) 126 127 for _, filename := range []string{"abc", "def"} { 128 err = ioutil.WriteFile(filepath.Join(tempDir, filename), []byte{}, 0400) 129 Expect(err).ToNot(HaveOccurred()) 130 } 131 132 for _, dir := range []string{"adir", "bdir"} { 133 err = os.Mkdir(filepath.Join(tempDir, dir), 0700) 134 Expect(err).ToNot(HaveOccurred()) 135 } 136 }) 137 138 AfterEach(func() { 139 err = os.RemoveAll(tempDir) 140 Expect(err).ToNot(HaveOccurred()) 141 }) 142 143 It("returns matching paths in $HOME", func() { 144 matches := path.Complete(fmt.Sprintf("~%c", os.PathSeparator)) 145 Expect(matches).To(ConsistOf( 146 flags.Completion{Item: fmt.Sprintf("~%cabc", os.PathSeparator)}, 147 flags.Completion{Item: fmt.Sprintf("~%cdef", os.PathSeparator)}, 148 flags.Completion{Item: fmt.Sprintf("~%cadir%c", os.PathSeparator, os.PathSeparator)}, 149 flags.Completion{Item: fmt.Sprintf("~%cbdir%c", os.PathSeparator, os.PathSeparator)}, 150 )) 151 }) 152 }) 153 }) 154 155 When("the prefix starts with ~/", func() { 156 var prevHome string 157 158 BeforeEach(func() { 159 prevHome = os.Getenv("HOME") 160 }) 161 162 AfterEach(func() { 163 os.Setenv("HOME", prevHome) 164 }) 165 166 When("$HOME is set", func() { 167 var ( 168 tempDir string 169 err error 170 ) 171 172 BeforeEach(func() { 173 tempDir, err = ioutil.TempDir("", "") 174 Expect(err).ToNot(HaveOccurred()) 175 os.Setenv("HOME", tempDir) 176 177 for _, filename := range []string{"abc", "def"} { 178 err = ioutil.WriteFile(filepath.Join(tempDir, filename), []byte{}, 0400) 179 Expect(err).ToNot(HaveOccurred()) 180 } 181 182 for _, dir := range []string{"adir", "bdir"} { 183 err = os.Mkdir(filepath.Join(tempDir, dir), 0700) 184 Expect(err).ToNot(HaveOccurred()) 185 } 186 }) 187 188 AfterEach(func() { 189 err = os.RemoveAll(tempDir) 190 Expect(err).ToNot(HaveOccurred()) 191 }) 192 193 It("returns matching paths in $HOME", func() { 194 matches := path.Complete(fmt.Sprintf("~%ca", os.PathSeparator)) 195 Expect(matches).To(ConsistOf( 196 flags.Completion{Item: fmt.Sprintf("~%cabc", os.PathSeparator)}, 197 flags.Completion{Item: fmt.Sprintf("~%cadir%c", os.PathSeparator, os.PathSeparator)}, 198 )) 199 }) 200 }) 201 }) 202 }) 203 }) 204 205 Describe("PathWithExistenceCheck", func() { 206 var pathWithExistenceCheck PathWithExistenceCheck 207 208 BeforeEach(func() { 209 pathWithExistenceCheck = PathWithExistenceCheck("") 210 }) 211 212 // The Complete method is not tested because it shares the same code as 213 // Path.Complete(). 214 215 Describe("UnmarshalFlag", func() { 216 When("the path does not exist", func() { 217 It("returns a path does not exist error", func() { 218 err := pathWithExistenceCheck.UnmarshalFlag("./some-dir/some-file") 219 Expect(err).To(MatchError(&flags.Error{ 220 Type: flags.ErrRequired, 221 Message: "The specified path './some-dir/some-file' does not exist.", 222 })) 223 }) 224 }) 225 226 When("the path exists", func() { 227 It("sets the path", func() { 228 err := pathWithExistenceCheck.UnmarshalFlag("abc") 229 Expect(err).ToNot(HaveOccurred()) 230 Expect(pathWithExistenceCheck).To(BeEquivalentTo("abc")) 231 }) 232 }) 233 }) 234 }) 235 236 Describe("JSONOrFileWithValidation", func() { 237 var jsonOrFile JSONOrFileWithValidation 238 239 BeforeEach(func() { 240 jsonOrFile = JSONOrFileWithValidation(nil) 241 }) 242 243 // The Complete method is not tested because it shares the same code as 244 // Path.Complete(). 245 246 Describe("UnmarshalFlag", func() { 247 When("the file exists", func() { 248 var tempPath string 249 250 When("the file has valid JSON", func() { 251 BeforeEach(func() { 252 tempPath = tempFile(`{"this is":"valid JSON"}`) 253 }) 254 255 It("sets the path", func() { 256 err := jsonOrFile.UnmarshalFlag(tempPath) 257 Expect(err).ToNot(HaveOccurred()) 258 Expect(jsonOrFile).To(BeEquivalentTo(map[string]interface{}{ 259 "this is": "valid JSON", 260 })) 261 }) 262 }) 263 264 When("the file has invalid JSON", func() { 265 BeforeEach(func() { 266 tempPath = tempFile(`{"this is":"invalid JSON"`) 267 }) 268 269 It("errors with the invalid configuration error", func() { 270 err := jsonOrFile.UnmarshalFlag(tempPath) 271 Expect(err).To(Equal(&flags.Error{ 272 Type: flags.ErrRequired, 273 Message: "Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object.", 274 })) 275 }) 276 }) 277 }) 278 279 When("the JSON is invalid", func() { 280 It("errors with the invalid configuration error", func() { 281 err := jsonOrFile.UnmarshalFlag(`{"this is":"invalid JSON"`) 282 Expect(err).To(Equal(&flags.Error{ 283 Type: flags.ErrRequired, 284 Message: "Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object.", 285 })) 286 }) 287 }) 288 289 When("the JSON is valid", func() { 290 It("sets the path", func() { 291 err := jsonOrFile.UnmarshalFlag(`{"this is":"valid JSON"}`) 292 Expect(err).ToNot(HaveOccurred()) 293 Expect(jsonOrFile).To(BeEquivalentTo(map[string]interface{}{ 294 "this is": "valid JSON", 295 })) 296 }) 297 }) 298 }) 299 }) 300 301 Describe("PathWithExistenceCheckOrURL", func() { 302 var pathWithExistenceCheckOrURL PathWithExistenceCheckOrURL 303 304 BeforeEach(func() { 305 pathWithExistenceCheckOrURL = PathWithExistenceCheckOrURL("") 306 }) 307 308 // The Complete method is not tested because it shares the same code as 309 // Path.Complete(). 310 311 Describe("UnmarshalFlag", func() { 312 When("the path is a URL", func() { 313 It("sets the path if it starts with 'http://'", func() { 314 err := pathWithExistenceCheckOrURL.UnmarshalFlag("http://example.com/payload.tgz") 315 Expect(err).ToNot(HaveOccurred()) 316 Expect(pathWithExistenceCheckOrURL).To(BeEquivalentTo("http://example.com/payload.tgz")) 317 }) 318 319 It("sets the path if it starts with 'https://'", func() { 320 err := pathWithExistenceCheckOrURL.UnmarshalFlag("https://example.com/payload.tgz") 321 Expect(err).ToNot(HaveOccurred()) 322 Expect(pathWithExistenceCheckOrURL).To(BeEquivalentTo("https://example.com/payload.tgz")) 323 }) 324 }) 325 326 When("the path does not exist", func() { 327 It("returns a path does not exist error", func() { 328 err := pathWithExistenceCheckOrURL.UnmarshalFlag("./some-dir/some-file") 329 Expect(err).To(MatchError(&flags.Error{ 330 Type: flags.ErrRequired, 331 Message: "The specified path './some-dir/some-file' does not exist.", 332 })) 333 }) 334 }) 335 336 When("the path exists", func() { 337 It("sets the path", func() { 338 err := pathWithExistenceCheckOrURL.UnmarshalFlag("abc") 339 Expect(err).ToNot(HaveOccurred()) 340 Expect(pathWithExistenceCheckOrURL).To(BeEquivalentTo("abc")) 341 }) 342 }) 343 }) 344 }) 345 346 Describe("PathWithAt", func() { 347 var pathWithAt PathWithAt 348 349 Describe("Complete", func() { 350 When("the prefix is empty", func() { 351 It("returns no matches", func() { 352 Expect(pathWithAt.Complete("")).To(BeEmpty()) 353 }) 354 }) 355 356 When("the prefix doesn't start with @", func() { 357 It("returns no matches", func() { 358 Expect(pathWithAt.Complete("a@b")).To(BeEmpty()) 359 }) 360 }) 361 362 When("the prefix starts with @", func() { 363 When("there are no characters after the @", func() { 364 It("returns all files and directories", func() { 365 matches := pathWithAt.Complete("@") 366 Expect(matches).To(ConsistOf( 367 flags.Completion{Item: "@abc"}, 368 flags.Completion{Item: "@abd"}, 369 flags.Completion{Item: fmt.Sprintf("@~add%c", os.PathSeparator)}, 370 flags.Completion{Item: "@~abd"}, 371 flags.Completion{Item: fmt.Sprintf("@add%c", os.PathSeparator)}, 372 flags.Completion{Item: fmt.Sprintf("@aee%c", os.PathSeparator)}, 373 flags.Completion{Item: "@tfg"}, 374 flags.Completion{Item: "@ABCD"}, 375 )) 376 }) 377 }) 378 379 When("there are characters after the @", func() { 380 When("there are matching paths", func() { 381 It("returns the matching paths", func() { 382 matches := pathWithAt.Complete("@a") 383 Expect(matches).To(ConsistOf( 384 flags.Completion{Item: "@abc"}, 385 flags.Completion{Item: "@abd"}, 386 flags.Completion{Item: fmt.Sprintf("@add%c", os.PathSeparator)}, 387 flags.Completion{Item: fmt.Sprintf("@aee%c", os.PathSeparator)}, 388 )) 389 }) 390 391 It("is case sensitive", func() { 392 matches := pathWithAt.Complete("@A") 393 Expect(matches).To(ConsistOf( 394 flags.Completion{Item: "@ABCD"}, 395 )) 396 }) 397 }) 398 399 When("there are no matching paths", func() { 400 It("returns no matches", func() { 401 Expect(pathWithAt.Complete("@z")).To(BeEmpty()) 402 }) 403 }) 404 }) 405 }) 406 407 When("the prefix is @~/", func() { 408 var prevHome string 409 410 BeforeEach(func() { 411 prevHome = os.Getenv("HOME") 412 }) 413 414 AfterEach(func() { 415 os.Setenv("HOME", prevHome) 416 }) 417 418 When("$HOME is set", func() { 419 var ( 420 tempDir string 421 err error 422 ) 423 424 BeforeEach(func() { 425 tempDir, err = ioutil.TempDir("", "") 426 Expect(err).ToNot(HaveOccurred()) 427 os.Setenv("HOME", tempDir) 428 429 for _, filename := range []string{"abc", "def"} { 430 err = ioutil.WriteFile(filepath.Join(tempDir, filename), []byte{}, 0400) 431 Expect(err).ToNot(HaveOccurred()) 432 } 433 434 for _, dir := range []string{"adir", "bdir"} { 435 err = os.Mkdir(filepath.Join(tempDir, dir), 0700) 436 Expect(err).ToNot(HaveOccurred()) 437 } 438 }) 439 440 AfterEach(func() { 441 err = os.RemoveAll(tempDir) 442 Expect(err).ToNot(HaveOccurred()) 443 }) 444 445 It("returns matching paths in $HOME", func() { 446 matches := pathWithAt.Complete(fmt.Sprintf("@~%c", os.PathSeparator)) 447 Expect(matches).To(ConsistOf( 448 flags.Completion{Item: fmt.Sprintf("@~%cabc", os.PathSeparator)}, 449 flags.Completion{Item: fmt.Sprintf("@~%cdef", os.PathSeparator)}, 450 flags.Completion{Item: fmt.Sprintf("@~%cadir%c", os.PathSeparator, os.PathSeparator)}, 451 flags.Completion{Item: fmt.Sprintf("@~%cbdir%c", os.PathSeparator, os.PathSeparator)}, 452 )) 453 }) 454 }) 455 }) 456 457 When("the prefix starts with @~/", func() { 458 var prevHome string 459 460 BeforeEach(func() { 461 prevHome = os.Getenv("HOME") 462 }) 463 464 AfterEach(func() { 465 os.Setenv("HOME", prevHome) 466 }) 467 468 When("$HOME is set", func() { 469 var ( 470 tempDir string 471 err error 472 ) 473 474 BeforeEach(func() { 475 tempDir, err = ioutil.TempDir("", "") 476 Expect(err).ToNot(HaveOccurred()) 477 os.Setenv("HOME", tempDir) 478 479 for _, filename := range []string{"abc", "def"} { 480 err = ioutil.WriteFile(filepath.Join(tempDir, filename), []byte{}, 0400) 481 Expect(err).ToNot(HaveOccurred()) 482 } 483 484 for _, dir := range []string{"adir", "bdir"} { 485 err = os.Mkdir(filepath.Join(tempDir, dir), 0700) 486 Expect(err).ToNot(HaveOccurred()) 487 } 488 }) 489 490 AfterEach(func() { 491 err = os.RemoveAll(tempDir) 492 Expect(err).ToNot(HaveOccurred()) 493 }) 494 495 It("returns matching paths in $HOME", func() { 496 matches := pathWithAt.Complete(fmt.Sprintf("@~%ca", os.PathSeparator)) 497 Expect(matches).To(ConsistOf( 498 flags.Completion{Item: fmt.Sprintf("@~%cabc", os.PathSeparator)}, 499 flags.Completion{Item: fmt.Sprintf("@~%cadir%c", os.PathSeparator, os.PathSeparator)}, 500 )) 501 }) 502 }) 503 }) 504 }) 505 }) 506 507 Describe("PathWithBool", func() { 508 var pathWithBool PathWithBool 509 510 Describe("Complete", func() { 511 When("the prefix is empty", func() { 512 It("returns bool choices and all files and directories", func() { 513 matches := pathWithBool.Complete("") 514 Expect(matches).To(ConsistOf( 515 flags.Completion{Item: "true"}, 516 flags.Completion{Item: "false"}, 517 flags.Completion{Item: "abc"}, 518 flags.Completion{Item: "abd"}, 519 flags.Completion{Item: fmt.Sprintf("add%c", os.PathSeparator)}, 520 flags.Completion{Item: "~abd"}, 521 flags.Completion{Item: fmt.Sprintf("~add%c", os.PathSeparator)}, 522 flags.Completion{Item: fmt.Sprintf("aee%c", os.PathSeparator)}, 523 flags.Completion{Item: "tfg"}, 524 flags.Completion{Item: "ABCD"}, 525 )) 526 }) 527 }) 528 529 When("the prefix is not empty", func() { 530 When("there are matching bool/paths", func() { 531 It("returns the matching bool/paths", func() { 532 matches := pathWithBool.Complete("t") 533 Expect(matches).To(ConsistOf( 534 flags.Completion{Item: "true"}, 535 flags.Completion{Item: "tfg"}, 536 )) 537 }) 538 539 It("paths are case sensitive", func() { 540 matches := pathWithBool.Complete("A") 541 Expect(matches).To(ConsistOf( 542 flags.Completion{Item: "ABCD"}, 543 )) 544 }) 545 546 It("bools are not case sensitive", func() { 547 matches := pathWithBool.Complete("Tr") 548 Expect(matches).To(ConsistOf( 549 flags.Completion{Item: "true"}, 550 )) 551 }) 552 }) 553 554 When("there are no matching bool/paths", func() { 555 It("returns no matches", func() { 556 Expect(pathWithBool.Complete("z")).To(BeEmpty()) 557 }) 558 }) 559 }) 560 }) 561 }) 562 })