Improves config loading and tests

This commit is contained in:
Florent Vilmart
2016-04-04 20:02:34 -04:00
parent 27dd2ebf5d
commit 8c92b80b8f
8 changed files with 155 additions and 39 deletions

View File

@@ -1,3 +1,4 @@
'use strict';
var commander = require("../src/cli/utils/commander").default;
var definitions = {
@@ -11,7 +12,7 @@ var definitions = {
action: function(value) {
var value = parseInt(value);
if (!Number.isInteger(value)) {
throw "port is invalid";
throw "arg2 is invalid";
}
return value;
}
@@ -81,7 +82,58 @@ describe("commander additions", () => {
"PROGRAM_ARG_1": "arg1ENVValue",
"PROGRAM_ARG_2": "hello",
});
}).toThrow("port is invalid");
}).toThrow("arg2 is invalid");
done();
});
it("should not override config.json", (done) => {
commander.loadDefinitions(definitions);
commander.parse(["node","./CLI.spec.js","--arg0", "arg0Value", "./spec/configs/CLIConfig.json"], {
"PROGRAM_ARG_0": "arg0ENVValue",
"PROGRAM_ARG_1": "arg1ENVValue",
});
let options = commander.getOptions();
expect(options.arg2).toBe(8888);
expect(options.arg3).toBe("hello"); //config value
expect(options.arg4).toBe('/1');
done();
});
it("should fail with invalid values in JSON", (done) => {
commander.loadDefinitions(definitions);
expect(() => {
commander.parse(["node","./CLI.spec.js","--arg0", "arg0Value", "./spec/configs/CLIConfigFail.json"], {
"PROGRAM_ARG_0": "arg0ENVValue",
"PROGRAM_ARG_1": "arg1ENVValue",
});
}).toThrow("arg2 is invalid")
done();
});
it("should fail when too many apps are set", (done) => {
commander.loadDefinitions(definitions);
expect(() => {
commander.parse(["node","./CLI.spec.js","./spec/configs/CLIConfigFailTooManyApps.json"]);
}).toThrow("Multiple apps are not supported")
done();
});
it("should load config from apps", (done) => {
commander.loadDefinitions(definitions);
commander.parse(["node", "./CLI.spec.js", "./spec/configs/CLIConfigApps.json"]);
let options = commander.getOptions();
expect(options.arg1).toBe("my_app");
expect(options.arg2).toBe(8888);
expect(options.arg3).toBe("hello"); //config value
expect(options.arg4).toBe('/1');
done();
});
it("should fail when passing an invalid arguement", (done) => {
commander.loadDefinitions(definitions);
expect(() => {
commander.parse(["node", "./CLI.spec.js", "./spec/configs/CLIConfigUnknownArg.json"]);
}).toThrow('error: unknown option myArg')
done();
});
});

View File

@@ -0,0 +1,6 @@
{
"arg1": "my_app",
"arg2": "8888",
"arg3": "hello",
"arg4": "/1"
}

View File

@@ -0,0 +1,9 @@
{
"apps": [
{
"arg1": "my_app",
"arg2": 8888,
"arg3": "hello",
"arg4": "/1"
}]
}

View File

@@ -0,0 +1,6 @@
{
"arg1": "my_app",
"arg2": "hello",
"arg3": "hello",
"arg4": "/1"
}

View File

@@ -0,0 +1,16 @@
{
"apps": [
{
"arg1": "my_app",
"arg2": "99999",
"arg3": "hello",
"arg4": "/1"
},
{
"arg1": "my_app2",
"arg2": "9999",
"arg3": "hello",
"arg4": "/1"
}
]
}

View File

@@ -0,0 +1,6 @@
{
"arg1": "my_app",
"arg2": "8888",
"arg3": "hello",
"myArg": "/1"
}

View File

@@ -3,6 +3,7 @@ import express from 'express';
import { ParseServer } from '../index';
import definitions from './cli-definitions';
import program from './utils/commander';
import { mergeWithOptions } from './utils/commander';
import colors from 'colors';
program.loadDefinitions(definitions);
@@ -34,28 +35,7 @@ program.on('--help', function(){
program.parse(process.argv, process.env);
let options = {};
if (program.args.length > 0 ) {
let jsonPath = program.args[0];
jsonPath = path.resolve(jsonPath);
let jsonConfig = require(jsonPath);
if (jsonConfig.apps) {
if (jsonConfig.apps.length > 1) {
throw 'Multiple apps are not supported';
}
options = jsonConfig.apps[0];
} else {
options = jsonConfig;
}
console.log(`Configuation loaded from ${jsonPath}`)
}
options = Object.keys(definitions).reduce(function (options, key) {
if (typeof program[key] !== 'undefined') {
options[key] = program[key];
}
return options;
}, options);
let options = program.getOptions();
if (!options.serverURL) {
options.serverURL = `http://localhost:${options.port}${options.mountPath}`;

View File

@@ -1,5 +1,5 @@
import { Command } from 'commander';
import path from 'path';
let _definitions;
let _reverseDefinitions;
let _defaults;
@@ -62,6 +62,35 @@ function parseEnvironment(env = {}) {
}, {});
}
function parseConfigFile(program) {
let options = {};
if (program.args.length > 0) {
let jsonPath = program.args[0];
jsonPath = path.resolve(jsonPath);
let jsonConfig = require(jsonPath);
if (jsonConfig.apps) {
if (jsonConfig.apps.length > 1) {
throw 'Multiple apps are not supported';
}
options = jsonConfig.apps[0];
} else {
options = jsonConfig;
}
Object.keys(options).forEach((key) => {
let value = options[key];
if (!_definitions[key]) {
throw `error: unknown option ${key}`;
}
let action = _definitions[key].action;
if (action) {
options[key] = action(value);
}
})
console.log(`Configuation loaded from ${jsonPath}`)
}
return options;
}
Command.prototype.setValuesIfNeeded = function(options) {
Object.keys(options).forEach((key) => {
if (!this[key]) {
@@ -76,10 +105,22 @@ Command.prototype.parse = function(args, env) {
this._parse(args);
// Parse the environment first
const envOptions = parseEnvironment(env);
const fromFile = parseConfigFile(this);
// Load the env if not passed from command line
this.setValuesIfNeeded(envOptions);
// Load from file to override
this.setValuesIfNeeded(fromFile);
// Last set the defaults
this.setValuesIfNeeded(_defaults);
}
Command.prototype.getOptions = function() {
return Object.keys(_definitions).reduce((options, key) => {
if (typeof this[key] !== 'undefined') {
options[key] = this[key];
}
return options;
}, {});
}
export default new Command();