Mongoose, tests versioned
This commit is contained in:
parent
4e849a9f7a
commit
e281e7e8a6
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
var mongoose = require('mongoose');
|
||||
|
||||
exports.initialize = function initializeSchema(schema, callback) {
|
||||
schema.client = mongoose.connect(schema.settings.url);
|
||||
schema.adapter = new MongooseAdapter(schema.client);
|
||||
};
|
||||
|
||||
function MongooseAdapter(client) {
|
||||
this._models = {};
|
||||
this.client = client;
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
MongooseAdapter.prototype.define = function (descr) {
|
||||
var props = {};
|
||||
Object.keys(descr.properties).forEach(function (key) {
|
||||
props[key] = descr.properties[key].type;
|
||||
if (props[key].name === 'Text') props[key] = String;
|
||||
});
|
||||
var schema = new mongoose.Schema(props);
|
||||
this._models[descr.model.modelName] = mongoose.model(descr.model.modelName, schema);
|
||||
this.cache[descr.model.modelName] = {};
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.setCache = function (model, instance) {
|
||||
this.cache[model][instance.id] = instance;
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.getCached = function (model, id, cb) {
|
||||
if (this.cache[model][id]) {
|
||||
cb(null, this.cache[model][id]);
|
||||
} else {
|
||||
this._models[model].findById(id, function (err, instance) {
|
||||
if (err) return cb(err);
|
||||
this.cache[model][id] = instance;
|
||||
cb(null, instance);
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.create = function (model, data, callback) {
|
||||
var m = new this._models[model](data);
|
||||
m.save(function (err) {
|
||||
callback(err, err ? null : m.id);
|
||||
});
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.save = function (model, data, callback) {
|
||||
this.getCached(model, data.id, function (err, inst) {
|
||||
if (err) return callback(err);
|
||||
merge(inst, data);
|
||||
inst.save(callback);
|
||||
});
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.exists = function (model, id, callback) {
|
||||
delete this.cache[model][id];
|
||||
this.getCached(model, id, function (err, data) {
|
||||
if (err) return callback(err);
|
||||
callback(err, !!data);
|
||||
});
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.find = function find(model, id, callback) {
|
||||
delete this.cache[model][id];
|
||||
this.getCached(model, id, function (err, data) {
|
||||
if (err) return callback(err);
|
||||
callback(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.destroy = function destroy(model, id, callback) {
|
||||
this.getCached(model, id, function (err, data) {
|
||||
if (err) return callback(err);
|
||||
if (data) data.remove(callback);
|
||||
else callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.all = function all(model, filter, callback) {
|
||||
this._models[model].find(typeof filter === 'function' ? {} : filter, function (err, data) {
|
||||
if (err) return callback(err);
|
||||
callback(null, data);
|
||||
});
|
||||
};
|
||||
|
||||
function applyFilter(filter) {
|
||||
if (typeof filter === 'function') {
|
||||
return filter;
|
||||
}
|
||||
var keys = Object.keys(filter);
|
||||
return function (obj) {
|
||||
var pass = true;
|
||||
keys.forEach(function (key) {
|
||||
if (!test(filter[key], obj[key])) {
|
||||
pass = false;
|
||||
}
|
||||
});
|
||||
return pass;
|
||||
}
|
||||
|
||||
function test(example, value) {
|
||||
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') {
|
||||
return value.match(example);
|
||||
}
|
||||
// not strict equality
|
||||
return example == value;
|
||||
}
|
||||
}
|
||||
|
||||
MongooseAdapter.prototype.destroyAll = function destroyAll(model, callback) {
|
||||
var wait = 0;
|
||||
this._models[model].find(function (err, data) {
|
||||
if (err) return callback(err);
|
||||
wait = data.length;
|
||||
data.forEach(function (obj) {
|
||||
obj.remove(done)
|
||||
});
|
||||
});
|
||||
|
||||
var error = null;
|
||||
function done(err) {
|
||||
error = error || err;
|
||||
if (--wait === 0) {
|
||||
callback(error);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.count = function count(model, callback) {
|
||||
this._models[model].count(callback);
|
||||
};
|
||||
|
||||
MongooseAdapter.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
||||
this.getCached(model, id, function (err, inst) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
} else if (inst) {
|
||||
merge(inst, data);
|
||||
inst.save(cb);
|
||||
} else cb();
|
||||
});
|
||||
};
|
||||
|
||||
function merge(base, update) {
|
||||
Object.keys(update).forEach(function (key) {
|
||||
base[key] = update[key];
|
||||
});
|
||||
return base;
|
||||
}
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
var Schema = require('../index').Schema;
|
||||
var Text = Schema.Text;
|
||||
|
||||
require('./spec_helper').init(exports);
|
||||
|
||||
var schemas = {
|
||||
/*
|
||||
riak: {},
|
||||
sequelize: {
|
||||
database: 'sequ-test',
|
||||
username: 'root'
|
||||
}
|
||||
*/
|
||||
neo4j: { url: 'http://localhost:7474/' },
|
||||
mongoose: { url: 'mongodb://localhost/test' },
|
||||
redis: {},
|
||||
memory: {}
|
||||
};
|
||||
|
||||
Object.keys(schemas).forEach(function (schemaName) {
|
||||
if (process.env.ONLY && process.env.ONLY !== schemaName) return;
|
||||
context(schemaName, function () {
|
||||
var schema = new Schema(schemaName, schemas[schemaName]);
|
||||
testOrm(schema);
|
||||
});
|
||||
});
|
||||
|
||||
function testOrm(schema) {
|
||||
|
||||
var Post;
|
||||
var start = Date.now();
|
||||
|
||||
it('should define class', function (test) {
|
||||
|
||||
var User = schema.define('User', {
|
||||
name: String,
|
||||
bio: Text,
|
||||
approved: Boolean,
|
||||
joinedAt: Date,
|
||||
age: Number
|
||||
});
|
||||
|
||||
Post = schema.define('Post', {
|
||||
title: { type: String, length: 255 },
|
||||
content: { type: Text },
|
||||
date: { type: Date, detault: Date.now },
|
||||
published: { type: Boolean, default: false }
|
||||
});
|
||||
|
||||
var user = new User;
|
||||
|
||||
test.ok(User instanceof Function);
|
||||
|
||||
// class methods
|
||||
test.ok(User.find instanceof Function);
|
||||
test.ok(User.create instanceof Function);
|
||||
|
||||
// instance methods
|
||||
test.ok(user.save instanceof Function);
|
||||
|
||||
schema.automigrate(function (err) {
|
||||
if (err) {
|
||||
console.log('Error while migrating');
|
||||
console.log(err);
|
||||
} else {
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should initialize object properly', function (test) {
|
||||
var hw = 'Hello word', post = new Post({title: hw});
|
||||
test.equal(post.title, hw);
|
||||
test.ok(!post.propertyChanged('title'));
|
||||
post.title = 'Goodbye, Lenin';
|
||||
test.equal(post.title_was, hw);
|
||||
test.ok(post.propertyChanged('title'));
|
||||
// test.ok(post.isNewRecord());
|
||||
test.done();
|
||||
});
|
||||
|
||||
it('should be expoted to JSON', function (test) {
|
||||
test.equal(JSON.stringify(new Post({id: 1, title: 'hello, json'})),
|
||||
'{"id":1,"title":"hello, json","content":null,"date":null,"published":null}');
|
||||
test.done();
|
||||
});
|
||||
|
||||
it('should create object', function (test) {
|
||||
Post.create(function (err, post) {
|
||||
if (err) throw err;
|
||||
test.ok(post.id);
|
||||
test.ok(!post.title, 'Title is blank');
|
||||
test.ok(!post.date, 'Date is blank');
|
||||
Post.exists(post.id, function (err, exists) {
|
||||
if (err) throw err;
|
||||
test.ok(exists);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should save object', function (test) {
|
||||
var title = 'Initial title', title2 = 'Hello world',
|
||||
date = new Date;
|
||||
|
||||
Post.create({
|
||||
title: title,
|
||||
date: date
|
||||
}, function (err, obj) {
|
||||
test.ok(obj.id);
|
||||
test.equals(obj.title, title);
|
||||
// test.equals(obj.date, date);
|
||||
obj.title = title2;
|
||||
test.ok(obj.propertyChanged('title'), 'Title changed');
|
||||
obj.save(function (err, obj) {
|
||||
test.equal(obj.title, title2);
|
||||
test.ok(!obj.propertyChanged('title'));
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should create object with initial data', function (test) {
|
||||
var title = 'Initial title',
|
||||
date = new Date;
|
||||
|
||||
Post.create({
|
||||
title: title,
|
||||
date: date
|
||||
}, function (err, obj) {
|
||||
test.ok(obj.id);
|
||||
test.equals(obj.title, title);
|
||||
test.equals(obj.date, date);
|
||||
Post.find(obj.id, function () {
|
||||
test.equal(obj.title, title);
|
||||
test.equal(obj.date, date.toString());
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not create new instances for the same object', function (test) {
|
||||
var title = 'Initial title';
|
||||
Post.create({ title: title }, function (err, post) {
|
||||
test.ok(post.id, 'Object should have id');
|
||||
test.equals(post.title, title);
|
||||
Post.find(post.id, function (err, foundPost) {
|
||||
if (err) throw err;
|
||||
test.equal(post.title, title);
|
||||
test.strictEqual(post, foundPost);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not re-instantiate object on saving', function (test) {
|
||||
var title = 'Initial title';
|
||||
var post = new Post({title: title});
|
||||
post.save(function (err, savedPost) {
|
||||
test.strictEqual(post, savedPost);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should destroy object', function (test) {
|
||||
Post.create(function (err, post) {
|
||||
Post.exists(post.id, function (err, exists) {
|
||||
test.ok(exists, 'Object exists');
|
||||
post.destroy(function () {
|
||||
Post.exists(post.id, function (err, exists) {
|
||||
test.ok(!exists, 'Hey! ORM told me that object exists, but it looks like it doesn\'t. Something went wrong...');
|
||||
Post.find(post.id, function (err, obj) {
|
||||
test.equal(obj, null, 'Param obj should be null');
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should update single attribute', function (test) {
|
||||
Post.create({title: 'title', content: 'content', published: true}, function (err, post) {
|
||||
post.content = 'New content';
|
||||
post.updateAttribute('title', 'New title', function () {
|
||||
test.equal(post.title, 'New title');
|
||||
test.ok(!post.propertyChanged('title'));
|
||||
test.equal(post.content, 'New content');
|
||||
test.ok(post.propertyChanged('content'));
|
||||
post.reload(function () {
|
||||
test.equal(post.title, 'New title');
|
||||
test.ok(!post.propertyChanged('title'));
|
||||
test.equal(post.content, 'content');
|
||||
test.ok(!post.propertyChanged('content'));
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var countOfposts;
|
||||
it('should fetch collection', function (test) {
|
||||
Post.all(function (err, posts) {
|
||||
countOfposts = posts.length;
|
||||
test.ok(countOfposts > 0);
|
||||
test.ok(posts[0] instanceof Post);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fetch count of records in collection', function (test) {
|
||||
Post.count(function (err, count) {
|
||||
test.equal(countOfposts, count);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should find filtered set of records', function (test) {
|
||||
var wait = 3;
|
||||
|
||||
// exact match with string
|
||||
Post.all({title: 'New title'}, function (err, res) {
|
||||
var pass = true;
|
||||
res.forEach(function (r) {
|
||||
if (r.title != 'New title') pass = false;
|
||||
});
|
||||
test.ok(res.length > 0);
|
||||
test.ok(pass, 'Exact match with string');
|
||||
done();
|
||||
});
|
||||
|
||||
// matching null
|
||||
Post.all({date: null, title: null}, function (err, res) {
|
||||
var pass = true;
|
||||
res.forEach(function (r) {
|
||||
if (r.date != null || r.title != null) pass = false;
|
||||
});
|
||||
test.ok(res.length > 0);
|
||||
test.ok(pass, 'Matching null');
|
||||
done();
|
||||
});
|
||||
|
||||
// matching regexp
|
||||
Post.all({title: /hello/i}, function (err, res) {
|
||||
var pass = true;
|
||||
res.forEach(function (r) {
|
||||
if (!r.title || !r.title.match(/hello/i)) pass = false;
|
||||
});
|
||||
test.ok(res.length > 0);
|
||||
test.ok(pass, 'Matching regexp');
|
||||
done();
|
||||
});
|
||||
|
||||
function done() {
|
||||
if (--wait === 0) {
|
||||
test.done();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('should destroy all records', function (test) {
|
||||
Post.destroyAll(function (err) {
|
||||
Post.all(function (err, posts) {
|
||||
test.equal(posts.length, 0);
|
||||
Post.count(function (err, count) {
|
||||
test.equal(count, 0);
|
||||
test.done();
|
||||
process.nextTick(allTestsDone);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function allTestsDone() {
|
||||
console.log('Test done in %dms\n', Date.now() - start);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,317 @@
|
|||
require('./spec_helper').init(exports);
|
||||
|
||||
[ 'redis~'
|
||||
, 'mysql'
|
||||
, 'mongodb~'
|
||||
, 'postgres~'
|
||||
].forEach(function (driver) {
|
||||
// context(driver, testCasesFor(driver));
|
||||
});
|
||||
|
||||
function testCasesFor (driver) {
|
||||
return function () {
|
||||
|
||||
function Post () { this.initialize.apply(this, Array.prototype.slice.call(arguments)); }
|
||||
function Comment () { this.initialize.apply(this, Array.prototype.slice.call(arguments)); }
|
||||
|
||||
var properties = {};
|
||||
|
||||
properties['post'] = {
|
||||
title: { type: String, validate: /.{10,255}/ },
|
||||
content: { type: String },
|
||||
published: { type: Boolean, default: false },
|
||||
date: { type: Date, default: function () {return new Date} }
|
||||
};
|
||||
|
||||
properties['comment'] = {
|
||||
content: { type: String, validate: /./ },
|
||||
date: { type: Date },
|
||||
author: { type: String },
|
||||
approved: { type: Boolean }
|
||||
};
|
||||
|
||||
var associations = {};
|
||||
associations['post'] = {
|
||||
comments: {className: 'Comment', relationType: 'n', tableName: 'comment'}
|
||||
};
|
||||
|
||||
associations['comment'] = {
|
||||
post: {className: 'Post', relationType: '<', tableName: 'post'}
|
||||
};
|
||||
|
||||
try {
|
||||
var orm = require('../lib/datamapper/' + driver);
|
||||
if (driver == 'mysql') {
|
||||
orm.configure({
|
||||
host: 'webdesk.homelinux.org',
|
||||
port: 3306,
|
||||
database: 'test',
|
||||
user: 'guest',
|
||||
password: ''
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
return;
|
||||
}
|
||||
orm.debugMode = true;
|
||||
orm.mixPersistMethods(Post, {
|
||||
className: 'Post',
|
||||
tableName: 'post',
|
||||
properties: properties['post'],
|
||||
associations: associations['post']
|
||||
});
|
||||
orm.mixPersistMethods(Comment, {
|
||||
className: 'Comment',
|
||||
tableName: 'comment',
|
||||
properties: properties['comment'],
|
||||
associations: associations['comment'],
|
||||
scopes: {
|
||||
approved: { conditions: { approved: true } },
|
||||
author: { block: function (author) { return {conditions: {author: author}}; } }
|
||||
}
|
||||
});
|
||||
|
||||
var HOW_MANY_RECORDS = 1;
|
||||
|
||||
it('cleanup database', function (test) {
|
||||
var wait = 0;
|
||||
var time = new Date;
|
||||
var len;
|
||||
Post.allInstances(function (posts) {
|
||||
if (posts.length === 0) test.done();
|
||||
len = posts.length;
|
||||
posts.forEach(function (post) {
|
||||
wait += 1;
|
||||
post.destroy(done);
|
||||
});
|
||||
});
|
||||
|
||||
function done () {
|
||||
if (--wait === 0) {
|
||||
test.done();
|
||||
console.log('Cleanup %d records completed in %d ms', len, new Date - time);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('create a lot of data', function (test) {
|
||||
var wait = HOW_MANY_RECORDS;
|
||||
var time = new Date;
|
||||
for (var i = wait; i > 0; i -= 1) {
|
||||
Post.create({title: Math.random().toString(), content: arguments.callee.caller.toString(), date: new Date, published: false}, done);
|
||||
}
|
||||
|
||||
function done () {
|
||||
if (--wait === 0) {
|
||||
test.done();
|
||||
console.log('Creating %d records completed in %d ms', HOW_MANY_RECORDS, new Date - time);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should retrieve all data fast', function (test) {
|
||||
var time = new Date;
|
||||
Post.allInstances(function (posts) {
|
||||
test.equal(posts.length, HOW_MANY_RECORDS);
|
||||
console.log('Retrieving %d records completed in %d ms', HOW_MANY_RECORDS, new Date - time);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should initialize object properly', function (test) {
|
||||
var hw = 'Hello world', post = new Post({title: hw});
|
||||
test.equal(post.title, hw);
|
||||
test.ok(!post.propertyChanged('title'));
|
||||
post.title = 'Goodbye, Lenin';
|
||||
test.equal(post.title_was, hw);
|
||||
test.ok(post.propertyChanged('title'));
|
||||
test.ok(post.isNewRecord());
|
||||
test.done();
|
||||
});
|
||||
|
||||
it('should create object', function (test) {
|
||||
Post.create(function () {
|
||||
test.ok(this.id);
|
||||
Post.exists(this.id, function (exists) {
|
||||
test.ok(exists);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should save object', function (test) {
|
||||
var title = 'Initial title', title2 = 'Hello world',
|
||||
date = new Date;
|
||||
|
||||
Post.create({
|
||||
title: title,
|
||||
date: date
|
||||
}, function () {
|
||||
test.ok(this.id);
|
||||
test.equals(this.title, title);
|
||||
test.equals(this.date, date);
|
||||
this.title = title2;
|
||||
this.save(function () {
|
||||
test.equal(this.title, title2);
|
||||
test.ok(!this.propertyChanged('title'));
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should create object with initial data', function (test) {
|
||||
var title = 'Initial title',
|
||||
date = new Date;
|
||||
|
||||
Post.create({
|
||||
title: title,
|
||||
date: date
|
||||
}, function () {
|
||||
test.ok(this.id);
|
||||
test.equals(this.title, title);
|
||||
test.equals(this.date, date);
|
||||
Post.find(this.id, function () {
|
||||
test.equal(this.title, title);
|
||||
test.equal(this.date, date.toString());
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not create new instances for the same object', function (test) {
|
||||
var title = 'Initial title';
|
||||
Post.create({ title: title }, function () {
|
||||
var post = this;
|
||||
test.ok(this.id, 'Object should have id');
|
||||
test.equals(this.title, title);
|
||||
Post.find(this.id, function () {
|
||||
test.equal(this.title, title);
|
||||
test.strictEqual(this, post);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should destroy object', function (test) {
|
||||
Post.create(function () {
|
||||
var post = this;
|
||||
Post.exists(post.id, function (exists) {
|
||||
test.ok(exists, 'Object exists');
|
||||
post.destroy(function () {
|
||||
Post.exists(post.id, function (exists) {
|
||||
test.ok(!exists, 'Object not exists');
|
||||
Post.find(post.id, function (err, obj) {
|
||||
test.ok(err, 'Object not found');
|
||||
test.equal(obj, null, 'Param obj should be null');
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should update single attribute', function (test) {
|
||||
Post.create({title: 'title', content: 'content'}, function () {
|
||||
this.content = 'New content';
|
||||
this.updateAttribute('title', 'New title', function () {
|
||||
test.equal(this.title, 'New title');
|
||||
test.ok(!this.propertyChanged('title'));
|
||||
test.equal(this.content, 'New content');
|
||||
test.ok(this.propertyChanged('content'));
|
||||
this.reload(function () {
|
||||
test.equal(this.title, 'New title');
|
||||
test.ok(!this.propertyChanged('title'));
|
||||
test.equal(this.content, 'content');
|
||||
test.ok(!this.propertyChanged('content'));
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// NOTE: this test rely on previous
|
||||
it('should fetch collection', function (test) {
|
||||
Post.allInstances(function (posts) {
|
||||
test.ok(posts.length > 0);
|
||||
test.strictEqual(posts[0].constructor, Post);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
// NOTE: this test rely on previous
|
||||
it('should fetch first, second, third and last elements of class', function (test) {
|
||||
test.done(); return;
|
||||
var queries = 4;
|
||||
test.expect(queries);
|
||||
function done () { if (--queries == 0) test.done(); }
|
||||
|
||||
Post.first(function (post) {
|
||||
test.strictEqual(post.constructor, Post);
|
||||
done();
|
||||
});
|
||||
Post.second(function (post) {
|
||||
test.strictEqual(post.constructor, Post);
|
||||
done();
|
||||
});
|
||||
Post.third(function (post) {
|
||||
test.strictEqual(post.constructor, Post);
|
||||
done();
|
||||
});
|
||||
Post.last(function (post) {
|
||||
test.strictEqual(post.constructor, Post);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should load associated collection', function (test) {
|
||||
test.done(); return;
|
||||
Post.last(function (post) {
|
||||
post.comments.approved.where('author = ?', 'me').load();
|
||||
});
|
||||
});
|
||||
|
||||
it('should find record and associated association', function (test) {
|
||||
test.done(); return;
|
||||
Post.last(function (post) {
|
||||
Post.find(post.id, {include: 'comments'}, function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fetch associated collection', function (test) {
|
||||
test.done(); return;
|
||||
Post.create(function () {
|
||||
// load collection
|
||||
this.comments(function () {
|
||||
});
|
||||
// creating associated object
|
||||
this.comments.create(function () {
|
||||
});
|
||||
this.comments.build().save();
|
||||
// named scopes
|
||||
this.comments.pending(function () {
|
||||
});
|
||||
this.comments.approved(function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should validate object', function (test) {
|
||||
test.done(); return;
|
||||
var post = new Post;
|
||||
test.ok(!post.isValid());
|
||||
post.save(function (id) {
|
||||
test.ok(!id, 'Post should not be saved');
|
||||
});
|
||||
post.title = 'Title';
|
||||
test.ok(post.isValid());
|
||||
post.save(function (id) {
|
||||
test.ok(id);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
};
|
|
@ -0,0 +1,70 @@
|
|||
try {
|
||||
global.sinon = require('sinon');
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
var group_name = false, EXT_EXP;
|
||||
function it (should, test_case) {
|
||||
check_external_exports();
|
||||
if (group_name) {
|
||||
EXT_EXP[group_name][should] = test_case;
|
||||
} else {
|
||||
EXT_EXP[should] = test_case;
|
||||
}
|
||||
}
|
||||
|
||||
global.it = it;
|
||||
|
||||
function context(name, tests) {
|
||||
check_external_exports();
|
||||
EXT_EXP[name] = {};
|
||||
group_name = name;
|
||||
tests({
|
||||
before: function (f) {
|
||||
it('setUp', f);
|
||||
},
|
||||
after: function (f) {
|
||||
it('tearDown', f);
|
||||
}
|
||||
});
|
||||
group_name = false;
|
||||
}
|
||||
|
||||
global.context = context;
|
||||
|
||||
exports.init = function (external_exports) {
|
||||
EXT_EXP = external_exports;
|
||||
if (external_exports.done) {
|
||||
external_exports.done();
|
||||
}
|
||||
};
|
||||
|
||||
function check_external_exports() {
|
||||
if (!EXT_EXP) throw new Error(
|
||||
'Before run this, please ensure that ' +
|
||||
'require("spec_helper").init(exports); called');
|
||||
}
|
||||
|
||||
// add assertions
|
||||
|
||||
var assert = require(require('module')._resolveFilename('nodeunit')[0].replace(/index\.js$/, 'lib/assert'));
|
||||
|
||||
// Check response status code 200 OK
|
||||
assert.status200 = function (response, message) {
|
||||
if (response.statusCode !== 200) {
|
||||
assert.fail(response.statusCode, 200, message || 'Status code is not 200', '===', assert.status200);
|
||||
}
|
||||
}
|
||||
|
||||
// Check redirection
|
||||
assert.redirect = function (response, path, message) {
|
||||
if (response.statusCode !== 302) {
|
||||
assert.fail(response.statusCode, 302, 'Status code is not 302', '===', assert.redirect);
|
||||
}
|
||||
var realPath = require('url').parse(response.headers.location).pathname;
|
||||
if (realPath !== path) {
|
||||
assert.fail(realPath, path, message || 'Wrong location', '===', assert.redirect);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue