[dist api test] Finished integrating features from reconf and updating associated tests
This commit is contained in:
parent
add8922c04
commit
a6533aa7bf
7 changed files with 151 additions and 27 deletions
|
@ -5,7 +5,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
var stores = require('./stores');
|
||||
var optimist = require('optimist'),
|
||||
stores = require('./stores');
|
||||
|
||||
//
|
||||
// ### function Provider (options)
|
||||
|
@ -14,7 +15,10 @@ var stores = require('./stores');
|
|||
// for exposing the pluggable storage features of `nconf`.
|
||||
//
|
||||
var Provider = exports.Provider = function (options) {
|
||||
options = options || {};
|
||||
options = options || {};
|
||||
this.overrides = options.overrides || null
|
||||
this.useArgv = options.useArgv || false;
|
||||
|
||||
this.store = stores.create(options.type || 'memory', options);
|
||||
};
|
||||
|
||||
|
@ -50,6 +54,14 @@ Provider.prototype.use = function (type, options) {
|
|||
// Retrieves the value for the specified key (if any).
|
||||
//
|
||||
Provider.prototype.get = function (key, callback) {
|
||||
if (this.overrides && Object.prototype.hasOwnProperty.call(this.overrides, key)) {
|
||||
if (callback) {
|
||||
callback(null, this.overrides[key]);
|
||||
}
|
||||
|
||||
return this.overrides[key];
|
||||
}
|
||||
|
||||
return this.store.get(key, callback);
|
||||
};
|
||||
|
||||
|
@ -155,3 +167,22 @@ Provider.prototype.save = function (value, callback) {
|
|||
Provider.prototype.reset = function (callback) {
|
||||
return this.store.reset(callback);
|
||||
};
|
||||
|
||||
//
|
||||
// ### getter @useArgv {boolean}
|
||||
// Gets a property indicating if we should wrap calls to `.get`
|
||||
// by checking `optimist.argv`.
|
||||
//
|
||||
Provider.prototype.__defineGetter__('useArgv', function () {
|
||||
return this._useArgv;
|
||||
});
|
||||
|
||||
//
|
||||
// ### setter @useArgv {boolean}
|
||||
// Sets a property indicating if we should wrap calls to `.get`
|
||||
// by checking `optimist.argv`.
|
||||
//
|
||||
Provider.prototype.__defineSetter__('useArgv', function (val) {
|
||||
this._useArgv = val || false;
|
||||
this.overrides = this.overrides || optimist.argv;
|
||||
});
|
|
@ -25,7 +25,7 @@ var File = exports.File = function (options) {
|
|||
|
||||
this.type = 'file';
|
||||
this.file = options.file;
|
||||
this.search = options.search || false;
|
||||
this.dir = options.dir || process.cwd();
|
||||
this.format = options.format || {
|
||||
stringify: function (obj) {
|
||||
return JSON.stringify(obj, null, 2)
|
||||
|
@ -144,21 +144,26 @@ File.prototype.loadSync = function () {
|
|||
};
|
||||
|
||||
//
|
||||
// ### function resolve (base)
|
||||
// ### function search (base)
|
||||
// #### @base {string} Base directory (or file) to begin searching for the target file.
|
||||
// Attempts to find `this.file` by iteratively searching up the
|
||||
// directory structure
|
||||
//
|
||||
File.prototype.resolve = function (base) {
|
||||
var looking = this.search,
|
||||
File.prototype.search = function (base) {
|
||||
var looking = true,
|
||||
fullpath,
|
||||
previous,
|
||||
stats;
|
||||
|
||||
base = base || process.cwd();
|
||||
|
||||
if (this.file[0] === '/') {
|
||||
//
|
||||
// If filename for this instance is a fully qualified path
|
||||
// (i.e. it starts with a `'/'`) then check if it exists
|
||||
//
|
||||
try {
|
||||
stats = fs.statSync(fs.realpathSync(fullpath));
|
||||
stats = fs.statSync(fs.realpathSync(this.file));
|
||||
if (stats.isFile()) {
|
||||
fullpath = this.file;
|
||||
looking = false;
|
||||
|
@ -186,26 +191,32 @@ File.prototype.resolve = function (base) {
|
|||
}
|
||||
|
||||
while (looking) {
|
||||
//
|
||||
// Iteratively look up the directory structure from `base`
|
||||
//
|
||||
try {
|
||||
stats = fs.statSync(fs.realpathSync(fullpath = path.join(base, this.file)));
|
||||
looking = stats.isDirectory();
|
||||
}
|
||||
catch (ex) {
|
||||
var olddir = dir;
|
||||
dir = path.dirname(dir);
|
||||
previous = base;
|
||||
base = path.dirname(base);
|
||||
|
||||
if (olddir === dir) {
|
||||
if (previous === base) {
|
||||
//
|
||||
// If we've reached the top of the directory structure then simply use
|
||||
// the default file path.
|
||||
//
|
||||
try {
|
||||
var stat = fs.statSync(fs.realpathSync(configPath = path.join(process.env.HOME, filename)));
|
||||
if(stat.isDirectory()) {
|
||||
configPath = undefined;
|
||||
stats = fs.statSync(fs.realpathSync(fullpath = path.join(this.dir, this.file)));
|
||||
if (stats.isDirectory()) {
|
||||
fullpath = undefined;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
//
|
||||
// Ignore errors
|
||||
//
|
||||
configPath = undefined;
|
||||
}
|
||||
|
||||
looking = false;
|
||||
|
@ -213,5 +224,12 @@ File.prototype.resolve = function (base) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Set the file for this instance to the fullpath
|
||||
// that we have found during the search. In the event that
|
||||
// the search was unsuccessful use the original value for `this.file`.
|
||||
//
|
||||
this.file = fullpath || this.file;
|
||||
|
||||
return fullpath;
|
||||
};
|
|
@ -10,6 +10,7 @@
|
|||
"keywords": ["configuration", "key value store", "plugabble"],
|
||||
"dependencies": {
|
||||
"async": "0.1.x",
|
||||
"optimist": "0.2.x",
|
||||
"pkginfo": "0.2.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -101,4 +101,36 @@ vows.describe('nconf/stores/file').addBatch({
|
|||
}
|
||||
}
|
||||
}
|
||||
}).addBatch({
|
||||
"When using the nconf file store": {
|
||||
"the search() method": {
|
||||
"when the target file exists higher in the directory tree": {
|
||||
topic: function () {
|
||||
var filePath = this.filePath = path.join(process.env.HOME, '.nconf');
|
||||
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
||||
return new (nconf.stores.File)({
|
||||
file: '.nconf'
|
||||
})
|
||||
},
|
||||
"should update the file appropriately": function (store) {
|
||||
store.search();
|
||||
assert.equal(store.file, this.filePath);
|
||||
fs.unlinkSync(this.filePath);
|
||||
}
|
||||
},
|
||||
"when the target file doesn't exist higher in the directory tree": {
|
||||
topic: function () {
|
||||
var filePath = this.filePath = path.join(__dirname, 'fixtures', 'search-store.json');
|
||||
return new (nconf.stores.File)({
|
||||
dir: path.dirname(filePath),
|
||||
file: 'search-store.json'
|
||||
})
|
||||
},
|
||||
"should update the file appropriately": function (store) {
|
||||
store.search();
|
||||
assert.equal(store.file, this.filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).export(module);
|
11
test/fixtures/scripts/default-override.js
vendored
Normal file
11
test/fixtures/scripts/default-override.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* nconf-override.js: Test fixture for using optimist defaults with nconf.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins
|
||||
*
|
||||
*/
|
||||
|
||||
var nconf = require('../../../lib/nconf');
|
||||
|
||||
nconf.useArgv = true;
|
||||
process.stdout.write(nconf.get('something'));
|
12
test/fixtures/scripts/nconf-override.js
vendored
Normal file
12
test/fixtures/scripts/nconf-override.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* nconf-override.js: Test fixture for using optimist defaults with nconf.
|
||||
*
|
||||
* (C) 2011, Charlie Robbins
|
||||
*
|
||||
*/
|
||||
|
||||
var nconf = require('../../../lib/nconf');
|
||||
|
||||
var provider = new (nconf.Provider)({ useArgv: true });
|
||||
|
||||
process.stdout.write(provider.get('something'));
|
|
@ -5,28 +5,47 @@
|
|||
*
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
var assert = require('assert'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
spawn = require('child_process').spawn,
|
||||
vows = require('vows'),
|
||||
assert = require('assert'),
|
||||
nconf = require('../lib/nconf')
|
||||
|
||||
var first = '/path/to/file1',
|
||||
second = '/path/to/file2';
|
||||
|
||||
function assertDefaults (script) {
|
||||
return {
|
||||
topic: function () {
|
||||
spawn('node', [script, '--something', 'foobar'])
|
||||
.stdout.once('data', this.callback.bind(this, null));
|
||||
},
|
||||
"should respond with the value passed into the script": function (_, data) {
|
||||
assert.equal(data.toString(), 'foobar');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vows.describe('nconf/provider').addBatch({
|
||||
"When using an instance of nconf.Provier": {
|
||||
"calling the use() method with the same store type and different options": {
|
||||
topic: new nconf.Provider().use('file', { file: first }),
|
||||
"should use a new instance of the store type": function (provider) {
|
||||
var old = provider.store;
|
||||
"When using nconf": {
|
||||
"an instance of 'nconf.Provider'": {
|
||||
"calling the use() method with the same store type and different options": {
|
||||
topic: new nconf.Provider().use('file', { file: first }),
|
||||
"should use a new instance of the store type": function (provider) {
|
||||
var old = provider.store;
|
||||
|
||||
assert.equal(provider.store.file, first);
|
||||
provider.use('file', { file: second });
|
||||
assert.equal(provider.store.file, first);
|
||||
provider.use('file', { file: second });
|
||||
|
||||
assert.notStrictEqual(old, provider.store);
|
||||
assert.equal(provider.store.file, second);
|
||||
}
|
||||
assert.notStrictEqual(old, provider.store);
|
||||
assert.equal(provider.store.file, second);
|
||||
}
|
||||
},
|
||||
"when 'useArgv' is true": assertDefaults(path.join(__dirname, 'fixtures', 'scripts', 'nconf-override.js'))
|
||||
},
|
||||
"the default nconf provider": {
|
||||
"when 'useArgv' is true": assertDefaults(path.join(__dirname, 'fixtures', 'scripts', 'default-override.js'))
|
||||
}
|
||||
}
|
||||
}).export(module);
|
Loading…
Reference in a new issue