Revision d7c10cbac3dc5208661a12289b33d626321a502e authored by Valeri Karpov on 23 December 2015, 21:58:19 UTC, committed by Valeri Karpov on 23 December 2015, 21:58:19 UTC
1 parent 1b44616
types.documentarray.test.js
/**
* Module dependencies.
*/
var start = require('./common')
, mongoose = require('./common').mongoose
, random = require('../lib/utils').random
, setValue = require('../lib/utils').setValue
, MongooseArray = mongoose.Types.Array
, MongooseDocumentArray = mongoose.Types.DocumentArray
, EmbeddedDocument = require('../lib/types/embedded')
, DocumentArray = require('../lib/types/documentarray')
, Schema = mongoose.Schema
, assert = require('assert')
, collection = 'types.documentarray_' + random();
/**
* Setup.
*/
function TestDoc(schema) {
var Subdocument = function() {
EmbeddedDocument.call(this, {}, new DocumentArray);
};
/**
* Inherits from EmbeddedDocument.
*/
Subdocument.prototype.__proto__ = EmbeddedDocument.prototype;
/**
* Set schema.
*/
var SubSchema = new Schema({
title: { type: String }
});
Subdocument.prototype.$__setSchema(schema || SubSchema);
return Subdocument;
}
/**
* Test.
*/
describe('types.documentarray', function() {
it('behaves and quacks like an array', function(done) {
var a = new MongooseDocumentArray();
assert.ok(a instanceof Array);
assert.ok(a.isMongooseArray);
assert.ok(a.isMongooseDocumentArray);
assert.ok(Array.isArray(a));
assert.equal('Object', a._atomics.constructor.name);
assert.equal('object', typeof a);
var b = new MongooseArray([1,2,3,4]);
assert.equal('object', typeof b);
assert.equal(Object.keys(b.toObject()).length,4);
done();
});
it('#id', function(done) {
var Subdocument = TestDoc();
var sub1 = new Subdocument();
sub1.title = 'Hello again to all my friends';
var id = sub1.id;
var a = new MongooseDocumentArray([sub1]);
assert.equal(a.id(id).title, 'Hello again to all my friends');
assert.equal(a.id(sub1._id).title, 'Hello again to all my friends');
// test with custom string _id
var Custom = new Schema({
title: { type: String }
, _id: { type: String, required: true }
});
Subdocument = TestDoc(Custom);
var sub2 = new Subdocument();
sub2.title = 'together we can play some rock-n-roll';
sub2._id = 'a25';
var id2 = sub2.id;
a = new MongooseDocumentArray([sub2]);
assert.equal(a.id(id2).title, 'together we can play some rock-n-roll');
assert.equal(a.id(sub2._id).title, 'together we can play some rock-n-roll');
// test with custom number _id
var CustNumber = new Schema({
title: { type: String }
, _id: { type: Number, required: true }
});
Subdocument = TestDoc(CustNumber);
var sub3 = new Subdocument();
sub3.title = 'rock-n-roll';
sub3._id = 1995;
var id3 = sub3.id;
a = new MongooseDocumentArray([sub3]);
assert.equal(a.id(id3).title, 'rock-n-roll');
assert.equal(a.id(sub3._id).title, 'rock-n-roll');
// test with object as _id
Custom = new Schema({
title: { type: String }
, _id: { one: { type: String }, two: { type: String } }
});
Subdocument = TestDoc(Custom);
sub1 = new Subdocument();
sub1._id = {one: 'rolling', two: 'rock'};
sub1.title = 'to be a rock and not to roll';
sub2 = new Subdocument();
sub2._id = {one: 'rock', two: 'roll'};
sub2.title = 'rock-n-roll';
a = new MongooseDocumentArray([sub1,sub2]);
assert.notEqual(a.id({one: 'rolling', two: 'rock'}).title, 'rock-n-roll');
assert.equal(a.id({one: 'rock', two: 'roll'}).title, 'rock-n-roll');
// test with no _id
var NoId = new Schema({
title: { type: String }
}, { noId: true });
Subdocument = TestDoc(NoId);
var sub4 = new Subdocument();
sub4.title = 'rock-n-roll';
a = new MongooseDocumentArray([sub4]);
var threw = false;
try {
a.id('i better not throw');
} catch (err) {
threw = err;
}
assert.equal(false, threw);
// test the _id option, noId is deprecated
NoId = new Schema({
title: { type: String }
}, { _id: false });
Subdocument = TestDoc(NoId);
sub4 = new Subdocument();
sub4.title = 'rock-n-roll';
a = new MongooseDocumentArray([sub4])
, threw = false;
try {
a.id('i better not throw');
} catch (err) {
threw = err;
}
assert.equal(false, threw);
// undefined and null should not match a nonexistent _id
assert.strictEqual(null, a.id(undefined));
assert.strictEqual(null, a.id(null));
// test when _id is a populated document
Custom = new Schema({
title: { type: String }
});
var Custom1 = new Schema({}, { id: false });
Subdocument = TestDoc(Custom);
var Subdocument1 = TestDoc(Custom1);
var sub = new Subdocument1();
sub1 = new Subdocument1();
sub.title = 'Hello again to all my friends';
id = sub1._id.toString();
setValue('_id', sub1 , sub);
a = new MongooseDocumentArray([sub]);
assert.equal(a.id(id).title, 'Hello again to all my friends');
done();
});
describe('inspect', function() {
it('works with bad data', function(done) {
var threw = false;
var a = new MongooseDocumentArray([null]);
try {
a.inspect();
} catch (err) {
threw = true;
console.error(err.stack);
}
assert.ok(!threw);
done();
});
});
describe('toObject', function() {
it('works with bad data', function(done) {
var threw = false;
var a = new MongooseDocumentArray([null]);
try {
a.toObject();
} catch (err) {
threw = true;
console.error(err.stack);
}
assert.ok(!threw);
done();
});
it('passes options to its documents (gh-1415)', function(done) {
var subSchema = new Schema({
title: { type: String }
});
subSchema.set('toObject', {
transform: function(doc, ret) {
// this should not be called because custom options are
// passed during MongooseArray#toObject() calls
ret.changed = 123;
return ret;
}
});
var db = mongoose.createConnection();
var M = db.model('gh-1415', { docs: [subSchema] });
var m = new M;
m.docs.push({ docs: [{ title: 'hello' }] });
var delta = m.$__delta()[1];
assert.equal(undefined, delta.$pushAll.docs[0].changed);
done();
});
it('uses the correct transform (gh-1412)', function(done) {
var db = start();
var SecondSchema = new Schema({});
SecondSchema.set('toObject', {
transform: function second(doc, ret) {
ret.secondToObject = true;
return ret;
}
});
var FirstSchema = new Schema({
second: [SecondSchema]
});
FirstSchema.set('toObject', {
transform: function first(doc, ret) {
ret.firstToObject = true;
return ret;
}
});
var First = db.model('first', FirstSchema);
var Second = db.model('second', SecondSchema);
var first = new First({
});
first.second.push(new Second());
first.second.push(new Second());
var obj = first.toObject();
assert.ok(obj.firstToObject);
assert.ok(obj.second[0].secondToObject);
assert.ok(obj.second[1].secondToObject);
assert.ok(!obj.second[0].firstToObject);
assert.ok(!obj.second[1].firstToObject);
db.close(done);
});
});
describe('create()', function() {
it('works', function(done) {
var a = new MongooseDocumentArray([]);
assert.equal('function', typeof a.create);
var schema = new Schema({ docs: [new Schema({ name: 'string' })] });
var T = mongoose.model('embeddedDocument#create_test', schema, 'asdfasdfa' + random());
var t = new T;
assert.equal('function', typeof t.docs.create);
var subdoc = t.docs.create({ name: 100 });
assert.ok(subdoc._id);
assert.equal(subdoc.name, '100');
assert.ok(subdoc instanceof EmbeddedDocument);
done();
});
});
describe('push()', function() {
it('does not re-cast instances of its embedded doc', function(done) {
var db = start();
var child = new Schema({ name: String, date: Date });
child.pre('save', function(next) {
this.date = new Date;
next();
});
var schema = Schema({ children: [child] });
var M = db.model('embeddedDocArray-push-re-cast', schema, 'edarecast-' + random());
var m = new M;
m.save(function(err) {
assert.ifError(err);
M.findById(m._id, function(err, doc) {
assert.ifError(err);
var c = doc.children.create({ name: 'first' });
assert.equal(undefined, c.date);
doc.children.push(c);
assert.equal(undefined, c.date);
doc.save(function(err) {
assert.ifError(err);
assert.ok(doc.children[doc.children.length - 1].date);
assert.equal(c.date, doc.children[doc.children.length - 1].date);
doc.children.push(c);
doc.children.push(c);
doc.save(function(err) {
assert.ifError(err);
M.findById(m._id, function(err, doc) {
assert.ifError(err);
assert.equal(3, doc.children.length);
doc.children.forEach(function(child) {
assert.equal(doc.children[0].id, child.id);
});
db.close(done);
});
});
});
});
});
});
it('corrects #ownerDocument() if value was created with array.create() (gh-1385)', function(done) {
var mg = new mongoose.Mongoose;
var M = mg.model('1385', { docs: [{ name: String }] });
var m = new M;
var doc = m.docs.create({ name: 'test 1385' });
assert.notEqual(String(doc.ownerDocument()._id), String(m._id));
m.docs.push(doc);
assert.equal(doc.ownerDocument()._id, String(m._id));
done();
});
});
it('#push should work on EmbeddedDocuments more than 2 levels deep', function(done) {
var Comments = new Schema;
Comments.add({
title : String
, comments : [Comments]
});
var BlogPost = new Schema({
title : String
, comments : [Comments]
});
var db = start()
, Post = db.model('docarray-BlogPost', BlogPost, collection);
var p = new Post({ title: "comment nesting" });
var c1 = p.comments.create({ title: "c1" });
var c2 = p.comments.create({ title: "c2" });
var c3 = p.comments.create({ title: "c3" });
p.comments.push(c1);
c1.comments.push(c2);
c2.comments.push(c3);
p.save(function(err) {
assert.ifError(err);
Post.findById(p._id, function(err, p) {
assert.ifError(err);
var c4 = p.comments.create({ title: "c4" });
p.comments[0].comments[0].comments[0].comments.push(c4);
p.save(function(err) {
assert.ifError(err);
Post.findById(p._id, function(err, p) {
assert.ifError(err);
assert.equal(p.comments[0].comments[0].comments[0].comments[0].title, 'c4');
db.close(done);
});
});
});
});
});
describe('invalidate()', function() {
it('works', function(done) {
var schema = Schema({ docs: [{ name: 'string' }] });
schema.pre('validate', function(next) {
var subdoc = this.docs[this.docs.length - 1];
subdoc.invalidate('name', 'boo boo', '%');
next();
});
var T = mongoose.model('embeddedDocument#invalidate_test', schema, 'asdfasdfa' + random());
var t = new T;
t.docs.push({ name: 100 });
var subdoc = t.docs.create({ name: 'yep' });
assert.throws(function() {
// has no parent array
subdoc.invalidate('name', 'junk', 47);
}, /^Error: Unable to invalidate a subdocument/);
t.validate(function() {
var e = t.errors['docs.0.name'];
assert.ok(e);
assert.equal(e.path, 'docs.0.name');
assert.equal(e.kind, 'user defined');
assert.equal(e.message, 'boo boo');
assert.equal(e.value, '%');
done();
});
});
it('handles validation failures', function(done) {
var db = start();
var nested = Schema({ v: { type: Number, max: 30 }});
var schema = Schema({
docs: [nested]
}, { collection: 'embedded-invalidate-' + random() });
var M = db.model('embedded-invalidate', schema);
var m = new M({ docs: [{ v: 900 }] });
m.save(function(err) {
assert.equal(900, err.errors['docs.0.v'].value);
db.close(done);
});
});
it('removes attached event listeners when creating new doc array', function(done) {
var db = start();
var nested = Schema({ v: { type: Number }});
var schema = Schema({
docs: [nested]
}, { collection: 'gh-2159' });
var M = db.model('gh-2159', schema);
M.create({ docs: [{v: 900}] }, function(error, m) {
m.shouldPrint = true;
assert.ifError(error);
var numListeners = m.listeners('save').length;
assert.ok(numListeners > 0);
m.docs = [{ v: 9000 }];
m.save(function(error, m) {
assert.ifError(error);
assert.equal(numListeners, m.listeners('save').length);
db.close(done);
});
});
});
});
});
Computing file changes ...