From 52e88a37032c39205e480c1a7b2a2b1c6ce395e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20D=C3=ADaz?= Date: Tue, 31 Jul 2018 23:23:32 -0600 Subject: [PATCH] This allows extra documents in a yaml config file to be embeded as hosts.(#40) This allows extra documents in a yaml config file to be embeded as hosts. --- .../__snapshots__/utils.spec.js.snap | 3 + bin/cli/utils.js | 15 +- examples/hosts.yml | 30 +-- src/__tests__/__snapshots__/beau.spec.js.snap | 235 ++++++++---------- .../__snapshots__/config.spec.js.snap | 12 +- .../__snapshots__/plugins.spec.js.snap | 1 + src/__tests__/beau.spec.js | 19 +- src/__tests__/config.spec.js | 80 +++--- src/plugins.js | 6 +- src/requestList.js | 6 +- 10 files changed, 197 insertions(+), 210 deletions(-) diff --git a/bin/cli/__tests__/__snapshots__/utils.spec.js.snap b/bin/cli/__tests__/__snapshots__/utils.spec.js.snap index 17860e4..6041913 100644 --- a/bin/cli/__tests__/__snapshots__/utils.spec.js.snap +++ b/bin/cli/__tests__/__snapshots__/utils.spec.js.snap @@ -10,6 +10,9 @@ Config { }, "HOSTS": Array [], "PLUGINS": Plugins { + "autoload": Array [ + "std", + ], "context": Object { "createReadStream": [Function], }, diff --git a/bin/cli/utils.js b/bin/cli/utils.js index c9d2b27..695b37c 100644 --- a/bin/cli/utils.js +++ b/bin/cli/utils.js @@ -10,7 +10,20 @@ const openConfigFile = configFile => { throw new Error(`The config file, ${configFile} was not found.`); } - return yaml.safeLoad(fs.readFileSync(configFile, 'utf-8')); + let config; + yaml.safeLoadAll(fs.readFileSync(configFile, 'utf-8'), doc => { + if (typeof config === 'undefined') { + config = doc; + } else { + if (typeof config.hosts === 'undefined') { + config.hosts = []; + } + + config.hosts.push(doc); + } + }); + + return config; }; const loadConfig = (configFile, params = []) => { diff --git a/examples/hosts.yml b/examples/hosts.yml index 2f754e9..ea8ea08 100644 --- a/examples/hosts.yml +++ b/examples/hosts.yml @@ -1,4 +1,5 @@ version: 1 +endpoint: http://httpbin.org environment: the: @@ -8,25 +9,14 @@ defaults: headers: hello: 'Hello2' -GET http://jsonplaceholder.typicode.com/posts/1: - alias: a-post - headers: - hello: $jpa2:get-post.body.id - - -hosts: - - host: jpa - endpoint: http://jsonplaceholder.typicode.com - GET /posts/$env.the.post: get-post - GET /users/$jpa:get-post.body.userId: hello - - - host: jpa2 - endpoint: http://jsonplaceholder.typicode.com - defaults: - headers: false - - GET /posts/$jpa:get-post.body.id: - alias: get-post - +POST /anything: + alias: anything + payload: + title: $jpa:get-post.body.title +--- +host: jpa +endpoint: http://jsonplaceholder.typicode.com +GET /posts/$env.the.post: get-post +GET /users/$jpa:get-post.body.userId: hello diff --git a/src/__tests__/__snapshots__/beau.spec.js.snap b/src/__tests__/__snapshots__/beau.spec.js.snap index 2d40116..b849475 100644 --- a/src/__tests__/__snapshots__/beau.spec.js.snap +++ b/src/__tests__/__snapshots__/beau.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Beau's config Loader. should create a request list 1`] = ` +exports[`Beau's config Loader. should load the config 1`] = ` Beau { "config": Config { "COOKIEJAR": false, @@ -9,10 +9,13 @@ Beau { "authentication": "hello", }, }, - "ENDPOINT": "http://jsonplaceholder.typicode.com", + "ENDPOINT": "http://example.com", "ENVIRONMENT": Object {}, "HOSTS": Array [], "PLUGINS": Plugins { + "autoload": Array [ + "std", + ], "context": Object {}, "registry": Object { "dynamicValues": Array [], @@ -20,27 +23,7 @@ Beau { "preRequestModifiers": Array [], }, }, - "REQUESTS": Array [ - Object { - "ALIAS": "get-post", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - }, - "REQUEST": "GET /posts/1", - }, - Object { - "ALIAS": "user", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - "hello": "world", - }, - "REQUEST": "GET /user", - }, - ], + "REQUESTS": Array [], "VERSION": 1, "configKeys": Array [ "VERSION", @@ -53,43 +36,82 @@ Beau { ], }, "requests": RequestList { - "REQUESTS": Array [ - Object { - "ALIAS": "get-post", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - }, - "REQUEST": "GET /posts/1", + "PLUGINS": Plugins { + "autoload": Array [ + "std", + ], + "context": Object {}, + "registry": Object { + "dynamicValues": Array [], + "postRequestModifiers": Array [], + "preRequestModifiers": Array [], }, - Object { - "ALIAS": "user", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - "hello": "world", - }, - "REQUEST": "GET /user", - }, - ], + }, + "REQUESTS": Array [], "cache": RequestCache { "$cache": Object { "env": Object {}, }, }, - "config": Config { + "list": Array [], + }, +} +`; + +exports[`Beau's config Loader. should load the request list using the configuration 1`] = ` +RequestList { + "PLUGINS": Plugins { + "autoload": Array [ + "std", + ], + "context": Object {}, + "registry": Object { + "dynamicValues": Array [], + "postRequestModifiers": Array [], + "preRequestModifiers": Array [], + }, + }, + "REQUESTS": Array [ + Object { + "ALIAS": "get-post", "COOKIEJAR": false, - "DEFAULTS": Object { - "headers": Object { - "authentication": "hello", - }, + "ENDPOINT": "http://example.com", + "REQUEST": "GET /posts/1", + }, + Object { + "ALIAS": "user", + "COOKIEJAR": false, + "ENDPOINT": "http://example.com", + "HEADERS": Object { + "hello": "world", }, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "ENVIRONMENT": Object {}, - "HOSTS": Array [], - "PLUGINS": Plugins { + "REQUEST": "GET /user", + }, + ], + "cache": RequestCache { + "$cache": Object { + "env": Object {}, + }, + }, + "list": Array [ + Request { + "ALIAS": "get-post", + "COOKIEJAR": false, + "DEPENDENCIES": Set {}, + "ENDPOINT": "http://example.com", + "PATH": "/posts/1", + "REQUEST": "GET /posts/1", + "VERB": "GET", + "originalRequest": Object { + "ALIAS": "get-post", + "COOKIEJAR": false, + "ENDPOINT": "http://example.com", + "REQUEST": "GET /posts/1", + }, + "plugins": Plugins { + "autoload": Array [ + "std", + ], "context": Object {}, "registry": Object { "dynamicValues": Array [], @@ -97,100 +119,39 @@ Beau { "preRequestModifiers": Array [], }, }, - "REQUESTS": Array [ - Object { - "ALIAS": "get-post", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - }, - "REQUEST": "GET /posts/1", - }, - Object { - "ALIAS": "user", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - "hello": "world", - }, - "REQUEST": "GET /user", - }, - ], - "VERSION": 1, - "configKeys": Array [ - "VERSION", - "ENDPOINT", - "PLUGINS", - "DEFAULTS", - "ENVIRONMENT", - "HOSTS", - "COOKIEJAR", - ], }, - "list": Array [ - Request { - "ALIAS": "get-post", - "COOKIEJAR": false, - "DEPENDENCIES": Set {}, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - }, - "PATH": "/posts/1", - "REQUEST": "GET /posts/1", - "VERB": "GET", - "originalRequest": Object { - "ALIAS": "get-post", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - }, - "REQUEST": "GET /posts/1", - }, - "plugins": Plugins { - "context": Object {}, - "registry": Object { - "dynamicValues": Array [], - "postRequestModifiers": Array [], - "preRequestModifiers": Array [], - }, - }, + Request { + "ALIAS": "user", + "COOKIEJAR": false, + "DEPENDENCIES": Set {}, + "ENDPOINT": "http://example.com", + "HEADERS": Object { + "hello": "world", }, - Request { + "PATH": "/user", + "REQUEST": "GET /user", + "VERB": "GET", + "originalRequest": Object { "ALIAS": "user", "COOKIEJAR": false, - "DEPENDENCIES": Set {}, - "ENDPOINT": "http://jsonplaceholder.typicode.com", + "ENDPOINT": "http://example.com", "HEADERS": Object { - "authentication": "hello", "hello": "world", }, - "PATH": "/user", "REQUEST": "GET /user", - "VERB": "GET", - "originalRequest": Object { - "ALIAS": "user", - "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", - "HEADERS": Object { - "authentication": "hello", - "hello": "world", - }, - "REQUEST": "GET /user", - }, - "plugins": Plugins { - "context": Object {}, - "registry": Object { - "dynamicValues": Array [], - "postRequestModifiers": Array [], - "preRequestModifiers": Array [], - }, + }, + "plugins": Plugins { + "autoload": Array [ + "std", + ], + "context": Object {}, + "registry": Object { + "dynamicValues": Array [], + "postRequestModifiers": Array [], + "preRequestModifiers": Array [], }, }, - ], - }, + }, + ], } `; diff --git a/src/__tests__/__snapshots__/config.spec.js.snap b/src/__tests__/__snapshots__/config.spec.js.snap index 744aea0..d451c22 100644 --- a/src/__tests__/__snapshots__/config.spec.js.snap +++ b/src/__tests__/__snapshots__/config.spec.js.snap @@ -42,6 +42,9 @@ Config { }, ], "PLUGINS": Plugins { + "autoload": Array [ + "std", + ], "context": Object {}, "registry": Object { "dynamicValues": Array [], @@ -130,10 +133,13 @@ Config { "authentication": "hello", }, }, - "ENDPOINT": "http://jsonplaceholder.typicode.com", + "ENDPOINT": "http://example.com", "ENVIRONMENT": Object {}, "HOSTS": Array [], "PLUGINS": Plugins { + "autoload": Array [ + "std", + ], "context": Object {}, "registry": Object { "dynamicValues": Array [], @@ -145,7 +151,7 @@ Config { Object { "ALIAS": "get-post", "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", + "ENDPOINT": "http://example.com", "HEADERS": Object { "authentication": "hello", }, @@ -154,7 +160,7 @@ Config { Object { "ALIAS": "user", "COOKIEJAR": false, - "ENDPOINT": "http://jsonplaceholder.typicode.com", + "ENDPOINT": "http://example.com", "HEADERS": Object { "authentication": "hello", "hello": "world", diff --git a/src/__tests__/__snapshots__/plugins.spec.js.snap b/src/__tests__/__snapshots__/plugins.spec.js.snap index b5a29ac..3eb746e 100644 --- a/src/__tests__/__snapshots__/plugins.spec.js.snap +++ b/src/__tests__/__snapshots__/plugins.spec.js.snap @@ -20,6 +20,7 @@ Object { exports[`Beau's plugin system shouldn't do anything when given an empty array. 1`] = ` Plugins { + "autoload": Array [], "context": Object {}, "registry": Object { "dynamicValues": Array [], diff --git a/src/__tests__/beau.spec.js b/src/__tests__/beau.spec.js index eb94e8a..61d1338 100644 --- a/src/__tests__/beau.spec.js +++ b/src/__tests__/beau.spec.js @@ -8,16 +8,28 @@ const requireg = require('requireg'); requireg.resolving = false; describe(`Beau's config Loader.`, () => { - it('should create a request list', () => { + it('should load the config', () => { moduleVersion.mockReturnValue(1); const doc = yaml.safeLoad(` version: 1 - endpoint: 'http://jsonplaceholder.typicode.com' + endpoint: 'http://example.com' defaults: headers: authentication: hello + `); + + const beau = new Beau(doc); + expect(beau).toMatchSnapshot(); + }); + + it(`should load the request list using the configuration`, () => { + moduleVersion.mockReturnValue(1); + + const doc = yaml.safeLoad(` + version: 1 + endpoint: 'http://example.com' GET /posts/1: get-post GET /user: @@ -27,8 +39,7 @@ describe(`Beau's config Loader.`, () => { `); const beau = new Beau(doc); - - expect(beau).toMatchSnapshot(); + expect(beau.requests).toMatchSnapshot(); }); it('should display a warning if the module version and the beau file version are different', () => { diff --git a/src/__tests__/config.spec.js b/src/__tests__/config.spec.js index 915dd34..5a64a68 100644 --- a/src/__tests__/config.spec.js +++ b/src/__tests__/config.spec.js @@ -5,21 +5,21 @@ const requireg = require('requireg'); requireg.resolving = false; describe('Config', () => { - it('should load valid config keys', () => { - const doc = yaml.safeLoad(` + it('should load valid config keys', () => { + const doc = yaml.safeLoad(` 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(` + it('should load requests', () => { + const doc = yaml.safeLoad(` endpoint: http://example.com GET /profile: get-profile @@ -31,14 +31,14 @@ describe('Config', () => { 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(` + it('should set up defaults for all requests', () => { + const doc = yaml.safeLoad(` version: 1 - endpoint: 'http://jsonplaceholder.typicode.com' + endpoint: 'http://example.com' defaults: HEADERS: @@ -51,16 +51,16 @@ describe('Config', () => { 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(` + it('should load multiple hosts', () => { + const doc = yaml.safeLoad(` version: 1 endpoint: http://example.org @@ -99,13 +99,13 @@ describe('Config', () => { 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(` + it('should namespace all aliases within an host', () => { + const doc = yaml.safeLoad(` hosts: - host: test1 endpoint: http://example.com @@ -115,14 +115,14 @@ describe('Config', () => { 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(` + it(`should throw if host doesn't have a host key`, () => { + const doc = yaml.safeLoad(` hosts: - endpoint: http://example.com GET /posts: posts @@ -132,11 +132,11 @@ describe('Config', () => { 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(` + it(`should merge host settings with global settings`, () => { + const doc = yaml.safeLoad(` defaults: headers: hello: 1 @@ -154,7 +154,7 @@ describe('Config', () => { 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); + }); }); diff --git a/src/plugins.js b/src/plugins.js index 071f549..9b9a725 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -14,7 +14,9 @@ class Plugins { this.context = {}; - this.loadPlugins(autoload.concat(plugins)); + this.autoload = autoload; + + this.loadPlugins(plugins.concat(this.autoload)); } normalizePlugins(plugins) { @@ -52,7 +54,7 @@ class Plugins { const plugin = requireg(module); new plugin(this, plugins[name]); } else { - if (name === 'std') return; + if (this.autoload.includes(name)) return; console.warn( `Plugin ${name} couldn't be found. It is available globally?` diff --git a/src/requestList.js b/src/requestList.js index e3ed9e5..4a36803 100644 --- a/src/requestList.js +++ b/src/requestList.js @@ -3,13 +3,13 @@ const RequestCache = require('./requestCache'); class RequestList { constructor(config = { REQUESTS: [] }) { - this.config = config; + this.PLUGINS = config.PLUGINS; this.REQUESTS = config.REQUESTS; this.list = this.loadRequests(); this.cache = new RequestCache(); - this.cache.add(`env`, this.config.ENVIRONMENT); + this.cache.add(`env`, config.ENVIRONMENT); } async execByAlias(alias) { @@ -46,7 +46,7 @@ class RequestList { let requests = []; this.REQUESTS.forEach(request => { try { - requests.push(new Request(request, this.config.PLUGINS)); + requests.push(new Request(request, this.PLUGINS)); } catch (e) { throw new Error(`${request.request} was ignored: ${e}`); }