Merge branch 'master' into pagination

* master:
  done handler in final then, to ensure errors in last block are reported
  missing a done or two
  using grunt validate for npm test, fixing random jslint errors
  using promises correctly in tests
  adding mocha, getting npm test working
This commit is contained in:
Tim Griesser 2013-05-27 10:11:55 -04:00
commit 4d0b2ee0c4
13 changed files with 148 additions and 184 deletions

View File

@ -64,7 +64,7 @@
console.log('user found: ', user); console.log('user found: ', user);
req.session.user = "ghostadmin"; req.session.user = "ghostadmin";
res.redirect(req.query.redirect || '/ghost/'); res.redirect(req.query.redirect || '/ghost/');
}, function(err) { }, function (err) {
// Do something here to signal the reason for an error // Do something here to signal the reason for an error
console.log(err.stack); console.log(err.stack);
res.redirect('/ghost/login/'); res.redirect('/ghost/login/');

View File

@ -1,4 +1,4 @@
(function() { (function () {
"use strict"; "use strict";
var _ = require('underscore'), var _ = require('underscore'),
@ -8,7 +8,7 @@
* Basic error handling helpers * Basic error handling helpers
*/ */
errors = { errors = {
throwError: function(err) { throwError: function (err) {
if (!err) { if (!err) {
return; return;
} }

View File

@ -20,11 +20,11 @@
// Simple bootstraping of the data model for now. // Simple bootstraping of the data model for now.
var migration = require('../data/migration/001'); var migration = require('../data/migration/001');
migration.down().then(function() { return migration.down().then(function () {
migration.up().then(function () { return migration.up();
console.log('all done....');
});
}); });
}).then(function () {
console.log('all done....');
}); });
} }

View File

@ -1,4 +1,4 @@
(function() { (function () {
"use strict"; "use strict";
var _ = require('underscore'), var _ = require('underscore'),

View File

@ -1,4 +1,4 @@
(function() { (function () {
"use strict"; "use strict";
var _ = require('underscore'), var _ = require('underscore'),
@ -17,7 +17,7 @@
util.inherits(SettingsProvider, BaseProvider); util.inherits(SettingsProvider, BaseProvider);
SettingsProvider.prototype.read = function(_key) { SettingsProvider.prototype.read = function (_key) {
// Allow for just passing the key instead of attributes // Allow for just passing the key instead of attributes
if (_.isString(_key)) { if (_.isString(_key)) {
_key = { key: _key }; _key = { key: _key };
@ -25,7 +25,7 @@
return BaseProvider.prototype.read.call(this, _key); return BaseProvider.prototype.read.call(this, _key);
}; };
SettingsProvider.prototype.edit = function(_data) { SettingsProvider.prototype.edit = function (_data) {
return when.all(_.map(_data, function (value, key) { return when.all(_.map(_data, function (value, key) {
return this.model.forge({ key: key }).fetch().then(function (setting) { return this.model.forge({ key: key }).fetch().then(function (setting) {
return setting.set('value', value).save(); return setting.set('value', value).save();

View File

@ -1,4 +1,4 @@
(function() { (function () {
"use strict"; "use strict";
var util = require('util'), var util = require('util'),
@ -30,7 +30,7 @@
// Clone the _user so we don't expose the hashed password unnecessarily // Clone the _user so we don't expose the hashed password unnecessarily
userData = _.extend({}, _user); userData = _.extend({}, _user);
return nodefn.call(bcrypt.hash, _user.password, 10).then(function(hash) { return nodefn.call(bcrypt.hash, _user.password, 10).then(function (hash) {
userData.password = hash; userData.password = hash;
return BaseProvider.prototype.add.call(self, userData); return BaseProvider.prototype.add.call(self, userData);
}); });
@ -46,7 +46,7 @@
return this.model.forge({ return this.model.forge({
email_address: _userdata.email email_address: _userdata.email
}).fetch().then(function (user) { }).fetch().then(function (user) {
return nodefn.call(bcrypt.compare, _userdata.pw, user.get('password')).then(function(matched) { return nodefn.call(bcrypt.compare, _userdata.pw, user.get('password')).then(function (matched) {
if (!matched) { if (!matched) {
return when.reject(new Error('Password does not match')); return when.reject(new Error('Password does not match'));
} }

View File

@ -29,7 +29,7 @@
DataProvider.prototype.globals.data = []; DataProvider.prototype.globals.data = [];
DataProvider.prototype.globals.findAll = function() { DataProvider.prototype.globals.findAll = function () {
return when(this.data); return when(this.data);
}; };

View File

@ -26,9 +26,7 @@
results.length.should.equal(2); results.length.should.equal(2);
done(); done();
}, function (error) { }).then(null, done);
throw error;
});
}); });
it('can read', function (done) { it('can read', function (done) {
@ -41,44 +39,38 @@
firstPost = results.models[0]; firstPost = results.models[0];
posts.read({slug: firstPost.attributes.slug}).then(function (found) { return posts.read({slug: firstPost.attributes.slug});
should.exist(found); }).then(function (found) {
should.exist(found);
found.attributes.title.should.equal(firstPost.attributes.title); found.attributes.title.should.equal(firstPost.attributes.title);
done(); done();
}, function (error) { }).then(null, done);
throw error;
});
}, function (error) {
throw error;
});
}); });
it('can edit', function (done) { it('can edit', function (done) {
var firstPost; var firstPost;
posts.browse().then(function (results) { posts.browse().then(function (results) {
should.exist(results); should.exist(results);
results.length.should.be.above(0); results.length.should.be.above(0);
firstPost = results.models[0]; firstPost = results.models[0];
posts.edit({id: firstPost.id, title: "new title"}).then(function (edited) { return posts.edit({id: firstPost.id, title: "new title"});
should.exist(edited);
edited.attributes.title.should.equal('new title'); }).then(function (edited) {
done(); should.exist(edited);
}, function (error) {
throw error;
});
}, function (error) { edited.attributes.title.should.equal('new title');
throw error;
}); done();
}).then(null, done);
}); });
it('can add', function (done) { it('can add', function (done) {
@ -95,45 +87,39 @@
createdPost.attributes.slug.should.equal(newPost.title.toLowerCase().replace(/ /g, '-'), 'slug is correct'); createdPost.attributes.slug.should.equal(newPost.title.toLowerCase().replace(/ /g, '-'), 'slug is correct');
done(); done();
}, function (error) { }).then(null, done);
throw error;
});
}); });
it('can delete', function (done) { it('can delete', function (done) {
var firstPostId, var firstPostId;
ids,
hasDeletedId;
posts.browse().then(function (results) { posts.browse().then(function (results) {
should.exist(results); should.exist(results);
results.length.should.be.above(0); results.length.should.be.above(0);
firstPostId = results.models[0].id; firstPostId = results.models[0].id;
posts.destroy(firstPostId).then(function () { return posts.destroy(firstPostId);
posts.browse().then(function (newResults) { }).then(function () {
ids = _.pluck(newResults.models, "id"); return posts.browse();
hasDeletedId = _.any(ids, function (id) { }).then(function (newResults) {
return id === firstPostId; var ids, hasDeletedId;
});
hasDeletedId.should.equal(false); ids = _.pluck(newResults.models, "id");
done(); hasDeletedId = _.any(ids, function (id) {
}, function (error) { return id === firstPostId;
throw error;
});
}, function (error) {
throw error;
}); });
}, function (error) {
throw error; hasDeletedId.should.equal(false);
});
done();
}).then(null, done);
}); });
}); });
}()); }());

View File

@ -27,9 +27,7 @@
results.length.should.be.above(0); results.length.should.be.above(0);
done(); done();
}, function (error) { }).then(null, done);
throw error;
});
}); });
it('can read', function (done) { it('can read', function (done) {
@ -43,20 +41,17 @@
firstSetting = results.models[0]; firstSetting = results.models[0];
settings.read(firstSetting.attributes.key).then(function (found) { return settings.read(firstSetting.attributes.key);
should.exist(found); }).then(function (found) {
found.attributes.value.should.equal(firstSetting.attributes.value); should.exist(found);
done(); found.attributes.value.should.equal(firstSetting.attributes.value);
}, function (error) {
throw error;
});
}, function (error) { done();
throw error;
}); }).then(null, done);
}); });
it('can edit single', function (done) { it('can edit single', function (done) {
@ -71,29 +66,26 @@
firstPost = results.models[0]; firstPost = results.models[0];
// The edit method has been modified to take an object of // The edit method has been modified to take an object of
// key/value pairs // key/value pairs
toEdit[firstPost.attributes.key] = "new value"; toEdit[firstPost.attributes.key] = "new value";
settings.edit(toEdit).then(function (edited) { return settings.edit(toEdit);
should.exist(edited); }).then(function (edited) {
edited.length.should.equal(1); should.exist(edited);
edited = edited[0]; edited.length.should.equal(1);
edited.attributes.key.should.equal(firstPost.attributes.key); edited = edited[0];
edited.attributes.value.should.equal('new value');
done(); edited.attributes.key.should.equal(firstPost.attributes.key);
}, function (error) { edited.attributes.value.should.equal('new value');
throw error;
});
}, function (error) { done();
throw error;
}); }).then(null, done);
}); });
it('can edit multiple', function (done) { it('can edit multiple', function (done) {
@ -111,34 +103,32 @@
firstPost = results.models[0]; firstPost = results.models[0];
secondPost = results.models[1]; secondPost = results.models[1];
// The edit method has been modified to take an object of // The edit method has been modified to take an object of
// key/value pairs // key/value pairs
toEdit[firstPost.attributes.key] = "new value1"; toEdit[firstPost.attributes.key] = "new value1";
toEdit[secondPost.attributes.key] = "new value2"; toEdit[secondPost.attributes.key] = "new value2";
settings.edit(toEdit).then(function (edited) { return settings.edit(toEdit);
should.exist(edited); }).then(function (edited) {
edited.length.should.equal(2); should.exist(edited);
editedPost = edited[0]; edited.length.should.equal(2);
editedPost.attributes.key.should.equal(firstPost.attributes.key); editedPost = edited[0];
editedPost.attributes.value.should.equal('new value1');
editedPost = edited[1]; editedPost.attributes.key.should.equal(firstPost.attributes.key);
editedPost.attributes.value.should.equal('new value1');
editedPost.attributes.key.should.equal(secondPost.attributes.key); editedPost = edited[1];
editedPost.attributes.value.should.equal('new value2');
done(); editedPost.attributes.key.should.equal(secondPost.attributes.key);
}, function (error) { editedPost.attributes.value.should.equal('new value2');
throw error;
}); done();
}, function (error) {
throw error; }).then(null, done);
});
}); });
it('can add', function (done) { it('can add', function (done) {
@ -155,15 +145,11 @@
createdSetting.attributes.value.should.equal(newSetting.value, "value is correct"); createdSetting.attributes.value.should.equal(newSetting.value, "value is correct");
done(); done();
}, function (error) { }).then(null, done);
throw error;
});
}); });
it('can delete', function (done) { it('can delete', function (done) {
var firstSettingId, var firstSettingId;
ids,
hasDeletedId;
settings.browse().then(function (results) { settings.browse().then(function (results) {
@ -173,28 +159,27 @@
firstSettingId = results.models[0].id; firstSettingId = results.models[0].id;
settings.destroy(firstSettingId).then(function () { return settings.destroy(firstSettingId);
settings.browse().then(function (newResults) { }).then(function () {
ids = _.pluck(newResults.models, "id"); return settings.browse();
hasDeletedId = _.any(ids, function (id) { }).then(function (newResults) {
return id === firstSettingId;
});
hasDeletedId.should.equal(false); var ids, hasDeletedId;
done(); ids = _.pluck(newResults.models, "id");
}, function (error) {
throw error; hasDeletedId = _.any(ids, function (id) {
}); return id === firstSettingId;
}, function (error) {
throw error;
}); });
}, function (error) {
throw error; hasDeletedId.should.equal(false);
});
done();
}).then(null, done);
}); });
}); });
}()); }());

View File

@ -20,6 +20,7 @@
}); });
it('can browse', function (done) { it('can browse', function (done) {
users.browse().then(function (results) { users.browse().then(function (results) {
should.exist(results); should.exist(results);
@ -27,9 +28,8 @@
results.length.should.be.above(0); results.length.should.be.above(0);
done(); done();
}, function (error) {
throw error; }).then(null, done);
});
}); });
it('can read', function (done) { it('can read', function (done) {
@ -43,18 +43,18 @@
firstUser = results.models[0]; firstUser = results.models[0];
users.read({email_address: firstUser.attributes.email_address}).then(function (found) { return users.read({email_address: firstUser.attributes.email_address});
should.exist(found); }).then(function (found) {
found.attributes.username.should.equal(firstUser.attributes.username); should.exist(found);
done(); found.attributes.username.should.equal(firstUser.attributes.username);
}, function (error) {
throw error; done();
});
}).then(null, done);
});
}); });
it('can edit', function (done) { it('can edit', function (done) {
@ -68,19 +68,17 @@
firstUser = results.models[0]; firstUser = results.models[0];
users.edit({id: firstUser.id, url: "some.newurl.com"}).then(function (edited) { return users.edit({id: firstUser.id, url: "some.newurl.com"});
should.exist(edited); }).then(function (edited) {
edited.attributes.url.should.equal('some.newurl.com'); should.exist(edited);
done(); edited.attributes.url.should.equal('some.newurl.com');
}, function (error) {
throw error; done();
});
}, function (error) { }).then(null, done);
throw error;
});
}); });
it('can add', function (done) { it('can add', function (done) {
@ -97,15 +95,11 @@
createdUser.attributes.email_address.should.eql(userData.email_address, "email address corred"); createdUser.attributes.email_address.should.eql(userData.email_address, "email address corred");
done(); done();
}, function (error) { }).then(null, done);
throw error;
});
}); });
it('can delete', function (done) { it('can delete', function (done) {
var firstUserId, var firstUserId;
ids,
hasDeletedId;
users.browse().then(function (results) { users.browse().then(function (results) {
@ -115,33 +109,31 @@
firstUserId = results.models[0].id; firstUserId = results.models[0].id;
users.destroy(firstUserId).then(function () { return users.destroy(firstUserId);
users.browse().then(function (newResults) { }).then(function () {
if (newResults.length < 1) { return users.browse();
// Bug out if we only had one user and deleted it.
return done();
}
ids = _.pluck(newResults.models, "id"); }).then(function (newResults) {
var ids, hasDeletedId;
hasDeletedId = _.any(ids, function (id) { if (newResults.length < 1) {
return id === firstUserId; // Bug out if we only had one user and deleted it.
}); return done();
}
hasDeletedId.should.equal(false); ids = _.pluck(newResults.models, "id");
done(); hasDeletedId = _.any(ids, function (id) {
}, function (error) { return id === firstUserId;
throw error;
});
}, function (error) {
throw error;
}); });
}, function (error) {
throw error; hasDeletedId.should.equal(false);
});
done();
}).then(null, done);
}); });
}); });

View File

@ -19,7 +19,7 @@
errors.throwError(toThrow); errors.throwError(toThrow);
}; };
runThrowError.should.throw("test1"); runThrowError.should['throw']("test1");
}); });
it("throws error strings", function () { it("throws error strings", function () {
@ -28,7 +28,7 @@
errors.throwError(toThrow); errors.throwError(toThrow);
}; };
runThrowError.should.throw("test2"); runThrowError.should['throw']("test2");
}); });
it("logs errors", function () { it("logs errors", function () {
@ -52,7 +52,7 @@
logStub.restore(); logStub.restore();
}); });
it("logs promise errors with custom messages", function(done) { it("logs promise errors with custom messages", function (done) {
var def = when.defer(), var def = when.defer(),
prom = def.promise, prom = def.promise,
logStub = sinon.stub(console, "log"); logStub = sinon.stub(console, "log");
@ -71,12 +71,12 @@
def.reject(); def.reject();
}); });
it("logs promise errors and redirects", function(done) { it("logs promise errors and redirects", function (done) {
var def = when.defer(), var def = when.defer(),
prom = def.promise, prom = def.promise,
req = null, req = null,
res = { res = {
redirect: function() { redirect: function () {
return; return;
} }
}, },

View File

@ -1,4 +1,4 @@
(function() { (function () {
"use strict"; "use strict";
// Use 'testing' Ghost config // Use 'testing' Ghost config
@ -13,7 +13,7 @@
resetData: function () { resetData: function () {
return migrations.one.down().then(function () { return migrations.one.down().then(function () {
return migrations.one.up(); return migrations.one.up();
}, function() { }, function () {
throw new Error("Failed to reset data"); throw new Error("Failed to reset data");
}); });
} }

View File

@ -4,7 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node app", "start": "node app",
"test": "nodeunit core/test/ghost" "test": "grunt validate"
}, },
"dependencies": { "dependencies": {
"express": "3.1.x", "express": "3.1.x",
@ -28,6 +28,7 @@
"grunt-mocha-test": "~0.4.0", "grunt-mocha-test": "~0.4.0",
"grunt-shell": "~0.2.2", "grunt-shell": "~0.2.2",
"grunt-contrib-sass": "~0.3.0", "grunt-contrib-sass": "~0.3.0",
"sinon": "~1.7.2" "sinon": "~1.7.2",
"mocha": "~1.10.0"
} }
} }