Socket
Socket
Sign inDemoInstall

serverless-mocha-plugin

Package Overview
Dependencies
64
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.3 to 1.1.0

.eslintignore

348

index.js

@@ -8,14 +8,23 @@ 'use strict';

const path = require('path'),
fs = require('fs'),
lambdaWrapper = require('lambda-wrapper'),
Mocha = require('mocha'),
chai = require('chai'),
ejs = require('ejs'),
utils = require('./utils.js'),
BbPromise = require('bluebird'); // Serverless uses Bluebird Promises and we recommend you do to because they provide more than your average Promise :)
const path = require('path');
const fs = require('fs');
const lambdaWrapper = require('lambda-wrapper');
const Mocha = require('mocha');
const chai = require('chai');
const ejs = require('ejs');
const fse = require('fs-extra');
const utils = require('./utils');
const BbPromise = require('bluebird');
const yamlEdit = require('yaml-edit');
const testFolder = 'test'; // Folder used my mocha for tests
const templateFilename = 'sls-mocha-plugin-template.ejs';
const testTemplateFile = path.join('templates', 'test-template.ejs');
const functionTemplateFile = path.join('templates', 'function-template.ejs');
const validFunctionRuntimes = [
'aws-nodejs4.3',
];
const humanReadableFunctionRuntimes = `${validFunctionRuntimes
.map((template) => `"${template}"`).join(', ')}`;
class mochaPlugin {

@@ -33,3 +42,3 @@ constructor(serverless, options) {

lifecycleEvents: [
'test'
'test',
],

@@ -41,6 +50,23 @@ options: {

required: true,
}
}
}
}
},
},
},
function: {
usage: 'Create a function into the service',
lifecycleEvents: [
'create',
],
options: {
function: {
usage: 'Name of the function',
shortcut: 'f',
required: true,
},
handler: {
usage: 'Handler for the function (e.g. --handler my-function/index.handler)',
required: true,
},
},
},
},
},

@@ -53,3 +79,3 @@ invoke: {

lifecycleEvents: [
'test'
'test',
],

@@ -65,13 +91,13 @@ options: {

shortcut: 'R',
required: false
required: false,
},
"reporter-options": {
'reporter-options': {
usage: 'Options for mocha reporter',
shortcut: 'O',
required: false
}
}
}
}
}
required: false,
},
},
},
},
},
};

@@ -81,54 +107,62 @@

'create:test:test': () => {
BbPromise.bind(this)
.then(this.createTest);
BbPromise.bind(this)
.then(this.createTest);
},
'invoke:test:test': () => {
BbPromise.bind(this)
.then(this.runTests);
}
}
BbPromise.bind(this)
.then(this.runTests);
},
'create:function:create': () => {
BbPromise.bind(this)
.then(this.createFunction)
.then(this.createTest);
},
};
}
runTests() {
let _this = this;
let funcName = this.options.f || this.options.function || [];
let testFileMap = {};
let mocha = new Mocha({timeout: 6000});
const myModule = this;
const funcName = this.options.f || this.options.function || [];
const testFileMap = {};
const mocha = new Mocha({
timeout: 6000,
});
let stage = this.options.stage;
let region = this.options.region;
const stage = this.options.stage;
const region = this.options.region;
this.serverless.service.load({
stage: stage,
region: region
stage,
region,
})
.then( (inited) => {
_this.serverless.environment = inited.environment;
.then((inited) => {
myModule.serverless.environment = inited.environment;
_this.getFunctions(funcName)
myModule.getFunctions(funcName)
.then(utils.getTestFiles)
.then((funcs) => {
let funcNames = Object.keys(funcs);
const funcNames = Object.keys(funcs);
if (funcNames.length === 0) {
return _this.serverless.cli.log("No tests to run");
return myModule.serverless.cli.log('No tests to run');
}
funcNames.forEach(function(func) {
_this.setEnvVars(func, {
stage: stage,
region: region
funcNames.forEach((func) => {
myModule.setEnvVars(func, {
stage,
region,
});
testFileMap[func] = funcs[func];
mocha.addFile(funcs[func].mochaPlugin.testPath);
})
var reporter = _this.options.reporter;
if ( reporter !== undefined) {
var reporterOptions = {};
if (_this.options["reporter-options"] !== undefined) {
_this.options["reporter-options"].split(",").forEach(function(opt) {
var L = opt.split("=");
});
const reporter = myModule.options.reporter;
if (reporter !== undefined) {
const reporterOptions = {};
if (myModule.options['reporter-options'] !== undefined) {
myModule.options['reporter-options'].split(',').forEach((opt) => {
const L = opt.split('=');
if (L.length > 2 || L.length === 0) {
throw new Error("invalid reporter option '" + opt + "'");
throw new Error(`invalid reporter option "${opt}"`);
} else if (L.length === 2) {

@@ -141,69 +175,66 @@ reporterOptions[L[0]] = L[1];

}
mocha.reporter(reporter, reporterOptions)
mocha.reporter(reporter, reporterOptions);
}
mocha.run(function(failures){
process.on('exit', function () {
mocha.run((failures) => {
process.on('exit', () => {
process.exit(failures); // exit with non-zero status if there were failures
});
})
.on('suite', function(suite) {
let funcName = utils.funcNameFromPath(suite.file);
let func = testFileMap[funcName];
.on('suite', (suite) => {
const testFuncName = utils.funcNameFromPath(suite.file);
const func = testFileMap[testFuncName];
if (func) {
_this.setEnvVars(func, {
stage: stage,
region: region
});
}
})
.on('end', (e) => {
});
}, function(error) {
return _this.serverless.cli.log(error);
});
});
if (func) {
myModule.setEnvVars(func, {
stage,
region,
});
}
});
return null;
}, (error) => myModule.serverless.cli.log(error)
);
});
}
createTest() {
let funcName = this.options.f || this.options.function;
let _this = this;
const funcName = this.options.f || this.options.function;
const myModule = this;
utils.createTestFolder().then(function(testFolder) {
let testFilePath = utils.getTestFilePath(funcName);
let servicePath = _this.serverless.config.servicePath;
let func = _this.serverless.service.functions[funcName];
let handlerParts = func.handler.split('.');
let funcPath = (handlerParts[0] + '.js').replace(/\\/g, "/");
let funcCall = handlerParts[1];
utils.createTestFolder().then((testFolder) => {
const testFilePath = utils.getTestFilePath(funcName);
const func = myModule.serverless.service.functions[funcName];
const handlerParts = func.handler.split('.');
const funcPath = (`${handlerParts[0]}.js`).replace(/\\/g, '/');
const funcCall = handlerParts[1];
fs.exists(testFilePath, function (exists) {
fs.exists(testFilePath, (exists) => {
if (exists) {
_this.serverless.cli.log(`Test file ${testFilePath} already exists`)
myModule.serverless.cli.log(`Test file ${testFilePath} already exists`);
return (new Error(`File ${testFilePath} already exists`));
}
let templateFilenamePath = path.join(testFolder, templateFilename);
fs.exists(templateFilenamePath, function (exists) {
if (! exists) {
templateFilenamePath = path.join(__dirname, templateFilename);
let templateFilenamePath = path.join(testFolder, testTemplateFile);
fs.exists(templateFilenamePath, (exists2) => {
if (!exists2) {
templateFilenamePath = path.join(__dirname, testTemplateFile);
}
let templateString = utils.getTemplateFromFile(templateFilenamePath);
const templateString = utils.getTemplateFromFile(templateFilenamePath);
let content = ejs.render(templateString, {
'functionName': funcName,
'functionPath': funcPath,
'handlerName': funcCall
const content = ejs.render(templateString, {
functionName: funcName,
functionPath: funcPath,
handlerName: funcCall,
});
fs.writeFile(testFilePath, content, function(err) {
fs.writeFile(testFilePath, content, (err) => {
if (err) {
_this.serverless.cli.log(`Creating file ${testFilePath} failed: ${err}`);
myModule.serverless.cli.log(`Creating file ${testFilePath} failed: ${err}`);
return new Error(`Creating file ${testFilePath} failed: ${err}`);
}
return _this.serverless.cli.log(`serverless-mocha-plugin: created ${testFilePath}`);
})
return myModule.serverless.cli.log(`serverless-mocha-plugin: created ${testFilePath}`);
});
});
return null;
});

@@ -214,21 +245,20 @@ });

// Helper functions
getFunctions(funcNames) {
let _this = this;
return new BbPromise(function(resolve, reject) {
let funcObjs = {};
let allFuncs = _this.serverless.service.functions;
if (typeof(funcNames) === 'string') {
funcNames = [ funcNames ];
const myModule = this;
let funcList = funcNames;
return new BbPromise((resolve) => {
const funcObjs = {};
const allFuncs = myModule.serverless.service.functions;
if (typeof funcNames === 'string') {
funcList = [funcNames];
}
if (funcNames.length === 0) {
let sFuncs = allFuncs;
return resolve(sFuncs);
return resolve(allFuncs);
}
let func;
funcNames.forEach(function(funcName, idx) {
funcList.forEach((funcName) => {
func = allFuncs[funcName];

@@ -238,6 +268,8 @@ if (func) {

} else {
_this.serverless.cli.log(`Warning: Could not find function '${funcName}'.`);
myModule.serverless.cli.log(`Warning: Could not find function '${funcName}'.`);
}
});
resolve(funcObjs);
return null;
});

@@ -253,3 +285,4 @@ }

if (options.region) {
utils.setEnv(this.serverless.environment.stages[options.stage].regions[options.region].vars);
utils.setEnv(this.serverless.environment.stages[options.stage]
.regions[options.region].vars);
}

@@ -259,7 +292,88 @@ }

}
createAWSNodeJSFuncFile(handlerPath) {
const handlerInfo = path.parse(handlerPath);
const handlerDir = path.join(this.serverless.config.servicePath, handlerInfo.dir);
const handlerFile = `${handlerInfo.name}.js`;
const handlerFunction = handlerInfo.ext.replace(/^\./, '');
const templateText = fse.readFileSync(path.join(__dirname, functionTemplateFile)).toString();
const jsFile = ejs.render(templateText, {
handlerFunction,
});
const filePath = path.join(handlerDir, handlerFile);
this.serverless.utils.writeFileDir(filePath);
if (this.serverless.utils.fileExistsSync(filePath)) {
const errorMessage = [
`File "${filePath}" already exists. Cannot create function.`,
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
fse.writeFileSync(path.join(handlerDir, handlerFile), jsFile);
this.serverless.cli.log(`Created function file "${path.join(handlerDir, handlerFile)}"`);
return BbPromise.resolve();
}
createFunction() {
this.serverless.cli.log('Generating function…');
const functionName = this.options.function;
const handler = this.options.handler;
const serverlessYmlFilePath = path
.join(this.serverless.config.servicePath, 'serverless.yml');
const serverlessYmlFileContent = fse
.readFileSync(serverlessYmlFilePath).toString();
return this.serverless.yamlParser.parse(serverlessYmlFilePath)
.then((config) => {
const runtime = [config.provider.name, config.provider.runtime].join('-');
if (validFunctionRuntimes.indexOf(runtime) < 0) {
const errorMessage = [
`Provider / Runtime "${runtime}" is not supported.`,
` Supported runtimes are: ${humanReadableFunctionRuntimes}.`,
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
const ymlEditor = yamlEdit(serverlessYmlFileContent);
if (ymlEditor.hasKey(`functions.${functionName}`)) {
const errorMessage = [
`Function "${functionName}" already exists. Cannot create function.`,
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
const funcDoc = {};
funcDoc[functionName] = this.serverless.service.functions[functionName] = {
handler,
};
if (ymlEditor.insertChild('functions', funcDoc)) {
const errorMessage = [
`Could not find functions in ${serverlessYmlFilePath}`,
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
fse.writeFileSync(serverlessYmlFilePath, ymlEditor.dump());
if (runtime === 'aws-nodejs4.3') {
return this.createAWSNodeJSFuncFile(handler);
}
return BbPromise.resolve();
});
}
}
module.exports = mochaPlugin;
module.exports.lambdaWrapper = lambdaWrapper;
module.exports.chai = chai;
{
"name": "serverless-mocha-plugin",
"version": "1.0.3",
"version": "1.1.0",
"engines": {

@@ -35,4 +35,16 @@ "node": ">=4.0"

"devDependencies": {
"chai": "^3.2.0",
"eslint": "^3.3.1",
"eslint-config-airbnb": "^10.0.1",
"eslint-config-airbnb-base": "^5.0.2",
"eslint-plugin-import": "^1.13.0",
"eslint-plugin-jsx-a11y": "^2.1.0",
"eslint-plugin-react": "^6.1.1",
"mocha": "^2.2.5",
"serverless": "^1.1.0",
"sinon": "^1.17.6"
},
"dependencies": {
"aws-sdk": "^2.4.0",
"bluebird": "3.0.6",

@@ -43,4 +55,5 @@ "chai": "3.2.0",

"mocha": "2.2.5",
"aws-sdk": "^2.4.0"
"fs-extra": "^1.0.0",
"yaml-edit": "^0.1.3"
}
}

@@ -13,2 +13,3 @@ # Serverless Mocha Plugin

* It provides commands to create and run tests manually
* It provides a command to create a function, which automatically also creates a test

@@ -20,3 +21,3 @@ ## Installation

```bash
npm install --save-dev serverless-mocha-plugin@1.0
npm install --save-dev serverless-mocha-plugin
```

@@ -33,7 +34,22 @@

### Creating functions
Functions (and associated tests) can be created using the command
```
sls create function -f functionName --handler handler
```
e.g.
```
sls create function -f myFunction --handler functions/myFunction/index.handler
```
creates a new function `myFunction` into `serverless.yml` with a code template for
the handler in `functions/myFunction/index.js` and a Javascript function `module.exports.handler`
as the entrypoint for the Lambda function. A test template is also created into `test/myFunction.js`.
### Creating tests
When the plug-in is installed, tests are automatically created to the test/ directory
when creating new functions (only when using node 4.3 runtime).
Functions can also be added manually using the mocha-create command

@@ -81,17 +97,7 @@

## Release History
## Release History (1.x)
* 2016/11/09 - v1.1.0 - Added function create command.
* 2016/09/23 - v1.0.2 - Bugfixes, configurable test timeouts
* 2016/08/15 - v1.0.0 - Preliminary version for Serverless 1.0
* 2016/06/28 - v0.5.13 - Increase default test timeout to 6000ms
* 2016/06/27 - v0.5.12 - Add support for using template test files
* 2016/06/22 - v0.5.11 - Add support for running tests from live environment
* 2016/06/21 - v0.5.9 - Prompt for region / stage when running tests. Set environment separately for each test
* 2016/06/03 - v0.5.7 - Fix entangled function tests, Move wrapper.init into 'it' scope in generated mocha test code.
- Fix non-posix path separator in Windows.
- set environment variables correctly also when running all tests
* 2016/05/10 - v0.5.5 - Fix error message for mocha-create.
- Create tests with mocha-create without path in test name (as function create does)
* 2016/05/09 - v0.5.3 - Set environment variables during mocha-run (by AniKo)
- Add reporter options, return non-zero status for failures (by chouandy)
* 2016/04/09 - v0.5.0 - Initial version of module for serverless 0.5.*

@@ -98,0 +104,0 @@ ## License

'use strict';
const BbPromise = require('bluebird'),
path = require('path'),
fs = require('fs');
const BbPromise = require('bluebird');
const path = require('path');
const fs = require('fs');
const testFolder = 'test'; // Folder used my mocha for tests
const templateFilename = 'sls-mocha-plugin-template.ejs';
function getTestFilePath(funcName) {
return path.join(testFolder, `${funcName.replace(/.*\//g, '')}.js`);
}
// getTestFiles. If no functions provided, returns all files
function getTestFiles(funcs) {
return new BbPromise(function(resolve, reject) {
var funcNames = Object.keys(funcs);
return new BbPromise((resolve) => {
const funcNames = Object.keys(funcs);
const resFuncs = funcs;
if (funcNames && (funcNames.length > 0)) {
funcNames.forEach(function(val, idx) {
funcs[val].mochaPlugin = {
testPath: getTestFilePath(val)
funcNames.forEach((val) => {
resFuncs[val].mochaPlugin = {
testPath: getTestFilePath(val),
};
});
return resolve(funcs);
return resolve(resFuncs);
}

@@ -27,8 +32,8 @@ return resolve({});

function createTestFolder() {
return new BbPromise(function(resolve, reject) {
fs.exists(testFolder, function(exists) {
return new BbPromise((resolve, reject) => {
fs.exists(testFolder, (exists) => {
if (exists) {
return resolve(testFolder);
return resolve(testFolder);
}
fs.mkdir(testFolder, function(err) {
fs.mkdir(testFolder, (err) => {
if (err) {

@@ -38,4 +43,5 @@ return reject(err);

return resolve(testFolder);
})
})
});
return null;
});
});

@@ -48,8 +54,4 @@ }

function getTestFilePath(funcName) {
return path.join(testFolder, `${funcName.replace(/.*\//g, '')}.js`);
}
function funcNameFromPath(filePath) {
let data = path.parse(filePath);
const data = path.parse(filePath);

@@ -60,18 +62,21 @@ return data.name;

function setEnv(params) {
const myParams = params;
if (myParams) {
// Do the magic here
}
return null;
// Serverless does not seem to have any logic with regards to variables yet.
//let vars = Object.keys(params);
//vars.forEach((val, idx) => {
// process.env[val] = params[val];
//});
// let vars = Object.keys(params);
// vars.forEach((val, idx) => {
// process.env[val] = params[val];
// });
}
module.exports = {
getTestFilePath: getTestFilePath,
getTestFiles: getTestFiles,
createTestFolder: createTestFolder,
getTemplateFromFile: getTemplateFromFile,
funcNameFromPath: funcNameFromPath,
setEnv: setEnv
}
getTestFilePath,
getTestFiles,
createTestFolder,
getTemplateFromFile,
funcNameFromPath,
setEnv,
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc