I actually tried to use @types/* directly but came across several issues which prevented me from switching over: - https://github.com/Microsoft/TypeScript/issues/8715 - https://github.com/Microsoft/TypeScript/issues/8723
		
			
				
	
	
		
			376 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			376 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| let mockfs = require('mock-fs');
 | |
| import fs = require('fs');
 | |
| import path = require('path');
 | |
| import {TreeDiffer} from './tree-differ';
 | |
| 
 | |
| 
 | |
| describe('TreeDiffer', () => {
 | |
| 
 | |
|   afterEach(() => mockfs.restore());
 | |
| 
 | |
| 
 | |
|   describe('diff of added and changed files', () => {
 | |
| 
 | |
|     it('should list all files (but no directories) during the first diff', () => {
 | |
|       let testDir = {
 | |
|         'dir1': {
 | |
|           'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}),
 | |
|           'file-2.txt': mockfs.file({content: 'file-2.txt content', mtime: new Date(1000)}),
 | |
|           'subdir-1': {
 | |
|             'file-1.1.txt': mockfs.file({content: 'file-1.1.txt content', mtime: new Date(1000)})
 | |
|           },
 | |
|           'empty-dir': {}
 | |
|         }
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths)
 | |
|           .toEqual(['file-1.txt', 'file-2.txt', 'subdir-1' + path.sep + 'file-1.1.txt']);
 | |
| 
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should return empty diff if nothing has changed', () => {
 | |
|       let testDir = {
 | |
|         'dir1': {
 | |
|           'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}),
 | |
|           'file-2.txt': mockfs.file({content: 'file-2.txt content', mtime: new Date(1000)}),
 | |
|           'subdir-1': {
 | |
|             'file-1.1.txt': mockfs.file({content: 'file-1.1.txt content', mtime: new Date(1000)})
 | |
|           },
 | |
|         }
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).not.toEqual([]);
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).toEqual([]);
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should list only changed files during the subsequent diffs', () => {
 | |
|       let testDir = {
 | |
|         'dir1': {
 | |
|           'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}),
 | |
|           'file-2.txt': mockfs.file({content: 'file-2.txt content', mtime: new Date(1000)}),
 | |
|           'subdir-1': {
 | |
|             'file-1.1.txt':
 | |
|                 mockfs.file({content: 'file-1.1.txt content', mtime: new Date(1000)})
 | |
|           }
 | |
|         }
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths)
 | |
|           .toEqual(['file-1.txt', 'file-2.txt', 'subdir-1' + path.sep + 'file-1.1.txt']);
 | |
| 
 | |
|       // change two files
 | |
|       testDir['dir1']['file-1.txt'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['subdir-1']['file-1.1.txt'] =
 | |
|           mockfs.file({content: 'file-1.1.txt content', mtime: new Date(9999)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.changedPaths)
 | |
|           .toEqual(['file-1.txt', 'subdir-1' + path.sep + 'file-1.1.txt']);
 | |
| 
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       // change one file
 | |
|       testDir['dir1']['file-1.txt'] = mockfs.file({content: 'super new', mtime: new Date(1000)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.txt']);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should handle changes via symbolic links', () => {
 | |
|       let testDir = {
 | |
|         'orig_path': {
 | |
|           'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}),
 | |
|           'file-2.txt': mockfs.file({content: 'file-2.txt content', mtime: new Date(1000)}),
 | |
|           'subdir-1': {
 | |
|             'file-1.1.txt': mockfs.file({content: 'file-1.1.txt content', mtime: new Date(1000)})
 | |
|           }
 | |
|         },
 | |
|         'symlinks': {
 | |
|           'file-1.txt': mockfs.symlink({path: '../orig_path/file-1.txt'}),
 | |
|           'file-2.txt': mockfs.symlink({path: '../orig_path/file-2.txt'}),
 | |
|           'subdir-1':
 | |
|               {'file-1.1.txt': mockfs.symlink({path: '../../orig_path/subdir-1/file-1.1.txt'})}
 | |
|         }
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'symlinks');
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths)
 | |
|           .toEqual(['file-1.txt', 'file-2.txt', 'subdir-1' + path.sep + 'file-1.1.txt']);
 | |
| 
 | |
|       // change two files
 | |
|       testDir['orig_path']['file-1.txt'] =
 | |
|           mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['orig_path']['subdir-1']['file-1.1.txt'] =
 | |
|           mockfs.file({content: 'file-1.1.txt content', mtime: new Date(9999)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).toEqual([]);
 | |
|       expect(diffResult.changedPaths)
 | |
|           .toEqual(['file-1.txt', 'subdir-1' + path.sep + 'file-1.1.txt']);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       // change one file
 | |
|       testDir['orig_path']['file-1.txt'] =
 | |
|           mockfs.file({content: 'super new', mtime: new Date(1000)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.txt']);
 | |
| 
 | |
|       // remove a link
 | |
|       delete testDir['orig_path']['file-1.txt'];
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.addedPaths).toEqual([]);
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual(['file-1.txt']);
 | |
| 
 | |
|       // don't report it as a removal twice
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       // re-add it.
 | |
|       testDir['orig_path']['file-1.txt'] =
 | |
|           mockfs.file({content: 'super new', mtime: new Date(1000)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.addedPaths).toEqual(['file-1.txt']);
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it("should throw an error if an extension isn't prefixed with doc", () => {
 | |
|       // includeExtensions
 | |
|       expect(() => new TreeDiffer('testLabel', 'dir1', ['js']))
 | |
|           .toThrowError("Extension must begin with '.'. Was: 'js'");
 | |
| 
 | |
|       // excludeExtentions
 | |
|       expect(() => new TreeDiffer('testLabel', 'dir1', [], ['js']))
 | |
|           .toThrowError("Extension must begin with '.'. Was: 'js'");
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should ignore files with extensions not listed in includeExtensions', () => {
 | |
|       let testDir = {
 | |
|         'dir1': {
 | |
|           'file-1.js': mockfs.file({content: 'file-1.js content', mtime: new Date(1000)}),
 | |
|           'file-2.md': mockfs.file({content: 'file-2.md content', mtime: new Date(1000)}),
 | |
|           'file-3.coffee': mockfs.file({content: 'file-3.coffee content', mtime: new Date(1000)}),
 | |
|           'subdir-1': {
 | |
|             'file-1.1.cc': mockfs.file({content: 'file-1.1.cc content', mtime: new Date(1000)})
 | |
|           }
 | |
|         }
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1', ['.js', '.coffee']);
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).toEqual(['file-1.js', 'file-3.coffee']);
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       // change two files
 | |
|       testDir['dir1']['file-1.js'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['file-3.coffee'] =
 | |
|           mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['subdir-1']['file-1.1.cc'] =
 | |
|           mockfs.file({content: 'file-1.1.cc content', mtime: new Date(9999)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).toEqual([]);
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.js', 'file-3.coffee']);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       // change one file
 | |
|       testDir['dir1']['file-1.js'] = mockfs.file({content: 'super new', mtime: new Date(1000)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.js']);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should ignore files with extensions listed in excludeExtensions', () => {
 | |
|       let testDir = {
 | |
|         'dir1': {
 | |
|           'file-1.ts': mockfs.file({content: 'file-1.ts content', mtime: new Date(1000)}),
 | |
|           'file-1.cs': mockfs.file({content: 'file-1.cs content', mtime: new Date(1000)}),
 | |
|           'file-1d.cs': mockfs.file({content: 'file-1d.cs content', mtime: new Date(1000)}),
 | |
|           'file-1.d.cs': mockfs.file({content: 'file-1.d.cs content', mtime: new Date(1000)}),
 | |
|           'file-2.md': mockfs.file({content: 'file-2.md content', mtime: new Date(1000)}),
 | |
|           'file-3.ts': mockfs.file({content: 'file-3.ts content', mtime: new Date(1000)}),
 | |
|           'file-4.d.ts': mockfs.file({content: 'file-4.d.ts content', mtime: new Date(1000)}),
 | |
|           'subdir-1': {
 | |
|             'file-1.1.cc': mockfs.file({content: 'file-1.1.cc content', mtime: new Date(1000)})
 | |
|           }
 | |
|         }
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1', ['.ts', '.cs'], ['.d.ts', '.d.cs']);
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).toEqual(['file-1.cs', 'file-1.ts', 'file-1d.cs', 'file-3.ts']);
 | |
| 
 | |
|       // change two files
 | |
|       testDir['dir1']['file-1.ts'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['file-1.cs'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['file-1.d.cs'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['file-3.ts'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['file-4.d.ts'] = mockfs.file({content: 'new content', mtime: new Date(1000)});
 | |
|       testDir['dir1']['subdir-1']['file-1.1.cc'] =
 | |
|           mockfs.file({content: 'file-1.1.cc content', mtime: new Date(9999)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
| 
 | |
|       expect(diffResult.addedPaths).toEqual([]);
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.cs', 'file-1.ts', 'file-3.ts']);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
| 
 | |
|       // change one file
 | |
|       testDir['dir1']['file-4.d.ts'] = mockfs.file({content: 'super new', mtime: new Date(1000)});
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       diffResult = differ.diffTree();
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   describe('diff of new files', () => {
 | |
| 
 | |
|     it('should detect file additions', () => {
 | |
|       let testDir: any = {
 | |
|         'dir1':
 | |
|             {'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})}
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
|       differ.diffTree();
 | |
| 
 | |
|       testDir['dir1']['file-2.txt'] = 'new file';
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
|       expect(diffResult.addedPaths).toEqual(['file-2.txt']);
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual([]);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should detect file additions mixed with file changes', () => {
 | |
|       let testDir: any = {
 | |
|         'dir1':
 | |
|             {'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})}
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
|       differ.diffTree();
 | |
| 
 | |
|       testDir['dir1']['file-1.txt'] = 'new content';
 | |
|       testDir['dir1']['file-2.txt'] = 'new file';
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
|       expect(diffResult.addedPaths).toEqual(['file-2.txt']);
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.txt']);
 | |
|     });
 | |
|   });
 | |
| 
 | |
| 
 | |
|   describe('diff of removed files', () => {
 | |
| 
 | |
|     it('should detect file removals and report them as removed files', () => {
 | |
|       let testDir = {
 | |
|         'dir1':
 | |
|             {'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})}
 | |
|       };
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
|       differ.diffTree();
 | |
| 
 | |
|       delete testDir['dir1']['file-1.txt'];
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
|       expect(diffResult.changedPaths).toEqual([]);
 | |
|       expect(diffResult.removedPaths).toEqual(['file-1.txt']);
 | |
|     });
 | |
| 
 | |
| 
 | |
|     it('should detect file removals mixed with file changes and additions', () => {
 | |
|       let testDir: any = {
 | |
|         'dir1': {
 | |
|           'file-1.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)}),
 | |
|           'file-2.txt': mockfs.file({content: 'file-1.txt content', mtime: new Date(1000)})
 | |
|         }
 | |
|       };
 | |
| 
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let differ = new TreeDiffer('testLabel', 'dir1');
 | |
|       differ.diffTree();
 | |
| 
 | |
|       testDir['dir1']['file-1.txt'] = 'changed content';
 | |
|       delete testDir['dir1']['file-2.txt'];
 | |
|       testDir['dir1']['file-3.txt'] = 'new content';
 | |
|       mockfs(testDir);
 | |
| 
 | |
|       let diffResult = differ.diffTree();
 | |
|       expect(diffResult.addedPaths).toEqual(['file-3.txt']);
 | |
|       expect(diffResult.changedPaths).toEqual(['file-1.txt']);
 | |
|       expect(diffResult.removedPaths).toEqual(['file-2.txt']);
 | |
|     });
 | |
|   });
 | |
| });
 |