I'm new to Node.js and jasmine, and my JavaScript experience is old and rusty, so I'm a newbie there too. I finished Manuel Kiessling's book, The Node Beginner Book, and I am working my way through his second book, The Node Craftsman Book. I'm stuck on the FilesizeWatcher tutorial. I've been able to run earlier tests but this one is not working. There is a similar question on SO: No output from jasmine-node but the answer isn't working for me.
I'll post my code here and hopefully somebody can tell me what I'm doing wrong.
FilesizeWatcherSpec.js:
'use strict';
var FilesizeWatcher = require('./FilesizeWatcher');
var exec = require('child_process').exec;
describe('FilesizeWatcher', function() {
var watcher;
afterEach(function() {
watcher.stop();
});
it('should fire a "grew" event when the file grew in size', function(done) {
var path = './var/tmp/filesizewatcher.test';
exec('rm -f ' + path + ' ; touch ' + path, function() {
watcher = new FilesizeWatcher(path);
watcher.on('grew', function(gain) {
expect(gain).toBe(5);
done();
});
exec('echo "test" > ' + path, function(){});
});
});
it('should fire a "shrank" event when the file shrank in size', function(done) {
var path = './var/tmp/filesizewatcher.test';
exec('rm -f ' + path + ' ; echo "test" > ' + path, function() {
watcher = new FilesizeWather(path);
watcher.on('shrank', function(loss) {
expect(loss).toBe(3);
done();
});
exec('echo "a" > ' + path, function(){});
});
});
it('should fire an "error" if path does not start', function(done) {
var path = 'var/tmp/filesizewatcher.test';
watcher = new FilesizeWather(path);
watcher.on('error', function(err) {
expect(err).toBe('Path does not start with a slash');
done();
});
});
});
FilesizeWatcher.js:
'use strict';
var fs = require('fs');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var FilesizeWatcher = function (path) {
var self = this;
if (/^\//.test(path) === false) {
process.nextTick(function() {
self.emit('error', 'Path does not start with a slash');
});
return;
}
fs.stat(path, function (err, stats) {
console.log('stats= ' + stats);
self.lastfilesize = stats.size;
});
self.interval = setInterval(
function () {
console.log('We are in function()');
fs.stat(path, function (err, stats) {
if (stats.size > self.lastfilesize) {
self.emit('grew', stats.size - self.lastfilesize);
self.lastfilesize = stats.size;
}
if (stats.size < self.lastfilesize) {
self.emit('shrank', self.lastfilesize - stats.size);
self.lastfilesize = stats.size;
}
}, 1000);
});
};
util.inherits(FilesizeWatcher, EventEmitter);
FilesizeWatcher.prototype.stop = function () {
clearInterval(this.interval);
};
module.exports = FilesizeWatcher;
Console output:
C:\Users\pdl\Projects\NodeCraftsman>jasmine-node ./FilesizeWatcherSpec.js
C:\Users\pdl\Projects\NodeCraftsman>
Other tests run fine:
C:\Users\pdl\Projects\NodeCraftsmanTestDrivenDevelopment>jasmine-node spec\greetSpec.js
..
Finished in 0.006 seconds
2 tests, 2 assertions, 0 failures, 0 skipped
C:\Users\pdl\Projects\NodeCraftsmanTestDrivenDevelopment>
I added --captureExceptions to see if I could get any information and I got the TypeError: self.callbacks.error is not a function.
My first problem was as Eppilo suggested below, that I needed to use process.nextTick on self.callbacks'error'. Mixing async code with sync code causes the error event to be fired before the error handler is registered. So I made the changes and am now using the EventEmitter but I'm still getting the following errors:
If I include the "." in the path: var path = './var/tmp/filesizewatcher.test';
then the file gets written. Otherwise, it does not.
If the file does NOT get written, stats= undefined and I receive this error:
TypeError: Cannot read property 'size' of undefined
at C:\Users\pdl\Projects\NodeCraftsman\FilesizeWatcher.js:19:34
at FSReqWrap.oncomplete (fs.js:82:15)
If the file DOES get written, then I receive this error:
Error: Uncaught, unspecified "error" event. (Path does not start with a slash)
at emit (events.js:144:17)
at C:\Users\pdl\Projects\NodeCraftsman\FilesizeWatcher.js:12:18
at nextTickCallbackWith0Args (node.js:419:9)
at process._tickCallback (node.js:348:13)
Of course, it's not supposed to start with a slash. That is the test. But when I remove the --captureExceptions from the command, I still get no output.