UNPKG

5.79 kBPlain TextView Raw
1import {EventEmitter} from 'eventemitter3';
2import {InternalEventsEmitter} from '../src/utils';
3import * as Promise from 'bluebird';
4import {expect} from 'chai';
5import {EventsMatcher} from '../test-kit/drivers/events-matcher';
6import {SlowFs} from '../test-kit/drivers/slow-fs';
7
8import {
9 FileSystem,
10 fileSystemEventNames,
11 CacheFileSystem,
12 MemoryFileSystem
13} from '../src/universal';
14
15import {
16 assertFileSystemContract,
17 ignoredDir,
18 ignoredFile,
19 fileName,
20 dirName,
21 content
22} from './implementation-suite';
23
24describe(`the cache file system implementation`, () => {
25
26 const eventMatcherOptions: EventsMatcher.Options = {
27 interval: 1,
28 noExtraEventsGrace: 10,
29 timeout: 30
30 };
31
32 assertFileSystemContract(
33 () => Promise.resolve(new CacheFileSystem(new MemoryFileSystem(undefined, [ignoredDir, ignoredFile]))),
34 eventMatcherOptions
35 );
36
37 describe(`using slow FileSystem`, () => {
38 const timeout = 200;
39
40 let timer;
41 let fs: FileSystem;
42 let slow: FileSystem;
43 let startTimestamp: number;
44 let matcher: EventsMatcher;
45
46 beforeEach(() => {
47 startTimestamp = Date.now();
48 slow = new SlowFs(timeout)
49 fs = new CacheFileSystem(slow)
50 matcher = new EventsMatcher(eventMatcherOptions);
51 matcher.track(fs.events as any as EventEmitter, ...fileSystemEventNames)
52 });
53
54
55 it('loads file faster after it has been saved', () => {
56 return fs.saveFile(fileName, content)
57 .then(() => fs.loadTextFile(fileName))
58 .then(() => expect(Date.now() - startTimestamp).to.be.lessThan(timeout * 2));
59 })
60
61 it('loads file faster after it has been saved from outside', () => {
62 const onFileCreated = new Promise((resolve, reject) => {
63 fs.events.once('fileCreated', () => {
64 fs.loadTextFile(fileName)
65 .then(() => resolve(Date.now() - startTimestamp))
66 })
67 })
68
69 slow.saveFile(fileName, content)
70 return expect(onFileCreated).to.be.eventually.lessThan(timeout * 2)
71
72 })
73
74 it('loads tree faster after it has been loaded before', () => {
75 return fs.loadDirectoryTree()
76 .then(() => fs.loadDirectoryTree())
77 .then(() => expect(Date.now() - startTimestamp).to.be.lessThan(timeout * 2))
78 })
79 });
80
81 describe(`unexpected error behaviour`, () => {
82 let fs: FileSystem;
83 let original: FileSystem;
84 let matcher: EventsMatcher;
85
86 beforeEach(() => {
87 original = new MemoryFileSystem();
88 fs = new CacheFileSystem(original);
89 matcher = new EventsMatcher({
90 interval: 2,
91 noExtraEventsGrace: 150,
92 timeout: 300
93 });
94 matcher.track(fs.events as any as EventEmitter, ...fileSystemEventNames)
95 });
96
97 it('emits `fileCreated` if there is not cached file after error', () => {
98 original.events.removeAllListeners('fileCreated')
99 return original.saveFile(fileName, content)
100 .then(() => matcher.expect([]))
101 .then(() => (original.events as InternalEventsEmitter).emit('unexpectedError', {type: 'unexpectedError'}))
102 .then(() => matcher.expect([{type: 'fileCreated', fullPath: fileName, newContent: content}]))
103 })
104
105 it('emits `directoryCreated` if there is not cached dir after error', () => {
106 original.events.removeAllListeners('directoryCreated');
107 return original.ensureDirectory(dirName)
108 .then(() => matcher.expect([]))
109 .then(() => (original.events as InternalEventsEmitter).emit('unexpectedError', {type: 'unexpectedError'}))
110 .then(() => matcher.expect([{type: 'directoryCreated', fullPath: dirName}]))
111 })
112
113 it('emits `fileDeleted` if there is cached file and no real file after error', () => {
114 return fs.saveFile(fileName, content).then(() => {
115 original.events.removeAllListeners('fileDeleted');
116 return original.deleteFile(fileName)
117 .then(() => matcher.expect([{type: 'fileCreated', fullPath: fileName}]))
118 .then(() => (original.events as InternalEventsEmitter).emit('unexpectedError', {type: 'unexpectedError'}))
119 .then(() => matcher.expect([{type: 'fileDeleted', fullPath: fileName}]))
120
121 })
122 })
123
124 it('emits `directoryDeleted` if there is cached dir and no real dir after error', () => {
125 return fs.ensureDirectory(dirName).then(() => {
126 original.events.removeAllListeners('directoryDeleted');
127 return original.deleteDirectory(dirName)
128 .then(() => matcher.expect([{type: 'directoryCreated', fullPath: dirName}]))
129 .then(() => (original.events as InternalEventsEmitter).emit('unexpectedError', {type: 'unexpectedError'}))
130 .then(() => matcher.expect([{type: 'directoryDeleted', fullPath: dirName}]))
131 })
132 })
133
134 it('emits `unexpectedError` if cache created with `rescanOnError = false` flag', () => {
135 const fs = new CacheFileSystem(original, false);
136 const matcher = new EventsMatcher(eventMatcherOptions);
137 matcher.track(fs.events as any as EventEmitter, ...fileSystemEventNames);
138 (original.events as InternalEventsEmitter).emit('unexpectedError', {type: 'unexpectedError'});
139 return matcher.expect([{type: 'unexpectedError'}]);
140 })
141 });
142});