mirror of https://github.com/Seich/Beau.git
Formatted all code with new prettier conf.
This commit is contained in:
parent
a9eb8c97dd
commit
7598ecb487
|
|
@ -1,6 +1,6 @@
|
|||
const fs = jest.genMockFromModule('fs');
|
||||
const fs = jest.genMockFromModule('fs')
|
||||
|
||||
fs.existsSync = filename => filename === 'beau.yml';
|
||||
fs.existsSync = (filename) => filename === 'beau.yml'
|
||||
fs.readFileSync = () => `
|
||||
version: 1
|
||||
endpoint: https://example.org/
|
||||
|
|
@ -9,6 +9,6 @@ GET /anything:
|
|||
alias: anything
|
||||
payload:
|
||||
name: $env.params.name
|
||||
`;
|
||||
`
|
||||
|
||||
module.exports = fs;
|
||||
module.exports = fs
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
const ListCommand = require('../commands/list');
|
||||
const ListCommand = require('../commands/list')
|
||||
|
||||
jest.mock('../../../src/shared');
|
||||
jest.mock('../../../src/shared')
|
||||
|
||||
jest.mock('../base');
|
||||
jest.mock('../base')
|
||||
|
||||
describe('List Command', () => {
|
||||
let result;
|
||||
let result
|
||||
|
||||
beforeEach(() => {
|
||||
result = [];
|
||||
jest.spyOn(process.stdout, 'write').mockImplementation(val =>
|
||||
result = []
|
||||
jest.spyOn(process.stdout, 'write').mockImplementation((val) =>
|
||||
result.push(require('strip-ansi')(val.toString('utf8')))
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
afterEach(() => jest.restoreAllMocks());
|
||||
afterEach(() => jest.restoreAllMocks())
|
||||
|
||||
test.each([[], ['--no-format']])('with flags:', async (...args) => {
|
||||
await ListCommand.run(args);
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
await ListCommand.run(args)
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
const RequestCommand = require('../commands/request');
|
||||
const requestPromiseNativeMock = require('request-promise-native');
|
||||
const RequestCommand = require('../commands/request')
|
||||
const requestPromiseNativeMock = require('request-promise-native')
|
||||
|
||||
jest.mock('../../../src/shared');
|
||||
jest.mock('../../../src/shared')
|
||||
|
||||
jest.mock('../base');
|
||||
jest.mock('../base')
|
||||
|
||||
describe('Request Command', () => {
|
||||
let result;
|
||||
let result
|
||||
|
||||
beforeEach(() => {
|
||||
requestPromiseNativeMock.fail = false;
|
||||
result = [];
|
||||
jest.spyOn(process.stdout, 'write').mockImplementation(val =>
|
||||
requestPromiseNativeMock.fail = false
|
||||
result = []
|
||||
jest.spyOn(process.stdout, 'write').mockImplementation((val) =>
|
||||
result.push(require('strip-ansi')(val.toString('utf8')))
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
afterEach(() => jest.restoreAllMocks());
|
||||
afterEach(() => jest.restoreAllMocks())
|
||||
|
||||
test.each([
|
||||
['alias'],
|
||||
|
|
@ -26,12 +26,12 @@ describe('Request Command', () => {
|
|||
['alias', '--no-format'],
|
||||
['alias', '--quiet']
|
||||
])('with flags: %s %s %s', async (...args) => {
|
||||
await RequestCommand.run(args);
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
await RequestCommand.run(args)
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should throw an error when the request fails', async () => {
|
||||
requestPromiseNativeMock.fail = true;
|
||||
await expect(RequestCommand.run(['anything'])).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
requestPromiseNativeMock.fail = true
|
||||
await expect(RequestCommand.run(['anything'])).rejects.toThrow(Error)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
class DynamicValues {
|
||||
constructor(registry, settings = {}) {
|
||||
registry.defineDynamicValue('add', this.add);
|
||||
registry.defineDynamicValue('add', this.add)
|
||||
}
|
||||
|
||||
add(x, y) {
|
||||
return x + y;
|
||||
return x + y
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DynamicValues;
|
||||
module.exports = DynamicValues
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
class Modifiers {
|
||||
constructor(registry, settings = {}) {
|
||||
registry.addPreRequestModifier(this.preRequest);
|
||||
registry.addPostRequestModifier(this.postRequest);
|
||||
registry.addPreRequestModifier(this.preRequest)
|
||||
registry.addPostRequestModifier(this.postRequest)
|
||||
}
|
||||
|
||||
preRequest(request, orig) {
|
||||
request.headers = request.headers || {};
|
||||
request.headers.preRequestModifier = true;
|
||||
return request;
|
||||
request.headers = request.headers || {}
|
||||
request.headers.preRequestModifier = true
|
||||
return request
|
||||
}
|
||||
|
||||
postRequest(response, orig) {
|
||||
response.body = 'Hello World';
|
||||
response.response.body = 'Hello World';
|
||||
return response;
|
||||
response.body = 'Hello World'
|
||||
response.response.body = 'Hello World'
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Modifiers;
|
||||
module.exports = Modifiers
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
class BeauStd {
|
||||
constructor(registry, settings) {
|
||||
registry.defineDynamicValue('createReadStream', () => {});
|
||||
registry.defineDynamicValue('createReadStream', () => {})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BeauStd;
|
||||
module.exports = BeauStd
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
function Request(request) {
|
||||
if (Request.fail) {
|
||||
throw new Error();
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
@ -14,9 +14,9 @@ function Request(request) {
|
|||
statusCode: 200,
|
||||
headers: [],
|
||||
body: '{"hello": "world"}'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Request.fail = false;
|
||||
Request.fail = false
|
||||
|
||||
module.exports = Request;
|
||||
module.exports = Request
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
function requireg(name) {
|
||||
return require(name);
|
||||
return require(name)
|
||||
}
|
||||
|
||||
requireg.resolving = true;
|
||||
requireg.resolving = true
|
||||
|
||||
requireg.resolve = function(name) {
|
||||
requireg.resolve = function (name) {
|
||||
if (requireg.resolving) {
|
||||
return '';
|
||||
return ''
|
||||
} else {
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = requireg;
|
||||
module.exports = requireg
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = {
|
||||
...jest.requireActual('../shared'),
|
||||
moduleVersion: jest.fn().mockReturnValue(1)
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
const yaml = require('js-yaml');
|
||||
const Beau = require('../beau');
|
||||
const { moduleVersion } = require('../shared');
|
||||
const yaml = require('js-yaml')
|
||||
const Beau = require('../beau')
|
||||
const { moduleVersion } = require('../shared')
|
||||
|
||||
jest.mock('../shared');
|
||||
jest.mock('../shared')
|
||||
|
||||
const requireg = require('requireg');
|
||||
requireg.resolving = false;
|
||||
const requireg = require('requireg')
|
||||
requireg.resolving = false
|
||||
|
||||
describe(`Beau's config Loader.`, () => {
|
||||
it('should load the config', () => {
|
||||
moduleVersion.mockReturnValue(1);
|
||||
moduleVersion.mockReturnValue(1)
|
||||
|
||||
const doc = yaml.safeLoad(`
|
||||
version: 1
|
||||
|
|
@ -18,14 +18,14 @@ describe(`Beau's config Loader.`, () => {
|
|||
defaults:
|
||||
headers:
|
||||
authentication: hello
|
||||
`);
|
||||
`)
|
||||
|
||||
const beau = new Beau(doc);
|
||||
expect(beau).toMatchSnapshot();
|
||||
});
|
||||
const beau = new Beau(doc)
|
||||
expect(beau).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it(`should load the request list using the configuration`, () => {
|
||||
moduleVersion.mockReturnValue(1);
|
||||
moduleVersion.mockReturnValue(1)
|
||||
|
||||
const doc = yaml.safeLoad(`
|
||||
version: 1
|
||||
|
|
@ -36,24 +36,24 @@ describe(`Beau's config Loader.`, () => {
|
|||
alias: user
|
||||
headers:
|
||||
hello: world
|
||||
`);
|
||||
`)
|
||||
|
||||
const beau = new Beau(doc);
|
||||
expect(beau.requests).toMatchSnapshot();
|
||||
});
|
||||
const beau = new Beau(doc)
|
||||
expect(beau.requests).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should display a warning if the module version and the beau file version are different', () => {
|
||||
let stdout;
|
||||
let stdout
|
||||
let spy = jest
|
||||
.spyOn(console, 'warn')
|
||||
.mockImplementation(val => (stdout = val));
|
||||
.mockImplementation((val) => (stdout = val))
|
||||
|
||||
moduleVersion.mockReturnValue(2);
|
||||
moduleVersion.mockReturnValue(2)
|
||||
|
||||
const beau = new Beau({ version: 1 });
|
||||
expect(stdout).toEqual('This Beau file expects v1. You are using v2.');
|
||||
const beau = new Beau({ version: 1 })
|
||||
expect(stdout).toEqual('This Beau file expects v1. You are using v2.')
|
||||
|
||||
spy.mockReset();
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
spy.mockReset()
|
||||
spy.mockRestore()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
const yaml = require('js-yaml');
|
||||
const Config = require('../config');
|
||||
const yaml = require('js-yaml')
|
||||
const Config = require('../config')
|
||||
|
||||
const requireg = require('requireg');
|
||||
requireg.resolving = false;
|
||||
const requireg = require('requireg')
|
||||
requireg.resolving = false
|
||||
|
||||
describe('Config', () => {
|
||||
it('should load valid config keys', () => {
|
||||
|
|
@ -10,13 +10,13 @@ describe('Config', () => {
|
|||
version: 1
|
||||
endpoint: http://martianwabbit.com
|
||||
shouldntBeAdded: true
|
||||
`);
|
||||
`)
|
||||
|
||||
const config = new Config(doc);
|
||||
expect(config.ENDPOINT).toBe(doc.endpoint);
|
||||
expect(config.VERSION).toBe(doc.version);
|
||||
expect(config.shouldntBeAdded).toBeUndefined();
|
||||
});
|
||||
const config = new Config(doc)
|
||||
expect(config.ENDPOINT).toBe(doc.endpoint)
|
||||
expect(config.VERSION).toBe(doc.version)
|
||||
expect(config.shouldntBeAdded).toBeUndefined()
|
||||
})
|
||||
|
||||
it('should load requests', () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -29,11 +29,11 @@ describe('Config', () => {
|
|||
alias: user
|
||||
headers:
|
||||
hello: world
|
||||
`);
|
||||
`)
|
||||
|
||||
const config = new Config(doc);
|
||||
expect(Object.keys(config.REQUESTS).length).toBe(4);
|
||||
});
|
||||
const config = new Config(doc)
|
||||
expect(Object.keys(config.REQUESTS).length).toBe(4)
|
||||
})
|
||||
|
||||
it('should set up defaults for all requests', () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -49,15 +49,15 @@ describe('Config', () => {
|
|||
alias: user
|
||||
headers:
|
||||
hello: world
|
||||
`);
|
||||
`)
|
||||
|
||||
const config = new Config(doc);
|
||||
const config = new Config(doc)
|
||||
|
||||
expect(config).toMatchSnapshot();
|
||||
Object.values(config.REQUESTS).forEach(r => {
|
||||
expect(r.HEADERS.authentication).toMatch('hello');
|
||||
});
|
||||
});
|
||||
expect(config).toMatchSnapshot()
|
||||
Object.values(config.REQUESTS).forEach((r) => {
|
||||
expect(r.HEADERS.authentication).toMatch('hello')
|
||||
})
|
||||
})
|
||||
|
||||
it('should load multiple hosts', () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -97,12 +97,12 @@ describe('Config', () => {
|
|||
endpoint: http://example.info
|
||||
|
||||
GET /posts: posts
|
||||
`);
|
||||
`)
|
||||
|
||||
let config = new Config(doc);
|
||||
let config = new Config(doc)
|
||||
|
||||
expect(config).toMatchSnapshot();
|
||||
});
|
||||
expect(config).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should namespace all aliases within an host', () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -113,13 +113,13 @@ describe('Config', () => {
|
|||
- host: test2
|
||||
endpoint: http://example.net
|
||||
GET /posts: posts
|
||||
`);
|
||||
`)
|
||||
|
||||
let config = new Config(doc);
|
||||
let config = new Config(doc)
|
||||
|
||||
expect(config.REQUESTS[0].ALIAS).toBe('test1:posts');
|
||||
expect(config.REQUESTS[1].ALIAS).toBe('test2:posts');
|
||||
});
|
||||
expect(config.REQUESTS[0].ALIAS).toBe('test1:posts')
|
||||
expect(config.REQUESTS[1].ALIAS).toBe('test2:posts')
|
||||
})
|
||||
|
||||
it(`should throw if host doesn't have a host key`, () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -130,10 +130,10 @@ describe('Config', () => {
|
|||
- host: test2
|
||||
endpoint: http://example.net
|
||||
GET /posts: posts
|
||||
`);
|
||||
`)
|
||||
|
||||
expect(() => new Config(doc)).toThrow();
|
||||
});
|
||||
expect(() => new Config(doc)).toThrow()
|
||||
})
|
||||
|
||||
it(`should merge host settings with global settings`, () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -152,11 +152,11 @@ describe('Config', () => {
|
|||
headers: false
|
||||
|
||||
GET /posts: posts
|
||||
`);
|
||||
`)
|
||||
|
||||
let config = new Config(doc);
|
||||
expect(config.REQUESTS[0].HEADERS.hello).toBe(1);
|
||||
});
|
||||
let config = new Config(doc)
|
||||
expect(config.REQUESTS[0].HEADERS.hello).toBe(1)
|
||||
})
|
||||
|
||||
it(`should allow different settings for the same request`, () => {
|
||||
const doc = yaml.safeLoad(`
|
||||
|
|
@ -168,9 +168,9 @@ describe('Config', () => {
|
|||
- alias: req2
|
||||
headers:
|
||||
request: 2
|
||||
`);
|
||||
`)
|
||||
|
||||
let config = new Config(doc);
|
||||
expect(config.REQUESTS.length).toBe(2);
|
||||
});
|
||||
});
|
||||
let config = new Config(doc)
|
||||
expect(config.REQUESTS.length).toBe(2)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,41 +1,41 @@
|
|||
const Plugins = require('../plugins');
|
||||
const Request = require('../request');
|
||||
const RequestCache = require('../requestCache');
|
||||
const requireg = require('requireg');
|
||||
const Plugins = require('../plugins')
|
||||
const Request = require('../request')
|
||||
const RequestCache = require('../requestCache')
|
||||
const requireg = require('requireg')
|
||||
|
||||
describe(`Beau's plugin system`, () => {
|
||||
let request;
|
||||
let plugins;
|
||||
let request
|
||||
let plugins
|
||||
|
||||
beforeEach(() => {
|
||||
plugins = new Plugins([{ Modifiers: [Object] }, 'DynamicValues'], []);
|
||||
});
|
||||
plugins = new Plugins([{ Modifiers: [Object] }, 'DynamicValues'], [])
|
||||
})
|
||||
|
||||
it('should load all plugins', () => {
|
||||
expect(plugins.registry.preRequestModifiers.length).toBe(1);
|
||||
expect(plugins.registry.postRequestModifiers.length).toBe(1);
|
||||
expect(plugins.registry.dynamicValues.length).toBe(1);
|
||||
});
|
||||
expect(plugins.registry.preRequestModifiers.length).toBe(1)
|
||||
expect(plugins.registry.postRequestModifiers.length).toBe(1)
|
||||
expect(plugins.registry.dynamicValues.length).toBe(1)
|
||||
})
|
||||
|
||||
it(`should throw if given an invalid configuration`, () => {
|
||||
expect(() => new Plugins([{ test1: true, test2: true }])).toThrow();
|
||||
});
|
||||
expect(() => new Plugins([{ test1: true, test2: true }])).toThrow()
|
||||
})
|
||||
|
||||
it(`shouldn't do anything when given an empty array.`, () => {
|
||||
expect(new Plugins([], [])).toMatchSnapshot();
|
||||
});
|
||||
expect(new Plugins([], [])).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it(`should warn if the plugin is not available.`, () => {
|
||||
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
requireg.resolving = false;
|
||||
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
requireg.resolving = false
|
||||
|
||||
new Plugins(['not-a-Package']);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
new Plugins(['not-a-Package'])
|
||||
expect(spy).toHaveBeenCalled()
|
||||
|
||||
requireg.resolving = true;
|
||||
spy.mockReset();
|
||||
spy.mockRestore();
|
||||
});
|
||||
requireg.resolving = true
|
||||
spy.mockReset()
|
||||
spy.mockRestore()
|
||||
})
|
||||
|
||||
describe(`Request Modifiers`, () => {
|
||||
beforeEach(() => {
|
||||
|
|
@ -46,13 +46,13 @@ describe(`Beau's plugin system`, () => {
|
|||
alias: 'update'
|
||||
},
|
||||
plugins
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it(`should modify the request and response using modifiers.`, async () => {
|
||||
await expect(request.exec()).resolves.toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
await expect(request.exec()).resolves.toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe(`Dynamic Values`, () => {
|
||||
beforeEach(() => {
|
||||
|
|
@ -68,34 +68,34 @@ describe(`Beau's plugin system`, () => {
|
|||
payload: 'counted $[add(1, $value2)] so far.'
|
||||
},
|
||||
plugins
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
let cache = new RequestCache();
|
||||
cache.add('value2', '2');
|
||||
let cache = new RequestCache()
|
||||
cache.add('value2', '2')
|
||||
|
||||
it(`should look for dynamic values executing and replacing them`, async () => {
|
||||
let req = await request.exec(cache);
|
||||
expect(req).toHaveProperty('request.body', 'counted 3 so far.');
|
||||
});
|
||||
let req = await request.exec(cache)
|
||||
expect(req).toHaveProperty('request.body', 'counted 3 so far.')
|
||||
})
|
||||
|
||||
it(`should change the internal datatype if the only thing in the value is the dynamic value`, async () => {
|
||||
let req = await request.exec(cache);
|
||||
expect(req).toHaveProperty('request.headers.count', 3);
|
||||
});
|
||||
let req = await request.exec(cache)
|
||||
expect(req).toHaveProperty('request.headers.count', 3)
|
||||
})
|
||||
|
||||
it(`should return empty values as empty`, async () => {
|
||||
let req = await request.exec(cache);
|
||||
expect(req).toHaveProperty('request.headers.empty', '');
|
||||
});
|
||||
let req = await request.exec(cache)
|
||||
expect(req).toHaveProperty('request.headers.empty', '')
|
||||
})
|
||||
|
||||
it(`should throw when calling an undefined dynamic value`, async () => {
|
||||
request = new Request({
|
||||
request: 'POST /hello/$[notAvailable(1, 2)]',
|
||||
alias: 'say-hello'
|
||||
});
|
||||
})
|
||||
|
||||
await expect(request.exec()).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
await expect(request.exec()).rejects.toThrow()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
const Request = require('../request');
|
||||
const RequestCache = require('../requestCache');
|
||||
const requestPromiseNativeMock = require('request-promise-native');
|
||||
const Request = require('../request')
|
||||
const RequestCache = require('../requestCache')
|
||||
const requestPromiseNativeMock = require('request-promise-native')
|
||||
|
||||
describe('Request', () => {
|
||||
let cache;
|
||||
let validRequestConfig;
|
||||
let invalidRequestConfig;
|
||||
let request;
|
||||
let requestWithoutDependencies;
|
||||
let cache
|
||||
let validRequestConfig
|
||||
let invalidRequestConfig
|
||||
let request
|
||||
let requestWithoutDependencies
|
||||
|
||||
beforeEach(() => {
|
||||
validRequestConfig = {
|
||||
|
|
@ -23,78 +23,78 @@ describe('Request', () => {
|
|||
payload: {
|
||||
username: 'seich'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
invalidRequestConfig = {
|
||||
request: `POST /session`,
|
||||
endpoint: 'http://example.com'
|
||||
};
|
||||
}
|
||||
|
||||
cache = new RequestCache();
|
||||
cache.add('session', { token: 'abc123' });
|
||||
cache.add('profile', { UserId: 14 });
|
||||
cache = new RequestCache()
|
||||
cache.add('session', { token: 'abc123' })
|
||||
cache.add('profile', { UserId: 14 })
|
||||
|
||||
request = new Request(validRequestConfig);
|
||||
request = new Request(validRequestConfig)
|
||||
requestWithoutDependencies = new Request({
|
||||
endpoint: 'http://example.com',
|
||||
request: 'GET /user',
|
||||
alias: 'show'
|
||||
});
|
||||
})
|
||||
|
||||
requestPromiseNativeMock.fail = false;
|
||||
});
|
||||
requestPromiseNativeMock.fail = false
|
||||
})
|
||||
|
||||
it('should load up the given request', () => {
|
||||
expect(request.VERB).toBe('POST');
|
||||
expect(request.ENDPOINT).toBe(validRequestConfig.endpoint);
|
||||
expect(request.HEADERS).toBeDefined();
|
||||
expect(request.PAYLOAD).toBeDefined();
|
||||
expect(request.PARAMS).toBeDefined();
|
||||
});
|
||||
expect(request.VERB).toBe('POST')
|
||||
expect(request.ENDPOINT).toBe(validRequestConfig.endpoint)
|
||||
expect(request.HEADERS).toBeDefined()
|
||||
expect(request.PAYLOAD).toBeDefined()
|
||||
expect(request.PARAMS).toBeDefined()
|
||||
})
|
||||
|
||||
it('should throw if a given request is invalid', () => {
|
||||
expect(() => new Request(invalidRequestConfig)).toThrow();
|
||||
});
|
||||
expect(() => new Request(invalidRequestConfig)).toThrow()
|
||||
})
|
||||
|
||||
it('should list all of its dependencies', () => {
|
||||
expect(request.DEPENDENCIES.size).toBe(2);
|
||||
expect(request.DEPENDENCIES).toContain('session');
|
||||
expect(request.DEPENDENCIES).toContain('profile');
|
||||
});
|
||||
expect(request.DEPENDENCIES.size).toBe(2)
|
||||
expect(request.DEPENDENCIES).toContain('session')
|
||||
expect(request.DEPENDENCIES).toContain('profile')
|
||||
})
|
||||
|
||||
it('should execute a request', async () => {
|
||||
await expect(request.exec(cache)).resolves.toMatchSnapshot();
|
||||
await expect(request.exec(cache)).resolves.toMatchSnapshot()
|
||||
await expect(
|
||||
requestWithoutDependencies.exec()
|
||||
).resolves.toMatchSnapshot();
|
||||
});
|
||||
).resolves.toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should throw if the request fails', async () => {
|
||||
requestPromiseNativeMock.fail = true;
|
||||
await expect(requestWithoutDependencies.exec()).rejects.toThrow(Error);
|
||||
});
|
||||
requestPromiseNativeMock.fail = true
|
||||
await expect(requestWithoutDependencies.exec()).rejects.toThrow(Error)
|
||||
})
|
||||
|
||||
it(`should use the full url if given one as part of the path instead of the global endpoint`, async () => {
|
||||
const requestWithPath = new Request({
|
||||
endpoint: 'http://example.com',
|
||||
request: 'GET http://martianwabbit.com/user',
|
||||
alias: 'get-user'
|
||||
});
|
||||
})
|
||||
|
||||
const requestWithoutPath = new Request({
|
||||
endpoint: 'http://example.com',
|
||||
request: 'GET /user',
|
||||
alias: 'get-user'
|
||||
});
|
||||
})
|
||||
|
||||
await expect(requestWithPath.exec()).resolves.toHaveProperty(
|
||||
'request.endpoint',
|
||||
'http://martianwabbit.com/user'
|
||||
);
|
||||
)
|
||||
|
||||
await expect(requestWithoutPath.exec()).resolves.toHaveProperty(
|
||||
'request.endpoint',
|
||||
'http://example.com/user'
|
||||
);
|
||||
});
|
||||
});
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
const RequestCache = require('../requestCache');
|
||||
const RequestCache = require('../requestCache')
|
||||
|
||||
describe('Request Cache', () => {
|
||||
let cache;
|
||||
let cache
|
||||
|
||||
beforeEach(() => {
|
||||
cache = new RequestCache();
|
||||
cache = new RequestCache()
|
||||
|
||||
cache.add('session', {
|
||||
hello: 'World'
|
||||
});
|
||||
})
|
||||
|
||||
cache.add('array', [
|
||||
{
|
||||
|
|
@ -19,36 +19,36 @@ describe('Request Cache', () => {
|
|||
id: 2,
|
||||
name: 'Angela'
|
||||
}
|
||||
]);
|
||||
});
|
||||
])
|
||||
})
|
||||
|
||||
it('should add keys to the cache', () => {
|
||||
expect(cache.$cache.session.hello).toBe('World');
|
||||
});
|
||||
expect(cache.$cache.session.hello).toBe('World')
|
||||
})
|
||||
|
||||
describe('get', () => {
|
||||
it('should be able to find key values with a given path', () => {
|
||||
expect(cache.get('session.hello')).toBe('World');
|
||||
});
|
||||
expect(cache.get('session.hello')).toBe('World')
|
||||
})
|
||||
|
||||
it('should throw when given an invalid path', () => {
|
||||
expect(() => cache.get('$session.world')).toThrow();
|
||||
});
|
||||
});
|
||||
expect(() => cache.get('$session.world')).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('parse', () => {
|
||||
it("should transform variables in strings using it's cache", () => {
|
||||
expect(cache.parse('Hello $session.hello')).toBe('Hello World');
|
||||
});
|
||||
expect(cache.parse('Hello $session.hello')).toBe('Hello World')
|
||||
})
|
||||
|
||||
it('should go transform variables in all values when given an object', () => {
|
||||
let parsed = cache.parse({
|
||||
hello: 'hello $session.hello',
|
||||
earth: '$session.hello'
|
||||
});
|
||||
expect(parsed.hello).toBe('hello World');
|
||||
expect(parsed.earth).toBe('World');
|
||||
});
|
||||
})
|
||||
expect(parsed.hello).toBe('hello World')
|
||||
expect(parsed.earth).toBe('World')
|
||||
})
|
||||
|
||||
it('should return every non-string value as-is', () => {
|
||||
let parsed = cache.parse({
|
||||
|
|
@ -56,34 +56,34 @@ describe('Request Cache', () => {
|
|||
nulled: null,
|
||||
truthy: false,
|
||||
hello: '$session.hello'
|
||||
});
|
||||
expect(parsed.number).toBe(1);
|
||||
expect(parsed.nulled).toBeNull();
|
||||
expect(parsed.truthy).toBe(false);
|
||||
expect(parsed.hello).toBe('World');
|
||||
});
|
||||
})
|
||||
expect(parsed.number).toBe(1)
|
||||
expect(parsed.nulled).toBeNull()
|
||||
expect(parsed.truthy).toBe(false)
|
||||
expect(parsed.hello).toBe('World')
|
||||
})
|
||||
|
||||
it('should parse arrays as well', () => {
|
||||
let parsed = cache.parse({ hello: '$array.0.name' });
|
||||
expect(parsed.hello).toBe('Sergio');
|
||||
});
|
||||
let parsed = cache.parse({ hello: '$array.0.name' })
|
||||
expect(parsed.hello).toBe('Sergio')
|
||||
})
|
||||
|
||||
it('should return an object when given an undefined value', () => {
|
||||
expect(cache.parse(undefined)).toEqual({});
|
||||
});
|
||||
expect(cache.parse(undefined)).toEqual({})
|
||||
})
|
||||
|
||||
it('should parse any value other than undefined', () => {
|
||||
expect(cache.parse('Hello $session.hello')).toBe('Hello World');
|
||||
});
|
||||
expect(cache.parse('Hello $session.hello')).toBe('Hello World')
|
||||
})
|
||||
|
||||
it('should return null when passed null', () => {
|
||||
expect(cache.parse(null)).toBe(null);
|
||||
});
|
||||
expect(cache.parse(null)).toBe(null)
|
||||
})
|
||||
|
||||
it(`shouldn't replace escaped variables`, () => {
|
||||
expect(cache.parse(`\\$session.hello is $session.hello`)).toBe(
|
||||
`$session.hello is World`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
const Config = require('../config');
|
||||
const RequestList = require('../requestList');
|
||||
const requestPromiseNativeMock = require('request-promise-native');
|
||||
const Config = require('../config')
|
||||
const RequestList = require('../requestList')
|
||||
const requestPromiseNativeMock = require('request-promise-native')
|
||||
|
||||
describe('RequestList', () => {
|
||||
const endpoint = 'http://martianwabbit.com';
|
||||
const endpoint = 'http://martianwabbit.com'
|
||||
|
||||
let env = {
|
||||
environmental: true
|
||||
};
|
||||
}
|
||||
|
||||
const doc = {
|
||||
ENDPOINT: endpoint,
|
||||
|
|
@ -20,49 +20,49 @@ describe('RequestList', () => {
|
|||
lastname: 'Diaz'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let requests;
|
||||
let requests
|
||||
beforeEach(() => {
|
||||
requestPromiseNativeMock.fail = false;
|
||||
requestPromiseNativeMock.fail = false
|
||||
|
||||
let config = new Config(doc);
|
||||
requests = new RequestList(config);
|
||||
});
|
||||
let config = new Config(doc)
|
||||
requests = new RequestList(config)
|
||||
})
|
||||
|
||||
it('should allow an empty request list', () => {
|
||||
requests = new RequestList();
|
||||
expect(requests.list.length).toBe(0);
|
||||
});
|
||||
requests = new RequestList()
|
||||
expect(requests.list.length).toBe(0)
|
||||
})
|
||||
|
||||
it('should load valid requests', () => {
|
||||
expect(requests.list.length).toBe(2);
|
||||
});
|
||||
expect(requests.list.length).toBe(2)
|
||||
})
|
||||
|
||||
it('should fetch dependencies', async () => {
|
||||
await expect(
|
||||
requests.fetchDependencies(['get-posts'])
|
||||
).resolves.toMatchSnapshot();
|
||||
});
|
||||
).resolves.toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should execute requests by alias.', async () => {
|
||||
await expect(requests.execByAlias('user')).resolves.toMatchSnapshot();
|
||||
});
|
||||
await expect(requests.execByAlias('user')).resolves.toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should fail if the request fails', async () => {
|
||||
requestPromiseNativeMock.fail = true;
|
||||
await expect(requests.execByAlias('user')).rejects.toThrow();
|
||||
});
|
||||
requestPromiseNativeMock.fail = true
|
||||
await expect(requests.execByAlias('user')).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('should return a cached result if available', async () => {
|
||||
const obj = { test: true };
|
||||
requests.cache.add('test', obj);
|
||||
await expect(requests.execByAlias('test')).resolves.toBe(obj);
|
||||
});
|
||||
const obj = { test: true }
|
||||
requests.cache.add('test', obj)
|
||||
await expect(requests.execByAlias('test')).resolves.toBe(obj)
|
||||
})
|
||||
|
||||
it('should fail if the alias is not found', async () => {
|
||||
await expect(requests.execByAlias('notAnAlias')).rejects.toThrow();
|
||||
});
|
||||
await expect(requests.execByAlias('notAnAlias')).rejects.toThrow()
|
||||
})
|
||||
|
||||
it(`should fail if a given request doesn't have an alias`, () => {
|
||||
let config = new Config({
|
||||
|
|
@ -71,8 +71,8 @@ describe('RequestList', () => {
|
|||
hello: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
expect(() => new RequestList(config, config)).toThrow();
|
||||
});
|
||||
});
|
||||
expect(() => new RequestList(config, config)).toThrow()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const {
|
|||
removeOptionalKeys,
|
||||
toKebabCase,
|
||||
replaceInObject
|
||||
} = require('../shared');
|
||||
} = require('../shared')
|
||||
|
||||
describe('Shared Utilities', () => {
|
||||
describe('requestRegex', () => {
|
||||
|
|
@ -21,9 +21,9 @@ describe('Shared Utilities', () => {
|
|||
['TRACE /hello', true],
|
||||
['PATCH /hello', true]
|
||||
])('should match: %s', (example, expected) => {
|
||||
expect(requestRegex.test(example)).toBe(expected);
|
||||
});
|
||||
});
|
||||
expect(requestRegex.test(example)).toBe(expected)
|
||||
})
|
||||
})
|
||||
|
||||
describe('replacementRegex', () => {
|
||||
test.each([
|
||||
|
|
@ -32,9 +32,9 @@ describe('Shared Utilities', () => {
|
|||
['PUT /hi/$a.a/$a.b', ['$a.a', '$a.b']],
|
||||
[`\\$value`, ['\\$value']]
|
||||
])('should match: %s', (example, expected) => {
|
||||
expect(example.match(replacementRegex)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
expect(example.match(replacementRegex)).toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
describe('dynamicValueRegex', () => {
|
||||
test.each([
|
||||
|
|
@ -42,34 +42,34 @@ describe('Shared Utilities', () => {
|
|||
['$[test(1, 2, 3)]', ['$[test(1, 2, 3)]']],
|
||||
[`$[test({ \n id: 1 \n })]`, ['$[test({ \n id: 1 \n })]']]
|
||||
])('should match: %s', (example, expected) => {
|
||||
expect(example.match(dynamicValueRegex)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
expect(example.match(dynamicValueRegex)).toEqual(expected)
|
||||
})
|
||||
})
|
||||
|
||||
describe('UpperCaseKeys', () => {
|
||||
it('should uppercase all first-level keys in an object', () => {
|
||||
let a = { test: 1, Test2: 2 };
|
||||
expect(UpperCaseKeys(a)).toEqual({ TEST: 1, TEST2: 2 });
|
||||
});
|
||||
});
|
||||
let a = { test: 1, Test2: 2 }
|
||||
expect(UpperCaseKeys(a)).toEqual({ TEST: 1, TEST2: 2 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('removeOptionalKeys', () => {
|
||||
it('should remove empty objects from an object', () => {
|
||||
let a = { b: {}, c: 2, d: {} };
|
||||
expect(removeOptionalKeys(a, ['b', 'd'])).toEqual({ c: 2 });
|
||||
});
|
||||
});
|
||||
let a = { b: {}, c: 2, d: {} }
|
||||
expect(removeOptionalKeys(a, ['b', 'd'])).toEqual({ c: 2 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('toKebabCase', () => {
|
||||
it('should convert camel case to kebab case', () => {
|
||||
expect(toKebabCase('helloWorld')).toBe('hello-world');
|
||||
});
|
||||
});
|
||||
expect(toKebabCase('helloWorld')).toBe('hello-world')
|
||||
})
|
||||
})
|
||||
|
||||
describe('replaceInObject', () => {
|
||||
it('should replace every value in an object with the output of a function', () => {
|
||||
let a = { b: 'b', c: 'c' };
|
||||
expect(replaceInObject(a, obj => 'a')).toEqual({ b: 'a', c: 'a' });
|
||||
});
|
||||
});
|
||||
});
|
||||
let a = { b: 'b', c: 'c' }
|
||||
expect(replaceInObject(a, (obj) => 'a')).toEqual({ b: 'a', c: 'a' })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
14
src/beau.js
14
src/beau.js
|
|
@ -1,20 +1,20 @@
|
|||
const RequestList = require('./requestList');
|
||||
const Config = require('./config');
|
||||
const { moduleVersion } = require('./shared');
|
||||
const RequestList = require('./requestList')
|
||||
const Config = require('./config')
|
||||
const { moduleVersion } = require('./shared')
|
||||
|
||||
class Beau {
|
||||
constructor(doc, env = {}) {
|
||||
this.config = new Config(doc, env);
|
||||
this.requests = new RequestList(this.config);
|
||||
this.config = new Config(doc, env)
|
||||
this.requests = new RequestList(this.config)
|
||||
|
||||
if (this.config.VERSION !== moduleVersion()) {
|
||||
console.warn(
|
||||
`This Beau file expects v${
|
||||
this.config.VERSION
|
||||
}. You are using v${moduleVersion()}.`
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Beau;
|
||||
module.exports = Beau
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const deepMerge = require('deepmerge');
|
||||
const { requestRegex, UpperCaseKeys, moduleVersion } = require('./shared');
|
||||
const Plugins = require('./plugins');
|
||||
const deepMerge = require('deepmerge')
|
||||
const { requestRegex, UpperCaseKeys, moduleVersion } = require('./shared')
|
||||
const Plugins = require('./plugins')
|
||||
|
||||
class Config {
|
||||
constructor(doc, env = {}) {
|
||||
|
|
@ -12,43 +12,43 @@ class Config {
|
|||
ENVIRONMENT: {},
|
||||
HOSTS: [],
|
||||
COOKIEJAR: false
|
||||
};
|
||||
}
|
||||
|
||||
this.configKeys = Object.keys(defaultConfigValues);
|
||||
this.configKeys = Object.keys(defaultConfigValues)
|
||||
|
||||
let config = this.loadConfig(doc);
|
||||
Object.assign(this, defaultConfigValues, config);
|
||||
let config = this.loadConfig(doc)
|
||||
Object.assign(this, defaultConfigValues, config)
|
||||
|
||||
this.ENVIRONMENT = deepMerge(this.ENVIRONMENT, env);
|
||||
this.ENVIRONMENT = deepMerge(this.ENVIRONMENT, env)
|
||||
|
||||
this.REQUESTS = [];
|
||||
this.REQUESTS = []
|
||||
|
||||
this.loadRequests(doc, {
|
||||
DEFAULTS: this.DEFAULTS,
|
||||
ENDPOINT: this.ENDPOINT
|
||||
});
|
||||
})
|
||||
|
||||
this.loadHosts(this.HOSTS, config, defaultConfigValues);
|
||||
this.loadHosts(this.HOSTS, config, defaultConfigValues)
|
||||
|
||||
this.PLUGINS = new Plugins(this.PLUGINS);
|
||||
this.PLUGINS = new Plugins(this.PLUGINS)
|
||||
}
|
||||
|
||||
loadHosts(hosts, rootConfig, defaultConfigValues) {
|
||||
hosts.forEach(host => {
|
||||
hosts.forEach((host) => {
|
||||
if (typeof host.host === 'undefined') {
|
||||
throw new Error(`Host doesn't indicate it's host name.`);
|
||||
throw new Error(`Host doesn't indicate it's host name.`)
|
||||
}
|
||||
|
||||
let config = deepMerge(defaultConfigValues, this.loadConfig(host));
|
||||
let config = deepMerge(defaultConfigValues, this.loadConfig(host))
|
||||
|
||||
config.DEFAULTS = deepMerge(rootConfig.DEFAULTS, config.DEFAULTS);
|
||||
config.DEFAULTS = deepMerge(rootConfig.DEFAULTS, config.DEFAULTS)
|
||||
|
||||
this.loadRequests(host, {
|
||||
DEFAULTS: config.DEFAULTS,
|
||||
ENDPOINT: config.ENDPOINT,
|
||||
NAMESPACE: host.host
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
loadRequests(host, settings) {
|
||||
|
|
@ -56,45 +56,45 @@ class Config {
|
|||
.filter(([key]) => requestRegex.test(key))
|
||||
.forEach(([key, rDefinition]) => {
|
||||
if (Array.isArray(rDefinition)) {
|
||||
rDefinition.forEach(req =>
|
||||
rDefinition.forEach((req) =>
|
||||
this.addRequest(key, req, settings)
|
||||
);
|
||||
)
|
||||
} else {
|
||||
this.addRequest(key, rDefinition, settings);
|
||||
this.addRequest(key, rDefinition, settings)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
addRequest(key, rDefinition, settings) {
|
||||
let requestDefinitionIsString = typeof rDefinition === 'string';
|
||||
let requestDefinitionIsString = typeof rDefinition === 'string'
|
||||
let originalRequest = requestDefinitionIsString
|
||||
? { ALIAS: rDefinition }
|
||||
: rDefinition;
|
||||
: rDefinition
|
||||
|
||||
let request = UpperCaseKeys(originalRequest);
|
||||
let request = UpperCaseKeys(originalRequest)
|
||||
|
||||
if (settings.NAMESPACE) {
|
||||
request.ALIAS = `${settings.NAMESPACE}:${request.ALIAS}`;
|
||||
request.ALIAS = `${settings.NAMESPACE}:${request.ALIAS}`
|
||||
}
|
||||
|
||||
request.REQUEST = key;
|
||||
request.COOKIEJAR = this.COOKIEJAR;
|
||||
request.ENDPOINT = settings.ENDPOINT;
|
||||
request.REQUEST = key
|
||||
request.COOKIEJAR = this.COOKIEJAR
|
||||
request.ENDPOINT = settings.ENDPOINT
|
||||
|
||||
let defaults = UpperCaseKeys(settings.DEFAULTS);
|
||||
let defaults = UpperCaseKeys(settings.DEFAULTS)
|
||||
|
||||
this.REQUESTS.push(deepMerge(defaults, request));
|
||||
this.REQUESTS.push(deepMerge(defaults, request))
|
||||
}
|
||||
|
||||
loadConfig(host) {
|
||||
let config = {};
|
||||
let config = {}
|
||||
|
||||
Object.entries(host)
|
||||
.filter(([key]) => this.configKeys.includes(key.toUpperCase()))
|
||||
.forEach(([key, value]) => (config[key.toUpperCase()] = value));
|
||||
.forEach(([key, value]) => (config[key.toUpperCase()] = value))
|
||||
|
||||
return config;
|
||||
return config
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Config;
|
||||
module.exports = Config
|
||||
|
|
|
|||
102
src/plugins.js
102
src/plugins.js
|
|
@ -1,8 +1,8 @@
|
|||
const vm = require('vm');
|
||||
const requireg = require('requireg');
|
||||
const deepmerge = require('deepmerge');
|
||||
const { toKebabCase, dynamicValueRegex, replaceInObject } = require('./shared');
|
||||
const { isPlainObject } = require('is-plain-object');
|
||||
const vm = require('vm')
|
||||
const requireg = require('requireg')
|
||||
const deepmerge = require('deepmerge')
|
||||
const { toKebabCase, dynamicValueRegex, replaceInObject } = require('./shared')
|
||||
const { isPlainObject } = require('is-plain-object')
|
||||
|
||||
class Plugins {
|
||||
constructor(plugins = [], autoload = ['std']) {
|
||||
|
|
@ -10,112 +10,110 @@ class Plugins {
|
|||
preRequestModifiers: [],
|
||||
postRequestModifiers: [],
|
||||
dynamicValues: []
|
||||
};
|
||||
}
|
||||
|
||||
this.context = {};
|
||||
this.context = {}
|
||||
|
||||
this.autoload = autoload;
|
||||
this.autoload = autoload
|
||||
|
||||
this.loadPlugins(plugins.concat(this.autoload));
|
||||
this.loadPlugins(plugins.concat(this.autoload))
|
||||
}
|
||||
|
||||
normalizePlugins(plugins) {
|
||||
let results = {};
|
||||
let results = {}
|
||||
|
||||
plugins.forEach(plugin => {
|
||||
let name = plugin;
|
||||
let settings = undefined;
|
||||
plugins.forEach((plugin) => {
|
||||
let name = plugin
|
||||
let settings = undefined
|
||||
|
||||
if (typeof plugin === 'object') {
|
||||
let keys = Object.keys(plugin);
|
||||
let keys = Object.keys(plugin)
|
||||
|
||||
if (keys.length !== 1) {
|
||||
throw new Error(
|
||||
`Plugin items should contain only one key.`
|
||||
);
|
||||
throw new Error(`Plugin items should contain only one key.`)
|
||||
}
|
||||
|
||||
name = keys[0];
|
||||
settings = plugin[name];
|
||||
name = keys[0]
|
||||
settings = plugin[name]
|
||||
}
|
||||
|
||||
results[name] = settings;
|
||||
});
|
||||
results[name] = settings
|
||||
})
|
||||
|
||||
return results;
|
||||
return results
|
||||
}
|
||||
|
||||
loadPlugins(plugins) {
|
||||
plugins = this.normalizePlugins(plugins);
|
||||
Object.keys(plugins).forEach(name => {
|
||||
const module = `beau-${toKebabCase(name)}`;
|
||||
plugins = this.normalizePlugins(plugins)
|
||||
Object.keys(plugins).forEach((name) => {
|
||||
const module = `beau-${toKebabCase(name)}`
|
||||
|
||||
if (typeof requireg.resolve(module) !== 'undefined') {
|
||||
const plugin = requireg(module);
|
||||
new plugin(this, plugins[name]);
|
||||
const plugin = requireg(module)
|
||||
new plugin(this, plugins[name])
|
||||
} else {
|
||||
if (this.autoload.includes(name)) return;
|
||||
if (this.autoload.includes(name)) return
|
||||
|
||||
console.warn(
|
||||
`Plugin ${name} couldn't be found. It is available globally?`
|
||||
);
|
||||
)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
executeModifier(modifier, obj, orig) {
|
||||
let result = deepmerge({}, obj, { isMergeableObject: isPlainObject });
|
||||
let result = deepmerge({}, obj, { isMergeableObject: isPlainObject })
|
||||
|
||||
this.registry[modifier].forEach(
|
||||
modifier => (result = modifier(result, orig))
|
||||
);
|
||||
(modifier) => (result = modifier(result, orig))
|
||||
)
|
||||
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
replaceDynamicValues(obj) {
|
||||
vm.createContext(this.context);
|
||||
return replaceInObject(obj, val => {
|
||||
let valIsEmpty = val.trim().length === 0;
|
||||
vm.createContext(this.context)
|
||||
return replaceInObject(obj, (val) => {
|
||||
let valIsEmpty = val.trim().length === 0
|
||||
|
||||
if (valIsEmpty) {
|
||||
return val;
|
||||
return val
|
||||
}
|
||||
|
||||
try {
|
||||
let onlyHasDynamic =
|
||||
val.replace(dynamicValueRegex, '').trim() === '';
|
||||
val.replace(dynamicValueRegex, '').trim() === ''
|
||||
|
||||
if (onlyHasDynamic) {
|
||||
let call;
|
||||
let call
|
||||
val.replace(dynamicValueRegex, (match, c) => {
|
||||
call = c;
|
||||
});
|
||||
call = c
|
||||
})
|
||||
|
||||
return vm.runInContext(call, this.context);
|
||||
return vm.runInContext(call, this.context)
|
||||
}
|
||||
|
||||
return val.replace(dynamicValueRegex, (match, call) => {
|
||||
return vm.runInContext(call, this.context);
|
||||
});
|
||||
return vm.runInContext(call, this.context)
|
||||
})
|
||||
} catch (e) {
|
||||
throw new Error(`DynamicValue: ` + e);
|
||||
throw new Error(`DynamicValue: ` + e)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
addPreRequestModifier(modifier) {
|
||||
this.registry.preRequestModifiers.push(modifier);
|
||||
this.registry.preRequestModifiers.push(modifier)
|
||||
}
|
||||
|
||||
addPostRequestModifier(modifier) {
|
||||
this.registry.postRequestModifiers.push(modifier);
|
||||
this.registry.postRequestModifiers.push(modifier)
|
||||
}
|
||||
|
||||
defineDynamicValue(name, fn) {
|
||||
this.registry.dynamicValues.push({ name, fn });
|
||||
this.context[name] = fn;
|
||||
this.registry.dynamicValues.push({ name, fn })
|
||||
this.context[name] = fn
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Plugins;
|
||||
module.exports = Plugins
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const request = require('request-promise-native');
|
||||
const RequestCache = require('./requestCache');
|
||||
const Plugins = require('./plugins');
|
||||
const request = require('request-promise-native')
|
||||
const RequestCache = require('./requestCache')
|
||||
const Plugins = require('./plugins')
|
||||
|
||||
const {
|
||||
requestRegex,
|
||||
|
|
@ -8,63 +8,63 @@ const {
|
|||
UpperCaseKeys,
|
||||
removeOptionalKeys,
|
||||
isUrl
|
||||
} = require('./shared');
|
||||
} = require('./shared')
|
||||
|
||||
class Request {
|
||||
constructor(req, plugins = new Plugins()) {
|
||||
this.originalRequest = req;
|
||||
this.plugins = plugins;
|
||||
this.originalRequest = req
|
||||
this.plugins = plugins
|
||||
|
||||
req = UpperCaseKeys(req);
|
||||
Object.assign(this, req);
|
||||
req = UpperCaseKeys(req)
|
||||
Object.assign(this, req)
|
||||
|
||||
if (!this.ALIAS) {
|
||||
throw new Error(`${this.REQUEST} is missing an alias.`);
|
||||
throw new Error(`${this.REQUEST} is missing an alias.`)
|
||||
}
|
||||
|
||||
const { VERB, PATH } = this.parseRequest(this.REQUEST);
|
||||
const { VERB, PATH } = this.parseRequest(this.REQUEST)
|
||||
|
||||
this.VERB = VERB;
|
||||
this.PATH = PATH;
|
||||
this.VERB = VERB
|
||||
this.PATH = PATH
|
||||
|
||||
this.DEPENDENCIES = this.findDependencies(req);
|
||||
this.DEPENDENCIES = this.findDependencies(req)
|
||||
}
|
||||
|
||||
parseRequest(request) {
|
||||
const parts = request.match(requestRegex);
|
||||
const parts = request.match(requestRegex)
|
||||
|
||||
return {
|
||||
VERB: parts[1],
|
||||
PATH: parts[2]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
findDependencies(request, set = new Set()) {
|
||||
let type = typeof request;
|
||||
let type = typeof request
|
||||
|
||||
if (type === 'object' && request !== null) {
|
||||
Object.entries(request)
|
||||
.filter(([key]) => key !== 'ALIAS')
|
||||
.forEach(([key, value]) => {
|
||||
set = this.findDependencies(value, set);
|
||||
});
|
||||
set = this.findDependencies(value, set)
|
||||
})
|
||||
} else if (type === 'string') {
|
||||
const matches = [];
|
||||
const matches = []
|
||||
request.replace(
|
||||
replacementRegex,
|
||||
(match, g1) => !match.startsWith('\\') && matches.push(g1)
|
||||
);
|
||||
)
|
||||
|
||||
const deps = matches.map(m => m.split('.')[0]);
|
||||
const deps = matches.map((m) => m.split('.')[0])
|
||||
|
||||
return new Set([...set, ...deps]);
|
||||
return new Set([...set, ...deps])
|
||||
}
|
||||
|
||||
return set;
|
||||
return set
|
||||
}
|
||||
|
||||
async exec(cache = new RequestCache()) {
|
||||
const isPathFullUrl = isUrl(this.PATH);
|
||||
const isPathFullUrl = isUrl(this.PATH)
|
||||
|
||||
let settings = cache.parse({
|
||||
baseUrl: isPathFullUrl ? '' : this.ENDPOINT,
|
||||
|
|
@ -81,7 +81,7 @@ class Request {
|
|||
json: true,
|
||||
simple: false,
|
||||
resolveWithFullResponse: true
|
||||
});
|
||||
})
|
||||
|
||||
settings = removeOptionalKeys(settings, [
|
||||
'headers',
|
||||
|
|
@ -89,17 +89,17 @@ class Request {
|
|||
'body',
|
||||
'form',
|
||||
'formData'
|
||||
]);
|
||||
])
|
||||
|
||||
settings = this.plugins.replaceDynamicValues(settings);
|
||||
settings = this.plugins.replaceDynamicValues(settings)
|
||||
|
||||
settings = this.plugins.executeModifier(
|
||||
'preRequestModifiers',
|
||||
settings,
|
||||
this.originalRequest
|
||||
);
|
||||
)
|
||||
|
||||
const response = await request(settings);
|
||||
const response = await request(settings)
|
||||
|
||||
let results = {
|
||||
request: {
|
||||
|
|
@ -113,18 +113,18 @@ class Request {
|
|||
body: response.body
|
||||
},
|
||||
body: response.body
|
||||
};
|
||||
}
|
||||
|
||||
results = this.plugins.executeModifier(
|
||||
'postRequestModifiers',
|
||||
results,
|
||||
this.originalRequest
|
||||
);
|
||||
)
|
||||
|
||||
cache.add(this.ALIAS, results);
|
||||
cache.add(this.ALIAS, results)
|
||||
|
||||
return results;
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Request;
|
||||
module.exports = Request
|
||||
|
|
|
|||
|
|
@ -1,46 +1,46 @@
|
|||
const { replacementRegex, replaceInObject } = require('./shared');
|
||||
const { replacementRegex, replaceInObject } = require('./shared')
|
||||
|
||||
class RequestCache {
|
||||
constructor() {
|
||||
this.$cache = {};
|
||||
this.$cache = {}
|
||||
}
|
||||
|
||||
exists(key) {
|
||||
return typeof this.$cache[key] !== 'undefined';
|
||||
return typeof this.$cache[key] !== 'undefined'
|
||||
}
|
||||
|
||||
add(key, value) {
|
||||
this.$cache[key] = value;
|
||||
this.$cache[key] = value
|
||||
}
|
||||
|
||||
get(path) {
|
||||
let result = this.$cache;
|
||||
path.split('.').forEach(part => {
|
||||
let result = this.$cache
|
||||
path.split('.').forEach((part) => {
|
||||
if (result[part] === undefined) {
|
||||
throw new Error(`${path} not found in cache.`);
|
||||
throw new Error(`${path} not found in cache.`)
|
||||
}
|
||||
|
||||
result = result[part];
|
||||
});
|
||||
result = result[part]
|
||||
})
|
||||
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
parse(item) {
|
||||
if (item === null) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
return replaceInObject(item, item =>
|
||||
return replaceInObject(item, (item) =>
|
||||
item.replace(replacementRegex, (match, key) => {
|
||||
if (match.startsWith('\\')) {
|
||||
return match.replace('\\$', '$');
|
||||
return match.replace('\\$', '$')
|
||||
}
|
||||
|
||||
return this.get(key);
|
||||
return this.get(key)
|
||||
})
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RequestCache;
|
||||
module.exports = RequestCache
|
||||
|
|
|
|||
|
|
@ -1,56 +1,54 @@
|
|||
const Request = require('./request');
|
||||
const RequestCache = require('./requestCache');
|
||||
const Request = require('./request')
|
||||
const RequestCache = require('./requestCache')
|
||||
|
||||
class RequestList {
|
||||
constructor(config = { REQUESTS: [] }) {
|
||||
this.list = this.loadRequests(config.REQUESTS, config.PLUGINS);
|
||||
this.cache = new RequestCache();
|
||||
this.list = this.loadRequests(config.REQUESTS, config.PLUGINS)
|
||||
this.cache = new RequestCache()
|
||||
|
||||
this.cache.add(`env`, config.ENVIRONMENT);
|
||||
this.cache.add(`env`, config.ENVIRONMENT)
|
||||
}
|
||||
|
||||
async execByAlias(alias) {
|
||||
if (this.cache.exists(alias)) {
|
||||
return this.cache.get(alias);
|
||||
return this.cache.get(alias)
|
||||
}
|
||||
|
||||
const request = this.list.find(r => r.ALIAS === alias);
|
||||
const request = this.list.find((r) => r.ALIAS === alias)
|
||||
|
||||
if (typeof request === 'undefined') {
|
||||
throw new Error(`${alias} not found among the requests.`);
|
||||
throw new Error(`${alias} not found among the requests.`)
|
||||
}
|
||||
|
||||
try {
|
||||
await this.fetchDependencies(Array.from(request.DEPENDENCIES));
|
||||
return await request.exec(this.cache);
|
||||
await this.fetchDependencies(Array.from(request.DEPENDENCIES))
|
||||
return await request.exec(this.cache)
|
||||
} catch (reason) {
|
||||
throw new Error(
|
||||
`Request ${request.VERB} ${
|
||||
request.ENDPOINT
|
||||
} FAILED. \n${reason}`
|
||||
);
|
||||
`Request ${request.VERB} ${request.ENDPOINT} FAILED. \n${reason}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async fetchDependencies(dependencies) {
|
||||
dependencies = dependencies.map(d => this.execByAlias(d));
|
||||
await Promise.all(dependencies);
|
||||
dependencies = dependencies.map((d) => this.execByAlias(d))
|
||||
await Promise.all(dependencies)
|
||||
|
||||
return this.cache;
|
||||
return this.cache
|
||||
}
|
||||
|
||||
loadRequests(REQUESTS, PLUGINS) {
|
||||
let requests = [];
|
||||
REQUESTS.forEach(request => {
|
||||
let requests = []
|
||||
REQUESTS.forEach((request) => {
|
||||
try {
|
||||
requests.push(new Request(request, PLUGINS));
|
||||
requests.push(new Request(request, PLUGINS))
|
||||
} catch (e) {
|
||||
throw new Error(`${request.request} was ignored: ${e}`);
|
||||
throw new Error(`${request.request} was ignored: ${e}`)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
return requests;
|
||||
return requests
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RequestList;
|
||||
module.exports = RequestList
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const { URL } = require('url');
|
||||
const { URL } = require('url')
|
||||
|
||||
const httpVerbs = [
|
||||
'GET',
|
||||
|
|
@ -10,72 +10,72 @@ const httpVerbs = [
|
|||
'OPTIONS',
|
||||
'TRACE',
|
||||
'PATCH'
|
||||
];
|
||||
]
|
||||
|
||||
const requestRegex = new RegExp(`(${httpVerbs.join('|')})\\s(.*)`, 'i');
|
||||
const replacementRegex = /(?:\\?)\$([a-zA-Z\.\d\-\_\:]+)/g;
|
||||
const dynamicValueRegex = /\$\[(\w+\((?:.|[\n\r])*?\))\]/g;
|
||||
const requestRegex = new RegExp(`(${httpVerbs.join('|')})\\s(.*)`, 'i')
|
||||
const replacementRegex = /(?:\\?)\$([a-zA-Z\.\d\-\_\:]+)/g
|
||||
const dynamicValueRegex = /\$\[(\w+\((?:.|[\n\r])*?\))\]/g
|
||||
|
||||
const UpperCaseKeys = function(obj) {
|
||||
let result = {};
|
||||
Object.entries(obj).forEach(([k, v]) => (result[k.toUpperCase()] = v));
|
||||
return result;
|
||||
};
|
||||
const UpperCaseKeys = function (obj) {
|
||||
let result = {}
|
||||
Object.entries(obj).forEach(([k, v]) => (result[k.toUpperCase()] = v))
|
||||
return result
|
||||
}
|
||||
|
||||
const isEmptyObject = obj =>
|
||||
Object.keys(obj).length === 0 && obj.constructor === Object;
|
||||
const isEmptyObject = (obj) =>
|
||||
Object.keys(obj).length === 0 && obj.constructor === Object
|
||||
|
||||
const removeOptionalKeys = function(obj, optionalValues) {
|
||||
let result = {};
|
||||
const removeOptionalKeys = function (obj, optionalValues) {
|
||||
let result = {}
|
||||
|
||||
Object.entries(obj).forEach(([key, value]) => {
|
||||
if (optionalValues.includes(key) && isEmptyObject(value)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
result[key] = value;
|
||||
});
|
||||
result[key] = value
|
||||
})
|
||||
|
||||
return result;
|
||||
};
|
||||
return result
|
||||
}
|
||||
|
||||
const toKebabCase = function(str) {
|
||||
const toKebabCase = function (str) {
|
||||
return str
|
||||
.trim()
|
||||
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
||||
.toLowerCase();
|
||||
};
|
||||
.toLowerCase()
|
||||
}
|
||||
|
||||
const replaceInObject = function(obj, fn) {
|
||||
const replaceInObject = function (obj, fn) {
|
||||
if (obj === null) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
switch (typeof obj) {
|
||||
case 'undefined':
|
||||
return {};
|
||||
return {}
|
||||
case 'string':
|
||||
return fn(obj);
|
||||
return fn(obj)
|
||||
case 'object':
|
||||
obj = Object.assign({}, obj);
|
||||
obj = Object.assign({}, obj)
|
||||
Object.entries(obj).forEach(
|
||||
([key, value]) => (obj[key] = replaceInObject(value, fn))
|
||||
);
|
||||
)
|
||||
default:
|
||||
return obj;
|
||||
return obj
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const moduleVersion = () => parseInt(require('../package.json').version, 10);
|
||||
const moduleVersion = () => parseInt(require('../package.json').version, 10)
|
||||
|
||||
const isUrl = function(str) {
|
||||
const isUrl = function (str) {
|
||||
try {
|
||||
new URL(str);
|
||||
return true;
|
||||
new URL(str)
|
||||
return true
|
||||
} catch (e) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
requestRegex,
|
||||
|
|
@ -87,4 +87,4 @@ module.exports = {
|
|||
replaceInObject,
|
||||
moduleVersion,
|
||||
isUrl
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue