As an exercise in TDD in Node.js, I'm trying to implement a very simple "database" that stores things as flat files. Here's the very beginning of the DB module code:
var fs = require( 'fs' );
exports.create = function( path, readycallback ) {
new FlatFileDB( path, readycallback );
};
function FlatFileDB( path, readycallback ) {
this.path = path;
readycallback( null, this );
}
FlatFileDB.prototype.getPath = function() {
return this.path;
};
The DB creation is asynchronous, and in my test case, I have a check to see if calling the create() function actually results in two distinct objects:
var vows = require('vows'),
assert = require('assert'),
fs = require( 'fs' ),
flatfileDB = require( '../lib/flatfileDB' );
var twoDBs = {};
vows.describe( 'flatfileDB' ).addBatch( {
'creating the database': {
topic: flatfileDB,
'calling create': {
topic: function( flatfileDB ) {
flatfileDB.create( './createTest', this.callback );
},
'results in an object with the path passed in': function( err, db ) {
assert.equal( db.getPath(), './createTest' );
}
},
'calling create more than once': {
topic: function( flatfileDB ) {
flatfileDB.create( './db1', function( err, newdb ) {
twoDBs.db1 = newdb;
flatfileDB.create( './db2', function( err, newdb ) {
twoDBs.db2 = newdb;
this.callback( null, twoDBs );
} );
});
},
'results in two objects with different paths.': function( err, dbs ) {
console.log( 'twoDBs. db1: ' + twoDBs.db1 + ', db2: ' + twoDBs.db2 );
console.log( 'dbs: ' + JSON.stringify( dbs ) );
assert.notEqual( twoDBs.db1.getPath(), twoDBs.db2.getPath() );
}
}
},
}).run();
The output of those two console.log lines surprises me, though:
twoDBs. db1: [object Object], db2: [object Object] dbs: {}
since I'm passing twoDBs to the test callback, I had expected dbs and twoDBs to be the some object, but they don't appear to be. Can anyone help me out with what's going on here?
dbs
scope is inside of that callback. You wont be able to access because invoke ofthis.callback()
isn't scoped in that callback. You need to you pass it along withthis.callback(null, dbs, twoDBs)
or you create a var intopic
and assigndbs
to it in the callback. This isn't so much an issue with Vows; It has much more to do with JavaScript's lexical scoping and callbacks.What I do in these cases is pass along needed vars by add parameters to
this.callback()
.Edit: What's above isn't right, but the fix came out in the comments below: