Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

refactored code, use jQuery extend, remove globalKey option, update deps

  • Loading branch information...
commit 7be10ae66fa96152e5019eac38495a8844804f04 1 parent 7ec34eb
@mgutz authored
View
1  .gitignore
@@ -18,3 +18,4 @@ pids
logs
result
!.gitignore
+node_modules
View
23 Bakefile
@@ -0,0 +1,23 @@
+PATH=node-modules/mocha/bin:$PATH
+PATH=node-modules/coffee-script/bin:$PATH
+
+#. Run tests
+function test {
+ compile
+ mocha test/*Test.js
+}
+
+
+#. Compiles sources
+function compile {
+ invoke clean
+ coffee -c -o . src
+}
+
+
+#. Cleans output files
+function clean {
+ rm -rf test
+ rm -rf lib
+ rm index.js
+}
View
27 Makefile
@@ -1,27 +0,0 @@
-ROOT_DIR ?= $(realpath .)
-SRC_DIR=src
-BUILD_DIR=$(ROOT_DIR)
-
-# compute coffee dependencies
-COFFEE := $(shell find $(SRC_DIR) -name '*.coffee')
-GEN_JS = $(COFFEE:$(SRC_DIR)/%.coffee=$(BUILD_DIR)/%.js)
-
-.PHONY: all clean
-
-all: generate
-
-generate: $(GEN_JS)
-
-test: clean generate
- @expresso test/*.test.js
-
-clean:
- @rm -f $(GEN_JS)
-
-$(BUILD_DIR)/%.js: $(SRC_DIR)/%.coffee
- @mkdir -p $(dir $@)
- @cat res/GENERATED_JS_HEADER > $@
- @echo // Original file: $< >> $@
- @coffee -b -p -c $< >> $@
-
-# vim: noexpandtab ts=4 :
View
111 README.md
@@ -6,115 +6,94 @@ Simple, hierarchical environment-based app settings.
npm install settings
-## Usage
+## Usage
-Configuration file `config/environment.js`
+Configuration file `config.js`
- exports.common = {
- storage: {
- host: 'localhost',
- database: 'server_dev',
- user: 'qirogami_user',
- password: 'password'
- }
- };
-
- // Rest of environments are deep merged over `common`.
-
- exports.development = {};
+ module.exports = {
+ common: {
+ storage: {
+ host: 'localhost',
+ database: 'server_dev',
+ user: 'qirogami_user',
+ password: 'password'
+ }
+ };
- exports.test = {
- storage: {
- database: 'server_test',
- password: 'foo'
- }
- };
+ // Rest of environments are deep merged over `common`.
- exports.production = {
+ development: {};
+ test: {
+ storage: {
+ database: 'server_test',
+ password: 'foo'
+ }
+ };
+ production: {
storage: {
- password: 'secret'
+ password: 'secret'
}
+ };
};
-Application file
+Application file `app.js`
var Settings = require('settings');
- var file = __dirname + '/config/environment.js';
- var settings = new Settings(file).getEnvironment('test');
-
+ var config = new Settings(require('./config'));
// inherited from common
- assert.equal(settings.storage.host, 'localhost');
-
+ assert.equal(config.storage.host, 'localhost');
// specific to test
- assert.equal(settings.storage.password, 'foo');
+ assert.equal(config.storage.password, 'foo');
### Environments
The environment to use is based on (highest precedence first):
-1. `forceEnv` property in settings file
-
- ## config/environment.js
- exports.forceEnv = 'production'
+1. `forceEnv` property in config file
-2. `$NODE_ENV` environment variable
+ ## config/environment.js
+ exports.forceEnv = 'production'
- NODE_ENV=production node app.js
-
-3. Environment argument passed to `Settings#getEnvironment()`
-
- # the environment argument is ignored if either of the above is set
- settings.getEnvironment('production')
-
-### Install Globally
+2. `$NODE_ENV` environment variable
-If `globalKey` option is set, the environment settings are installed
-into global space.
+ NODE_ENV=production node app.js
- var settings = new Settings(file, { globalKey: '$settings' }).
- getEnvironment();
-
- assert.equal($settings.storage.host, 'localhost');
+3. `env` option passed to constructor. `new Settings(file, {env: 'test'})`
### Application Defaults
-Property defaults may be preset in code. These defaults may be overridden
-by the app's external settings.
+Property defaults may be preset in code.
- var settings = new Settings(file, {
- globalKey: '$settings',
+ var settings = new Settings(file, {
defaults: {
framework: {
views: 'app/views'
}
}
- }).getEnvironment();
-
+ });
+ assert.equal(settings.framework.views, 'app/views');
- assert.equal($settings.framework.views, 'app/views');
+## Hacking on the source
-## Generate and Test
+To compile and test
-To generate JavaScript from CoffeeScript
-
- make
-
-To test
-
- npm install expresso
- make test
+ npm install bake-bash -g
+ npm install -d
+ bake test
## Notes
-JavaScript files are generated by Coffee and should not be edited.
+`globalKey` option has been removed. Do this instead
+
+ global.APP = new Settings(file)
## Credits
-[shimondoodkin's node-js-clone-extend](https://github.com/shimondoodkin/nodejs-clone-extend)
+jQuery library for `support/extend.js`
## License
View
12 index.js
@@ -1,8 +1,6 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
+// Generated by CoffeeScript 1.3.3
+(function() {
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/index.coffee
-module.exports = require('./lib');
+ module.exports = require('./lib/settings');
+
+}).call(this);
View
8 lib/index.js
@@ -1,8 +0,0 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
-
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/lib/index.coffee
-module.exports = require('./settings');
View
149 lib/settings.js
@@ -1,68 +1,87 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
+// Generated by CoffeeScript 1.3.3
+(function() {
+ var Extend, Settings, assert, coffee, loadModule;
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/lib/settings.coffee
-var Settings, assert, merger;
-var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
-assert = require('assert');
-merger = require('../support/merger');
-try {
- require('coffee-script');
-} catch (ex) {
+ assert = require('assert');
-}
-Settings = function(pathOrModule, options) {
- this.options = options != null ? options : {};
- if (typeof pathOrModule === 'string') {
- this.path = pathOrModule;
- }
- this.environments = Settings.loadModule(pathOrModule);
- if (this.options.globalKey != null) {
- this._settings = this.getEnvironment();
- global.__defineGetter__(this.options.globalKey, __bind(function() {
- return this._settings;
- }, this));
- }
- return this;
-};
-Settings.prototype.getEnvironment = function(environ) {
- var common, result;
- this.env = this.environments.forceEnv || environ || process.env.NODE_ENV || 'common';
- assert.ok(this.environments.common, 'Environment common not found in: ' + this.path);
- assert.ok(this.environments[this.env], 'Environment `' + this.env + '` not found in: ' + this.path);
- if (this.options.defaults != null) {
- common = merger.cloneextend(this.options.defaults, this.environments.common);
- } else {
- common = merger.clone(this.environments.common);
- }
- if (this.env === 'common') {
- result = common;
- } else {
- result = merger.extend(common, this.environments[this.env]);
- }
- if (this.options.globalKey != null) {
- this._settings = result;
- }
- result.override = Settings.override;
- return result;
-};
-Settings.loadModule = function(pathOrModule) {
- if (typeof pathOrModule === 'string') {
- return require(pathOrModule);
- } else {
- return pathOrModule;
- }
-};
-Settings.override = function(pathOrModule) {
- var mod;
- mod = Settings.loadModule(pathOrModule);
- if (mod.common != null) {
- mod = new Settings(mod).getEnvironment();
+ Extend = require('../support/extend');
+
+ try {
+ coffee = require('coffee-script');
+ } catch (ex) {
+ null;
}
- merger.extend(this, mod);
- return this;
-};
-module.exports = Settings;
+
+ loadModule = function(pathOrModule) {
+ var mod;
+ if (typeof pathOrModule === 'string') {
+ mod = require(pathOrModule);
+ } else {
+ mod = pathOrModule;
+ }
+ return mod;
+ };
+
+ Settings = function(pathOrModule, options) {
+ this.options = options != null ? options : {};
+ if (typeof pathOrModule === 'string') {
+ this.path = pathOrModule;
+ }
+ this.environments = loadModule(pathOrModule);
+ this._useEnvironment(this.options.env, this.options.root);
+ return this._settings;
+ };
+
+ Settings.prototype._useEnvironment = function(environ, root) {
+ var common, result;
+ if (environ != null) {
+ if (!this.environments[environ]) {
+ environ = void 0;
+ }
+ }
+ this.env = this.environments.forceEnv || environ || process.env.NODE_ENV || 'common';
+ assert.ok(this.environments.common, 'Environment common not found in: ' + this.path);
+ assert.ok(this.environments[this.env], 'Environment `' + this.env + '` not found in: ' + this.path);
+ if (this.options.defaults != null) {
+ common = Extend.cloneExtend(this.options.defaults, this.environments.common);
+ } else {
+ common = Extend.clone(this.environments.common);
+ }
+ if (this.env === 'common') {
+ result = common;
+ } else {
+ result = Extend.extend(common, this.environments[this.env]);
+ }
+ return this._setSettingsScope(result, root);
+ };
+
+ Settings.prototype.override = function(pathOrModule, root) {
+ var mod;
+ mod = loadModule(pathOrModule);
+ if (mod.common != null) {
+ mod = new Settings(mod, {
+ env: this.env
+ });
+ mod._obj = null;
+ }
+ if (root != null) {
+ console.assert(mod[root] != null, "configuration root property not found: " + root);
+ mod = mod[root];
+ }
+ Extend.extend(this._settings, mod);
+ return this._settings._obj = this;
+ };
+
+ Settings.prototype._setSettingsScope = function(settings, root) {
+ if (root != null) {
+ this.root = root;
+ }
+ this._settings = root != null ? settings[root] : settings;
+ this._settings._obj = this;
+ this._settings.ENV = this.env;
+ return this._settings;
+ };
+
+ module.exports = Settings;
+
+}).call(this);
View
10 package.json
@@ -1,7 +1,11 @@
{ "name": "settings",
- "version": "0.0.3",
+ "version": "0.1.0",
"description": "Simple environment-based application settings",
"author": "Mario Gutierrez <mario@mgutz.com>",
- "main": "index",
- "repository" : "git://github.com/mgutz/node-settings"
+ "repository" : "git://github.com/mgutz/node-settings",
+ "devDependencies": {
+ "chai": "~1.0.4",
+ "coffee-script": "~1.3.3",
+ "mocha": "~1.1.0"
+ }
}
View
6 res/GENERATED_JS_HEADER
@@ -1,6 +0,0 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
-
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
View
2  src/index.coffee
@@ -1 +1 @@
-module.exports = require('./lib')
+module.exports = require('./lib/settings')
View
1  src/lib/index.coffee
@@ -1 +0,0 @@
-module.exports = require('./settings')
View
91 src/lib/settings.coffee
@@ -2,22 +2,30 @@
# Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
# MIT Licensed
#
-# TODO - add watcher on settings file
assert = require('assert')
-merger = require('../support/merger')
+Extend = require('../support/extend')
-# IF coffee is installed, also read configs written in CoffeeScript.
try
- # coffee extension is registered with node as a side-effect
- require('coffee-script') # allows use of coffee for configs
+ coffee = require('coffee-script') # allows use of coffee for configs
catch ex
+ null
+
+loadModule = (pathOrModule) ->
+ if typeof pathOrModule == 'string'
+ mod = require(pathOrModule)
+ else
+ mod = pathOrModule
+ mod
+
+# TODO - add watcher on settings file
# Provides settings from an environment file or an object.
#
# The settings module must export, at a minimum, a `common` property.
-# Other environments are deep merged over `common`.
+#
+# Other environments are deep merged into `common`.
#
# @param {String | Object} pathOrModule The file to load or an object.
#
@@ -36,14 +44,9 @@ Settings = (pathOrModule, @options = {}) ->
if typeof pathOrModule == 'string'
@path = pathOrModule
- @environments = Settings.loadModule(pathOrModule)
-
- if @options.globalKey?
- @_settings = @getEnvironment()
- global.__defineGetter__ @options.globalKey, =>
- @_settings
-
- this
+ @environments = loadModule(pathOrModule)
+ @_useEnvironment @options.env, @options.root
+ @_settings
# Get settings for a specific environment.
@@ -56,40 +59,62 @@ Settings = (pathOrModule, @options = {}) ->
# 2. $NODE_ENV environment variable
# 3. `common` environment
#
-Settings.prototype.getEnvironment = (environ) ->
+Settings.prototype._useEnvironment = (environ, root) ->
+ if environ?
+ environ = undefined if !@environments[environ]
@env = @environments.forceEnv || environ || process.env.NODE_ENV || 'common'
assert.ok @environments.common, 'Environment common not found in: ' + @path
assert.ok @environments[@env], 'Environment `' + @env + '` not found in: ' + @path
if @options.defaults?
- common = merger.cloneextend(@options.defaults, @environments.common)
+ common = Extend.cloneExtend(@options.defaults, @environments.common)
else
- common = merger.clone(@environments.common)
+ common = Extend.clone(@environments.common)
if @env == 'common'
result = common
else
- result = merger.extend common, @environments[@env]
+ result = Extend.extend(common, @environments[@env])
- if @options.globalKey?
- @_settings = result
+ @_setSettingsScope result, root
- result.override = Settings.override
- result
-Settings.loadModule = (pathOrModule) ->
- if typeof pathOrModule == 'string'
- require(pathOrModule)
- else
- pathOrModule
-
-Settings.override = (pathOrModule) ->
- mod = Settings.loadModule(pathOrModule)
+# Override settings from path or module with an option to specify
+# a property as `root`.
+#
+# @param pathOrModule {String | Object} The path or module.
+# @param root {String} [optional] The property to use as root.
+# @returns A settings object.
+Settings.prototype.override = (pathOrModule, root) ->
+ mod = loadModule(pathOrModule)
if mod.common?
- mod = new Settings(mod).getEnvironment()
- merger.extend this, mod
- this
+ mod = new Settings(mod, env: @env)
+ mod._obj = null
+
+ if root?
+ console.assert mod[root]?, "configuration root property not found: "+root
+ mod = mod[root]
+
+ Extend.extend @_settings, mod
+ @_settings._obj = this
+
+
+# Sets internal settings to `settings` with the option to
+# use a property as `root`.
+#
+# @param settings {Object} The object whose properties become the settings.
+# If this is null, then existing settings are used.
+# @param root {String} The root name.
+# @returns A settings object.
+Settings.prototype._setSettingsScope = (settings, root) ->
+ if root?
+ @root = root
+ @_settings = if root? then settings[root] else settings
+ @_settings._obj = this
+ @_settings.ENV = @env
+ @_settings
module.exports = Settings
+
View
22 src/test/coffee.test.coffee
@@ -1,22 +0,0 @@
-Settings = require('../lib')
-assert = require('assert')
-
-# read the original coffee file
-_settings = new Settings(__dirname + '/../src/test/config/environment')
-
-# Coffee compiles to javascript. A single test is enough here.
-# Exhaustive tests are performed against javascript configuration files.
-module.exports =
- "should get specific environment": ->
- settings = _settings.getEnvironment('development')
- assert.equal 'server_dev', settings.storage.database
-
- # default should be 'common'
- settings = _settings.getEnvironment()
- assert.equal 'server_dev', settings.storage.database
-
- settings = _settings.getEnvironment('test')
- assert.equal 'server_test', settings.storage.database
-
- settings = _settings.getEnvironment('production')
- assert.equal 'server_production', settings.storage.database
View
3  src/test/config/environment.coffee
@@ -1,10 +1,11 @@
-# define all common settings here
+# define all common settings here
exports.common =
storage:
host: 'localhost',
database: 'server_dev',
user: 'qirogami_user',
password: 'password'
+ re: /^foo$/
# deep merges over common
View
4 src/test/config/overrideRoot.coffee
@@ -0,0 +1,4 @@
+module.exports =
+ fubar:
+ storage:
+ host: 'override'
View
4 src/test/config/overrideRoot2.coffee
@@ -0,0 +1,4 @@
+exports.common =
+ bar:
+ storage:
+ host: 'override2'
View
134 src/test/settings.test.coffee
@@ -1,134 +0,0 @@
-assert = require('assert')
-Settings = require('../lib')
-
-_settings = new Settings(__dirname + '/config/environment')
-
-module.exports =
-
- "should be global installable using custom key": ->
- environments =
- 'common':
- foo: 'boo'
- 'development':
- foo: 'bar'
-
- settings = new Settings(environments, { globalKey: '$settings' }).getEnvironment('development')
- assert.equal 'bar', $settings.foo
-
- "issue 1 - global install not merged with common": ->
- environments =
- 'common':
- foo: 'boo'
- bah: 'baz'
- 'development':
- foo: 'bar'
-
- settings = new Settings(environments, { globalKey: '$settings' }).getEnvironment('development')
- assert.equal 'baz', $settings.bah
-
-
- "should get specific environment": ->
- settings = _settings.getEnvironment('development')
- assert.equal 'server_dev', settings.storage.database
-
- # default should be 'common'
- settings = _settings.getEnvironment()
- assert.equal 'server_dev', settings.storage.database
-
- settings = _settings.getEnvironment('test')
- assert.equal 'server_test', settings.storage.database
-
- settings = _settings.getEnvironment('production')
- assert.equal 'server_production', settings.storage.database
-
-
- "should get value from ancestor if key is not found": ->
- settings = _settings.getEnvironment('test')
- assert.equal 'password', settings.storage.password
-
-
- "should have a forceEnv property to force all settings through an environment": ->
- environments =
- 'common':
- foo: 'boo'
- 'development':
- foo: 'bar'
- 'test':
- foo: 'bah'
- 'prod':
- foo: 'baz'
- forceEnv: 'development'
-
- settings = new Settings(environments)
- set = settings.getEnvironment('development')
- assert.equal 'bar', set.foo
-
- set = settings.getEnvironment('test')
- assert.equal 'bar', set.foo
-
- set = settings.getEnvironment('prod')
- assert.equal 'bar', set.foo
-
-
- "should replace array values, not merge them": ->
- environments =
- 'common':
- arr: [1, 2, 3]
- 'development':
- arr: [4, 5, 6]
-
- settings = new Settings(environments).getEnvironment('development')
- assert.eql [4, 5, 6], settings.arr
-
-
- "should do a deep merge": ->
- environments =
- 'common': { a: { b: { c: { arr: [1, 2, 3], bah: 'baz' }, bar: 'bar' } } }
- 'development': { a: { b: { c: { arr: [4, 5, 6], fu: 'bot' } } } }
-
- settings = new Settings(environments).getEnvironment('development')
- assert.eql [4, 5, 6], settings.a.b.c.arr
- assert.eql 'baz', settings.a.b.c.bah
- assert.eql 'bar', settings.a.b.bar
- assert.eql 'bot', settings.a.b.c.fu
-
-
- "should say which environment is current": ->
- settings = _settings.getEnvironment('development')
- assert.equal 'development', _settings.env
-
- settings = _settings.getEnvironment('test')
- assert.equal 'test', _settings.env
-
-
- "should accept defaults": ->
- environments =
- 'common':
- foo: 'boo'
- 'development':
- foo: 'bar'
-
- options =
- globalKey: '$settings'
-
- defaults:
- framework:
- views: 'app/views'
- models: 'app/models'
-
- settings = new Settings(environments, options).getEnvironment('development')
- assert.equal 'app/views', settings.framework.views
-
- "should be overriden from file": ->
- settings = _settings.getEnvironment('test')
- assert.equal 'server_test', settings.storage.database
- assert.equal 'localhost', settings.storage.host
- settings.override __dirname + "/config/override"
- assert.equal 'server_test', settings.storage.database
- assert.equal 'override', settings.storage.host
- settings.override __dirname + "/config/override2"
- assert.equal 'server_test', settings.storage.database
- assert.equal 'override2', settings.storage.host
-
-
-
View
134 src/test/settingsTest.coffee
@@ -0,0 +1,134 @@
+{assert} = require("chai")
+Settings = require("../lib/settings")
+
+instance = ->
+ new Settings(__dirname + "/config/environment")
+
+
+describe "Settings", ->
+
+ it "should get specific environment", ->
+ settings = instance()._obj._useEnvironment('development')
+ assert.equal 'server_dev', settings.storage.database
+
+ # default should be 'development'
+ settings = instance()._obj._useEnvironment()
+ assert.equal 'server_dev', settings.storage.database
+
+ settings = instance()._obj._useEnvironment('test')
+ assert.equal 'server_test', settings.storage.database
+
+ settings = instance()._obj._useEnvironment('production')
+ assert.equal 'server_production', settings.storage.database
+
+
+ it "should get value from ancestor if key is not found", ->
+ settings = instance()._obj._useEnvironment('test')
+ assert.equal 'password', settings.storage.password
+
+
+ it "should have a forceEnv property to force all settings through an environment", ->
+ environments =
+ 'common':
+ foo: 'boo'
+ 'development':
+ foo: 'bar'
+ 'test':
+ foo: 'bah'
+ 'prod':
+ foo: 'baz'
+ forceEnv: 'development'
+
+ settings = new Settings(environments)
+ set = settings._obj._useEnvironment('development')
+ assert.equal 'bar', set.foo
+
+ set = settings._obj._useEnvironment('test')
+ assert.equal 'bar', set.foo
+
+ set = settings._obj._useEnvironment('prod')
+ assert.equal 'bar', set.foo
+
+
+ it "should replace array values, not merge them", ->
+ environments =
+ 'common':
+ arr: [1, 2, 3]
+ 'development':
+ arr: [4, 5, 6]
+
+ settings = new Settings(environments)._obj._useEnvironment('development')
+ assert.deepEqual [4, 5, 6], settings.arr
+
+
+ it "should do a deep merge", ->
+ environments =
+ 'common': { a: { b: { c: { arr: [1, 2, 3], bah: 'baz' }, bar: 'bar' } } }
+ 'development': { a: { b: { c: { arr: [4, 5, 6], fu: 'bot' } } } }
+
+ settings = new Settings(environments)._obj._useEnvironment('development')
+ assert.deepEqual [4, 5, 6], settings.a.b.c.arr
+ assert.deepEqual 'baz', settings.a.b.c.bah
+ assert.deepEqual 'bar', settings.a.b.bar
+ assert.deepEqual 'bot', settings.a.b.c.fu
+
+
+ it "should say which environment is current", ->
+ settings = instance()
+ assert.equal 'common', settings.ENV
+
+ settings = new Settings(__dirname + '/config/environment', env: 'production')
+ assert.equal 'production', settings.ENV
+
+
+ settings = instance()._obj._useEnvironment('test')
+ assert.equal 'test', settings.ENV
+
+
+ it "should accept defaults", ->
+ environments =
+ 'common':
+ foo: 'boo'
+ 'development':
+ foo: 'bar'
+
+ options =
+ globalKey: '$settings'
+
+ defaults:
+ framework:
+ views: 'foo/views'
+ models: 'foo/models'
+
+ settings = new Settings(environments, options)._obj._useEnvironment('development')
+ assert.equal 'foo/views', settings.framework.views
+
+
+ it "should be overriden from file", ->
+ settings = instance()._obj._useEnvironment('test')
+ assert.equal 'server_test', settings.storage.database
+ assert.equal 'localhost', settings.storage.host
+ settings._obj.override __dirname + "/config/override"
+ assert.equal 'server_test', settings.storage.database
+ assert.equal 'override', settings.storage.host
+ settings._obj.override __dirname + "/config/override2"
+ assert.equal 'server_test', settings.storage.database
+ assert.equal 'override2', settings.storage.host
+
+
+ it "should override with root", ->
+ settings = new Settings(__dirname + '/config/environment', env: 'test')
+ assert.equal 'server_test', settings.storage.database
+ assert.equal 'localhost', settings.storage.host
+ settings._obj.override __dirname + "/config/overrideRoot", 'fubar'
+ assert.equal 'server_test', settings.storage.database
+ assert.equal 'override', settings.storage.host
+ settings._obj.override __dirname + "/config/overrideRoot2", 'bar'
+ assert.equal 'server_test', settings.storage.database
+ assert.equal 'override2', settings.storage.host
+
+ it "should handle regex literals", ->
+ settings = new Settings(__dirname + '/config/environment')
+ assert.ok /asdf/ instanceof RegExp
+ assert.ok settings.re instanceof RegExp
+
View
167 support/extend.js
@@ -0,0 +1,167 @@
+/*
+ jQuery.extend extracted from the jQuery source & optimised for NodeJS
+ Twitter: @FGRibreau / fgribreau.com
+
+ Usage:
+ var Extend = require('./Extend');
+
+
+ // Extend
+ var obj = Extend({opt1:true, opt2:true}, {opt1:false});
+
+ // Deep Copy
+ var clonedObject = Extend(true, {}, myObject);
+ var clonedArray = Extend(true, [], ['a',['b','c',['d']]]);
+*/
+var toString = Object.prototype.toString,
+ hasOwn = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ trim = String.prototype.trim,
+ indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+// Populate the class2type map
+"Boolean Number String Function Array Date RegExp Object".split(" ").forEach(function(name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function type(obj){
+ return obj == null ?
+ String( obj ) :
+ class2type[ toString.call(obj) ] || "object";
+}
+
+function isPlainObject( obj ) {
+ if ( !obj || type(obj) !== "object") {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call(obj, "constructor") &&
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+}
+
+function extend(){
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && type(target) !== "function") {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( isPlainObject(copy) || (copyIsArray = type(copy) === "array") ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && type(src) === "array" ? src : [];
+
+ } else {
+ clone = src && isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+
+
+/**
+ * Extends `target` with properties from `source`.
+ */
+exports.extend = function deepExtend(target, source){
+ return extend(true, target, source);
+};
+
+
+exports.shallowExtend = function(target, source) {
+ return extend(target, source);
+};
+
+
+exports.clone = function(o){
+ var result;
+
+ if (isPlainObject(o)) {
+ result = extend(true, {}, o);
+ }
+ if (type(o) == "array") {
+ result = extend(true, [], o);
+ }
+ return result;
+};
+
+
+/**
+ * Deep clones `target`, then deep extends the clone with `source`.
+ */
+exports.cloneExtend = function(target, source) {
+ var result = exports.clone(target);
+ return exports.extend(result, source);
+}
+
+
+exports.shallowClone = function(o) {
+ if (isPlainObject(o)) {
+ o = extend(false, {}, o);
+ }
+ if (type(o) == "array") {
+ o = extend(false, [], o);
+ }
+ return o;
+}
View
278 support/merger.js
@@ -1,278 +0,0 @@
-/*============================================================================
- CREDIT: https://github.com/shimondoodkin/nodejs-clone-extend.git
-============================================================================*/
-
-function replace(a, b) {
- if (!b) {
- return a;
- }
- var key;
- for (key in b) {
- if (b.hasOwnProperty(key)) {
- a[key] = b[key];
- }
- }
-
- return a;
-}
-this.replace = replace;
-
-function add(a, b) {
- if (!b) {
- return a;
- }
- var key;
- for (key in b) {
- if (b.hasOwnProperty(key)) {
- if (typeof a[key] === 'undefined' || a[key] === null) {
- a[key] = b[key];
- }
- }
- }
- return a;
-}
-this.add = add;
-
-
-function extend(a, b, context, newobjs, aparent, aname, haveaparent) // context is anti circular references mechanism
-{
- if (a == b) {
- return a;
- }
- if (!b) {
- return a;
- }
-
- var key, clean_context = false,
- return_sublevel = false,
- b_pos;
- if (!haveaparent) {
- aparent = {
- 'a': a
- };
- aname = 'a';
- }
- if (!context) {
- clean_context = true;
- context = [];
- newobjs = [];
- }
- b_pos = context.indexOf(b);
- if (b_pos == -1) {
- context.push(b);
- newobjs.push([aparent, aname]);
- } else {
- return newobjs[b_pos][0][newobjs[b_pos][1]];
- }
-
- for (key in b) {
- if (b.hasOwnProperty(key)) {
- if (typeof a[key] === 'undefined') {
- if (typeof b[key] === 'object') {
- if (b[key] instanceof Array) // http://javascript.crockford.com/remedial.html
- {
- a[key] = extend([], b[key], context, newobjs, a, key, true);
- } else if (b[key] === null) {
- a[key] = null;
- } else {
- a[key] = extend({}, b[key], context, newobjs, a, key, true); /*a[key].constructor = b[key].constructor; a[key].prototype = b[key].prototype;*/
- }
- } else {
- a[key] = b[key];
- }
- } else if (typeof a[key] === 'object' && a[key] !== null) {
- a[key] = extend(a[key], b[key], context, newobjs, a, key, true); /*a[key].constructor = b[key].constructor; a[key].prototype = b[key].prototype;*/
- } else {
- a[key] = b[key];
- }
- }
- }
- if (clean_context) {
- context = null;
- newobjs = null;
- }
- if (!haveaparent) {
- aparent = null;
- return a;
- }
- if (typeof a === 'object' && !(a instanceof Array)) {
-/*a.constructor = b.constructor;
- a.prototype = b.prototype*/
- ;
- }
- return a;
-}
-this.extend = extend;
-
-function extenduptolevel(a, b, levels, context, newobjs, aparent, aname, haveaparent) {
- if (a == b) {
- return a;
- }
- if (!b) {
- return a;
- }
-
- var key, clean_context = false,
- return_sublevel = false;
- if (!haveaparent) {
- aparent = {
- 'a': a
- };
- aname = 'a';
- }
- if (!context) {
- clean_context = true;
- context = [];
- newobjs = [];
- }
- b_pos = context.indexOf(b);
- if (b_pos == -1) {
- context.push(b);
- newobjs.push([aparent, aname]);
- } else {
- return newobjs[b_pos][0][newobjs[b_pos][1]];
- }
-
- for (key in b) {
- if (b.hasOwnProperty(key)) {
- if (typeof a[key] === 'undefined') {
- if (typeof b[key] === 'object' && levels > 0) {
- if (b[key] instanceof Array) // http://javascript.crockford.com/remedial.html
- {
- a[key] = extenduptolevel([], b[key], levels - 1, context, newobjs, a, key, true);
- } else if (b[key] === null) {
- a[key] = null;
- } else {
- a[key] = extenduptolevel({}, b[key], levels - 1, context, newobjs, a, key, true);
- }
- } else {
- a[key] = b[key];
- }
- } else if (typeof a[key] === 'object' && a[key] !== null && levels > 0) {
- a[key] = extenduptolevel(a[key], b[key], levels - 1, context, newobjs, a, key, true);
- } else {
- a[key] = b[key];
- }
- }
- }
- if (clean_context) {
- context = null;
- newobjs = null;
- }
-
- if (!haveaparent) {
- aparent = null;
- return a;
- }
- if (typeof a === 'object' && !(a instanceof Array)) {
-/*a.constructor = b.constructor;
- a.prototype = b.prototype;*/
- }
- return a;
-}
-this.extenduptolevel = extenduptolevel;
-
-function clone(obj) {
- if (typeof obj === 'object') {
- if (obj === null) {
- return null;
- }
- if (obj instanceof Array) {
- return extend([], obj);
- } else {
- return extend({}, obj);
- }
- }
- return obj;
-}
-this.clone = clone;
-
-function cloneextend(obj, exteddata) {
- if (typeof obj === 'object') {
- if (obj === null) {
- return null;
- }
- return extend(clone(obj), exteddata);
- }
- return obj;
-}
-this.cloneextend = cloneextend;
-
-
-function cloneuptolevel(obj, level) // clone only numlevels levels other levels leave references
-{
- if (typeof obj === 'object') {
- if (obj === null) {
- return null;
- }
- if (obj instanceof Array) {
- return extenduptolevel([], obj, level);
- }
- return extenduptolevel({}, obj, level);
- }
- return obj;
-}
-this.cloneuptolevel = cloneuptolevel;
-
-
-function ObjforEach(object, block, context) {
- for (var key in object) {
- if (object.hasOwnProperty(key)) {
- block.call(context, object[key], key, object);
- }
- }
-}
-
-function foreach(object, block, context) {
- if (object) {
- if (typeof object === "object" && object instanceof Array) return object.forEach(object, block, context)
- else //if (typeof object === "object") // or (object instanceof Function)...
- {
- if (object) for (var key in object) {
- if (object.hasOwnProperty(key)) {
- block.call(context, object[key], key, object);
- }
- }
- }
- }
-}
-this.foreach = foreach;
-
-/*
- hasbugs and useless yet interesting maybe developed layer for dot pathed object transformation:
-
- {
- 'foo.bar':'bluebar',
- 'foo.color':'blue'
- }
-
- transforemed to
-
- {
- foo:
- {
- bar:'bluebar',
- color:'blue'
- }
- }
- //
- function dotpath(data,dotkeys,create)
- {
- if(!create){var create=false;}
- if(create) if(!data) data={};
- var keys= dotkeys.split("."),value=data;
- for (var i=0;i<keys.length;i++)
- {
- if(!value[keys[i]]) //should you create one?
- {
- if(create)
- value[keys[i]]={};
- else
- return undefined;
- }
- value = value[keys[i]];
- }
- return value;
- }
- */
-
View
24 test/coffee.test.js
@@ -1,24 +0,0 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
-
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/test/coffee.test.coffee
-var Settings, assert, _settings;
-Settings = require('../lib');
-assert = require('assert');
-_settings = new Settings(__dirname + '/../src/test/config/environment');
-module.exports = {
- "should get specific environment": function() {
- var settings;
- settings = _settings.getEnvironment('development');
- assert.equal('server_dev', settings.storage.database);
- settings = _settings.getEnvironment();
- assert.equal('server_dev', settings.storage.database);
- settings = _settings.getEnvironment('test');
- assert.equal('server_test', settings.storage.database);
- settings = _settings.getEnvironment('production');
- return assert.equal('server_production', settings.storage.database);
- }
-};
View
52 test/config/environment.js
@@ -1,26 +1,28 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
+// Generated by CoffeeScript 1.3.3
+(function() {
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/test/config/environment.coffee
-exports.common = {
- storage: {
- host: 'localhost',
- database: 'server_dev',
- user: 'qirogami_user',
- password: 'password'
- }
-};
-exports.development = {};
-exports.test = {
- storage: {
- database: 'server_test'
- }
-};
-exports.production = {
- storage: {
- database: 'server_production'
- }
-};
+ exports.common = {
+ storage: {
+ host: 'localhost',
+ database: 'server_dev',
+ user: 'qirogami_user',
+ password: 'password'
+ },
+ re: /^foo$/
+ };
+
+ exports.development = {};
+
+ exports.test = {
+ storage: {
+ database: 'server_test'
+ }
+ };
+
+ exports.production = {
+ storage: {
+ database: 'server_production'
+ }
+ };
+
+}).call(this);
View
20 test/config/override.js
@@ -1,12 +1,10 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
+// Generated by CoffeeScript 1.3.3
+(function() {
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/test/config/override.coffee
-module.exports = {
- storage: {
- host: 'override'
- }
-};
+ module.exports = {
+ storage: {
+ host: 'override'
+ }
+ };
+
+}).call(this);
View
20 test/config/override2.js
@@ -1,12 +1,10 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
+// Generated by CoffeeScript 1.3.3
+(function() {
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/test/config/override2.coffee
-exports.common = {
- storage: {
- host: 'override2'
- }
-};
+ exports.common = {
+ storage: {
+ host: 'override2'
+ }
+ };
+
+}).call(this);
View
12 test/config/overrideRoot.js
@@ -0,0 +1,12 @@
+// Generated by CoffeeScript 1.3.3
+(function() {
+
+ module.exports = {
+ fubar: {
+ storage: {
+ host: 'override'
+ }
+ }
+ };
+
+}).call(this);
View
12 test/config/overrideRoot2.js
@@ -0,0 +1,12 @@
+// Generated by CoffeeScript 1.3.3
+(function() {
+
+ exports.common = {
+ bar: {
+ storage: {
+ host: 'override2'
+ }
+ }
+ };
+
+}).call(this);
View
170 test/settings.test.js
@@ -1,170 +0,0 @@
-/*============================================================================
- Copyright(c) 2010 Mario L Gutierrez <mario@mgutz.com>
- MIT Licensed
-
- AUTO-GENERATED. DO NOT EDIT.
-============================================================================*/
-// Original file: src/test/settings.test.coffee
-var Settings, assert, _settings;
-assert = require('assert');
-Settings = require('../lib');
-_settings = new Settings(__dirname + '/config/environment');
-module.exports = {
- "should be global installable using custom key": function() {
- var environments, settings;
- environments = {
- 'common': {
- foo: 'boo'
- },
- 'development': {
- foo: 'bar'
- }
- };
- settings = new Settings(environments, {
- globalKey: '$settings'
- }).getEnvironment('development');
- return assert.equal('bar', $settings.foo);
- },
- "issue 1 - global install not merged with common": function() {
- var environments, settings;
- environments = {
- 'common': {
- foo: 'boo',
- bah: 'baz'
- },
- 'development': {
- foo: 'bar'
- }
- };
- settings = new Settings(environments, {
- globalKey: '$settings'
- }).getEnvironment('development');
- return assert.equal('baz', $settings.bah);
- },
- "should get specific environment": function() {
- var settings;
- settings = _settings.getEnvironment('development');
- assert.equal('server_dev', settings.storage.database);
- settings = _settings.getEnvironment();
- assert.equal('server_dev', settings.storage.database);
- settings = _settings.getEnvironment('test');
- assert.equal('server_test', settings.storage.database);
- settings = _settings.getEnvironment('production');
- return assert.equal('server_production', settings.storage.database);
- },
- "should get value from ancestor if key is not found": function() {
- var settings;
- settings = _settings.getEnvironment('test');
- return assert.equal('password', settings.storage.password);
- },
- "should have a forceEnv property to force all settings through an environment": function() {
- var environments, set, settings;
- environments = {
- 'common': {
- foo: 'boo'
- },
- 'development': {
- foo: 'bar'
- },
- 'test': {
- foo: 'bah'
- },
- 'prod': {
- foo: 'baz'
- },
- forceEnv: 'development'
- };
- settings = new Settings(environments);
- set = settings.getEnvironment('development');
- assert.equal('bar', set.foo);
- set = settings.getEnvironment('test');
- assert.equal('bar', set.foo);
- set = settings.getEnvironment('prod');
- return assert.equal('bar', set.foo);
- },
- "should replace array values, not merge them": function() {
- var environments, settings;
- environments = {
- 'common': {
- arr: [1, 2, 3]
- },
- 'development': {
- arr: [4, 5, 6]
- }
- };
- settings = new Settings(environments).getEnvironment('development');
- return assert.eql([4, 5, 6], settings.arr);
- },
- "should do a deep merge": function() {
- var environments, settings;
- environments = {
- 'common': {
- a: {
- b: {
- c: {
- arr: [1, 2, 3],
- bah: 'baz'
- },
- bar: 'bar'
- }
- }
- },
- 'development': {
- a: {
- b: {
- c: {
- arr: [4, 5, 6],
- fu: 'bot'
- }
- }
- }
- }
- };
- settings = new Settings(environments).getEnvironment('development');
- assert.eql([4, 5, 6], settings.a.b.c.arr);
- assert.eql('baz', settings.a.b.c.bah);
- assert.eql('bar', settings.a.b.bar);
- return assert.eql('bot', settings.a.b.c.fu);
- },
- "should say which environment is current": function() {
- var settings;
- settings = _settings.getEnvironment('development');
- assert.equal('development', _settings.env);
- settings = _settings.getEnvironment('test');
- return assert.equal('test', _settings.env);
- },
- "should accept defaults": function() {
- var environments, options, settings;
- environments = {
- 'common': {
- foo: 'boo'
- },
- 'development': {
- foo: 'bar'
- }
- };
- options = {
- globalKey: '$settings',
- defaults: {
- framework: {
- views: 'app/views',
- models: 'app/models'
- }
- }
- };
- settings = new Settings(environments, options).getEnvironment('development');
- return assert.equal('app/views', settings.framework.views);
- },
- "should be overriden from file": function() {
- var settings;
- settings = _settings.getEnvironment('test');
- assert.equal('server_test', settings.storage.database);
- assert.equal('localhost', settings.storage.host);
- settings.override(__dirname + "/config/override");
- assert.equal('server_test', settings.storage.database);
- assert.equal('override', settings.storage.host);
- settings.override(__dirname + "/config/override2");
- assert.equal('server_test', settings.storage.database);
- return assert.equal('override2', settings.storage.host);
- }
-};
View
166 test/settingsTest.js
@@ -0,0 +1,166 @@
+// Generated by CoffeeScript 1.3.3
+(function() {
+ var Settings, assert, instance;
+
+ assert = require("chai").assert;
+
+ Settings = require("../lib/settings");
+
+ instance = function() {
+ return new Settings(__dirname + "/config/environment");
+ };
+
+ describe("Settings", function() {
+ it("should get specific environment", function() {
+ var settings;
+ settings = instance()._obj._useEnvironment('development');
+ assert.equal('server_dev', settings.storage.database);
+ settings = instance()._obj._useEnvironment();
+ assert.equal('server_dev', settings.storage.database);
+ settings = instance()._obj._useEnvironment('test');
+ assert.equal('server_test', settings.storage.database);
+ settings = instance()._obj._useEnvironment('production');
+ return assert.equal('server_production', settings.storage.database);
+ });
+ it("should get value from ancestor if key is not found", function() {
+ var settings;
+ settings = instance()._obj._useEnvironment('test');
+ return assert.equal('password', settings.storage.password);
+ });
+ it("should have a forceEnv property to force all settings through an environment", function() {
+ var environments, set, settings;
+ environments = {
+ 'common': {
+ foo: 'boo'
+ },
+ 'development': {
+ foo: 'bar'
+ },
+ 'test': {
+ foo: 'bah'
+ },
+ 'prod': {
+ foo: 'baz'
+ },
+ forceEnv: 'development'
+ };
+ settings = new Settings(environments);
+ set = settings._obj._useEnvironment('development');
+ assert.equal('bar', set.foo);
+ set = settings._obj._useEnvironment('test');
+ assert.equal('bar', set.foo);
+ set = settings._obj._useEnvironment('prod');
+ return assert.equal('bar', set.foo);
+ });
+ it("should replace array values, not merge them", function() {
+ var environments, settings;
+ environments = {
+ 'common': {
+ arr: [1, 2, 3]
+ },
+ 'development': {
+ arr: [4, 5, 6]
+ }
+ };
+ settings = new Settings(environments)._obj._useEnvironment('development');
+ return assert.deepEqual([4, 5, 6], settings.arr);
+ });
+ it("should do a deep merge", function() {
+ var environments, settings;
+ environments = {
+ 'common': {
+ a: {
+ b: {
+ c: {
+ arr: [1, 2, 3],
+ bah: 'baz'
+ },
+ bar: 'bar'
+ }
+ }
+ },
+ 'development': {
+ a: {
+ b: {
+ c: {
+ arr: [4, 5, 6],
+ fu: 'bot'
+ }
+ }
+ }
+ }
+ };
+ settings = new Settings(environments)._obj._useEnvironment('development');
+ assert.deepEqual([4, 5, 6], settings.a.b.c.arr);
+ assert.deepEqual('baz', settings.a.b.c.bah);
+ assert.deepEqual('bar', settings.a.b.bar);
+ return assert.deepEqual('bot', settings.a.b.c.fu);
+ });
+ it("should say which environment is current", function() {
+ var settings;
+ settings = instance();
+ assert.equal('common', settings.ENV);
+ settings = new Settings(__dirname + '/config/environment', {
+ env: 'production'
+ });
+ assert.equal('production', settings.ENV);
+ settings = instance()._obj._useEnvironment('test');
+ return assert.equal('test', settings.ENV);
+ });
+ it("should accept defaults", function() {
+ var environments, options, settings;
+ environments = {
+ 'common': {
+ foo: 'boo'
+ },
+ 'development': {
+ foo: 'bar'
+ }
+ };
+ options = {
+ globalKey: '$settings',
+ defaults: {
+ framework: {
+ views: 'foo/views',
+ models: 'foo/models'
+ }
+ }
+ };
+ settings = new Settings(environments, options)._obj._useEnvironment('development');
+ return assert.equal('foo/views', settings.framework.views);
+ });
+ it("should be overriden from file", function() {
+ var settings;
+ settings = instance()._obj._useEnvironment('test');
+ assert.equal('server_test', settings.storage.database);
+ assert.equal('localhost', settings.storage.host);
+ settings._obj.override(__dirname + "/config/override");
+ assert.equal('server_test', settings.storage.database);
+ assert.equal('override', settings.storage.host);
+ settings._obj.override(__dirname + "/config/override2");
+ assert.equal('server_test', settings.storage.database);
+ return assert.equal('override2', settings.storage.host);
+ });
+ it("should override with root", function() {
+ var settings;
+ settings = new Settings(__dirname + '/config/environment', {
+ env: 'test'
+ });
+ assert.equal('server_test', settings.storage.database);
+ assert.equal('localhost', settings.storage.host);
+ settings._obj.override(__dirname + "/config/overrideRoot", 'fubar');
+ assert.equal('server_test', settings.storage.database);
+ assert.equal('override', settings.storage.host);
+ settings._obj.override(__dirname + "/config/overrideRoot2", 'bar');
+ assert.equal('server_test', settings.storage.database);
+ return assert.equal('override2', settings.storage.host);
+ });
+ return it("should handle regex literals", function() {
+ var settings;
+ settings = new Settings(__dirname + '/config/environment');
+ assert.ok(/asdf/ instanceof RegExp);
+ return assert.ok(settings.re instanceof RegExp);
+ });
+ });
+
+}).call(this);
Please sign in to comment.
Something went wrong with that request. Please try again.