1namespace ts { 2 const caseInsensitiveBasePath = "c:/dev/"; 3 const caseInsensitiveTsconfigPath = "c:/dev/tsconfig.json"; 4 const caseInsensitiveHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: { 5 "c:/dev/a.ts": "", 6 "c:/dev/a.d.ts": "", 7 "c:/dev/a.js": "", 8 "c:/dev/b.ts": "", 9 "c:/dev/b.js": "", 10 "c:/dev/c.d.ts": "", 11 "c:/dev/z/a.ts": "", 12 "c:/dev/z/abz.ts": "", 13 "c:/dev/z/aba.ts": "", 14 "c:/dev/z/b.ts": "", 15 "c:/dev/z/bbz.ts": "", 16 "c:/dev/z/bba.ts": "", 17 "c:/dev/x/a.ts": "", 18 "c:/dev/x/aa.ts": "", 19 "c:/dev/x/b.ts": "", 20 "c:/dev/x/y/a.ts": "", 21 "c:/dev/x/y/b.ts": "", 22 "c:/dev/js/a.js": "", 23 "c:/dev/js/b.js": "", 24 "c:/dev/js/d.min.js": "", 25 "c:/dev/js/ab.min.js": "", 26 "c:/ext/ext.ts": "", 27 "c:/ext/b/a..b.ts": "", 28 }})); 29 30 const caseSensitiveBasePath = "/dev/"; 31 const caseSensitiveHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: caseSensitiveBasePath, files: { 32 "/dev/a.ts": "", 33 "/dev/a.d.ts": "", 34 "/dev/a.js": "", 35 "/dev/b.ts": "", 36 "/dev/b.js": "", 37 "/dev/A.ts": "", 38 "/dev/B.ts": "", 39 "/dev/c.d.ts": "", 40 "/dev/z/a.ts": "", 41 "/dev/z/abz.ts": "", 42 "/dev/z/aba.ts": "", 43 "/dev/z/b.ts": "", 44 "/dev/z/bbz.ts": "", 45 "/dev/z/bba.ts": "", 46 "/dev/x/a.ts": "", 47 "/dev/x/b.ts": "", 48 "/dev/x/y/a.ts": "", 49 "/dev/x/y/b.ts": "", 50 "/dev/q/a/c/b/d.ts": "", 51 "/dev/js/a.js": "", 52 "/dev/js/b.js": "", 53 }})); 54 55 const caseInsensitiveMixedExtensionHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: { 56 "c:/dev/a.ts": "", 57 "c:/dev/a.d.ts": "", 58 "c:/dev/a.js": "", 59 "c:/dev/b.tsx": "", 60 "c:/dev/b.d.ts": "", 61 "c:/dev/b.jsx": "", 62 "c:/dev/c.tsx": "", 63 "c:/dev/c.js": "", 64 "c:/dev/d.js": "", 65 "c:/dev/e.jsx": "", 66 "c:/dev/f.other": "", 67 }})); 68 69 const caseInsensitiveCommonFoldersHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: { 70 "c:/dev/a.ts": "", 71 "c:/dev/a.d.ts": "", 72 "c:/dev/a.js": "", 73 "c:/dev/b.ts": "", 74 "c:/dev/x/a.ts": "", 75 "c:/dev/node_modules/a.ts": "", 76 "c:/dev/bower_components/a.ts": "", 77 "c:/dev/jspm_packages/a.ts": "", 78 }})); 79 80 const caseInsensitiveDottedFoldersHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: { 81 "c:/dev/x/d.ts": "", 82 "c:/dev/x/y/d.ts": "", 83 "c:/dev/x/y/.e.ts": "", 84 "c:/dev/x/.y/a.ts": "", 85 "c:/dev/.z/.b.ts": "", 86 "c:/dev/.z/c.ts": "", 87 "c:/dev/w/.u/e.ts": "", 88 "c:/dev/g.min.js/.g/g.ts": "", 89 }})); 90 91 const caseInsensitiveOrderingDiffersWithCaseHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: { 92 "c:/dev/xylophone.ts": "", 93 "c:/dev/Yosemite.ts": "", 94 "c:/dev/zebra.ts": "", 95 }})); 96 97 const caseSensitiveOrderingDiffersWithCaseHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: caseSensitiveBasePath, files: { 98 "/dev/xylophone.ts": "", 99 "/dev/Yosemite.ts": "", 100 "/dev/zebra.ts": "", 101 }})); 102 103 function assertParsed(actual: ParsedCommandLine, expected: ParsedCommandLine): void { 104 assert.deepEqual(actual.fileNames, expected.fileNames); 105 assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories); 106 assert.deepEqual(actual.errors, expected.errors); 107 } 108 109 function validateMatches(expected: ParsedCommandLine, json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]) { 110 { 111 const jsonText = JSON.stringify(json); 112 const result = parseJsonText(caseInsensitiveTsconfigPath, jsonText); 113 const actual = parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack); 114 for (const error of expected.errors) { 115 if (error.file) { 116 error.file = result; 117 } 118 } 119 assertParsed(actual, expected); 120 } 121 { 122 const actual = parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack); 123 expected.errors = expected.errors.map((error): Diagnostic => ({ 124 category: error.category, 125 code: error.code, 126 file: undefined, 127 length: undefined, 128 messageText: error.messageText, 129 start: undefined, 130 reportsUnnecessary: undefined, 131 reportsDeprecated: undefined 132 })); 133 assertParsed(actual, expected); 134 } 135 } 136 137 function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: DiagnosticMessage, arg0: string) { 138 const text = JSON.stringify(json); 139 const file = { 140 fileName: caseInsensitiveTsconfigPath, 141 kind: SyntaxKind.SourceFile, 142 text 143 } as SourceFile; 144 return createFileDiagnostic(file, start, length, diagnosticMessage, arg0); 145 } 146 147 describe("unittests:: config:: matchFiles", () => { 148 it("with defaults", () => { 149 const json = {}; 150 const expected: ParsedCommandLine = { 151 options: {}, 152 errors: [], 153 fileNames: [ 154 "c:/dev/a.ts", 155 "c:/dev/b.ts", 156 "c:/dev/x/a.ts" 157 ], 158 wildcardDirectories: { 159 "c:/dev": WatchDirectoryFlags.Recursive 160 }, 161 }; 162 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 163 }); 164 165 describe("with literal file list", () => { 166 it("without exclusions", () => { 167 const json = { 168 files: [ 169 "a.ts", 170 "b.ts" 171 ] 172 }; 173 const expected: ParsedCommandLine = { 174 options: {}, 175 errors: [], 176 fileNames: [ 177 "c:/dev/a.ts", 178 "c:/dev/b.ts" 179 ], 180 wildcardDirectories: {}, 181 }; 182 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 183 }); 184 it("missing files are still present", () => { 185 const json = { 186 files: [ 187 "z.ts", 188 "x.ts" 189 ] 190 }; 191 const expected: ParsedCommandLine = { 192 options: {}, 193 errors: [], 194 fileNames: [ 195 "c:/dev/z.ts", 196 "c:/dev/x.ts" 197 ], 198 wildcardDirectories: {}, 199 }; 200 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 201 }); 202 it("are not removed due to excludes", () => { 203 const json = { 204 files: [ 205 "a.ts", 206 "b.ts" 207 ], 208 exclude: [ 209 "b.ts" 210 ] 211 }; 212 const expected: ParsedCommandLine = { 213 options: {}, 214 errors: [], 215 fileNames: [ 216 "c:/dev/a.ts", 217 "c:/dev/b.ts" 218 ], 219 wildcardDirectories: {}, 220 }; 221 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 222 }); 223 }); 224 225 describe("with literal include list", () => { 226 it("without exclusions", () => { 227 const json = { 228 include: [ 229 "a.ts", 230 "b.ts" 231 ] 232 }; 233 const expected: ParsedCommandLine = { 234 options: {}, 235 errors: [], 236 fileNames: [ 237 "c:/dev/a.ts", 238 "c:/dev/b.ts" 239 ], 240 wildcardDirectories: {}, 241 }; 242 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 243 }); 244 it("with non .ts file extensions are excluded", () => { 245 const json = { 246 include: [ 247 "a.js", 248 "b.js" 249 ] 250 }; 251 const expected: ParsedCommandLine = { 252 options: {}, 253 errors: [ 254 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 255 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 256 ], 257 fileNames: [], 258 wildcardDirectories: {}, 259 }; 260 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 261 }); 262 it("with missing files are excluded", () => { 263 const json = { 264 include: [ 265 "z.ts", 266 "x.ts" 267 ] 268 }; 269 const expected: ParsedCommandLine = { 270 options: {}, 271 errors: [ 272 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 273 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 274 ], 275 fileNames: [], 276 wildcardDirectories: {}, 277 }; 278 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 279 }); 280 it("with literal excludes", () => { 281 const json = { 282 include: [ 283 "a.ts", 284 "b.ts" 285 ], 286 exclude: [ 287 "b.ts" 288 ] 289 }; 290 const expected: ParsedCommandLine = { 291 options: {}, 292 errors: [], 293 fileNames: [ 294 "c:/dev/a.ts" 295 ], 296 wildcardDirectories: {}, 297 }; 298 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 299 }); 300 it("with wildcard excludes", () => { 301 const json = { 302 include: [ 303 "a.ts", 304 "b.ts", 305 "z/a.ts", 306 "z/abz.ts", 307 "z/aba.ts", 308 "x/b.ts" 309 ], 310 exclude: [ 311 "*.ts", 312 "z/??z.ts", 313 "*/b.ts" 314 ] 315 }; 316 const expected: ParsedCommandLine = { 317 options: {}, 318 errors: [], 319 fileNames: [ 320 "c:/dev/z/a.ts", 321 "c:/dev/z/aba.ts" 322 ], 323 wildcardDirectories: {}, 324 }; 325 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 326 }); 327 it("with recursive excludes", () => { 328 const json = { 329 include: [ 330 "a.ts", 331 "b.ts", 332 "x/a.ts", 333 "x/b.ts", 334 "x/y/a.ts", 335 "x/y/b.ts" 336 ], 337 exclude: [ 338 "**/b.ts" 339 ] 340 }; 341 const expected: ParsedCommandLine = { 342 options: {}, 343 errors: [], 344 fileNames: [ 345 "c:/dev/a.ts", 346 "c:/dev/x/a.ts", 347 "c:/dev/x/y/a.ts" 348 ], 349 wildcardDirectories: {}, 350 }; 351 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 352 }); 353 it("with case sensitive exclude", () => { 354 const json = { 355 include: [ 356 "B.ts" 357 ], 358 exclude: [ 359 "**/b.ts" 360 ] 361 }; 362 const expected: ParsedCommandLine = { 363 options: {}, 364 errors: [], 365 fileNames: [ 366 "/dev/B.ts" 367 ], 368 wildcardDirectories: {}, 369 }; 370 validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); 371 }); 372 it("with common package folders and no exclusions", () => { 373 const json = { 374 include: [ 375 "a.ts", 376 "b.ts", 377 "node_modules/a.ts", 378 "bower_components/a.ts", 379 "jspm_packages/a.ts" 380 ] 381 }; 382 const expected: ParsedCommandLine = { 383 options: {}, 384 errors: [], 385 fileNames: [ 386 "c:/dev/a.ts", 387 "c:/dev/b.ts", 388 "c:/dev/node_modules/a.ts", 389 "c:/dev/bower_components/a.ts", 390 "c:/dev/jspm_packages/a.ts" 391 ], 392 wildcardDirectories: {}, 393 }; 394 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 395 }); 396 it("with common package folders and exclusions", () => { 397 const json = { 398 include: [ 399 "a.ts", 400 "b.ts", 401 "node_modules/a.ts", 402 "bower_components/a.ts", 403 "jspm_packages/a.ts" 404 ], 405 exclude: [ 406 "a.ts", 407 "b.ts" 408 ] 409 }; 410 const expected: ParsedCommandLine = { 411 options: {}, 412 errors: [], 413 fileNames: [ 414 "c:/dev/node_modules/a.ts", 415 "c:/dev/bower_components/a.ts", 416 "c:/dev/jspm_packages/a.ts" 417 ], 418 wildcardDirectories: {}, 419 }; 420 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 421 }); 422 it("with common package folders and empty exclude", () => { 423 const json = { 424 include: [ 425 "a.ts", 426 "b.ts", 427 "node_modules/a.ts", 428 "bower_components/a.ts", 429 "jspm_packages/a.ts" 430 ] 431 }; 432 const expected: ParsedCommandLine = { 433 options: {}, 434 errors: [], 435 fileNames: [ 436 "c:/dev/a.ts", 437 "c:/dev/b.ts", 438 "c:/dev/node_modules/a.ts", 439 "c:/dev/bower_components/a.ts", 440 "c:/dev/jspm_packages/a.ts" 441 ], 442 wildcardDirectories: {}, 443 }; 444 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 445 }); 446 }); 447 448 describe("with wildcard include list", () => { 449 it("is sorted in include order, then in alphabetical order", () => { 450 const json = { 451 include: [ 452 "z/*.ts", 453 "x/*.ts" 454 ] 455 }; 456 const expected: ParsedCommandLine = { 457 options: {}, 458 errors: [], 459 fileNames: [ 460 "c:/dev/z/a.ts", 461 "c:/dev/z/aba.ts", 462 "c:/dev/z/abz.ts", 463 "c:/dev/z/b.ts", 464 "c:/dev/z/bba.ts", 465 "c:/dev/z/bbz.ts", 466 "c:/dev/x/a.ts", 467 "c:/dev/x/aa.ts", 468 "c:/dev/x/b.ts" 469 ], 470 wildcardDirectories: { 471 "c:/dev/z": WatchDirectoryFlags.None, 472 "c:/dev/x": WatchDirectoryFlags.None 473 }, 474 }; 475 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 476 }); 477 it("same named declarations are excluded", () => { 478 const json = { 479 include: [ 480 "*.ts" 481 ] 482 }; 483 const expected: ParsedCommandLine = { 484 options: {}, 485 errors: [], 486 fileNames: [ 487 "c:/dev/a.ts", 488 "c:/dev/b.ts", 489 "c:/dev/c.d.ts" 490 ], 491 wildcardDirectories: { 492 "c:/dev": WatchDirectoryFlags.None 493 }, 494 }; 495 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 496 }); 497 it("`*` matches only ts files", () => { 498 const json = { 499 include: [ 500 "*" 501 ] 502 }; 503 const expected: ParsedCommandLine = { 504 options: {}, 505 errors: [], 506 fileNames: [ 507 "c:/dev/a.ts", 508 "c:/dev/b.ts", 509 "c:/dev/c.d.ts" 510 ], 511 wildcardDirectories: { 512 "c:/dev": WatchDirectoryFlags.None 513 }, 514 }; 515 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 516 }); 517 it("`?` matches only a single character", () => { 518 const json = { 519 include: [ 520 "x/?.ts" 521 ] 522 }; 523 const expected: ParsedCommandLine = { 524 options: {}, 525 errors: [], 526 fileNames: [ 527 "c:/dev/x/a.ts", 528 "c:/dev/x/b.ts" 529 ], 530 wildcardDirectories: { 531 "c:/dev/x": WatchDirectoryFlags.None 532 }, 533 }; 534 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 535 }); 536 it("with recursive directory", () => { 537 const json = { 538 include: [ 539 "**/a.ts" 540 ] 541 }; 542 const expected: ParsedCommandLine = { 543 options: {}, 544 errors: [], 545 fileNames: [ 546 "c:/dev/a.ts", 547 "c:/dev/x/a.ts", 548 "c:/dev/x/y/a.ts", 549 "c:/dev/z/a.ts" 550 ], 551 wildcardDirectories: { 552 "c:/dev": WatchDirectoryFlags.Recursive 553 }, 554 }; 555 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 556 }); 557 it("with multiple recursive directories", () => { 558 const json = { 559 include: [ 560 "x/y/**/a.ts", 561 "x/**/a.ts", 562 "z/**/a.ts" 563 ] 564 }; 565 const expected: ParsedCommandLine = { 566 options: {}, 567 errors: [], 568 fileNames: [ 569 "c:/dev/x/y/a.ts", 570 "c:/dev/x/a.ts", 571 "c:/dev/z/a.ts" 572 ], 573 wildcardDirectories: { 574 "c:/dev/x": WatchDirectoryFlags.Recursive, 575 "c:/dev/z": WatchDirectoryFlags.Recursive 576 }, 577 }; 578 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 579 }); 580 it("case sensitive", () => { 581 const json = { 582 include: [ 583 "**/A.ts" 584 ] 585 }; 586 const expected: ParsedCommandLine = { 587 options: {}, 588 errors: [], 589 fileNames: [ 590 "/dev/A.ts" 591 ], 592 wildcardDirectories: { 593 "/dev": WatchDirectoryFlags.Recursive 594 }, 595 }; 596 validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); 597 }); 598 it("with missing files are excluded", () => { 599 const json = { 600 include: [ 601 "*/z.ts" 602 ] 603 }; 604 const expected: ParsedCommandLine = { 605 options: {}, 606 errors: [ 607 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 608 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 609 ], 610 fileNames: [], 611 wildcardDirectories: { 612 "c:/dev": WatchDirectoryFlags.Recursive 613 }, 614 }; 615 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 616 }); 617 it("always include literal files", () => { 618 const json = { 619 files: [ 620 "a.ts" 621 ], 622 include: [ 623 "*/z.ts" 624 ], 625 exclude: [ 626 "**/a.ts" 627 ] 628 }; 629 const expected: ParsedCommandLine = { 630 options: {}, 631 errors: [], 632 fileNames: [ 633 "c:/dev/a.ts" 634 ], 635 wildcardDirectories: { 636 "c:/dev": WatchDirectoryFlags.Recursive 637 }, 638 }; 639 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 640 }); 641 it("exclude folders", () => { 642 const json = { 643 include: [ 644 "**/*" 645 ], 646 exclude: [ 647 "z", 648 "x" 649 ] 650 }; 651 const expected: ParsedCommandLine = { 652 options: {}, 653 errors: [], 654 fileNames: [ 655 "c:/dev/a.ts", 656 "c:/dev/b.ts", 657 "c:/dev/c.d.ts" 658 ], 659 wildcardDirectories: { 660 "c:/dev": WatchDirectoryFlags.Recursive 661 } 662 }; 663 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 664 }); 665 describe("with common package folders", () => { 666 it("and no exclusions", () => { 667 const json = { 668 include: [ 669 "**/a.ts" 670 ] 671 }; 672 const expected: ParsedCommandLine = { 673 options: {}, 674 errors: [], 675 fileNames: [ 676 "c:/dev/a.ts", 677 "c:/dev/x/a.ts" 678 ], 679 wildcardDirectories: { 680 "c:/dev": WatchDirectoryFlags.Recursive 681 }, 682 }; 683 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 684 }); 685 it("and exclusions", () => { 686 const json = { 687 include: [ 688 "**/?.ts" 689 ], 690 exclude: [ 691 "a.ts" 692 ] 693 }; 694 const expected: ParsedCommandLine = { 695 options: {}, 696 errors: [], 697 fileNames: [ 698 "c:/dev/b.ts", 699 "c:/dev/x/a.ts" 700 ], 701 wildcardDirectories: { 702 "c:/dev": WatchDirectoryFlags.Recursive 703 }, 704 }; 705 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 706 }); 707 it("and empty exclude", () => { 708 const json = { 709 include: [ 710 "**/a.ts" 711 ], 712 exclude: [] as string[] 713 }; 714 const expected: ParsedCommandLine = { 715 options: {}, 716 errors: [], 717 fileNames: [ 718 "c:/dev/a.ts", 719 "c:/dev/x/a.ts" 720 ], 721 wildcardDirectories: { 722 "c:/dev": WatchDirectoryFlags.Recursive 723 }, 724 }; 725 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 726 }); 727 it("and explicit recursive include", () => { 728 const json = { 729 include: [ 730 "**/a.ts", 731 "**/node_modules/a.ts" 732 ] 733 }; 734 const expected: ParsedCommandLine = { 735 options: {}, 736 errors: [], 737 fileNames: [ 738 "c:/dev/a.ts", 739 "c:/dev/x/a.ts", 740 "c:/dev/node_modules/a.ts" 741 ], 742 wildcardDirectories: { 743 "c:/dev": WatchDirectoryFlags.Recursive 744 }, 745 }; 746 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 747 }); 748 it("and wildcard include", () => { 749 const json = { 750 include: [ 751 "*/a.ts" 752 ] 753 }; 754 const expected: ParsedCommandLine = { 755 options: {}, 756 errors: [], 757 fileNames: [ 758 "c:/dev/x/a.ts" 759 ], 760 wildcardDirectories: { 761 "c:/dev": WatchDirectoryFlags.Recursive 762 }, 763 }; 764 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 765 }); 766 it("and explicit wildcard include", () => { 767 const json = { 768 include: [ 769 "*/a.ts", 770 "node_modules/a.ts" 771 ] 772 }; 773 const expected: ParsedCommandLine = { 774 options: {}, 775 errors: [], 776 fileNames: [ 777 "c:/dev/x/a.ts", 778 "c:/dev/node_modules/a.ts" 779 ], 780 wildcardDirectories: { 781 "c:/dev": WatchDirectoryFlags.Recursive 782 }, 783 }; 784 validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath); 785 }); 786 }); 787 it("exclude .js files when allowJs=false", () => { 788 const json = { 789 compilerOptions: { 790 allowJs: false 791 }, 792 include: [ 793 "js/*" 794 ] 795 }; 796 const expected: ParsedCommandLine = { 797 options: { 798 allowJs: false 799 }, 800 errors: [ 801 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 802 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 803 ], 804 fileNames: [], 805 wildcardDirectories: { 806 "c:/dev/js": WatchDirectoryFlags.None 807 } 808 }; 809 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 810 }); 811 it("include .js files when allowJs=true", () => { 812 const json = { 813 compilerOptions: { 814 allowJs: true 815 }, 816 include: [ 817 "js/*" 818 ] 819 }; 820 const expected: ParsedCommandLine = { 821 options: { 822 allowJs: true 823 }, 824 errors: [], 825 fileNames: [ 826 "c:/dev/js/a.js", 827 "c:/dev/js/b.js" 828 ], 829 wildcardDirectories: { 830 "c:/dev/js": WatchDirectoryFlags.None 831 } 832 }; 833 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 834 }); 835 it("include explicitly listed .min.js files when allowJs=true", () => { 836 const json = { 837 compilerOptions: { 838 allowJs: true 839 }, 840 include: [ 841 "js/*.min.js" 842 ] 843 }; 844 const expected: ParsedCommandLine = { 845 options: { 846 allowJs: true 847 }, 848 errors: [], 849 fileNames: [ 850 "c:/dev/js/ab.min.js", 851 "c:/dev/js/d.min.js" 852 ], 853 wildcardDirectories: { 854 "c:/dev/js": WatchDirectoryFlags.None 855 } 856 }; 857 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 858 }); 859 it("include paths outside of the project", () => { 860 const json = { 861 include: [ 862 "*", 863 "c:/ext/*" 864 ] 865 }; 866 const expected: ParsedCommandLine = { 867 options: {}, 868 errors: [], 869 fileNames: [ 870 "c:/dev/a.ts", 871 "c:/dev/b.ts", 872 "c:/dev/c.d.ts", 873 "c:/ext/ext.ts" 874 ], 875 wildcardDirectories: { 876 "c:/dev": WatchDirectoryFlags.None, 877 "c:/ext": WatchDirectoryFlags.None 878 } 879 }; 880 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 881 }); 882 it("include paths outside of the project using relative paths", () => { 883 const json = { 884 include: [ 885 "*", 886 "../ext/*" 887 ], 888 exclude: [ 889 "**" 890 ] 891 }; 892 const expected: ParsedCommandLine = { 893 options: {}, 894 errors: [], 895 fileNames: [ 896 "c:/ext/ext.ts" 897 ], 898 wildcardDirectories: { 899 "c:/ext": WatchDirectoryFlags.None 900 } 901 }; 902 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 903 }); 904 it("exclude paths outside of the project using relative paths", () => { 905 const json = { 906 include: [ 907 "c:/**/*" 908 ], 909 exclude: [ 910 "../**" 911 ] 912 }; 913 const expected: ParsedCommandLine = { 914 options: {}, 915 errors: [ 916 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 917 caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))] 918 , 919 fileNames: [], 920 wildcardDirectories: {} 921 }; 922 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 923 }); 924 it("include files with .. in their name", () => { 925 const json = { 926 include: [ 927 "c:/ext/b/a..b.ts" 928 ], 929 exclude: [ 930 "**" 931 ] 932 }; 933 const expected: ParsedCommandLine = { 934 options: {}, 935 errors: [], 936 fileNames: [ 937 "c:/ext/b/a..b.ts" 938 ], 939 wildcardDirectories: {} 940 }; 941 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 942 }); 943 it("exclude files with .. in their name", () => { 944 const json = { 945 include: [ 946 "c:/ext/**/*" 947 ], 948 exclude: [ 949 "c:/ext/b/a..b.ts" 950 ] 951 }; 952 const expected: ParsedCommandLine = { 953 options: {}, 954 errors: [], 955 fileNames: [ 956 "c:/ext/ext.ts", 957 ], 958 wildcardDirectories: { 959 "c:/ext": WatchDirectoryFlags.Recursive 960 } 961 }; 962 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 963 }); 964 it("with jsx=none, allowJs=false", () => { 965 const json = { 966 compilerOptions: { 967 allowJs: false 968 } 969 }; 970 const expected: ParsedCommandLine = { 971 options: { 972 allowJs: false 973 }, 974 errors: [], 975 fileNames: [ 976 "c:/dev/a.ts", 977 "c:/dev/b.tsx", 978 "c:/dev/c.tsx", 979 ], 980 wildcardDirectories: { 981 "c:/dev": WatchDirectoryFlags.Recursive 982 } 983 }; 984 validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); 985 }); 986 it("with jsx=preserve, allowJs=false", () => { 987 const json = { 988 compilerOptions: { 989 jsx: "preserve", 990 allowJs: false 991 } 992 }; 993 const expected: ParsedCommandLine = { 994 options: { 995 jsx: JsxEmit.Preserve, 996 allowJs: false 997 }, 998 errors: [], 999 fileNames: [ 1000 "c:/dev/a.ts", 1001 "c:/dev/b.tsx", 1002 "c:/dev/c.tsx", 1003 ], 1004 wildcardDirectories: { 1005 "c:/dev": WatchDirectoryFlags.Recursive 1006 } 1007 }; 1008 validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); 1009 }); 1010 it("with jsx=react-native, allowJs=false", () => { 1011 const json = { 1012 compilerOptions: { 1013 jsx: "react-native", 1014 allowJs: false 1015 } 1016 }; 1017 const expected: ParsedCommandLine = { 1018 options: { 1019 jsx: JsxEmit.ReactNative, 1020 allowJs: false 1021 }, 1022 errors: [], 1023 fileNames: [ 1024 "c:/dev/a.ts", 1025 "c:/dev/b.tsx", 1026 "c:/dev/c.tsx", 1027 ], 1028 wildcardDirectories: { 1029 "c:/dev": WatchDirectoryFlags.Recursive 1030 } 1031 }; 1032 validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); 1033 }); 1034 it("with jsx=none, allowJs=true", () => { 1035 const json = { 1036 compilerOptions: { 1037 allowJs: true 1038 } 1039 }; 1040 const expected: ParsedCommandLine = { 1041 options: { 1042 allowJs: true 1043 }, 1044 errors: [], 1045 fileNames: [ 1046 "c:/dev/a.ts", 1047 "c:/dev/b.tsx", 1048 "c:/dev/c.tsx", 1049 "c:/dev/d.js", 1050 "c:/dev/e.jsx", 1051 ], 1052 wildcardDirectories: { 1053 "c:/dev": WatchDirectoryFlags.Recursive 1054 } 1055 }; 1056 validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); 1057 }); 1058 it("with jsx=preserve, allowJs=true", () => { 1059 const json = { 1060 compilerOptions: { 1061 jsx: "preserve", 1062 allowJs: true 1063 } 1064 }; 1065 const expected: ParsedCommandLine = { 1066 options: { 1067 jsx: JsxEmit.Preserve, 1068 allowJs: true 1069 }, 1070 errors: [], 1071 fileNames: [ 1072 "c:/dev/a.ts", 1073 "c:/dev/b.tsx", 1074 "c:/dev/c.tsx", 1075 "c:/dev/d.js", 1076 "c:/dev/e.jsx", 1077 ], 1078 wildcardDirectories: { 1079 "c:/dev": WatchDirectoryFlags.Recursive 1080 } 1081 }; 1082 validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); 1083 }); 1084 it("with jsx=react-native, allowJs=true", () => { 1085 const json = { 1086 compilerOptions: { 1087 jsx: "react-native", 1088 allowJs: true 1089 } 1090 }; 1091 const expected: ParsedCommandLine = { 1092 options: { 1093 jsx: JsxEmit.ReactNative, 1094 allowJs: true 1095 }, 1096 errors: [], 1097 fileNames: [ 1098 "c:/dev/a.ts", 1099 "c:/dev/b.tsx", 1100 "c:/dev/c.tsx", 1101 "c:/dev/d.js", 1102 "c:/dev/e.jsx", 1103 ], 1104 wildcardDirectories: { 1105 "c:/dev": WatchDirectoryFlags.Recursive 1106 } 1107 }; 1108 validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath); 1109 }); 1110 it("exclude .min.js files using wildcards", () => { 1111 const json = { 1112 compilerOptions: { 1113 allowJs: true 1114 }, 1115 include: [ 1116 "js/*.min.js" 1117 ], 1118 exclude: [ 1119 "js/a*" 1120 ] 1121 }; 1122 const expected: ParsedCommandLine = { 1123 options: { 1124 allowJs: true 1125 }, 1126 errors: [], 1127 fileNames: [ 1128 "c:/dev/js/d.min.js" 1129 ], 1130 wildcardDirectories: { 1131 "c:/dev/js": WatchDirectoryFlags.None 1132 } 1133 }; 1134 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 1135 }); 1136 1137 describe("with trailing recursive directory", () => { 1138 it("in includes", () => { 1139 const json = { 1140 include: [ 1141 "**" 1142 ] 1143 }; 1144 const expected: ParsedCommandLine = { 1145 options: {}, 1146 errors: [ 1147 createDiagnosticForConfigFile(json, 12, 4, Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"), 1148 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 1149 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 1150 ], 1151 fileNames: [], 1152 wildcardDirectories: {} 1153 }; 1154 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 1155 }); 1156 it("in excludes", () => { 1157 const json = { 1158 include: [ 1159 "**/*" 1160 ], 1161 exclude: [ 1162 "**" 1163 ] 1164 }; 1165 const expected: ParsedCommandLine = { 1166 options: {}, 1167 errors: [ 1168 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 1169 caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) 1170 ], 1171 fileNames: [], 1172 wildcardDirectories: {} 1173 }; 1174 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 1175 }); 1176 }); 1177 describe("with multiple recursive directory patterns", () => { 1178 it("in includes", () => { 1179 const json = { 1180 include: [ 1181 "**/x/**/*" 1182 ] 1183 }; 1184 const expected: ParsedCommandLine = { 1185 options: {}, 1186 errors: [], 1187 fileNames: [ 1188 "c:/dev/x/a.ts", 1189 "c:/dev/x/aa.ts", 1190 "c:/dev/x/b.ts", 1191 "c:/dev/x/y/a.ts", 1192 "c:/dev/x/y/b.ts", 1193 ], 1194 wildcardDirectories: { 1195 "c:/dev": WatchDirectoryFlags.Recursive 1196 } 1197 }; 1198 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 1199 }); 1200 it("in excludes", () => { 1201 const json = { 1202 include: [ 1203 "**/a.ts" 1204 ], 1205 exclude: [ 1206 "**/x/**" 1207 ] 1208 }; 1209 const expected: ParsedCommandLine = { 1210 options: {}, 1211 errors: [], 1212 fileNames: [ 1213 "c:/dev/a.ts", 1214 "c:/dev/z/a.ts" 1215 ], 1216 wildcardDirectories: { 1217 "c:/dev": WatchDirectoryFlags.Recursive 1218 } 1219 }; 1220 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 1221 }); 1222 }); 1223 1224 describe("with parent directory symbols after a recursive directory pattern", () => { 1225 it("in includes immediately after", () => { 1226 const json = { 1227 include: [ 1228 "**/../*" 1229 ] 1230 }; 1231 const expected: ParsedCommandLine = { 1232 options: {}, 1233 errors: [ 1234 createDiagnosticForConfigFile(json, 12, 9, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"), 1235 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 1236 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 1237 ], 1238 fileNames: [], 1239 wildcardDirectories: {} 1240 }; 1241 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 1242 }); 1243 1244 it("in includes after a subdirectory", () => { 1245 const json = { 1246 include: [ 1247 "**/y/../*" 1248 ] 1249 }; 1250 const expected: ParsedCommandLine = { 1251 options: {}, 1252 errors: [ 1253 createDiagnosticForConfigFile(json, 12, 11, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"), 1254 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 1255 caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]") 1256 ], 1257 fileNames: [], 1258 wildcardDirectories: {} 1259 }; 1260 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 1261 }); 1262 1263 it("in excludes immediately after", () => { 1264 const json = { 1265 include: [ 1266 "**/a.ts" 1267 ], 1268 exclude: [ 1269 "**/.." 1270 ] 1271 }; 1272 const expected: ParsedCommandLine = { 1273 options: {}, 1274 errors: [ 1275 createDiagnosticForConfigFile(json, 34, 7, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..") 1276 ], 1277 fileNames: [ 1278 "c:/dev/a.ts", 1279 "c:/dev/x/a.ts", 1280 "c:/dev/x/y/a.ts", 1281 "c:/dev/z/a.ts" 1282 ], 1283 wildcardDirectories: { 1284 "c:/dev": WatchDirectoryFlags.Recursive 1285 } 1286 }; 1287 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 1288 }); 1289 1290 it("in excludes after a subdirectory", () => { 1291 const json = { 1292 include: [ 1293 "**/a.ts" 1294 ], 1295 exclude: [ 1296 "**/y/.." 1297 ] 1298 }; 1299 const expected: ParsedCommandLine = { 1300 options: {}, 1301 errors: [ 1302 createDiagnosticForConfigFile(json, 34, 9, Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..") 1303 ], 1304 fileNames: [ 1305 "c:/dev/a.ts", 1306 "c:/dev/x/a.ts", 1307 "c:/dev/x/y/a.ts", 1308 "c:/dev/z/a.ts" 1309 ], 1310 wildcardDirectories: { 1311 "c:/dev": WatchDirectoryFlags.Recursive 1312 } 1313 }; 1314 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 1315 }); 1316 }); 1317 1318 describe("with implicit globbification", () => { 1319 it("Expands 'z' to 'z/**/*'", () => { 1320 const json = { 1321 include: ["z"] 1322 }; 1323 const expected: ParsedCommandLine = { 1324 options: {}, 1325 errors: [], 1326 fileNames: [ "a.ts", "aba.ts", "abz.ts", "b.ts", "bba.ts", "bbz.ts" ].map(x => `c:/dev/z/${x}`), 1327 wildcardDirectories: { 1328 "c:/dev/z": WatchDirectoryFlags.Recursive 1329 } 1330 }; 1331 validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath); 1332 }); 1333 }); 1334 }); 1335 1336 describe("with files or folders that begin with a .", () => { 1337 it("that are not explicitly included", () => { 1338 const json = { 1339 include: [ 1340 "x/**/*", 1341 "w/*/*" 1342 ] 1343 }; 1344 const expected: ParsedCommandLine = { 1345 options: {}, 1346 errors: [], 1347 fileNames: [ 1348 "c:/dev/x/d.ts", 1349 "c:/dev/x/y/d.ts", 1350 ], 1351 wildcardDirectories: { 1352 "c:/dev/x": WatchDirectoryFlags.Recursive, 1353 "c:/dev/w": WatchDirectoryFlags.Recursive 1354 } 1355 }; 1356 validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); 1357 }); 1358 describe("that are explicitly included", () => { 1359 it("without wildcards", () => { 1360 const json = { 1361 include: [ 1362 "x/.y/a.ts", 1363 "c:/dev/.z/.b.ts" 1364 ] 1365 }; 1366 const expected: ParsedCommandLine = { 1367 options: {}, 1368 errors: [], 1369 fileNames: [ 1370 "c:/dev/x/.y/a.ts", 1371 "c:/dev/.z/.b.ts" 1372 ], 1373 wildcardDirectories: {} 1374 }; 1375 validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); 1376 }); 1377 it("with recursive wildcards that match directories", () => { 1378 const json = { 1379 include: [ 1380 "**/.*/*" 1381 ] 1382 }; 1383 const expected: ParsedCommandLine = { 1384 options: {}, 1385 errors: [], 1386 fileNames: [ 1387 "c:/dev/.z/c.ts", 1388 "c:/dev/g.min.js/.g/g.ts", 1389 "c:/dev/w/.u/e.ts", 1390 "c:/dev/x/.y/a.ts" 1391 ], 1392 wildcardDirectories: { 1393 "c:/dev": WatchDirectoryFlags.Recursive 1394 } 1395 }; 1396 validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); 1397 }); 1398 it("with recursive wildcards that match nothing", () => { 1399 const json = { 1400 include: [ 1401 "x/**/.y/*", 1402 ".z/**/.*" 1403 ] 1404 }; 1405 const expected: ParsedCommandLine = { 1406 options: {}, 1407 errors: [], 1408 fileNames: [ 1409 "c:/dev/x/.y/a.ts", 1410 "c:/dev/.z/.b.ts" 1411 ], 1412 wildcardDirectories: { 1413 "c:/dev/.z": WatchDirectoryFlags.Recursive, 1414 "c:/dev/x": WatchDirectoryFlags.Recursive 1415 } 1416 }; 1417 validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath); 1418 }); 1419 it("with wildcard excludes that implicitly exclude dotted files", () => { 1420 const json = { 1421 include: [ 1422 "**/.*/*" 1423 ], 1424 exclude: [ 1425 "**/*" 1426 ] 1427 }; 1428 const expected: ParsedCommandLine = { 1429 options: {}, 1430 errors: [ 1431 createCompilerDiagnostic(Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, 1432 caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude)) 1433 ], 1434 fileNames: [], 1435 wildcardDirectories: {} 1436 }; 1437 validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath); 1438 }); 1439 }); 1440 }); 1441 1442 describe("exclude or include patterns which start with **", () => { 1443 it("can exclude dirs whose pattern starts with **", () => { 1444 const json = { 1445 exclude: [ 1446 "**/x" 1447 ] 1448 }; 1449 const expected: ParsedCommandLine = { 1450 options: {}, 1451 errors: [], 1452 fileNames: [ 1453 "/dev/A.ts", 1454 "/dev/B.ts", 1455 "/dev/a.ts", 1456 "/dev/b.ts", 1457 "/dev/c.d.ts", 1458 "/dev/q/a/c/b/d.ts", 1459 "/dev/z/a.ts", 1460 "/dev/z/aba.ts", 1461 "/dev/z/abz.ts", 1462 "/dev/z/b.ts", 1463 "/dev/z/bba.ts", 1464 "/dev/z/bbz.ts", 1465 ], 1466 wildcardDirectories: { 1467 "/dev": WatchDirectoryFlags.Recursive 1468 } 1469 }; 1470 validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); 1471 }); 1472 it("can include dirs whose pattern starts with **", () => { 1473 const json = { 1474 include: [ 1475 "**/x", 1476 "**/a/**/b" 1477 ] 1478 }; 1479 const expected: ParsedCommandLine = { 1480 options: {}, 1481 errors: [], 1482 fileNames: [ 1483 "/dev/x/a.ts", 1484 "/dev/x/b.ts", 1485 "/dev/x/y/a.ts", 1486 "/dev/x/y/b.ts", 1487 "/dev/q/a/c/b/d.ts", 1488 ], 1489 wildcardDirectories: { 1490 "/dev": WatchDirectoryFlags.Recursive 1491 } 1492 }; 1493 validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath); 1494 }); 1495 }); 1496 1497 it("can include files in the same order on multiple platforms", () => { 1498 function getExpected(basePath: string): ParsedCommandLine { 1499 return { 1500 options: {}, 1501 errors: [], 1502 fileNames: [ 1503 `${basePath}Yosemite.ts`, // capital always comes before lowercase letters 1504 `${basePath}xylophone.ts`, 1505 `${basePath}zebra.ts` 1506 ], 1507 wildcardDirectories: { 1508 [basePath.slice(0, basePath.length - 1)]: WatchDirectoryFlags.Recursive 1509 }, 1510 }; 1511 } 1512 const json = {}; 1513 validateMatches(getExpected(caseSensitiveBasePath), json, caseSensitiveOrderingDiffersWithCaseHost, caseSensitiveBasePath); 1514 validateMatches(getExpected(caseInsensitiveBasePath), json, caseInsensitiveOrderingDiffersWithCaseHost, caseInsensitiveBasePath); 1515 }); 1516 1517 it("when recursive symlinked directories are present", () => { 1518 const fs = new vfs.FileSystem(/*ignoreCase*/ true, { 1519 cwd: caseInsensitiveBasePath, files: { 1520 "c:/dev/index.ts": "" 1521 } 1522 }); 1523 fs.mkdirpSync("c:/dev/a/b/c"); 1524 fs.symlinkSync("c:/dev/A", "c:/dev/a/self"); 1525 fs.symlinkSync("c:/dev/a", "c:/dev/a/b/parent"); 1526 fs.symlinkSync("c:/dev/a", "c:/dev/a/b/c/grandparent"); 1527 const host = new fakes.ParseConfigHost(fs); 1528 const json = {}; 1529 const expected: ParsedCommandLine = { 1530 options: {}, 1531 errors: [], 1532 fileNames: [ 1533 "c:/dev/index.ts" 1534 ], 1535 wildcardDirectories: { 1536 "c:/dev": WatchDirectoryFlags.Recursive 1537 }, 1538 }; 1539 validateMatches(expected, json, host, caseInsensitiveBasePath); 1540 }); 1541 }); 1542} 1543