diff --git a/bin/cli/__tests__/__snapshots__/utils.spec.js.snap b/bin/cli/__tests__/__snapshots__/utils.spec.js.snap index fdf0190..17860e4 100644 --- a/bin/cli/__tests__/__snapshots__/utils.spec.js.snap +++ b/bin/cli/__tests__/__snapshots__/utils.spec.js.snap @@ -45,25 +45,6 @@ Config { "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, - }, } `; diff --git a/bin/cli/__tests__/list.spec.js b/bin/cli/__tests__/list.spec.js index 3227839..367aa3a 100644 --- a/bin/cli/__tests__/list.spec.js +++ b/bin/cli/__tests__/list.spec.js @@ -1,23 +1,23 @@ const ListCommand = require('../commands/list'); +jest.mock('../../../src/shared'); + jest.mock('../utils'); describe('List Command', () => { - let result; + let result; - beforeEach(() => { - result = []; - jest - .spyOn(process.stdout, 'write') - .mockImplementation(val => - result.push(require('strip-ansi')(val.toString('utf8'))) - ); - }); + beforeEach(() => { + 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(); - }); + test.each([[], ['--no-format']])('with flags:', async (...args) => { + await ListCommand.run(args); + expect(result).toMatchSnapshot(); + }); }); diff --git a/bin/cli/__tests__/request.spec.js b/bin/cli/__tests__/request.spec.js index ab3132a..b09e9a2 100644 --- a/bin/cli/__tests__/request.spec.js +++ b/bin/cli/__tests__/request.spec.js @@ -1,6 +1,8 @@ const RequestCommand = require('../commands/request'); const requestPromiseNativeMock = require('request-promise-native'); +jest.mock('../../../src/shared'); + jest.mock('../utils'); describe('Request Command', () => { @@ -9,11 +11,9 @@ describe('Request Command', () => { beforeEach(() => { requestPromiseNativeMock.fail = false; result = []; - jest - .spyOn(process.stdout, 'write') - .mockImplementation(val => - result.push(require('strip-ansi')(val.toString('utf8'))) - ); + jest.spyOn(process.stdout, 'write').mockImplementation(val => + result.push(require('strip-ansi')(val.toString('utf8'))) + ); }); afterEach(() => jest.restoreAllMocks()); diff --git a/bin/cli/__tests__/utils.spec.js b/bin/cli/__tests__/utils.spec.js index d4830a0..69877c0 100644 --- a/bin/cli/__tests__/utils.spec.js +++ b/bin/cli/__tests__/utils.spec.js @@ -1,5 +1,7 @@ const utils = require('../utils.js'); +jest.mock('../../../src/shared'); + jest.mock('fs'); describe('utils', () => { diff --git a/bin/cli/__tests__/validate.spec.js b/bin/cli/__tests__/validate.spec.js index c563130..8f99821 100644 --- a/bin/cli/__tests__/validate.spec.js +++ b/bin/cli/__tests__/validate.spec.js @@ -3,27 +3,25 @@ const ValidateCommand = require('../commands/validate'); jest.mock('../utils'); describe('Validate Command', () => { - let result; + let result; - beforeEach(() => { - result = []; - jest - .spyOn(process.stdout, 'write') - .mockImplementation(val => - result.push(require('strip-ansi')(val.toString('utf8'))) - ); - }); + beforeEach(() => { + result = []; + jest.spyOn(process.stdout, 'write').mockImplementation(val => + result.push(require('strip-ansi')(val.toString('utf8'))) + ); + }); - afterEach(() => jest.restoreAllMocks()); + afterEach(() => jest.restoreAllMocks()); - it('should validate the configuration file', async () => { - await ValidateCommand.run([]); - expect(result).toMatchSnapshot(); - }); + 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(); - }); + it('should show schema errors', async () => { + await expect( + ValidateCommand.run(['invalid-conf.yml']) + ).rejects.toThrow(); + }); }); diff --git a/src/__mocks__/shared.js b/src/__mocks__/shared.js new file mode 100644 index 0000000..26f2ff5 --- /dev/null +++ b/src/__mocks__/shared.js @@ -0,0 +1,4 @@ +module.exports = { + ...require.requireActual('../shared'), + moduleVersion: jest.fn().mockReturnValue(1) +}; diff --git a/src/__tests__/__snapshots__/beau.spec.js.snap b/src/__tests__/__snapshots__/beau.spec.js.snap index 7e07613..2d40116 100644 --- a/src/__tests__/__snapshots__/beau.spec.js.snap +++ b/src/__tests__/__snapshots__/beau.spec.js.snap @@ -51,31 +51,6 @@ Beau { "HOSTS", "COOKIEJAR", ], - "defaultConfigValues": Object { - "COOKIEJAR": false, - "DEFAULTS": Object {}, - "ENDPOINT": "", - "ENVIRONMENT": Object {}, - "HOSTS": Array [], - "PLUGINS": Array [], - "VERSION": 1, - }, - "doc": Object { - "GET /posts/1": "get-post", - "GET /user": Object { - "alias": "user", - "headers": Object { - "hello": "world", - }, - }, - "defaults": Object { - "headers": Object { - "authentication": "hello", - }, - }, - "endpoint": "http://jsonplaceholder.typicode.com", - "version": 1, - }, }, "requests": RequestList { "REQUESTS": Array [ @@ -153,31 +128,6 @@ Beau { "HOSTS", "COOKIEJAR", ], - "defaultConfigValues": Object { - "COOKIEJAR": false, - "DEFAULTS": Object {}, - "ENDPOINT": "", - "ENVIRONMENT": Object {}, - "HOSTS": Array [], - "PLUGINS": Array [], - "VERSION": 1, - }, - "doc": Object { - "GET /posts/1": "get-post", - "GET /user": Object { - "alias": "user", - "headers": Object { - "hello": "world", - }, - }, - "defaults": Object { - "headers": Object { - "authentication": "hello", - }, - }, - "endpoint": "http://jsonplaceholder.typicode.com", - "version": 1, - }, }, "list": Array [ Request { diff --git a/src/__tests__/__snapshots__/config.spec.js.snap b/src/__tests__/__snapshots__/config.spec.js.snap index 0cf6434..744aea0 100644 --- a/src/__tests__/__snapshots__/config.spec.js.snap +++ b/src/__tests__/__snapshots__/config.spec.js.snap @@ -119,55 +119,6 @@ Config { "HOSTS", "COOKIEJAR", ], - "defaultConfigValues": Object { - "COOKIEJAR": false, - "DEFAULTS": Object {}, - "ENDPOINT": "", - "ENVIRONMENT": Object {}, - "HOSTS": Array [], - "PLUGINS": Array [], - "VERSION": 1, - }, - "doc": Object { - "GET /e1": "e1", - "defaults": Object { - "HEADERS": Object { - "hello": "mars", - }, - }, - "endpoint": "http://example.org", - "hosts": Array [ - Object { - "GET /e2": "e2", - "GET /posts": "posts", - "defaults": Object { - "HEADERS": Object { - "hello": "world", - "world": "hello", - }, - }, - "endpoint": "http://example.com", - "host": "com", - }, - Object { - "GET /e3": "e3", - "GET /posts": "posts", - "defaults": Object { - "HEADERS": Object { - "hello": "world", - "world": "bye", - }, - }, - "endpoint": "http://example.net", - "host": "net", - }, - Object { - "GET /posts": "posts", - "endpoint": "http://example.info", - "host": "info", - }, - ], - }, } `; @@ -221,30 +172,5 @@ Config { "HOSTS", "COOKIEJAR", ], - "defaultConfigValues": Object { - "COOKIEJAR": false, - "DEFAULTS": Object {}, - "ENDPOINT": "", - "ENVIRONMENT": Object {}, - "HOSTS": Array [], - "PLUGINS": Array [], - "VERSION": 1, - }, - "doc": Object { - "GET /posts/1": "get-post", - "GET /user": Object { - "alias": "user", - "headers": Object { - "hello": "world", - }, - }, - "defaults": Object { - "HEADERS": Object { - "authentication": "hello", - }, - }, - "endpoint": "http://jsonplaceholder.typicode.com", - "version": 1, - }, } `; diff --git a/src/__tests__/__snapshots__/request.spec.js.snap b/src/__tests__/__snapshots__/request.spec.js.snap index 4f7c00b..ab94f3a 100644 --- a/src/__tests__/__snapshots__/request.spec.js.snap +++ b/src/__tests__/__snapshots__/request.spec.js.snap @@ -7,7 +7,7 @@ Object { "body": Object { "username": "seich", }, - "endpoint": "http://martianwabbit.com/user", + "endpoint": "http://example.com/user", "headers": Object { "authentication": "BEARER abc123", }, @@ -25,7 +25,7 @@ Object { "body": "{\\"hello\\": \\"world\\"}", "request": Object { "body": undefined, - "endpoint": "http://martianwabbit.com/user", + "endpoint": "http://example.com/user", "headers": undefined, }, "response": Object { diff --git a/src/__tests__/beau.spec.js b/src/__tests__/beau.spec.js index 9f7bbcf..eb94e8a 100644 --- a/src/__tests__/beau.spec.js +++ b/src/__tests__/beau.spec.js @@ -1,11 +1,16 @@ const yaml = require('js-yaml'); const Beau = require('../beau'); +const { moduleVersion } = require('../shared'); + +jest.mock('../shared'); const requireg = require('requireg'); requireg.resolving = false; describe(`Beau's config Loader.`, () => { it('should create a request list', () => { + moduleVersion.mockReturnValue(1); + const doc = yaml.safeLoad(` version: 1 endpoint: 'http://jsonplaceholder.typicode.com' @@ -23,7 +28,21 @@ describe(`Beau's config Loader.`, () => { const beau = new Beau(doc); - expect(beau.requests).toBeDefined(); expect(beau).toMatchSnapshot(); }); + + it('should display a warning if the module version and the beau file version are different', () => { + let stdout; + let spy = jest + .spyOn(console, 'warn') + .mockImplementation(val => (stdout = val)); + + moduleVersion.mockReturnValue(2); + + const beau = new Beau({ version: 1 }); + expect(stdout).toEqual('This Beau file expects v1. You are using v2.'); + + spy.mockReset(); + spy.mockRestore(); + }); }); diff --git a/src/__tests__/config.spec.js b/src/__tests__/config.spec.js index bde9f49..915dd34 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,12 +31,12 @@ 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' @@ -51,16 +51,17 @@ 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 defaults: @@ -98,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 @@ -114,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 @@ -131,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 @@ -153,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/__tests__/request.spec.js b/src/__tests__/request.spec.js index 4c111aa..edb0098 100644 --- a/src/__tests__/request.spec.js +++ b/src/__tests__/request.spec.js @@ -12,7 +12,7 @@ describe('Request', () => { beforeEach(() => { validRequestConfig = { request: 'POST /user', - endpoint: 'http://martianwabbit.com', + endpoint: 'http://example.com', alias: 'update', params: { userId: '$profile.UserId' @@ -27,7 +27,7 @@ describe('Request', () => { invalidRequestConfig = { request: `POST /session`, - endpoint: 'http://martianwabbit.com' + endpoint: 'http://example.com' }; cache = new RequestCache(); @@ -36,7 +36,7 @@ describe('Request', () => { request = new Request(validRequestConfig); requestWithoutDependencies = new Request({ - endpoint: 'http://martianwabbit.com', + endpoint: 'http://example.com', request: 'GET /user', alias: 'show' }); diff --git a/src/beau.js b/src/beau.js index f734940..9b3f2fb 100644 --- a/src/beau.js +++ b/src/beau.js @@ -1,10 +1,19 @@ 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); + + if (this.config.VERSION !== moduleVersion()) { + console.warn( + `This Beau file expects v${ + this.config.VERSION + }. You are using v${moduleVersion()}.` + ); + } } } diff --git a/src/config.js b/src/config.js index 9beaaa5..3af7b5a 100644 --- a/src/config.js +++ b/src/config.js @@ -1,11 +1,11 @@ const deepMerge = require('deepmerge'); -const { requestRegex, UpperCaseKeys } = require('./shared'); +const { requestRegex, UpperCaseKeys, moduleVersion } = require('./shared'); const Plugins = require('./plugins'); class Config { constructor(doc, env = {}) { - this.defaultConfigValues = { - VERSION: 1, + const defaultConfigValues = { + VERSION: moduleVersion(), ENDPOINT: '', PLUGINS: [], DEFAULTS: {}, @@ -14,11 +14,10 @@ class Config { COOKIEJAR: false }; - this.configKeys = Object.keys(this.defaultConfigValues); - this.doc = doc; + this.configKeys = Object.keys(defaultConfigValues); let config = this.loadConfig(doc); - Object.assign(this, this.defaultConfigValues, config); + Object.assign(this, defaultConfigValues, config); this.ENVIRONMENT = deepMerge(this.ENVIRONMENT, env); @@ -29,21 +28,18 @@ class Config { ENDPOINT: this.ENDPOINT }); - this.loadHosts(this.HOSTS, config); + this.loadHosts(this.HOSTS, config, defaultConfigValues); this.PLUGINS = new Plugins(this.PLUGINS); } - loadHosts(hosts, rootConfig) { + loadHosts(hosts, rootConfig, defaultConfigValues) { hosts.forEach(host => { if (typeof host.host === 'undefined') { throw new Error(`Host doesn't indicate it's host name.`); } - let config = deepMerge( - this.defaultConfigValues, - this.loadConfig(host) - ); + let config = deepMerge(defaultConfigValues, this.loadConfig(host)); config.DEFAULTS = deepMerge(rootConfig.DEFAULTS, config.DEFAULTS); diff --git a/src/shared.js b/src/shared.js index 4b0404d..2964c40 100644 --- a/src/shared.js +++ b/src/shared.js @@ -67,6 +67,8 @@ const replaceInObject = function(obj, fn) { return obj; }; +const moduleVersion = () => parseInt(require('../package.json').version, 10); + module.exports = { requestRegex, replacementRegex, @@ -74,5 +76,6 @@ module.exports = { UpperCaseKeys, removeOptionalKeys, toKebabCase, - replaceInObject + replaceInObject, + moduleVersion };