From 13f5753405967e71b6ee92f8d862756ac4b29fc1 Mon Sep 17 00:00:00 2001 From: indexzero Date: Sun, 5 Jun 2011 01:39:39 -0400 Subject: [PATCH] [minor] Update `nconf.version` to use pkginfo --- docs/nconf.html | 110 +++---------------------------- docs/nconf/provider.html | 120 ++++++++++++++++++++++++++++++++++ docs/nconf/stores.html | 18 +++-- docs/nconf/stores/file.html | 3 +- docs/nconf/stores/memory.html | 49 ++++++++++++-- docs/nconf/stores/redis.html | 111 +++++++++++++++++++++---------- lib/nconf.js | 4 +- package.json | 1 + test/nconf-test.js | 10 +++ 9 files changed, 276 insertions(+), 150 deletions(-) create mode 100644 docs/nconf/provider.html diff --git a/docs/nconf.html b/docs/nconf.html index 6d0ffde..91687c4 100644 --- a/docs/nconf.html +++ b/docs/nconf.html @@ -1,114 +1,22 @@ - nconf.js

nconf.js

/*
+      nconf.js           

nconf.js

/*
  * nconf.js: Top-level include for the nconf module
  *
  * (C) 2011, Charlie Robbins
  *
  */
 
-require.paths.unshift(__dirname);
-
-var nconf = exports;

Version 0.1.7 :: 4/20/2011

nconf.version = [0, 1, 7];

Include the various store types exposed by nconf

nconf.stores  = require('nconf/stores');

function use (type, options)

- -

@type {string} Type of the nconf store to use.

- -

@options {Object} Options for the store instance.

- -

Sets the active nconf.store to a new instance of the -specified type.

nconf.use = function (type, options) {
-  if (!nconf.store || type.toLowerCase() !== nconf.store.type) {
-    nconf.store = new nconf.stores.create(type, options);
-  }
-};

function get (key, callback)

- -

@key {string} Key to retrieve for this instance.

- -

@callback {function} Optional Continuation to respond to when complete.

- -

Retrieves the value for the specified key (if any).

nconf.get = function (key, callback) {
-  return nconf.store.get(key, callback);
-};

function set (key, value, callback)

- -

@key {string} Key to set in this instance

- -

@value {literal|Object} Value for the specified key

- -

@callback {function} Optional Continuation to respond to when complete.

- -

Sets the value for the specified key in this instance.

nconf.set = function (key, value, callback) {
-  return nconf.store.set(key, value, callback);
-};

function clear (key, callback)

- -

@key {string} Key to remove from this instance

- -

@callback {function} Optional Continuation to respond to when complete.

- -

Removes the value for the specified key from this instance.

nconf.clear = function (key, callback) {
-  return nconf.store.clear(key, callback);
-};

function load (callback)

- -

@callback {function} Continuation to respond to when complete.

- -

Responds with an Object representing all keys associated in this instance.

nconf.load = function (callback) {

If we don't have a callback and the current -store is capable of loading synchronously -then do so.

  if (!callback && nconf.store.loadSync) {
-    return nconf.store.loadSync();
-  }
-  
-  
-  if (!nconf.store.load) {
-    var error = new Error('nconf store ' + nconf.store.type + ' has no load() method');
-    if (callback) {
-      return callback (error);
-    }
-    
-    throw error;
-  }
-  
-  return nconf.store.load(callback);
-};

function save (value, callback)

- -

@value {Object} Optional Config object to set for this instance

- -

@callback {function} Continuation to respond to when complete.

- -

Removes any existing configuration settings that may exist in this -instance and then adds all key-value pairs in value.

nconf.save = function (value, callback) {
-  if (!callback) {
-    callback = value;
-    value = null;
-    

If we still don't have a callback and the -current store is capable of saving synchronously -then do so.

    if (!callback && nconf.store.saveSync) {
-      return nconf.store.saveSync();
-    }
-  }
-  
-  if (!nconf.store.save) {
-    var error = new Error('nconf store ' + nconf.store.type + ' has no save() method');
-    if (callback) {
-      return callback (error);
-    }
-    
-    throw error;
-  }
-  
-  return nconf.store.save(value, callback);
-};

function reset (callback)

- -

@callback {function} Optional Continuation to respond to when complete.

- -

Clears all keys associated with this instance.

nconf.reset = function (callback) {
-  return nconf.store.reset(callback);
-};

function key (arguments)

- -

Returns a : joined string from the arguments.

nconf.key = function () {
-  return Array.prototype.slice.call(arguments).join(':');
-};

function path (key)

+var Provider = require('./nconf/provider').Provider, + nconf = module.exports = Object.create(Provider.prototype);

Use the memory engine by default.

nconf.use('memory');

Version 0.1.9 :: 5/16/2011

nconf.version = [0, 1, 9];

function path (key)

@key {string} The ':' delimited key to split

Returns a fully-qualified path to a nested nconf key.

nconf.path = function (key) {
   return key.split(':');
-};

Use the memory engine by default

nconf.use('memory');
+};

function key (arguments)

+ +

Returns a : joined string from the arguments.

nconf.key = function () {
+  return Array.prototype.slice.call(arguments).join(':');
+};

Expose the various components included with nconf

nconf.stores   = require('./nconf/stores');
+nconf.Provider = Provider;
 
 
\ No newline at end of file diff --git a/docs/nconf/provider.html b/docs/nconf/provider.html new file mode 100644 index 0000000..776fb86 --- /dev/null +++ b/docs/nconf/provider.html @@ -0,0 +1,120 @@ + provider.js

provider.js

/*
+ * provider.js: Abstraction providing an interface into pluggable configuration storage.
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+
+var stores = require('./stores');

function Provider (options)

+ +

@options {Object} Options for this instance.

+ +

Constructor function for the Provider object responsible +for exposing the pluggable storage features of nconf.

var Provider = exports.Provider = function (options) {
+  options = options || {};
+  this.store = stores.create(options.type || 'memory', options);
+};

function use (type, options)

+ +

@type {string} Type of the nconf store to use.

+ +

@options {Object} Options for the store instance.

+ +

Sets the active this.store to a new instance of the +specified type.

Provider.prototype.use = function (type, options) {
+  if (!this.store || type.toLowerCase() !== this.store.type) {
+    this.store = stores.create(type, options);
+  }
+};

function get (key, callback)

+ +

@key {string} Key to retrieve for this instance.

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Retrieves the value for the specified key (if any).

Provider.prototype.get = function (key, callback) {
+  return this.store.get(key, callback);
+};

function set (key, value, callback)

+ +

@key {string} Key to set in this instance

+ +

@value {literal|Object} Value for the specified key

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Sets the value for the specified key in this instance.

Provider.prototype.set = function (key, value, callback) {
+  return this.store.set(key, value, callback);
+};

function merge (key, value)

+ +

@key {string} Key to merge the value into

+ +

@value {literal|Object} Value to merge into the key

+ +

Merges the properties in value into the existing object value +at key. If the existing value key is not an Object, it will be +completely overwritten.

Provider.prototype.merge = function (key, value, callback) {
+  return this.store.merge(key, value, callback);
+}

function clear (key, callback)

+ +

@key {string} Key to remove from this instance

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Removes the value for the specified key from this instance.

Provider.prototype.clear = function (key, callback) {
+  return this.store.clear(key, callback);
+};

function load (callback)

+ +

@callback {function} Continuation to respond to when complete.

+ +

Responds with an Object representing all keys associated in this instance.

Provider.prototype.load = function (callback) {

If we don't have a callback and the current +store is capable of loading synchronously +then do so.

  if (!callback && this.store.loadSync) {
+    return this.store.loadSync();
+  }
+  
+  
+  if (!this.store.load) {
+    var error = new Error('nconf store ' + this.store.type + ' has no load() method');
+    if (callback) {
+      return callback (error);
+    }
+    
+    throw error;
+  }
+  
+  return this.store.load(callback);
+};

function save (value, callback)

+ +

@value {Object} Optional Config object to set for this instance

+ +

@callback {function} Continuation to respond to when complete.

+ +

Removes any existing configuration settings that may exist in this +instance and then adds all key-value pairs in value.

Provider.prototype.save = function (value, callback) {
+  if (!callback) {
+    callback = value;
+    value = null;
+    

If we still don't have a callback and the +current store is capable of saving synchronously +then do so.

    if (!callback && this.store.saveSync) {
+      return this.store.saveSync();
+    }
+  }
+  
+  if (!this.store.save) {
+    var error = new Error('nconf store ' + this.store.type + ' has no save() method');
+    if (callback) {
+      return callback (error);
+    }
+    
+    throw error;
+  }
+  
+  return this.store.save(value, callback);
+};

function reset (callback)

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Clears all keys associated with this instance.

Provider.prototype.reset = function (callback) {
+  return this.store.reset(callback);
+};
+
+
\ No newline at end of file diff --git a/docs/nconf/stores.html b/docs/nconf/stores.html index ef7066b..b14c515 100644 --- a/docs/nconf/stores.html +++ b/docs/nconf/stores.html @@ -1,19 +1,23 @@ - stores.js

stores.js

/*
+      stores.js           

stores.js

/*
  * stores.js: Top-level include for all nconf stores
  *
  * (C) 2011, Charlie Robbins
  *
  */
  
-var stores = exports;
+var fs = require('fs'),
+    stores = exports;
 
 function capitalize (str) {
   return str && str[0].toUpperCase() + str.slice(1);
-};
-
-stores.Memory = require('nconf/stores/memory').Memory;
-stores.File   = require('nconf/stores/file').File;
-stores.Redis  = require('nconf/stores/redis').Redis;

function create (type, options)

+};

Setup all stores as lazy-loaded getters.

fs.readdirSync(__dirname + '/stores').forEach(function (file) {
+  var store = file.replace('.js', ''),
+      name  = capitalize(store);
+      
+  stores.__defineGetter__(name, function () {
+    return require('./stores/' + store)[name];
+  });
+});

function create (type, options)

@type {string} Type of the nconf store to use.

diff --git a/docs/nconf/stores/file.html b/docs/nconf/stores/file.html index 624dd14..a4f5158 100644 --- a/docs/nconf/stores/file.html +++ b/docs/nconf/stores/file.html @@ -1,4 +1,4 @@ - file.js

file.js

/*
+      file.js           

file.js

/*
  * file.js: Simple file storage engine for nconf files
  *
  * (C) 2011, Charlie Robbins
@@ -107,6 +107,7 @@ using the format specified by this.format synchronously.

} if (err) { + err.message = "Error parsing your JSON configuration file." throw err; } diff --git a/docs/nconf/stores/memory.html b/docs/nconf/stores/memory.html index 3d6f8c6..9e5bd5e 100644 --- a/docs/nconf/stores/memory.html +++ b/docs/nconf/stores/memory.html @@ -1,11 +1,11 @@ - memory.js

memory.js

/*
+      memory.js           

memory.js

/*
  * memory.js: Simple memory storage engine for nconf configuration(s)
  *
  * (C) 2011, Charlie Robbins
  *
  */
 
-var nconf = require('nconf');

function Memory (options)

+var nconf = require('../../nconf');

function Memory (options)

@options {Object} Options for this instance

@@ -25,7 +25,7 @@ a nested json structure based on key delimiters :.

var target = this.store, path = nconf.path(key);

Scope into the object to get the appropriate nested context

  while (path.length > 0) {
     key = path.shift();
-    if (!target[key]) {
+    if (!(target && key in target)) {
       return;
     }
     
@@ -46,12 +46,13 @@ a nested json structure based on key delimiters :.

Update the mtime (modified time) of the key

  this.mtimes[key] = Date.now();
   

Scope into the object to get the appropriate nested context

  while (path.length > 1) {
     key = path.shift();
-    if (!target[key]) {
+    if (!target[key] || typeof target[key] !== 'object') {
       target[key] = {};
     }
     
     target = target[key];
-  }

Set the specified value in the nested JSON structure

  key = path.shift();
+  }
+  

Set the specified value in the nested JSON structure

  key = path.shift();
   target[key] = value;
   return true;
 };

function clear (key)

@@ -73,7 +74,43 @@ a nested json structure based on key delimiters :.

Delete the key from the nested JSON structure

  key = path.shift();
   delete target[key];
   return true;
-};

function reset (callback)

+};

function merge (key, value)

+ +

@key {string} Key to merge the value into

+ +

@value {literal|Object} Value to merge into the key

+ +

Merges the properties in value into the existing object value +at key. If the existing value key is not an Object, it will be +completely overwritten.

Memory.prototype.merge = function (key, value) {

If the key is not an Object or is an Array, +then simply set it. Merging is for Objects.

  if (typeof value !== 'object' || Array.isArray(value)) {
+    return this.set(key, value);
+  }
+  
+  var self    = this,
+      target  = this.store, 
+      path    = nconf.path(key),
+      fullKey = key;
+  

Update the mtime (modified time) of the key

  this.mtimes[key] = Date.now();
+  

Scope into the object to get the appropriate nested context

  while (path.length > 1) {
+    key = path.shift();
+    if (!target[key]) {
+      target[key] = {};
+    }
+    
+    target = target[key];
+  }

Set the specified value in the nested JSON structure

  key = path.shift();
+  

If the current value at the key target is not an Object, +of is an Array then simply override it because the new value +is an Object.

  if (typeof target[key] !== 'object' || Array.isArray(target[key])) {
+    target[key] = value;
+    return true;
+  }
+  
+  return Object.keys(value).every(function (nested) {
+    return self.merge(fullKey + ':' + nested, value[nested]);
+  });
+};

function reset (callback)

Clears all keys associated with this instance.

Memory.prototype.reset = function () {
   this.mtimes = {};
diff --git a/docs/nconf/stores/redis.html b/docs/nconf/stores/redis.html
index ae3d9d2..b86fdbb 100644
--- a/docs/nconf/stores/redis.html
+++ b/docs/nconf/stores/redis.html
@@ -1,4 +1,4 @@
-      redis.js           

redis.js

/*
+      redis.js           
path=nconf.path(key);

redis.js

/*
  * redis.js: Redis storage engine for nconf configuration(s)
  *
  * (C) 2011, Charlie Robbins
@@ -7,7 +7,7 @@
 
 var async = require('async'),
     redis = require('redis'),
-    nconf = require('nconf'),
+    nconf = require('../../nconf'),
     Memory = require('./memory').Memory;

function Redis (options)

@options {Object} Options for this instance

@@ -33,7 +33,7 @@ a nested Redis key structure based on key delimiters :.

this.redis.auth(options.auth); }

Suppress errors from the Redis client

  this.redis.on('error', function (err) { 
-    require('eyes').inspect(err);
+    console.dir(err);
   });
 };

function get (key, callback)

@@ -104,33 +104,60 @@ and we can simply return the value from redis directly.

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };
   
-  function addKey (partial, next) {
-    var index  = path.indexOf(partial),
-        base   = [self.namespace].concat(path.slice(0, index)),
-        parent = nconf.key.apply(null, base.concat(['keys']));
-
-    self.redis.sadd(parent, partial, next);
-  };

Iterate over the entire key path and add each key to the -parent key-set if it doesn't exist already.

  async.forEach(path, addKey, function (err) {
+  this._addKeys(key, function (err) {
     if (err) {
       return callback(err);
     }
     
     var fullKey = nconf.key(self.namespace, key);
     
-    if (!Array.isArray(value) && typeof value === 'object') {

If the value is an Object (and not an Array) then + if (!Array.isArray(value) && value !== null && typeof value === 'object') {

If the value is an Object (and not an Array) then nest into the value and set the child keys appropriately. This is done for efficient lookup when setting Object keys. (i.e. If you set and Object then wish to later retrieve only a -member of that Object, the entire Object need not be retrieved).

      self._setObject(fullKey, value, callback);
+member of that Object, the entire Object need not be retrieved).  

      self.cache.set(key, value);
+      self._setObject(fullKey, value, callback);
     }
-    else {

If the value is a simple literal (or an Array) then JSON -stringify it and put it into Redis.

      value = JSON.stringify(value);
-      self.cache.set(key, value);
+    else {

If the value is a simple literal (or an Array) then JSON +stringify it and put it into Redis.

      self.cache.set(key, value);
+      value = JSON.stringify(value);
       self.redis.set(fullKey, value, callback);
     }
   });
-};

function clear (key, callback)

+};

function merge (key, value, callback)

+ +

@key {string} Key to merge the value into

+ +

@value {literal|Object} Value to merge into the key

+ +

2callback {function} Continuation to respond to when complete.

+ +

Merges the properties in value into the existing object value +at key. If the existing value key is not an Object, it will be +completely overwritten.

Redis.prototype.merge = function (key, value, callback) {

If the key is not an Object or is an Array, +then simply set it. Merging is for Objects.

  if (typeof value !== 'object' || Array.isArray(value)) {
+    return this.set(key, value, callback);
+  }
+  
+  var self    = this,
+      path    = nconf.path(key),
+      fullKey = nconf.key(this.namespace, key);
+  

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };
+  

Get the set of all children keys for the key supplied. If the value +to be returned is an Object, this list will not be empty.

  this._addKeys(key, function (err) {
+    self.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
+      function nextMerge (nested, next) {
+        var keyPath = nconf.key.apply(null, path.concat([nested]));
+        self.merge(keyPath, value[nested], next);
+      }
+      
+      if (keys && keys.length > 0) {

If there are existing keys then we must do a recursive merge +of the two Objects.

        return async.forEach(Object.keys(value), nextMerge, callback);
+      }

Otherwise, we can simply invoke set to override the current +literal or Array value with our new Object value

      self.set(key, value, callback);
+    });
+  });
+};

function clear (key, callback)

@key {string} Key to remove from this instance

@@ -141,22 +168,22 @@ stringify it and put it into Redis.

result = {}, path = [this.namespace].concat(nconf.path(key)), last = path.pop(), - fullKey = nconf.key(this.namespace, key);

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };

Clear the key from the cache for this instance

  this.cache.clear(key);
-  

Remove the key from the parent set of keys.

  this.redis.srem(nconf.key.apply(null, path.concat(['keys'])), last, function (err) {

Remove the value from redis by iterating over the set of keys (if any) + fullKey = nconf.key(this.namespace, key);

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };

Clear the key from the cache for this instance

  this.cache.clear(key);
+  

Remove the key from the parent set of keys.

  this.redis.srem(nconf.key.apply(null, path.concat(['keys'])), last, function (err) {

Remove the value from redis by iterating over the set of keys (if any) and deleting each value. If no keys, then just delete the simple literal.

    self.redis.smembers(nconf.key(fullKey, 'keys'), function (err, keys) {
-      function removeValue (child, next) {

Recursively call self.clear here to ensure we remove any + function removeValue (child, next) {

Recursively call self.clear here to ensure we remove any nested Objects completely from this instance.

        self.clear(nconf.key(key, child), next);
       }
        
-      if (keys && keys.length > 0) {

If there are child keys then iterate over them, + if (keys && keys.length > 0) {

If there are child keys then iterate over them, removing each child along the way.

        async.forEach(keys, removeValue, callback);
       }
-      else {

Otherwise if this is just a simple literal, then + else {

Otherwise if this is just a simple literal, then simply remove it from Redis directly.

        self.redis.del(fullKey, callback);
       }
     });
   });
-};

function save (value, callback)

+};

function save (value, callback)

@value {Object} Config object to set for this instance

@@ -170,22 +197,22 @@ instance and then adds all key-value pairs in value.

var self = this, keys = Object.keys(value); -

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };

Clear all existing keys associated with this instance.

  this.reset(function (err) {
+  

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };

Clear all existing keys associated with this instance.

  this.reset(function (err) {
     if (err) {
       return callback(err);
     }
-    

Iterate over the keys in the new value, setting each of them.

    async.forEach(keys, function (key, next) {
+    

Iterate over the keys in the new value, setting each of them.

    async.forEach(keys, function (key, next) {
       self.set(key, value[key], next);
     }, callback);
   });
-};

function load (callback)

+};

function load (callback)

@callback {function} Continuation to respond to when complete.

Responds with an Object representing all keys associated in this instance.

Redis.prototype.load = function (callback) {
   var self   = this,
       result = {};
-  

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };
+  

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };
 
   this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, keys) {
     if (err) {
@@ -208,14 +235,14 @@ instance and then adds all key-value pairs in value. 

return err ? callback(err) : callback(null, result); }); }); -};

function reset (callback)

+};

function reset (callback)

@callback {function} Continuation to respond to when complete.

Clears all keys associated with this instance.

Redis.prototype.reset = function (callback) {
   var self = this;
-  

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };
-  

Get the list of of top-level keys, then clear each of them

  this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, existing) {
+  

Set the callback if not provided for "fire and forget"

  callback = callback || function () { };
+  

Get the list of of top-level keys, then clear each of them

  this.redis.smembers(nconf.key(this.namespace, 'keys'), function (err, existing) {
     if (err) {
       return callback(err);
     }
@@ -225,7 +252,25 @@ instance and then adds all key-value pairs in value. 

self.clear(key, next); }, callback); }); -};

@private function _setObject (key, value, callback)

+};

@private function _addKeys (key, callback)

+ +

@key {string} Key to add parent keys for

+ +

@callback {function} Continuation to respond to when complete.

+ +

Adds the full key path to Redis via sadd.

Redis.prototype._addKeys = function (key, callback) {
+  var self = this,
+      path = nconf.path(key);
+  
+  function addKey (partial, next) {
+    var index  = path.indexOf(partial),
+        base   = [self.namespace].concat(path.slice(0, index)),
+        parent = nconf.key.apply(null, base.concat(['keys']));
+
+    self.redis.sadd(parent, partial, next);
+  };

Iterate over the entire key path and add each key to the +parent key-set if it doesn't exist already.

  async.forEach(path, addKey, callback);
+};

@private function _setObject (key, value, callback)

@key {string} Key to set in this instance

@@ -237,7 +282,7 @@ instance and then adds all key-value pairs in value.

var self = this, keys = Object.keys(value); - function addValue (child, next) {

Add the child key to the parent key-set, then set the value. + function addValue (child, next) {

Add the child key to the parent key-set, then set the value. Recursively call _setObject in the event of nested Object(s).

    self.redis.sadd(nconf.key(key, 'keys'), child, function (err) {
       if (err) {
         return next(err);
@@ -255,7 +300,7 @@ Recursively call _setObject in the event of nested Object(s).

} }); } -

Iterate over the keys of the Object and set the appropriate values.

  async.forEach(keys, addValue, function (err) {
+  

Iterate over the keys of the Object and set the appropriate values.

  async.forEach(keys, addValue, function (err) {
     return err ? callback(err) : callback();    
   });
 };
diff --git a/lib/nconf.js b/lib/nconf.js
index 39d1a35..47c3eb7 100644
--- a/lib/nconf.js
+++ b/lib/nconf.js
@@ -14,9 +14,9 @@ var Provider = require('./nconf/provider').Provider,
 nconf.use('memory');
 
 //
-// ### Version 0.1.9 :: 5/16/2011
+// Expose the version from the package.json using `pkginfo`.
 //
-nconf.version = [0, 1, 9];
+require('pkginfo')('version');
 
 //
 // ### function path (key)
diff --git a/package.json b/package.json
index f46c6d2..53c4126 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   "keywords": ["configuration", "key value store", "redis"],
   "dependencies": {
     "async": "0.1.x",
+    "pkginfo": "0.1.x",
     "redis": "0.6.x"
   },
   "main": "./lib/nconf",
diff --git a/test/nconf-test.js b/test/nconf-test.js
index 03bdc8a..72c71a2 100644
--- a/test/nconf-test.js
+++ b/test/nconf-test.js
@@ -30,6 +30,16 @@ vows.describe('nconf').addBatch({
         nconf.use('memory');
         assert.instanceOf(nconf.store, nconf.stores.Memory);
       }
+    },
+    "it should": {
+      topic: function () {
+        fs.readFile(path.join(__dirname, '..', 'package.json'), this.callback);
+      },
+      "have the correct version set": function (err, data) {
+        assert.isNull(err);
+        data = JSON.parse(data.toString());
+        assert.equal(nconf.version, data.version);
+      }
     }
   }
 }).addBatch({