hot-import
Version:
Hot Module Replacement (HMR) for Node.js
195 lines • 8.51 kB
JavaScript
;
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