Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fixed #56 error: Argument passed in must be a single String of 12 byt…

…es or a string of 24 hex characters; add more test case for conllection.js; add test coverage;
commit 2a4779b3d63fb2503aecc1784fa7f8cf6860c686 1 parent c919509
@fengmk2 fengmk2 authored
View
2  .gitignore
@@ -1 +1,3 @@
node_modules
+coverage.html
+lib-cov
View
3  .travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - 0.6
View
20 Makefile
@@ -0,0 +1,20 @@
+TESTS = $(shell find test -type f -name "*.js")
+TESTTIMEOUT = 5000
+REPORTER = spec
+PROJECT_DIR = $(shell pwd)
+
+test:
+ @npm install
+ @NODE_ENV=test ./node_modules/mocha/bin/mocha \
+ --reporter $(REPORTER) --timeout $(TESTTIMEOUT) $(TESTS)
+
+lib-cov:
+ @rm -rf ./$@
+ @jscoverage --encoding=utf-8 ./lib ./$@
+
+test-cov: lib-cov
+ @MONGOSKIN_COV=1 $(MAKE) test REPORTER=progress
+ @MONGOSKIN_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html
+ @$(MAKE) test REPORTER=markdown > test_results.md
+
+.PHONY: test test-cov lib-cov
View
43 Readme.md
@@ -1,11 +1,14 @@
-## This project is a wrapper of node-mongodb-native
+# mongoskin
-* node-mongodb-native document http://christkv.github.com/node-mongodb-native/
+[![Build Status](https://secure.travis-ci.org/kissjs/node-mongoskin.png)](http://travis-ci.org/kissjs/node-mongoskin)
-## How to validate input?
+This project is a wrapper of [node-mongodb-native](http://christkv.github.com/node-mongodb-native/).
+All api is same to mongodb-native, please see the [document](http://christkv.github.com/node-mongodb-native/) first.
-I wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform)
-base on [node-validator](https://github.com/chriso/node-validator)
+## Test
+
+* test results: [test_results.md](https://github.com/kissjs/node-mongoskin/blob/master/test_results.md)
+* jscoverage: [**70%**](http://fengmk2.github.com/coverage/mongoskin.html)
<a name='index'>
@@ -569,6 +572,36 @@ All these methods will return the SkinCursor itself.
[Back to index](#index)
+## How to validate input?
+
+I wrote a middleware to validate post data, [node-iform](https://github.com/guileen/node-iform)
+base on [node-validator](https://github.com/chriso/node-validator)
+
+## Authors
+
+Below is the output from `git-summary`.
+
+ project: node-mongoskin
+ commits: 108
+ active : 52 days
+ files : 29
+ authors:
+ 49 Lin Gui 45.4%
+ 34 guilin 桂林 31.5%
+ 5 guilin 4.6%
+ 5 fengmk2 4.6%
+ 2 François de Metz 1.9%
+ 2 Paul Gebheim 1.9%
+ 2 Gui Lin 1.9%
+ 1 humanchimp 0.9%
+ 1 Aneil Mallavarapu 0.9%
+ 1 wmertens 0.9%
+ 1 Harvey McQueen 0.9%
+ 1 Joe Faber 0.9%
+ 1 Matt Perpick 0.9%
+ 1 Quang Van 0.9%
+ 1 Rakshit Menpara 0.9%
+ 1 Wout Mertens 0.9%
## License
View
4 examples/config.js
@@ -1,5 +1,5 @@
var mongoskin = require('../lib/mongoskin/');
-require('myconsole').replace();
-
exports.db = mongoskin.db('localhost/test');
+
+mongoskin.db('localhost', { database: 'test' });
View
45 examples/replSetBenchmark.js
@@ -0,0 +1,45 @@
+
+var mongo = require('../');
+
+var conf = {
+ hosts: [
+ '127.0.0.1:27110/?auto_reconnect',
+ '127.0.0.1:27111/?auto_reconnect'
+ ],
+ dataDB: 'test'
+};
+
+var db = exports.db = mongo.db(conf.hosts, {
+ database: conf.dataDB
+});
+
+var noop = function() {};
+
+db.bind('user');
+// db.user.ensureIndex({ name: 1 }, { unique: true }, noop);
+// db.user.ensureIndex({ enable: 1 }, noop);
+// db.user.ensureIndex({ created_at: 1, enable: 1 }, noop);
+
+var counter = 0;
+setInterval(function () {
+ db.user.findItems({ name: 'name_' + counter }, function (err, items) {
+ if (err) {
+ console.error('findItems user error', err);
+ }
+ if (items) {
+ console.log('total: %d users', items.length);
+ }
+ });
+ db.user.insert({
+ name: 'name_' + counter,
+ createtime: new Date()
+ }, function(err, user) {
+ if (err) {
+ console.error('insert user error', err);
+ }
+ if (user && user[0]) {
+ console.log('new: %d %s', counter, user[0]._id);
+ }
+ });
+ counter++;
+}, 10);
View
2  index.js
@@ -1 +1 @@
-module.exports = require('./lib/mongoskin');
+module.exports = process.env.MONGOSKIN_COV ? require('./lib-cov/mongoskin') : require('./lib/mongoskin');
View
143 lib/mongoskin/collection.js
@@ -49,13 +49,15 @@ var SkinCollection = exports.SkinCollection = function(skinDb, collectionName) {
this.state = STATE_CLOSE;
this.internalHint;
var that = this;
- this.__defineGetter__('hint', function() { return this.internalHint; });
- this.__defineSetter__('hint', function(value) {
- this.internalHint = value;
- this.open(function(err, collection) {
- collection.hint = value;
- that.internalHint = collection.hint;
- });
+ this.__defineGetter__('hint', function () {
+ return this.internalHint;
+ });
+ this.__defineSetter__('hint', function (value) {
+ this.internalHint = value;
+ this.open(function(err, collection) {
+ collection.hint = value;
+ that.internalHint = collection.hint;
+ });
});
this.emitter = new events.EventEmitter();
@@ -96,28 +98,28 @@ SkinCollection.prototype.open = function(fn) {
return fn(null, this.collection);
case STATE_OPENNING:
return this.emitter.once('open', fn);
- case STATE_CLOSE:
+ // case STATE_CLOSE:
default:
var that = this;
this.emitter.once('open', fn);
this.state = STATE_OPENNING;
this.skinDb.open(function(err, db) {
- if (err) {
+ if (err) {
+ that.state = STATE_CLOSE;
+ return that.emitter.emit('open', err, null);
+ }
+ that.skinDb.db.collection(that.collectionName, function (err, collection) {
+ if (collection) {
+ that.state = STATE_OPEN;
+ that.collection = collection;
+ if (that.hint) {
+ that.collection.hint = that.hit;
+ }
+ } else {
that.state = STATE_CLOSE;
- return that.emitter.emit('open', err, null);
}
- that.skinDb.db.collection(that.collectionName, function(err, collection) {
- if (collection) {
- that.state = STATE_OPEN;
- that.collection = collection;
- if (that.hint) {
- that.collection.hint = that.hit;
- }
- }else {
- that.state = STATE_CLOSE;
- }
- that.emitter.emit('open', err, collection);
- });
+ that.emitter.emit('open', err, collection);
+ });
});
}
};
@@ -134,94 +136,109 @@ SkinCollection.prototype.drop = function(fn) {
/**
* same args as find, but use Array as callback result but not use Cursor
*
- * findItems(args, function(err, items){});
+ * findItems(args, function (err, items) {});
*
* same as
*
- * find(args, function(err, cursor){cursor.toArray(err, items){}});
+ * find(args).toArray(function (err, items) {});
+ *
+ * or using `mongodb.collection.find()`
+ *
+ * find(args, function (err, cursor) {
+ * cursor.toArray(function (err, items) {
+ * });
+ * });
*
*/
-SkinCollection.prototype.findItems = function() {
- var args = __slice.call(arguments),
- fn = args[args.length - 1];
-
- args[args.length - 1] = function(err, cursor) {
+SkinCollection.prototype.findItems = function (query, options, callback) {
+ var args = __slice.call(arguments);
+ var fn = args[args.length - 1];
+ args[args.length - 1] = function (err, cursor) {
if (err) {
- fn(err);
- } else {
- cursor.toArray(fn);
+ return fn(err);
}
- }
-
- this._find.apply(this, args);
+ cursor.toArray(fn);
+ };
+ this.find.apply(this, args);
};
/**
- * find and cursor.each
+ * find and cursor.each(fn).
+ *
+ * @param {Object} [query]
+ * @param {Object} [options]
+ * @param {Function(err, item)} eachCallback
*/
-SkinCollection.prototype.findEach = function() {
- var args = __slice.call(arguments),
- fn = args[args.length - 1];
-
- args[args.length - 1] = function(err, cursor) {
+SkinCollection.prototype.findEach = function (query, options, eachCallback) {
+ var args = __slice.call(arguments);
+ var fn = args[args.length - 1];
+ args[args.length - 1] = function (err, cursor) {
if (err) {
- fn(err);
- } else {
- cursor.each(fn);
+ return fn(err);
}
- }
-
- this._find.apply(this, args);
+ cursor.each(fn);
+ };
+ this.find.apply(this, args);
};
/**
- * @deprecated use SkinDb.id instead
+ * @deprecated use `SkinDb.toId` instead
*/
SkinCollection.prototype.id = function(hex) {
return this.skinDb.toId(hex);
};
/**
- * use hex id as first argument, support ObjectID and String id
+ * Find one object by _id.
*
- * @param {String/ObjectID} id
- * @param {Function} callback
- * @return {Object} cursor
+ * @param {String|ObjectID|Number} id, doc primary key `_id`
+ * @param {Function(err, doc)} callback
* @api public
*/
-SkinCollection.prototype.findById = function() {
+SkinCollection.prototype.findById = function (id, callback) {
var args = __slice.call(arguments);
args[0] = {_id: this.skinDb.toId(args[0])};
this.findOne.apply(this, args);
};
/**
- * use hex id as first argument
+ * Update doc by _id.
+ * @param {String|ObjectID|Number} id, doc primary key `_id`
+ * @param {Function(err)} callback
+ * @api public
*/
-SkinCollection.prototype.updateById = function() {
+SkinCollection.prototype.updateById = function (id, callback) {
var args = __slice.call(arguments);
args[0] = {_id: this.skinDb.toId(args[0])};
this.update.apply(this, args);
};
/**
- * use hex id as first argument
+ * Remove doc by _id.
+ * @param {String|ObjectID|Number} id, doc primary key `_id`
+ * @param {Function(err)} callback
+ * @api public
*/
-SkinCollection.prototype.removeById = function() {
+SkinCollection.prototype.removeById = function (id, callback) {
var args = __slice.call(arguments);
args[0] = {_id: this.skinDb.toId(args[0])};
this.remove.apply(this, args);
};
/**
- * if last argument is not a function, then returns a SkinCursor
+ * Creates a cursor for a query that can be used to iterate over results from MongoDB.
+ *
+ * @param {Object} query
+ * @param {Object} options
+ * @param {Function(err, docs)} callback
+ * @return {SkinCursor} if last argument is not a function, then returns a SkinCursor
+ * @api public
*/
-SkinCollection.prototype.find = function() {
+SkinCollection.prototype.find = function (query, options, callback) {
var args = arguments.length > 0 ? __slice.call(arguments, 0) : [];
- if (args.length > 0 && typeof(args[args.length - 1]) === 'function') {
+ if (args.length > 0 && typeof args[args.length - 1] === 'function') {
this._find.apply(this, args);
- }else {
+ } else {
return new SkinCursor(null, this, args);
}
-};
-
+};
View
9 lib/mongoskin/db.js
@@ -30,8 +30,11 @@ var SkinDb = exports.SkinDb = function(db, username, password) {
this.ObjectID = mongodb.ObjectID /* 0.9.7-3-2 */ || db.bson_serializer.ObjectID /* <= 0.9.7 */;
};
-SkinDb.prototype.toObjectID = SkinDb.prototype.toId = function(hex) {
- if(hex instanceof this.ObjectID) {
+SkinDb.prototype.toObjectID = SkinDb.prototype.toId = function (hex) {
+ if (hex instanceof this.ObjectID) {
+ return hex;
+ }
+ if (!hex || hex.length !== 24) {
return hex;
}
return this.ObjectID.createFromHexString(hex);
@@ -118,7 +121,7 @@ SkinDb.prototype.collection = function(name) {
*/
SkinDb.prototype.gridfs = function() {
return this.skinGridStore || (this.skinGridStore = new SkinGridStore(this));
-}
+};
/**
* bind additional method to SkinCollection
View
7 package.json
@@ -9,7 +9,7 @@
},
"main": "index",
"keywords": [
- "mongodb"
+ "mongodb", "database", "nosql"
],
"engines": {
"node": ">=0.4.0"
@@ -18,9 +18,8 @@
"mongodb": "1.0.x"
},
"devDependencies": {
- "myconsole": ">=0.1.2",
- "expresso": "0.9.2",
- "should": "0.3.2"
+ "mocha": "*",
+ "should": "*"
},
"directories": {
"lib": "lib/mongoskin"
View
281 test/collection.js
@@ -0,0 +1,281 @@
+/*!
+ * mongoskin - test/collection.js
+ * Copyright(c) 2012 fengmk2 <fengmk2@gmail.com>
+ * MIT Licensed
+ */
+
+"use strict";
+
+/**
+ * Module dependencies.
+ */
+
+var mongoskin = require('../');
+var should = require('should');
+
+describe('collection.js', function () {
+ var db;
+ before(function (done) {
+ db = mongoskin.db('localhost/mongoskin_test');
+ db.bind('testcollection');
+ db.testcollection.ensureIndex({title: -1});
+ db.testcollection.findItems(function (err, rows) {
+ if (err) {
+ return done(err);
+ }
+ rows.should.be.instanceof(Array).with.length(0);
+ done();
+ });
+ });
+ after(function (done) {
+ db.testcollection.drop(function (err, result) {
+ if (err) {
+ return done(err);
+ }
+ should.ok(result);
+ db.close(done);
+ });
+ });
+
+ describe('id()', function () {
+ it('should convert string id to ObjectID success', function () {
+ var id = '4ec4b2b9f44a927223000001';
+ id = db.testcollection.id(id);
+ id.should.be.instanceof(db.testcollection.ObjectID);
+ id = db.testcollection.id(id);
+ id.should.be.instanceof(db.testcollection.ObjectID);
+ id = '4ec4b2b9f44a927223000foo';
+ id = db.testcollection.id(id);
+ id.should.be.instanceof(db.testcollection.ObjectID);
+ });
+ it('should return source id when id length !== 24', function () {
+ var ids = [123, '4ec4b2b9f44a92722300000', 'abc', '4ec4b2b9f44a927223000f00123123'];
+ ids.forEach(function (id) {
+ db.testcollection.id(id).should.equal(id);
+ });
+ });
+ });
+
+ describe('find(), findItems(), findEach()', function () {
+ var objectIds = [], stringIds = [];
+ before(function (done) {
+ db.bind('comment');
+ var inserts = [];
+ for (var i = 0; i < 100; i++) {
+ inserts.push({
+ text: 'this is comment ' + i,
+ createtime: new Date()
+ });
+ }
+ db.comment.insert(inserts, function (err, docs) {
+ if (err) {
+ return done(err);
+ }
+ for (var i = 0, l = docs.length; i < l; i++) {
+ var doc = docs[i];
+ stringIds.push(doc._id.toString());
+ objectIds.push(doc._id);
+ }
+ done();
+ });
+ });
+ after(function (done) {
+ db.comment.drop(done);
+ });
+
+ it('should find().toArray() return 100 comments', function (done) {
+ db.comment.find().toArray(function (err, rows) {
+ should.not.exist(err);
+ rows.should.be.instanceof(Array).with.length(100);
+ done();
+ });
+ });
+
+ it('should findItems(fn) all comments', function (done) {
+ db.comment.findItems(function (err, comments) {
+ should.not.exist(err);
+ should.exist(comments);
+ comments.should.be.instanceof(Array).with.length(100);
+ done();
+ });
+ });
+
+ it('should findItems({} fn) all comments', function (done) {
+ db.comment.findItems(function (err, comments) {
+ should.not.exist(err);
+ should.exist(comments);
+ comments.should.be.instanceof(Array).with.length(100);
+ done();
+ });
+ });
+
+ it('should findItems({limit: 10}) query wrong return top 0 comments', function (done) {
+ db.comment.findItems({limit: 10}, function (err, comments) {
+ should.not.exist(err);
+ comments.should.be.instanceof(Array).with.length(0);
+ done();
+ });
+ });
+
+ it('should findItems({}, {limit: 10}) return top 10 comments', function (done) {
+ db.comment.findItems({}, {limit: 10}, function (err, comments) {
+ should.not.exist(err);
+ comments.should.be.instanceof(Array).with.length(10);
+ done();
+ });
+ });
+
+ it('should findEach(fn) call fn 100 times', function (done) {
+ var count = 0;
+ db.comment.findEach(function (err, comment) {
+ should.not.exist(err);
+ if (!comment) {
+ count.should.equal(100);
+ return done();
+ }
+ count++;
+ });
+ });
+
+ it('should findEach({}, {limit: 20}, fn) call fn 20 times', function (done) {
+ var count = 0;
+ db.comment.findEach({}, {limit: 20}, function (err, comment) {
+ should.not.exist(err);
+ if (!comment) {
+ count.should.equal(20);
+ return done();
+ }
+ count++;
+ });
+ });
+
+ describe('mock find() error', function () {
+ var _find;
+ before(function () {
+ _find = db.comment.find;
+ db.comment.find = function () {
+ var callback = arguments[arguments.length - 1];
+ process.nextTick(function () {
+ callback(new Error('mock find() error'));
+ });
+ };
+ });
+ after(function () {
+ if (_find) {
+ db.comment.find = _find;
+ }
+ });
+
+ it('should findItems() error', function (done) {
+ db.comment.findItems(function (err, docs) {
+ should.exist(err);
+ err.should.be.instanceof(Error).with.have.property('message', 'mock find() error');
+ should.not.exist(docs);
+ done();
+ });
+ });
+ it('should findEach() error', function (done) {
+ db.comment.findEach(function (err, docs) {
+ should.exist(err);
+ err.should.be.instanceof(Error).with.have.property('message', 'mock find() error');
+ should.not.exist(docs);
+ done();
+ });
+ });
+ });
+
+ });
+
+ describe('findById(), updateById(), removeById()', function () {
+ var now = new Date();
+ var articleId;
+ before(function (done) {
+ db.bind('article');
+ db.article.insert({title: 'test article title ' + now, created_at: now}, function (err, article) {
+ if (article) {
+ articleId = article[0]._id;
+ }
+ done(err);
+ });
+ });
+ after(function (done) {
+ db.article.drop(done);
+ });
+
+ describe('findById()', function () {
+ it('should find one object by ObjectID', function (done) {
+ db.article.findById(articleId, function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ article.should.have.property('_id').with.instanceof(db.ObjectID);
+ article.should.have.property('created_at').with.instanceof(Date);
+ article.should.have.property('title').with.include(now.toString());
+ article.created_at.toString().should.equal(now.toString());
+ done();
+ });
+ });
+ it('should find one object by String id', function (done) {
+ db.article.findById(articleId.toString(), function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ article.should.have.property('_id').with.instanceof(db.ObjectID);
+ article.should.have.property('created_at').with.instanceof(Date);
+ article.should.have.property('title').with.include(now.toString());
+ article.created_at.toString().should.equal(now.toString());
+ done();
+ });
+ });
+ it('should not find when id not exists', function (done) {
+ db.article.findById('foo', function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ done();
+ });
+ });
+ });
+
+ describe('updateById()', function () {
+ it('should update obj by id', function (done) {
+ var updatedTime = new Date();
+ var doc = {
+ $set: {
+ title: 'new title ' + updatedTime,
+ updated_at: updatedTime
+ }
+ };
+ db.article.updateById(articleId.toString(), doc, function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ db.article.findById(articleId, function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ article.should.have.property('title', 'new title ' + updatedTime);
+ article.should.have.property('updated_at').with.instanceof(Date);
+ article.updated_at.toString().should.equal(updatedTime.toString());
+ done();
+ });
+ });
+ });
+ });
+
+ describe('removeById()', function () {
+ it('should remove obj by id', function (done) {
+ var id = articleId.toString();
+ db.article.findById(id, function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ db.article.removeById(id, function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ db.article.findById(id, function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ done();
+ });
+ });
+ });
+ });
+ });
+
+ });
+});
View
55 test/collection.test.js
@@ -1,55 +0,0 @@
-
-/**
- * Module dependencies.
- */
-
-var mongoskin = require('../')
- , should = require('should');
-
-
-module.exports = {
- 'test id()': function() {
- var db = mongoskin.db('localhost/test');
- db.bind('testcollection');
- var id = '4ec4b2b9f44a927223000001';
- id = db.testcollection.id(id);
- id.should.be.instanceof(db.testcollection.ObjectID);
- id = db.testcollection.id(id);
- id.should.be.instanceof(db.testcollection.ObjectID);
- db.close();
- },
- 'test findById string id': function() {
- var db = mongoskin.db('localhost/test');
- var ObjectID = db.db.bson_serializer.ObjectID;
- db.bind('article');
- var now = new Date();
- var article = {title: 'test article title ' + now.getTime(), created_at: now};
- db.article.insert(article, function(err, obj) {
- should.not.exist(err);
- should.exist(obj);
- obj.should.have.length(1);
- article.should.have.property('_id').with.instanceof(ObjectID);
- obj[0].should.have.property('_id').with.instanceof(ObjectID);
-
- var count = 2;
- db.article.findById(article._id.toString(), function(err, obj) {
- should.not.exist(err);
- should.exist(obj);
- obj.should.have.property('_id').with.instanceof(ObjectID);
- obj._id.should.eql(article._id);
- if(--count === 0) {
- db.close();
- }
- });
- db.article.findById(article._id, function(err, obj) {
- should.not.exist(err);
- should.exist(obj);
- obj.should.have.property('_id').with.instanceof(ObjectID);
- obj._id.should.eql(article._id);
- if(--count === 0) {
- db.close();
- }
- });
- });
- }
-};
View
2  test/mocha.opts
@@ -0,0 +1,2 @@
+--require should
+--growl
View
216 test_results.md
@@ -0,0 +1,216 @@
+# TOC
+ - [collection.js](#collectionjs)
+ - [id()](#collectionjs-id)
+ - [find(), findItems(), findEach()](#collectionjs-find-finditems-findeach)
+ - [mock find() error](#collectionjs-find-finditems-findeach-mock-find-error)
+ - [findById(), updateById(), removeById()](#collectionjs-findbyid-updatebyid-removebyid)
+ - [findById()](#collectionjs-findbyid-updatebyid-removebyid-findbyid)
+ - [updateById()](#collectionjs-findbyid-updatebyid-removebyid-updatebyid)
+ - [removeById()](#collectionjs-findbyid-updatebyid-removebyid-removebyid)
+<a name="" />
+
+<a name="collectionjs" />
+# collection.js
+<a name="collectionjs-id" />
+## id()
+should convert string id to ObjectID success.
+
+```jsvar id = '4ec4b2b9f44a927223000001';
+id = db.testcollection.id(id);
+id.should.be.instanceof(db.testcollection.ObjectID);
+id = db.testcollection.id(id);
+id.should.be.instanceof(db.testcollection.ObjectID);
+id = '4ec4b2b9f44a927223000foo';
+id = db.testcollection.id(id);
+id.should.be.instanceof(db.testcollection.ObjectID);
+```
+
+should return source id when id length !== 24.
+
+```jsvar ids = [123, '4ec4b2b9f44a92722300000', 'abc', '4ec4b2b9f44a927223000f00123123'];
+ids.forEach(function (id) {
+ db.testcollection.id(id).should.equal(id);
+});
+```
+
+<a name="collectionjs-find-finditems-findeach" />
+## find(), findItems(), findEach()
+should find().toArray() return 100 comments.
+
+```jsdb.comment.find().toArray(function (err, rows) {
+ should.not.exist(err);
+ rows.should.be.instanceof(Array).with.length(100);
+ done();
+});
+```
+
+should findItems(fn) all comments.
+
+```jsdb.comment.findItems(function (err, comments) {
+ should.not.exist(err);
+ should.exist(comments);
+ comments.should.be.instanceof(Array).with.length(100);
+ done();
+});
+```
+
+should findItems({} fn) all comments.
+
+```jsdb.comment.findItems(function (err, comments) {
+ should.not.exist(err);
+ should.exist(comments);
+ comments.should.be.instanceof(Array).with.length(100);
+ done();
+});
+```
+
+should findItems({limit: 10}) query wrong return top 0 comments.
+
+```jsdb.comment.findItems({limit: 10}, function (err, comments) {
+ should.not.exist(err);
+ comments.should.be.instanceof(Array).with.length(0);
+ done();
+});
+```
+
+should findItems({}, {limit: 10}) return top 10 comments.
+
+```jsdb.comment.findItems({}, {limit: 10}, function (err, comments) {
+ should.not.exist(err);
+ comments.should.be.instanceof(Array).with.length(10);
+ done();
+});
+```
+
+should findEach(fn) call fn 100 times.
+
+```jsvar count = 0;
+db.comment.findEach(function (err, comment) {
+ should.not.exist(err);
+ if (!comment) {
+ count.should.equal(100);
+ return done();
+ }
+ count++;
+});
+```
+
+should findEach({}, {limit: 20}, fn) call fn 20 times.
+
+```jsvar count = 0;
+db.comment.findEach({}, {limit: 20}, function (err, comment) {
+ should.not.exist(err);
+ if (!comment) {
+ count.should.equal(20);
+ return done();
+ }
+ count++;
+});
+```
+
+<a name="collectionjs-find-finditems-findeach-mock-find-error" />
+### mock find() error
+should findItems() error.
+
+```jsdb.comment.findItems(function (err, docs) {
+ should.exist(err);
+ err.should.be.instanceof(Error).with.have.property('message', 'mock find() error');
+ should.not.exist(docs);
+ done();
+});
+```
+
+should findEach() error.
+
+```jsdb.comment.findEach(function (err, docs) {
+ should.exist(err);
+ err.should.be.instanceof(Error).with.have.property('message', 'mock find() error');
+ should.not.exist(docs);
+ done();
+});
+```
+
+<a name="collectionjs-findbyid-updatebyid-removebyid" />
+## findById(), updateById(), removeById()
+<a name="collectionjs-findbyid-updatebyid-removebyid-findbyid" />
+### findById()
+should find one object by ObjectID.
+
+```jsdb.article.findById(articleId, function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ article.should.have.property('_id').with.instanceof(db.ObjectID);
+ article.should.have.property('created_at').with.instanceof(Date);
+ article.should.have.property('title').with.include(now.toString());
+ article.created_at.toString().should.equal(now.toString());
+ done();
+});
+```
+
+should find one object by String id.
+
+```jsdb.article.findById(articleId.toString(), function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ article.should.have.property('_id').with.instanceof(db.ObjectID);
+ article.should.have.property('created_at').with.instanceof(Date);
+ article.should.have.property('title').with.include(now.toString());
+ article.created_at.toString().should.equal(now.toString());
+ done();
+});
+```
+
+should not find when id not exists.
+
+```jsdb.article.findById('foo', function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ done();
+});
+```
+
+<a name="collectionjs-findbyid-updatebyid-removebyid-updatebyid" />
+### updateById()
+should update obj by id.
+
+```jsvar updatedTime = new Date();
+var doc = {
+ $set: {
+ title: 'new title ' + updatedTime,
+ updated_at: updatedTime
+ }
+};
+db.article.updateById(articleId.toString(), doc, function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ db.article.findById(articleId, function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ article.should.have.property('title', 'new title ' + updatedTime);
+ article.should.have.property('updated_at').with.instanceof(Date);
+ article.updated_at.toString().should.equal(updatedTime.toString());
+ done();
+ });
+});
+```
+
+<a name="collectionjs-findbyid-updatebyid-removebyid-removebyid" />
+### removeById()
+should remove obj by id.
+
+```jsvar id = articleId.toString();
+db.article.findById(id, function (err, article) {
+ should.not.exist(err);
+ should.exist(article);
+ db.article.removeById(id, function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ db.article.findById(id, function (err, article) {
+ should.not.exist(err);
+ should.not.exist(article);
+ done();
+ });
+ });
+});
+```
+

0 comments on commit 2a4779b

Please sign in to comment.
Something went wrong with that request. Please try again.