Finish plugin architecture, write plugins test

This commit is contained in:
Austen Collins 2015-10-18 08:55:37 -07:00 committed by doapp-ryanp
parent 4084a6a1f1
commit d324edf6f7
6 changed files with 199 additions and 86 deletions

View File

@ -1,11 +1,11 @@
'use strict';
const path = require('path'),
utils = require('./utils/index'),
JawsCLI = require('./utils/cli'),
JawsError = require('./jaws-error'),
Promise = require('bluebird'),
AWSUtils = require('./utils/aws');
utils = require('./utils/index'),
JawsCLI = require('./utils/cli'),
JawsError = require('./jaws-error'),
Promise = require('bluebird'),
AWSUtils = require('./utils/aws');
/**
* Jaws base Class
@ -133,21 +133,21 @@ class Jaws {
* Set Action
*/
action(actionName, actionGenerator) {
action(actionName, action) {
// Check action is valid
if (!this.actions[actionName]) {
}
this.actions[actionName] = actionGenerator;
this.actions[actionName] = action;
}
/**
* Set Hook
*/
hook(hookName, hookGenerator, index) {
hook(hookName, hook, index) {
// Check hook is valid
if (!this.hooks[hookName]) {
@ -155,7 +155,7 @@ class Jaws {
}
index = (!index && index !== 0) ? this.hooks[hookName].length : index;
this.hooks[hookName].splice(index, 0, hookGenerator);
this.hooks[hookName].splice(index, 0, hook);
}
@ -181,32 +181,25 @@ class Jaws {
this._queue = this._queue.concat(this.hooks.PreProjectCreate);
this._queue.push(this.actions.ProjectCreate.bind({}, options));
this._queue = this._queue.concat(this.hooks.PostProjectCreate);
this._executeQueue();
return Promise.resolve();
return this._executeQueue();
}
/**
* Execute Queue
* - Recursive function
* - Leverages Promise.coroutine to:
* -- iterate yields in a generator
* -- wait for yielded promises to resolve (necessary for async)
* -- push data back to generator
*/
_executeQueue() {
let _this = this;
return Promise.coroutine(_this._queue[0])()
.then(function() {
_this._queue.splice(0, 1); //todo: change to .shift()
if (_this._queue.length) return _this._executeQueue();
return;
})
.catch(function(error) {
console.log('JAWS Plugin Error: ', error, error.stack);
return;
});
return Promise.try(function() {
return _this._queue;
})
.each(function(p) {
return p;
})
.catch(function(error) {
throw new JawsError(error);
});
}
/**

View File

@ -5,25 +5,27 @@
*/
const JawsPlugin = require('../../JawsPlugin'),
JawsError = require('../../jaws-error'),
JawsCLI = require('../../utils/cli'),
Promise = require('bluebird'),
fs = require('fs'),
path = require('path'),
os = require('os'),
AWSUtils = require('../../utils/aws'),
utils = require('../../utils'),
shortid = require('shortid');
JawsError = require('../../jaws-error'),
JawsCLI = require('../../utils/cli'),
Promise = require('bluebird'),
fs = require('fs'),
path = require('path'),
os = require('os'),
AWSUtils = require('../../utils/aws'),
utils = require('../../utils'),
shortid = require('shortid');
/**
* ProjectCreate Class
*/
class ProjectCreate extends JawsPlugin {
/**
* @param Jaws class object
* @param config object
*/
constructor(Jaws, config) {
super(Jaws, config);
}
@ -31,6 +33,7 @@ class ProjectCreate extends JawsPlugin {
/**
* @returns {Promise} upon completion of all registrations
*/
registerActions() {
this.Jaws.action('ProjectCreate', this._action());
return Promise.resolve();
@ -42,6 +45,7 @@ class ProjectCreate extends JawsPlugin {
* @returns {generator}
* @private
*/
_action() {
let _this = this;
@ -107,6 +111,7 @@ class ProjectCreate extends JawsPlugin {
/**
* Generate ShortId
*/
_generateShortId(maxLen) {
return shortid.generate().replace(/\W+/g, '').substring(0, maxLen).replace(/[_-]/g, '');
}
@ -116,6 +121,7 @@ class ProjectCreate extends JawsPlugin {
* @returns {*}
* @private
*/
_prompt() {
utils.jawsDebug('Prompting for new project information');
@ -229,63 +235,64 @@ class ProjectCreate extends JawsPlugin {
// Show Prompts
return _this.Prompter.getAsync(_this._prompts)
.then(function(answers) {
_this._name = answers.name;
_this._domain = answers.domain;
_this._stage = answers.stage.toLowerCase();
_this._notificationEmail = answers.notificationEmail;
_this._awsAdminKeyId = answers.awsAdminKeyId;
_this._awsAdminSecretKey = answers.awsAdminSecretKey;
.then(function(answers) {
_this._name = answers.name;
_this._domain = answers.domain;
_this._stage = answers.stage.toLowerCase();
_this._notificationEmail = answers.notificationEmail;
_this._awsAdminKeyId = answers.awsAdminKeyId;
_this._awsAdminSecretKey = answers.awsAdminSecretKey;
// If region exists, skip select prompt
if (_this._region) return;
// If region exists, skip select prompt
if (_this._region) return;
// Prompt: region select
let choices = [];
AWSUtils.validLambdaRegions.forEach(function(r) {
choices.push({
key: '',
value: r,
label: r,
// Prompt: region select
let choices = [];
AWSUtils.validLambdaRegions.forEach(function(r) {
choices.push({
key: '',
value: r,
label: r,
});
});
return JawsCLI.select('Select a region for your project: ', choices, false)
.then(function(results) {
_this._region = results[0].value;
});
})
.then(function() {
// If profile exists, skip select prompt
if (_this._profile) return Promise.resolve();
// If aws credentials were passed, skip select prompt
if (_this._awsAdminKeyId && _this._awsAdminSecretKey) return Promise.resolve();
// Prompt: profile select
let profilesList = AWSUtils.profilesMap(),
profiles = Object.keys(profilesList),
choices = [];
for (let i = 0; i < profiles.length; i++) {
choices.push({
key: '',
value: profiles[i],
label: profiles[i],
});
}
return JawsCLI.select('Select an AWS profile for your project: ', choices, false)
.then(function(results) {
_this._profile = results[0].value;
});
});
return JawsCLI.select('Select a region for your project: ', choices, false)
.then(function(results) {
_this._region = results[0].value;
});
})
.then(function() {
// If profile exists, skip select prompt
if (_this._profile) return Promise.resolve();
// If aws credentials were passed, skip select prompt
if (_this._awsAdminKeyId && _this._awsAdminSecretKey) return Promise.resolve();
// Prompt: profile select
let profilesList = AWSUtils.profilesMap(),
profiles = Object.keys(profilesList),
choices = [];
for (let i = 0; i < profiles.length; i++) {
choices.push({
key: '',
value: profiles[i],
label: profiles[i],
});
}
return JawsCLI.select('Select an AWS profile for your project: ', choices, false)
.then(function(results) {
_this._profile = results[0].value;
});
});
}
/**
* Prepare Project Data
*/
_prepareProjectData() {
let _this = this;
@ -324,5 +331,4 @@ class ProjectCreate extends JawsPlugin {
}
}
module.exports = ProjectCreate;

View File

@ -39,6 +39,8 @@
},
"dependencies": {
"async": "^0.9.0",
"asynquence": "^0.8.2",
"asynquence-contrib": "^0.22.0",
"aws-sdk": "^2.2.4",
"babelify": "^6.3.0",
"bluebird": "^2.9.34",
@ -46,6 +48,7 @@
"chalk": "^1.1.0",
"cli-spinner": "^0.2.1",
"commander": "^2.5.0",
"commop": "^1.2.0",
"debug": "^2.2.0",
"dotenv": "^1.2.0",
"download": "^4.2.0",

View File

@ -15,6 +15,7 @@ describe('AllTests', function() {
});
//require tests vs inline so we can run sequentially
require('./cli/TestPlugins');
//require('./cli/tag');
//require('./cli/env');
//require('./cli/module_create');
@ -28,5 +29,5 @@ describe('AllTests', function() {
//require('./cli/deploy_resources');
//require('./cli/deploy_endpoint');
//require('./cli/new_stage_region');
require('./cli/TestActionProjectCreate');
//require('./cli/TestActionProjectCreate');
});

View File

@ -51,7 +51,9 @@ describe('Test Project Create', function() {
Jaws.projectCreate(prjConfig)
.then(function() {
let jawsJson = utils.readAndParseJsonSync(path.join(os.tmpdir(), config.newName, 'jaws.json'));
let jawsJson = utils.readAndParseJsonSync(
path.join(os.tmpdir(), config.newName, 'jaws.json'));
let region = false;
for (let i = 0; i < jawsJson.stages[config.stage].length; i++) {

108
tests/cli/TestPlugins.js Normal file
View File

@ -0,0 +1,108 @@
'use strict';
/**
* Test: Plugins
*/
let JAWS = require('../../lib/Jaws.js'),
JawsPlugin = require('../../lib/JawsPlugin'),
JawsError = require('../../lib/jaws-error'),
path = require('path'),
os = require('os'),
utils = require('../../lib/utils'),
assert = require('chai').assert,
shortid = require('shortid'),
config = require('../config'),
Promise = require('bluebird');
/**
* JAWS
*/
let Jaws = new JAWS({
awsAdminKeyId: '123',
awsAdminSecretKey: '123',
interactive: false,
});
/**
* Define Plugin
*/
class PromisePlugin extends JawsPlugin {
constructor(Jaws, config) {
super(Jaws, config);
}
registerActions() {
this.Jaws.action('ProjectCreate', this._actionProjectCreate());
}
registerHooks() {
this.Jaws.hook('PreProjectCreate', this._hookPreProjectCreate());
this.Jaws.hook('PostProjectCreate', this._hookPostProjectCreate());
}
_hookPreProjectCreate() {
let _this = this;
return new Promise(function(resolve, reject) {
_this.Jaws.generatorPluginHookPre = true;
return resolve();
})
}
_actionProjectCreate() {
let _this = this;
return Promise.delay(500)
.then(function() {
_this.Jaws.generatorPluginHookAction = true;
});
}
_hookPostProjectCreate() {
let _this = this;
return Promise.delay(500)
.then(function() {
_this.Jaws.generatorPluginHookPost = true;
});
}
}
/**
* Run Tests
*/
describe('Test Promise Plugins', function() {
before(function(done) {
Jaws.addPlugin(new PromisePlugin(Jaws, {}));
done();
});
after(function(done) {
done();
});
describe('Test Promise Plugins', function() {
it('should run and attach values to context', function(done) {
Jaws.projectCreate({
name: 'test',
stage: 'test',
region: 'us-east-1',
domain: 'test.com',
notificationEmail: 'test@test.com',
})
.then(function() {
assert.isTrue(Jaws.generatorPluginHookPre);
assert.isTrue(Jaws.generatorPluginHookPost);
assert.isTrue(Jaws.generatorPluginHookAction);
done();
})
.catch(function(e) {
done(e);
});
});
});
});