Skip to content

Commit

Permalink
Add hjson support (#30)
Browse files Browse the repository at this point in the history
* add hjson support
  • Loading branch information
PSSGCSim authored and msimerson committed Sep 28, 2017
1 parent ce7243a commit e82a402
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 10 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ node_modules

# Optional REPL history
.node_repl_history

# npm manifestation of the manifest
# https://docs.npmjs.com/files/package-lock.json
package-lock.json
13 changes: 9 additions & 4 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ Config.prototype.getDir = function (name, opts, done) {
};

function merge_config (defaults, overrides, type) {
if (type === 'ini' || type === 'json' || type === 'yaml') {
return merge_struct(JSON.parse(JSON.stringify(defaults)), overrides);
switch (type) {
case 'ini':
case 'hjson':
case 'json':
case 'yaml':
return merge_struct(JSON.parse(JSON.stringify(defaults)), overrides);
}

if (Array.isArray(overrides) && Array.isArray(defaults) &&
Expand Down Expand Up @@ -113,7 +117,7 @@ Config.prototype.arrange_args = function (args) {
options = args[i];
break;
case 'string':
if (/^(ini|value|list|data|json|yaml|binary)$/.test(args[i])) {
if (/^(ini|value|list|data|h?json|yaml|binary)$/.test(args[i])) {
fs_type = args[i];
break;
}
Expand All @@ -125,7 +129,8 @@ Config.prototype.arrange_args = function (args) {
}

if (!fs_type) {
if (/\.json$/.test(fs_name)) fs_type = 'json';
if (/\.hjson$/.test(fs_name)) fs_type = 'hjson';
else if (/\.json$/.test(fs_name)) fs_type = 'json';
else if (/\.yaml$/.test(fs_name)) fs_type = 'yaml';
else if (/\.ini$/.test(fs_name)) fs_type = 'ini';
else fs_type = 'value';
Expand Down
7 changes: 4 additions & 3 deletions configfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,18 +337,18 @@ cfreader.load_config = function (name, type, options) {
let cfrType = cfreader.get_filetype_reader(type);

if (!fs.existsSync(name)) {

if (!/\.json$/.test(name)) {
if (!/\.h?json$/.test(name)) {
return cfrType.empty(options, type);
}

const yaml_name = name.replace(/\.json$/, '.yaml');
const yaml_name = name.replace(/\.h?json$/, '.yaml');
if (!fs.existsSync(yaml_name)) {
return cfrType.empty(options, type);
}

name = yaml_name;
type = 'yaml';

cfrType = cfreader.get_filetype_reader(type);
}

Expand All @@ -358,6 +358,7 @@ cfreader.load_config = function (name, type, options) {
case 'ini':
result = cfrType.load(name, options, regex);
break;
case 'hjson':
case 'json':
case 'yaml':
result = cfrType.load(name);
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"dependencies": {
"js-yaml": "^3.5.3"
},
"optionalDependencies": {},
"optionalDependencies": {
"hjson": "^3.1.0"
},
"devDependencies": {
"eslint": "*",
"eslint-plugin-haraka": "*",
Expand Down
12 changes: 12 additions & 0 deletions readers/hjson.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const fs = require('fs');
const hjson = require('hjson');

exports.load = function (name) {
return hjson.parse(fs.readFileSync(name, "utf8"));
};

exports.empty = function () {
return {};
};
56 changes: 55 additions & 1 deletion test/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ exports.arrange_args = {
test.done();
},
// config.get('name', type, cb, options);
'name, hjson type, callback, options' : function (test) {
test.expect(1);
test.deepEqual(
this.config.arrange_args(['test.ini','hjson',cb, opts]),
['test.ini', 'hjson', cb, opts]);
test.done();
},
// config.get('name', type, cb, options);
'name, json type, callback, options' : function (test) {
test.expect(1);
test.deepEqual(
Expand All @@ -174,6 +182,15 @@ exports.arrange_args = {
},
};

const hjsonRes = {
matt: 'waz here and also made comments',
differentArray: [ 'has element #1', 'has element #2' ],
object: {
'has a property one': 'with a value A',
'has a property two': 'with a value B'
}
};

const jsonRes = {
matt: 'waz here',
array: [ 'has an element' ],
Expand Down Expand Up @@ -296,6 +313,15 @@ exports.get = {
['line1', 'line2','line3', '', 'line5'] );
},

// config.get('test.hjson');
'test.hjson, type=' : function (test) {
_test_get(test, 'test.hjson', null, null, null, hjsonRes);
},
// config.get('test.hjson', 'hjson');
'test.hjson, type=hjson' : function (test) {
_test_get(test, 'test.hjson', 'hjson', null, null, hjsonRes);
},

// config.get('test.json');
'test.json, type=' : function (test) {
_test_get(test, 'test.json', null, null, null, jsonRes);
Expand All @@ -313,6 +339,10 @@ exports.get = {
'test.yaml, type=yaml' : function (test) {
_test_get(test, 'test.yaml', 'yaml', null, null, yamlRes);
},
// config.get('missing2.hjson');
'missing2.yaml, asked for hjson' : function (test) {
_test_get(test, 'missing2.hjson', 'hjson', null, null, {"matt": "waz here - hjson type"});
},
// config.get('missing.json');
'missing.yaml, asked for json' : function (test) {
_test_get(test, 'missing.json', 'json', null, null, {"matt": "waz here"});
Expand Down Expand Up @@ -438,6 +468,30 @@ exports.getDir = {
}
}

exports.hjsonOverrides = {
'setUp' : setUp,
'no override for smtpgreeting': function (test) {
test.expect(1);
// console.log(this.config);
test.deepEqual(
this.config.get('smtpgreeting', 'list'),
[]
);
test.done();
},
'with smtpgreeting override': function (test) {
test.expect(1);
process.env.WITHOUT_CONFIG_CACHE='';
const main = this.config.get('main.hjson');
console.log(main);
test.deepEqual(
this.config.get('smtpgreeting', 'list'),
[ 'this is line one for hjson', 'this is line two for hjson' ]
);
test.done();
}
}

exports.jsonOverrides = {
'setUp' : setUp,
'no override for smtpgreeting': function (test) {
Expand All @@ -460,4 +514,4 @@ exports.jsonOverrides = {
);
test.done();
}
}
}
11 changes: 11 additions & 0 deletions test/config/main.hjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
# specify smtp greeting (because comments are helpful!)
"!smtpgreeting":
[
# yes, commas are optional!
"this is line one for hjson"
"this is line two for hjson"
]
// prefer c-style comments?
/* feeling old fashioned? */
}
3 changes: 3 additions & 0 deletions test/config/missing2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
matt: "waz here - hjson type"
...
2 changes: 2 additions & 0 deletions test/config/override2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hasDifferent:
value: false
19 changes: 19 additions & 0 deletions test/config/test.hjson
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// sign matt (because comments are helpful!)
"matt": "waz here and also made comments",

// fill in this array
"differentArray": [
"has element #1",
'has element #2'
]
# best of all
# yes, commas are optional!

/* feeling old fashioned? */
"object": {
// prefer c-style comments?
"has a property one": 'with a value A',
'has a property two': with a value B
}
}
24 changes: 23 additions & 1 deletion test/configfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ exports.get_filetype_reader = {
test.equal(typeof reader.empty, 'function');
test.done();
},
'hjson': function (test) {
test.expect(2);
const reader = this.cfreader.get_filetype_reader('hjson');
test.equal(typeof reader.load, 'function');
test.equal(typeof reader.empty, 'function');
test.done();
},
'json': function (test) {
test.expect(2);
const reader = this.cfreader.get_filetype_reader('json');
Expand Down Expand Up @@ -221,6 +228,14 @@ exports.get_filetype_reader = {
exports.non_existing = {
setUp: _setUp,

'empty object for HJSON files': function (test) {
test.expect(1);
const result = this.cfreader.load_config(
'test/config/non-existent.hjson'
);
test.deepEqual(result, {});
test.done();
},
'empty object for JSON files': function (test) {
test.expect(1);
const result = this.cfreader.load_config(
Expand Down Expand Up @@ -388,6 +403,13 @@ exports.bad_config = {

exports.overrides = {
setUp: _setUp,
'missing hjson loads yaml instead' : function (test) {
test.expect(1);
test.deepEqual(
this.cfreader.load_config('test/config/override2.hjson'),
{ hasDifferent: { value: false } });
test.done();
},
'missing json loads yaml instead' : function (test) {
test.expect(1);
test.deepEqual(
Expand Down Expand Up @@ -423,4 +445,4 @@ exports.get_path_to_config_dir = {
test.ok(/haraka-config$/.test(this.cfreader.config_path), this.cfreader.config_path);
test.done();
},
}
}
30 changes: 30 additions & 0 deletions test/readers/hjson.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

const _set_up = function (done) {
this.hjson = require('../../readers/hjson');
done();
};

exports.load = {
setUp : _set_up,
'module is required' : function (test) {
test.expect(1);
test.ok(this.hjson);
test.done();
},
'has a load function': function (test) {
test.expect(1);
test.ok(typeof this.hjson.load === 'function');
test.done();
},
'loads the test HJSON file': function (test) {
test.expect(4);
const result = this.hjson.load('test/config/test.hjson');
// console.log(result);
test.equal(result.matt, 'waz here and also made comments');
test.ok(result.differentArray.length);
test.ok(result.object['has a property one']);
test.ok(result.object['has a property two']);
test.done();
},
};

0 comments on commit e82a402

Please sign in to comment.