UNPKG

hot-import

Version:

Hot Module Replacement (HMR) for Node.js

195 lines 8.51 kB
#!/usr/bin/env ts-node "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); // tslint:disable:no-shadowed-variable const test = require("blue-tape"); const brolog_1 = require("brolog"); // log.level('silly') const fixtures_1 = require("./fixtures"); const FILENAME = 'test.data'; function write(file, data) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { brolog_1.log.verbose('TestFsWatch', 'write(%s) ...', file); fs.writeFile(file, data, err => { if (err) { return reject(err); } brolog_1.log.verbose('TestFsWatch', 'write(%s) done', file); return resolve(); }); }); }); } function watch(file, cbChange, cbRename) { return __awaiter(this, void 0, void 0, function* () { const watcher = fs.watch(file) .on('error', e => { brolog_1.log.verbose('TestFsWatch', 'watch(%s) watcher.on(error): %s', file, e); }) .on('change', onChange) .on('rename', cbRename); // wait all io event loop to be cleared before return watcher yield new Promise(setImmediate); return watcher; function onChange(eventType) { let size; try { // the first change event is create a size 0 file // however, when we stat the file, the file might already be writen some data. // so we also might get a size>0 at here. size = fs.statSync(file).size; brolog_1.log.verbose('TestFsWatch', 'watch(%s) onChange(%s) size: %s', file, eventType, size); } catch (e) { brolog_1.log.verbose('TestFsWatch', 'watch(%s) onChange(%s) fs.statSync() exception: %s', file, eventType, e); return; } if (eventType !== 'change' || !size) { return; } cbChange(); } }); } test('1/4. fs.writeFileSync then fs.writeFile', (t) => __awaiter(this, void 0, void 0, function* () { let watcher; let changeCounter = 0; let renameCounter = 0; for (const workDir of fixtures_1.tmpDir()) { const file = path.join(workDir, FILENAME); // init the file fs.writeFileSync(file, Math.random()); yield new Promise(setImmediate); watcher = yield watch(file, () => changeCounter++, () => renameCounter++); // change the file yield write(file, Math.random()); } yield new Promise(resolve => setTimeout(resolve, 100)); t.ok(changeCounter >= 1, 'should monitored file change event at least once'); // t.ok(changeCounter <= 2, 'should monitored file change event at most twice') t.ok(watcher, 'should instanciated a watcher'); if (watcher) { watcher.close(); } })); test('2/4. fs.writeFileSync then fs.writeFileSync', (t) => __awaiter(this, void 0, void 0, function* () { let watcher; let renameCounter = 0; let changeCounter = 0; for (const workDir of fixtures_1.tmpDir()) { const file = path.join(workDir, FILENAME); // init the file fs.writeFileSync(file, Math.random()); yield new Promise(setImmediate); watcher = yield watch(file, () => changeCounter++, () => renameCounter++); // change the file fs.writeFileSync(file, Math.random()); } yield new Promise(resolve => setTimeout(resolve, 10)); // change event is not consistant through Windows & Linux: Windows fire twice, Linux fire once. // t.equal(changeCounter, 1, 'should monitored 1 change event') // rename event is not consistant through Mac & Linux: Mac fire once, Linux fire twice. // t.equal(renameCounter, 1, 'should monitored 1 rename event') t.ok(watcher, 'should instanciated a watcher'); if (watcher) { watcher.close(); } })); test('3/4. fs.writeFile then fs.writeFile', (t) => __awaiter(this, void 0, void 0, function* () { let watcher; let renameCounter = 0; let changeCounter = 0; for (const workDir of fixtures_1.tmpDir()) { const file = path.join(workDir, FILENAME); // init the file yield write(file, Math.random()); yield new Promise(setImmediate); watcher = yield watch(file, () => changeCounter++, () => renameCounter++); // change the file yield write(file, Math.random()); yield new Promise(setImmediate); } yield new Promise(setImmediate); t.equal(changeCounter, 1, 'should monitored 1 change event'); t.equal(renameCounter, 0, 'should monitored 0 rename event'); t.ok(watcher, 'should instanciated a watcher'); if (watcher) { watcher.close(); } })); test('4/4. fs.writeFile then fs.writeFileSync', (t) => __awaiter(this, void 0, void 0, function* () { let watcher; let renameCounter = 0; let changeCounter = 0; for (const workDir of fixtures_1.tmpDir()) { const file = path.join(workDir, FILENAME); // init the file yield write(file, Math.random()); yield new Promise(setImmediate); watcher = yield watch(file, () => changeCounter++, () => renameCounter++); // change the file fs.writeFileSync(file, Math.random()); } yield new Promise(resolve => setTimeout(resolve, 10)); // change event is not consistant through Windows & Linux: Windows fire twice, Linux fire once. // t.equal(changeCounter, 1, 'should monitored 1 file change event') // rename event is not consistant through Mac & Linux: Mac fire once, Linux fire twice. // t.equal(renameCounter, 1, 'should monitored 1 file rename event') t.ok(watcher, 'should instanciated a watcher'); if (watcher) { watcher.close(); } })); test('fixtures', (t) => __awaiter(this, void 0, void 0, function* () { var e_1, _a; let file; let watcher; let renameCounter = 0; let changeCounter = 0; try { for (var _b = __asyncValues(fixtures_1.changingVariableModuleFixtures()), _c; _c = yield _b.next(), !_c.done;) { const info = _c.value; if (!file) { file = info.file; watcher = yield watch(file, () => changeCounter++, () => renameCounter++); } else { break; // break on the 2nd loop } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b); } finally { if (e_1) throw e_1.error; } } yield new Promise(resolve => setTimeout(resolve, 20)); t.ok(changeCounter >= 1, 'should monitored file change event at least once'); // t.ok(changeCounter <= 2, 'should monitored file change event at most twice') t.equal(renameCounter, 0, 'should not monitored file rename event'); t.ok(watcher, 'should instanciated a watcher'); if (watcher) { watcher.close(); } })); //# sourceMappingURL=fs-watch.spec.js.map