Skip to content

Commit

Permalink
Unit tests for LockCollection and expanded parameter checking for same.
Browse files Browse the repository at this point in the history
  • Loading branch information
vsivsi committed Mar 30, 2014
1 parent 5783268 commit 66b65fd
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 12 deletions.
8 changes: 8 additions & 0 deletions HISTORY.md
@@ -0,0 +1,8 @@

### 0.0.5

Added Unit Tests

### 0.0.1 - 0.0.4

Initial revision and documentation fixes.
6 changes: 6 additions & 0 deletions Makefile
@@ -0,0 +1,6 @@
TESTS = test/index.coffee

test:
@./node_modules/mocha/bin/mocha --compilers coffee:coffee-script/register --reporter list $(TESTFLAGS) $(TESTS)

.PHONY: test
37 changes: 27 additions & 10 deletions index.js
Expand Up @@ -4,7 +4,6 @@
See included LICENSE file for details.
************************************************************************/

// Do not create a LockCollection directly using new, use the 'create' static method below
//
// Parameters:
//
Expand All @@ -16,21 +15,29 @@
// timeOut: Seconds to poll when obtaining a lock that is not available. Default: Do not poll
// metaData: side information to store in the lock documents, useful for debugging Default: null
//
// NOTE! -- Do not create a LockCollection directly using new, use the 'create' static method below
//
var LockCollection = exports.LockCollection = function(collection, options) {

var self = this;

if(!(self instanceof LockCollection) || (!options || !options._created)) {
throw new Error("LockCollections must be created using the 'LockCollection.create' static method")
return;
};

if (typeof collection.find !== 'function') {
throw new Error("Do not create a LockCollection directly using 'new', use the 'LockCollection.create' static method")
throw new Error("Invalid collection parameter in LockCollection constructor")
return;
}

var self = this;
options = options || {};
self.writeConcern = options.w == null ? 1 : options.w;

self.timeOut = options.timeOut || 0; // Locks do not poll by default
self.pollingInterval = options.pollingInterval || 5; // Secs
self.lockExpiration = options.lockExpiration || 0; // Never
self.timeOut = options.timeOut || 0; // Locks do not poll by default
self.pollingInterval = options.pollingInterval || 5; // Secs
self.lockExpiration = options.lockExpiration || 0; // Never
self.metaData = options.metaData || null; // None
self.collection = collection;
self.metaData = options.metaData || null;

};

// Static method for creation / initialization of a new LockCollection object.
Expand All @@ -49,15 +56,25 @@ var LockCollection = exports.LockCollection = function(collection, options) {
// callback: function(err, lockCollection) Mandatory.
//
LockCollection.create = function(db, root, options, callback) {
if (typeof db.collection !== 'function') {
if (!db || typeof db.collection !== 'function') {
throw new Error("db is not a valid Mongodb connection object.")
return;
}
if (root && (typeof root !== 'string')) {
throw new Error("root must be a string or falsy.")
return;
}
if (typeof callback !== 'function') {
throw new Error("A callback function must be provided")
return;
}

options = options || {};
options._created = true; // flag that this method was called
root = root || 'fs';
collectionName = root + '.locks';
db.collection(collectionName, function(err, collection) {
if(err) return callback(err);
// Ensure unique files_id so there can only be one lock doc per file
collection.ensureIndex([['files_id', 1]], {unique:true}, function(err, index) {
if(err) return callback(err);
Expand Down
6 changes: 4 additions & 2 deletions package.json
Expand Up @@ -5,10 +5,12 @@
"main": "index.js",
"dependencies": {},
"devDependencies": {
"mongodb": "~1.3.23"
"mongodb": "~1.3.23",
"coffee-script": "*",
"mocha": "*"
},
"scripts": {
"test": "echo \"Error: no test specified, requires MongoDB to run/test.\" && exit 1"
"test": "make test"
},
"repository": {
"type": "git",
Expand Down
79 changes: 79 additions & 0 deletions test/index.coffee
@@ -0,0 +1,79 @@
# Unit tests

assert = require 'assert'
mongo = require 'mongodb'

Lock = require('../index').Lock
LockCollection = require('../index').LockCollection

describe 'test', () ->

id = null
db = null

before (done) ->
server = new mongo.Server 'localhost', 27017
db = new mongo.Db 'gridfs_locks_test', server, {w:1}
db.open done

describe 'LockCollection', () ->

it "should be a function", () ->
assert 'function' is typeof LockCollection

it "shouldn't create instances without the new keyword", () ->
assert.throws (() -> LockCollection()), /LockCollections must be created using the/

it "shouldn't create instances without having used the .created method", () ->
assert.throws (() -> new LockCollection({})), /LockCollections must be created using the/
assert.throws (() -> new LockCollection({},{})), /LockCollections must be created using the/

it "should require a valid collection parameter", () ->
assert.throws (() -> new LockCollection({}, { _created: true})), /Invalid collection parameter/

describe 'LockCollection.create', () ->

it "should require a valid mongo db connection object", () ->
assert.throws (() -> LockCollection.create(null)), /db is not a valid Mongodb connection object/

it "should require a non-falsy root to be a string", () ->
assert.throws (() -> LockCollection.create(db, 1)), /root must be a string or falsy/

it "should require a callback function", () ->
assert.throws (() -> LockCollection.create(db, false, {})), /A callback function must be provided/

it "should create a valid mongodb collection", (done) ->
LockCollection.create db, false, {}, (e, lc) ->
assert.equal typeof lc.collection.find, 'function'
done()

it "should properly index the .locks collection", (done) ->
LockCollection.create db, false, {}, (e, lc) ->
lc.collection.indexExists "files_id_1", (e, ii) ->
assert.equal ii, true
done()

it "should use the default GridFS collection root when no root is given", (done) ->
LockCollection.create db, false, {}, (e, lc) ->
assert.equal lc.collection.collectionName, mongo.GridStore.DEFAULT_ROOT_COLLECTION + ".locks"
done()

it "should use the provided collection root name when given", (done) ->
LockCollection.create db, 'test', {}, (e, lc) ->
assert.equal lc.collection.collectionName, "test.locks"
done()

it "should properly record all options", (done) ->
LockCollection.create db, null, { w: 16, timeOut: 16, pollingInterval: 16, lockExpiration: 16, metaData: 16 }, (e, lc) ->
assert.equal lc.writeConcern, 16
assert.equal lc.timeOut, 16
assert.equal lc.pollingInterval, 16
assert.equal lc.lockExpiration, 16
assert.equal lc.metaData, 16
done()

describe 'Lock', () ->

after (done) ->
db.dropDatabase () ->
db.close true, done

0 comments on commit 66b65fd

Please sign in to comment.