mirror of https://github.com/Seich/Beau.git
Added tests to all CLI commands. (#28)
* Moved the spinner initialization to the base class. * Got rid of the base class, it complicated testing. Now it lives on as a utils file. Should make it easier to test the CLI. * Added a spec file for the ListCommand. * Added tests for all CLI commands. * Update some old tests. Added missing cases and tests. Most of these are kind useless but I hope I won't have to touch them again.
This commit is contained in:
parent
23064040df
commit
26b33fbf00
|
|
@ -0,0 +1,14 @@
|
||||||
|
const fs = jest.genMockFromModule('fs');
|
||||||
|
|
||||||
|
fs.existsSync = filename => filename === 'beau.yml';
|
||||||
|
fs.readFileSync = () => `
|
||||||
|
version: 1
|
||||||
|
endpoint: https://example.org/
|
||||||
|
|
||||||
|
GET /anything:
|
||||||
|
alias: anything
|
||||||
|
payload:
|
||||||
|
name: $env.params.name
|
||||||
|
`;
|
||||||
|
|
||||||
|
module.exports = fs;
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
const Beau = require('../../../src/beau');
|
||||||
|
const original = require.requireActual('../utils');
|
||||||
|
|
||||||
|
const utils = {};
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
environment: {
|
||||||
|
params: {
|
||||||
|
name: 'David'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endpoint: 'https://example.org',
|
||||||
|
version: 1,
|
||||||
|
'GET /anything': {
|
||||||
|
alias: 'anything',
|
||||||
|
payload: {
|
||||||
|
name: '$env.params.name'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'GET /status/418': {
|
||||||
|
alias: 'teapot'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
utils.loadConfig = function() {
|
||||||
|
return new Beau(config, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
utils.openConfigFile = function(filename) {
|
||||||
|
if (filename === 'beau.yml') {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename === 'invalid-conf.yml') {
|
||||||
|
return { plugins: [{ hello: 1, world: 2 }] };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
utils.baseFlags = original.baseFlags;
|
||||||
|
|
||||||
|
module.exports = utils;
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`List Command Should disable formatting when the flag is active. 1`] = `
|
||||||
|
Array [
|
||||||
|
"GET anything https://example.org/anything
|
||||||
|
",
|
||||||
|
"GET teapot https://example.org/status/418
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`List Command Should list available requests for a given file. 1`] = `
|
||||||
|
Array [
|
||||||
|
" HTTP Verb Alias Endpoint
|
||||||
|
",
|
||||||
|
" GET anything https://example.org/anything
|
||||||
|
",
|
||||||
|
" GET teapot https://example.org/status/418
|
||||||
|
",
|
||||||
|
"
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Request Command Should output an unformatted version 1`] = `
|
||||||
|
Array [
|
||||||
|
"200
|
||||||
|
",
|
||||||
|
"https://example.org/anything
|
||||||
|
",
|
||||||
|
"[]
|
||||||
|
",
|
||||||
|
"\\"{\\\\\\"hello\\\\\\": \\\\\\"world\\\\\\"}\\"
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Request Command Should output nothing 1`] = `Array []`;
|
||||||
|
|
||||||
|
exports[`Request Command Should output the response as json 1`] = `
|
||||||
|
Array [
|
||||||
|
"{\\"status\\":200,\\"headers\\":[],\\"body\\":\\"{\\\\\\"hello\\\\\\": \\\\\\"world\\\\\\"}\\"}
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Request Command Should output the response as json verboselly 1`] = `
|
||||||
|
Array [
|
||||||
|
"{\\"request\\":{\\"body\\":{\\"name\\":\\"David\\"},\\"endpoint\\":\\"https://example.org/anything\\"},\\"response\\":{\\"status\\":200,\\"headers\\":[],\\"body\\":\\"{\\\\\\"hello\\\\\\": \\\\\\"world\\\\\\"}\\"},\\"body\\":\\"{\\\\\\"hello\\\\\\": \\\\\\"world\\\\\\"}\\"}
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Request Command Should request the given alias 1`] = `
|
||||||
|
Array [
|
||||||
|
"",
|
||||||
|
" Status Endpoint
|
||||||
|
",
|
||||||
|
" 200 https://example.org/anything
|
||||||
|
",
|
||||||
|
"
|
||||||
|
",
|
||||||
|
"\\"{\\"hello\\": \\"world\\"}\\"
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Request Command Should show all information available when being verbose 1`] = `
|
||||||
|
Array [
|
||||||
|
"",
|
||||||
|
" Status Endpoint
|
||||||
|
",
|
||||||
|
" 200 https://example.org/anything
|
||||||
|
",
|
||||||
|
"
|
||||||
|
",
|
||||||
|
"{
|
||||||
|
request: {
|
||||||
|
body: {
|
||||||
|
name: \\"David\\"
|
||||||
|
},
|
||||||
|
endpoint: \\"https://example.org/anything\\"
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
status: 200,
|
||||||
|
headers: [],
|
||||||
|
body: \\"{\\"hello\\": \\"world\\"}\\"
|
||||||
|
},
|
||||||
|
body: \\"{\\"hello\\": \\"world\\"}\\"
|
||||||
|
}
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`utils loadConfig should load load the config onto Beau 1`] = `
|
||||||
|
Config {
|
||||||
|
"COOKIEJAR": false,
|
||||||
|
"DEFAULTS": Object {},
|
||||||
|
"ENDPOINT": "https://example.org/",
|
||||||
|
"ENVIRONMENT": Object {
|
||||||
|
"_": Object {},
|
||||||
|
},
|
||||||
|
"HOSTS": Array [],
|
||||||
|
"PLUGINS": Plugins {
|
||||||
|
"context": Object {
|
||||||
|
"createReadStream": [Function],
|
||||||
|
},
|
||||||
|
"registry": Object {
|
||||||
|
"dynamicValues": Array [
|
||||||
|
Object {
|
||||||
|
"fn": [Function],
|
||||||
|
"name": "createReadStream",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"postRequestModifiers": Array [],
|
||||||
|
"preRequestModifiers": Array [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"REQUESTS": Array [
|
||||||
|
Object {
|
||||||
|
"ALIAS": "anything",
|
||||||
|
"COOKIEJAR": false,
|
||||||
|
"ENDPOINT": "https://example.org/",
|
||||||
|
"PAYLOAD": Object {
|
||||||
|
"name": "$env.params.name",
|
||||||
|
},
|
||||||
|
"REQUEST": "GET /anything",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"VERSION": 1,
|
||||||
|
"configKeys": Array [
|
||||||
|
"VERSION",
|
||||||
|
"ENDPOINT",
|
||||||
|
"PLUGINS",
|
||||||
|
"DEFAULTS",
|
||||||
|
"ENVIRONMENT",
|
||||||
|
"HOSTS",
|
||||||
|
"COOKIEJAR",
|
||||||
|
],
|
||||||
|
"defaultConfigValues": Object {
|
||||||
|
"COOKIEJAR": false,
|
||||||
|
"DEFAULTS": Object {},
|
||||||
|
"ENDPOINT": "",
|
||||||
|
"ENVIRONMENT": Object {},
|
||||||
|
"HOSTS": Array [],
|
||||||
|
"PLUGINS": Array [],
|
||||||
|
"VERSION": 1,
|
||||||
|
},
|
||||||
|
"doc": Object {
|
||||||
|
"GET /anything": Object {
|
||||||
|
"alias": "anything",
|
||||||
|
"payload": Object {
|
||||||
|
"name": "$env.params.name",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"endpoint": "https://example.org/",
|
||||||
|
"version": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`utils loadConfig should load params onto the environment 1`] = `
|
||||||
|
Object {
|
||||||
|
"_": Object {
|
||||||
|
"BYE": "MARS",
|
||||||
|
"HELLO": "WORLD",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`utils openConfigFile should read and parse the given configuration file. 1`] = `
|
||||||
|
Object {
|
||||||
|
"GET /anything": Object {
|
||||||
|
"alias": "anything",
|
||||||
|
"payload": Object {
|
||||||
|
"name": "$env.params.name",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"endpoint": "https://example.org/",
|
||||||
|
"version": 1,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Validate Command should validate the configuration file 1`] = `
|
||||||
|
Array [
|
||||||
|
"beau.yml is valid.
|
||||||
|
",
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
const ListCommand = require('../commands/list');
|
||||||
|
|
||||||
|
jest.mock('../utils');
|
||||||
|
|
||||||
|
describe('List Command', () => {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
result = [];
|
||||||
|
jest
|
||||||
|
.spyOn(process.stdout, 'write')
|
||||||
|
.mockImplementation(val =>
|
||||||
|
result.push(require('strip-ansi')(val.toString('utf8')))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => jest.restoreAllMocks());
|
||||||
|
|
||||||
|
it('Should list available requests for a given file.', async () => {
|
||||||
|
await ListCommand.run([]);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should disable formatting when the flag is active.', async () => {
|
||||||
|
await ListCommand.run(['--no-format']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
const RequestCommand = require('../commands/request');
|
||||||
|
const requestPromiseNativeMock = require('request-promise-native');
|
||||||
|
|
||||||
|
jest.mock('../utils');
|
||||||
|
|
||||||
|
describe('Request Command', () => {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
requestPromiseNativeMock.fail = false;
|
||||||
|
result = [];
|
||||||
|
jest
|
||||||
|
.spyOn(process.stdout, 'write')
|
||||||
|
.mockImplementation(val =>
|
||||||
|
result.push(require('strip-ansi')(val.toString('utf8')))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => jest.restoreAllMocks());
|
||||||
|
|
||||||
|
it('Should request the given alias', async () => {
|
||||||
|
await RequestCommand.run(['anything']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should show all information available when being verbose', async () => {
|
||||||
|
await RequestCommand.run(['anything', '--verbose']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should output the response as json', async () => {
|
||||||
|
await RequestCommand.run(['anything', '--as-json']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should output the response as json verboselly', async () => {
|
||||||
|
await RequestCommand.run(['anything', '--as-json', '--verbose']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should output an unformatted version', async () => {
|
||||||
|
await RequestCommand.run(['anything', '--no-format']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should output nothing', async () => {
|
||||||
|
await RequestCommand.run(['anything', '--quiet']);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should thrown an error when the request fails', async () => {
|
||||||
|
requestPromiseNativeMock.fail = true;
|
||||||
|
await expect(RequestCommand.run(['anything'])).rejects.toThrow(Error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
const utils = require('../utils.js');
|
||||||
|
|
||||||
|
jest.mock('fs');
|
||||||
|
|
||||||
|
describe('utils', () => {
|
||||||
|
describe('openConfigFile', () => {
|
||||||
|
it('should read and parse the given configuration file.', () => {
|
||||||
|
expect(utils.openConfigFile('beau.yml')).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should thrown if given not given a file', () => {
|
||||||
|
expect(() => utils.openConfigFile('not-a-file.yml')).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('loadConfig', () => {
|
||||||
|
it('should load load the config onto Beau', () => {
|
||||||
|
let beau = utils.loadConfig('beau.yml');
|
||||||
|
expect(beau.config).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should load params onto the environment', () => {
|
||||||
|
let beau = utils.loadConfig('beau.yml', [
|
||||||
|
'HELLO=WORLD',
|
||||||
|
'BYE=MARS'
|
||||||
|
]);
|
||||||
|
expect(beau.config.ENVIRONMENT).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
const ValidateCommand = require('../commands/validate');
|
||||||
|
|
||||||
|
jest.mock('../utils');
|
||||||
|
|
||||||
|
describe('Validate Command', () => {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
result = [];
|
||||||
|
jest
|
||||||
|
.spyOn(process.stdout, 'write')
|
||||||
|
.mockImplementation(val =>
|
||||||
|
result.push(require('strip-ansi')(val.toString('utf8')))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => jest.restoreAllMocks());
|
||||||
|
|
||||||
|
it('should validate the configuration file', async () => {
|
||||||
|
await ValidateCommand.run([]);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show schema errors', async () => {
|
||||||
|
await expect(
|
||||||
|
ValidateCommand.run(['invalid-conf.yml'])
|
||||||
|
).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
const yaml = require('js-yaml');
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const dotenv = require('dotenv');
|
|
||||||
const { Command, flags } = require('@oclif/command');
|
|
||||||
|
|
||||||
const Beau = require('../../src/beau');
|
|
||||||
|
|
||||||
class Base extends Command {
|
|
||||||
openConfigFile(configFile) {
|
|
||||||
if (!fs.existsSync(configFile)) {
|
|
||||||
this.error(`The config file, ${configFile} was not found.`);
|
|
||||||
this.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return yaml.safeLoad(fs.readFileSync(configFile, 'utf-8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
loadConfig(configFile, params = []) {
|
|
||||||
const config = this.openConfigFile(configFile);
|
|
||||||
const env = dotenv.config().parsed || {};
|
|
||||||
params = dotenv.parse(params.reduce((a, p) => a + '\n' + p, ''));
|
|
||||||
|
|
||||||
const envParams = { _: Object.assign(env, params) };
|
|
||||||
|
|
||||||
const configFileDir = path.dirname(
|
|
||||||
path.resolve(process.cwd(), configFile)
|
|
||||||
);
|
|
||||||
|
|
||||||
process.chdir(configFileDir);
|
|
||||||
|
|
||||||
return new Beau(config, envParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Base.flags = {
|
|
||||||
config: flags.string({
|
|
||||||
char: 'c',
|
|
||||||
description: 'The configuration file to be used.',
|
|
||||||
default: 'beau.yml'
|
|
||||||
}),
|
|
||||||
verbose: flags.boolean({
|
|
||||||
char: 'V',
|
|
||||||
description: `Show all additional information available for a command.`
|
|
||||||
}),
|
|
||||||
'no-format': flags.boolean({
|
|
||||||
description: `Disables color formatting for usage on external tools.`
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Base;
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
const clc = require('cli-color');
|
const clc = require('cli-color');
|
||||||
const { Line } = require('clui');
|
const { Line } = require('clui');
|
||||||
const { flags } = require('@oclif/command');
|
const { flags, Command } = require('@oclif/command');
|
||||||
|
const { baseFlags, loadConfig } = require('../utils');
|
||||||
|
|
||||||
const Base = require('../base');
|
class ListCommand extends Command {
|
||||||
|
|
||||||
class ListCommand extends Base {
|
|
||||||
async run() {
|
async run() {
|
||||||
const { flags } = this.parse(ListCommand);
|
const { flags } = this.parse(ListCommand);
|
||||||
const Beau = this.loadConfig(flags.config);
|
const Beau = loadConfig(flags.config);
|
||||||
|
|
||||||
if (flags['no-format']) {
|
if (flags['no-format']) {
|
||||||
return Beau.requests.list.forEach(
|
return Beau.requests.list.forEach(
|
||||||
|
|
@ -47,6 +46,6 @@ class ListCommand extends Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
ListCommand.description = `Lists all available requests in the config file.`;
|
ListCommand.description = `Lists all available requests in the config file.`;
|
||||||
ListCommand.flags = { ...Base.flags };
|
ListCommand.flags = { ...baseFlags };
|
||||||
|
|
||||||
module.exports = ListCommand;
|
module.exports = ListCommand;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
const clc = require('cli-color');
|
const clc = require('cli-color');
|
||||||
const jsome = require('jsome');
|
const jsome = require('jsome');
|
||||||
const { Line, Spinner } = require('clui');
|
const { Line, Spinner } = require('clui');
|
||||||
const { flags } = require('@oclif/command');
|
const { flags, Command } = require('@oclif/command');
|
||||||
|
const { baseFlags, loadConfig } = require('../utils');
|
||||||
|
|
||||||
const Base = require('../base');
|
class RequestCommand extends Command {
|
||||||
|
|
||||||
class RequestCommand extends Base {
|
|
||||||
prettyOutput(res, verbose = false) {
|
prettyOutput(res, verbose = false) {
|
||||||
let { status, body } = res.response;
|
let { status, body } = res.response;
|
||||||
|
|
||||||
|
|
@ -29,7 +28,7 @@ class RequestCommand extends Base {
|
||||||
|
|
||||||
new Line().output();
|
new Line().output();
|
||||||
|
|
||||||
jsome((verbose ? res : body) || null);
|
this.log(jsome.getColoredString((verbose ? res : body) || null));
|
||||||
}
|
}
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
|
|
@ -45,13 +44,10 @@ class RequestCommand extends Base {
|
||||||
args
|
args
|
||||||
} = this.parse(RequestCommand);
|
} = this.parse(RequestCommand);
|
||||||
|
|
||||||
const Beau = this.loadConfig(config, params);
|
const Beau = loadConfig(config, params);
|
||||||
|
|
||||||
const spinnerSprite = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];
|
const spinnerSprite = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];
|
||||||
this.spinner = new Spinner(
|
this.spinner = new Spinner('', spinnerSprite);
|
||||||
clc.yellow(`Requesting: ${args.alias}`),
|
|
||||||
spinnerSprite
|
|
||||||
);
|
|
||||||
|
|
||||||
let spinnerEnabled = !noFormat && !asJson && !quiet;
|
let spinnerEnabled = !noFormat && !asJson && !quiet;
|
||||||
|
|
||||||
|
|
@ -78,7 +74,7 @@ class RequestCommand extends Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asJson) {
|
if (asJson) {
|
||||||
return this.log(JSON.stringify(res.response));
|
return this.log(JSON.stringify(verbose ? res : res.response));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noFormat) {
|
if (noFormat) {
|
||||||
|
|
@ -95,7 +91,7 @@ class RequestCommand extends Base {
|
||||||
|
|
||||||
RequestCommand.description = `Executes a request by name.`;
|
RequestCommand.description = `Executes a request by name.`;
|
||||||
RequestCommand.flags = {
|
RequestCommand.flags = {
|
||||||
...Base.flags,
|
...baseFlags,
|
||||||
param: flags.string({
|
param: flags.string({
|
||||||
char: 'P',
|
char: 'P',
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,13 @@
|
||||||
const clc = require('cli-color');
|
const { flags, Command } = require('@oclif/command');
|
||||||
const fs = require('fs');
|
const { baseFlags, openConfigFile } = require('../utils');
|
||||||
const yaml = require('js-yaml');
|
|
||||||
const { flags } = require('@oclif/command');
|
|
||||||
|
|
||||||
const Base = require('../base');
|
|
||||||
const { validate } = require('../../../src/schema.js');
|
const { validate } = require('../../../src/schema.js');
|
||||||
|
|
||||||
class ValidateCommand extends Base {
|
class ValidateCommand extends Command {
|
||||||
async run() {
|
async run() {
|
||||||
const { flags, args } = this.parse(ValidateCommand);
|
const { flags, args } = this.parse(ValidateCommand);
|
||||||
const configFile = args.alias || flags.config;
|
const configFile = args.alias || flags.config;
|
||||||
|
|
||||||
const config = this.openConfigFile(configFile);
|
const config = openConfigFile(configFile);
|
||||||
|
|
||||||
let result = await validate(config);
|
let result = await validate(config);
|
||||||
if (result.valid) {
|
if (result.valid) {
|
||||||
|
|
@ -23,7 +19,7 @@ class ValidateCommand extends Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateCommand.description = `Validates the given configuration file against Beau's configuration schema.`;
|
ValidateCommand.description = `Validates the given configuration file against Beau's configuration schema.`;
|
||||||
ValidateCommand.flags = { ...Base.flags };
|
ValidateCommand.flags = { ...baseFlags };
|
||||||
ValidateCommand.args = [
|
ValidateCommand.args = [
|
||||||
{
|
{
|
||||||
name: 'alias',
|
name: 'alias',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
const Beau = require('../../src/beau');
|
||||||
|
const { flags } = require('@oclif/command');
|
||||||
|
|
||||||
|
const openConfigFile = configFile => {
|
||||||
|
if (!fs.existsSync(configFile)) {
|
||||||
|
throw new Error(`The config file, ${configFile} was not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return yaml.safeLoad(fs.readFileSync(configFile, 'utf-8'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadConfig = (configFile, params = []) => {
|
||||||
|
const config = openConfigFile(configFile);
|
||||||
|
const env = dotenv.config().parsed || {};
|
||||||
|
params = dotenv.parse(params.reduce((a, p) => a + '\n' + p, ''));
|
||||||
|
|
||||||
|
const envParams = { _: Object.assign(env, params) };
|
||||||
|
|
||||||
|
const configFileDir = path.dirname(path.resolve(process.cwd(), configFile));
|
||||||
|
|
||||||
|
process.chdir(configFileDir);
|
||||||
|
|
||||||
|
return new Beau(config, envParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseFlags = {
|
||||||
|
config: flags.string({
|
||||||
|
char: 'c',
|
||||||
|
description: 'The configuration file to be used.',
|
||||||
|
default: 'beau.yml'
|
||||||
|
}),
|
||||||
|
verbose: flags.boolean({
|
||||||
|
char: 'V',
|
||||||
|
description: `Show all additional information available for a command.`
|
||||||
|
}),
|
||||||
|
'no-format': flags.boolean({
|
||||||
|
description: `Disables color formatting for usage on external tools.`
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openConfigFile,
|
||||||
|
loadConfig,
|
||||||
|
baseFlags
|
||||||
|
};
|
||||||
|
|
@ -1178,6 +1178,17 @@
|
||||||
"has-ansi": "^2.0.0",
|
"has-ansi": "^2.0.0",
|
||||||
"strip-ansi": "^3.0.0",
|
"strip-ansi": "^3.0.0",
|
||||||
"supports-color": "^2.0.0"
|
"supports-color": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ci-info": {
|
"ci-info": {
|
||||||
|
|
@ -6822,6 +6833,16 @@
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
"strip-ansi": "^3.0.0"
|
"strip-ansi": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
|
@ -6839,11 +6860,20 @@
|
||||||
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
|
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
|
||||||
},
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "3.0.1",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"strip-bom": {
|
"strip-bom": {
|
||||||
|
|
@ -7593,6 +7623,16 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"string-width": "^1.0.1",
|
"string-width": "^1.0.1",
|
||||||
"strip-ansi": "^3.0.1"
|
"strip-ansi": "^3.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "^2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:coverage": "jest --coverage"
|
"test:coverage": "jest --coverage ./src"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oclif/command": "^1.4.16",
|
"@oclif/command": "^1.4.16",
|
||||||
|
|
@ -29,7 +29,8 @@
|
||||||
},
|
},
|
||||||
"repository": "git@github.com:Seich/Beau.git",
|
"repository": "git@github.com:Seich/Beau.git",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jest": "^22.4.0"
|
"jest": "^22.4.0",
|
||||||
|
"strip-ansi": "^4.0.0"
|
||||||
},
|
},
|
||||||
"oclif": {
|
"oclif": {
|
||||||
"commands": "./bin/cli/commands",
|
"commands": "./bin/cli/commands",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
const yaml = require('js-yaml');
|
|
||||||
const Plugins = require('../plugins');
|
const Plugins = require('../plugins');
|
||||||
const Request = require('../request');
|
const Request = require('../request');
|
||||||
const RequestCache = require('../requestCache');
|
const RequestCache = require('../requestCache');
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
const Request = require('../request');
|
const Request = require('../request');
|
||||||
const RequestCache = require('../requestCache');
|
const RequestCache = require('../requestCache');
|
||||||
const RequestList = require('../requestList');
|
|
||||||
const requestPromiseNativeMock = require('request-promise-native');
|
const requestPromiseNativeMock = require('request-promise-native');
|
||||||
|
|
||||||
describe('Request', () => {
|
describe('Request', () => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
const schema = require('../schema');
|
||||||
|
|
||||||
|
describe('Schema', () => {
|
||||||
|
it(`should validate an object against the schema`, async () => {
|
||||||
|
await expect(
|
||||||
|
schema.validate({ endpoint: 'http://example.com' })
|
||||||
|
).resolves.toHaveProperty('valid', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should indicate the error when an schema is invalid`, async () => {
|
||||||
|
await expect(
|
||||||
|
schema.validate({ plugins: [{ hello: 1, world: 2 }] })
|
||||||
|
).resolves.toHaveProperty('valid', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -62,9 +62,7 @@ const schema = Joi.object()
|
||||||
|
|
||||||
const validate = async function(config) {
|
const validate = async function(config) {
|
||||||
try {
|
try {
|
||||||
let results = await Joi.validate(config, schema, {
|
await Joi.validate(config, schema, { allowUnknown: true });
|
||||||
allowUnknown: true
|
|
||||||
});
|
|
||||||
return { valid: true };
|
return { valid: true };
|
||||||
} catch ({ name, details }) {
|
} catch ({ name, details }) {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue