From ad5e929941081b0e6d4eff5942f069cc2c319422 Mon Sep 17 00:00:00 2001 From: ac360 Date: Wed, 3 Feb 2016 20:31:47 -0800 Subject: [PATCH] Classes: fix all tests --- lib/ServerlessEndpoint.js | 9 +- lib/ServerlessFunction.js | 179 ++++++++++-------- lib/utils/index.js | 2 - tests/all.js | 8 +- .../nodejscomponent/function0/s-function.json | 4 +- .../tests/classes/ServerlessComponentTest.js | 4 +- tests/tests/classes/ServerlessEndpointTest.js | 8 +- tests/tests/classes/ServerlessFunctionTest.js | 14 +- tests/tests/classes/ServerlessProjectTest.js | 12 +- tests/tests/classes/ServerlessStateTest.js | 14 +- 10 files changed, 136 insertions(+), 118 deletions(-) diff --git a/lib/ServerlessEndpoint.js b/lib/ServerlessEndpoint.js index d64407823..1efea82d8 100644 --- a/lib/ServerlessEndpoint.js +++ b/lib/ServerlessEndpoint.js @@ -170,8 +170,7 @@ class ServerlessEndpoint { return _.merge( this.getProject().getTemplates(), this.getComponent().getTemplates(), - this.getFunction().getTemplates(), - _.cloneDeep(this.templates) + this.getFunction().getTemplates() ); } @@ -231,7 +230,7 @@ class ServerlessEndpoint { getComponent() { let components = this._S.state.getComponents({ - component: this._config.component + paths: [this._config.sPath.split('/')[0]] }); if (components.length === 1) { @@ -249,9 +248,7 @@ class ServerlessEndpoint { getFunction() { let functions = this._S.state.getFunctions({ - component: this._config.component, - cPath: this._config.cPath, - function: this._config.function + paths: [this._config.sPath.split('@')[0]] }); if (functions.length === 1) { diff --git a/lib/ServerlessFunction.js b/lib/ServerlessFunction.js index c65d16e53..52677fe2b 100644 --- a/lib/ServerlessFunction.js +++ b/lib/ServerlessFunction.js @@ -7,12 +7,12 @@ */ const SError = require('./ServerlessError'), - SUtils = require('./utils/index'), - BbPromise = require('bluebird'), - async = require('async'), - path = require('path'), - fs = require('fs'), - _ = require('lodash'); + SUtils = require('./utils/index'), + BbPromise = require('bluebird'), + async = require('async'), + path = require('path'), + fs = require('fs'), + _ = require('lodash'); class ServerlessFunction { @@ -33,8 +33,8 @@ class ServerlessFunction { // Default properties _this.name = _this._config.function || 'function' + SUtils.generateShortId(6); _this.handler = path.posix.join( - _this._config.sPath.split('/').splice(1, _this._config.sPath.split('/').length).join('/'), - 'handler.handler'); + _this._config.sPath.split('/').splice(1, _this._config.sPath.split('/').length).join('/'), + 'handler.handler'); _this.timeout = 6; _this.memorySize = 1024; _this.custom = { @@ -107,47 +107,72 @@ class ServerlessFunction { load() { let _this = this, - functionJson; + functionJson; return BbPromise.try(function() { - // Validate: Check project path is set - if (!_this._S.config.projectPath) throw new SError('Function could not be loaded because no project path has been set on Serverless instance'); + // Validate: Check project path is set + if (!_this._S.config.projectPath) throw new SError('Function could not be loaded because no project path has been set on Serverless instance'); - // Validate: Check function exists - if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) { - throw new SError('Function could not be loaded because it does not exist in your project: ' + _this._config.sPath); - } + // Validate: Check function exists + if (!SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-function.json'))) { + throw new SError('Function could not be loaded because it does not exist in your project: ' + _this._config.sPath); + } - functionJson = SUtils.readAndParseJsonSync(path.join(_this._config.fullPath, 's-function.json')); - return functionJson.endpoints; - }) - .each(function(e, i) { + functionJson = SUtils.readAndParseJsonSync(path.join(_this._config.fullPath, 's-function.json')); + return functionJson.endpoints; + }) + .each(function(e, i) { - // Add Endpoint Class Instances - functionJson.endpoints[i] = new _this._S.classes.Endpoint(_this._S, { - sPath: _this._config.sPath + '@' + e.path + '~' + e.method - }); - - return functionJson.endpoints[i].load() - .then(function(instance) { - functionJson.endpoints[i] = instance; - return functionJson.endpoints[i]; - }); - }) - .then(function() { - - // Get templates - if (_this._config.fullPath && SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-templates.json'))) { - functionJson.templates = require(path.join(_this._config.fullPath, 's-templates.json')); - } - }) - .then(function() { - - // Merge - _.assign(_this, functionJson); - return _this; + // Add Endpoint Class Instances + functionJson.endpoints[i] = new _this._S.classes.Endpoint(_this._S, { + sPath: _this._config.sPath + '@' + e.path + '~' + e.method }); + + return functionJson.endpoints[i].load() + .then(function(instance) { + functionJson.endpoints[i] = instance; + return functionJson.endpoints[i]; + }); + }) + .then(function() { + + // Get templates + if (_this._config.fullPath && SUtils.fileExistsSync(path.join(_this._config.fullPath, 's-templates.json'))) { + functionJson.templates = require(path.join(_this._config.fullPath, 's-templates.json')); + } + + // Get templates in parent folders and merge into this.templates + let parentOne = path.join(_this._config.fullPath, '..'), + parentTwo = path.join(_this._config.fullPath, '..', '..'), + parentTemplateOne = {}, + parentTemplateTwo = {}; + + if (!SUtils.fileExistsSync(path.join(parentOne, 's-component.json'))) { + if (SUtils.fileExistsSync(path.join(parentOne, 's-templates.json'))) { + parentTemplateOne = SUtils.readAndParseJsonSync(path.join(parentOne, 's-templates.json')); + } + + if (!SUtils.fileExistsSync(path.join(parentTwo, 's-component.json'))) { + if (SUtils.fileExistsSync(path.join(parentTwo, 's-templates.json'))) { + parentTemplateTwo = SUtils.readAndParseJsonSync(path.join(parentTwo, 's-templates.json')); + } + } + } + + // Merge + functionJson.templates = _.merge( + parentTemplateTwo, + parentTemplateOne, + functionJson.templates + ); + }) + .then(function() { + + // Merge + _.assign(_this, functionJson); + return _this; + }); } /** @@ -203,9 +228,9 @@ class ServerlessFunction { getTemplates() { return _.merge( - this.getProject().getTemplates(), - this.getComponent().getTemplates(), - _.cloneDeep(this.templates) + this.getProject().getTemplates(), + this.getComponent().getTemplates(), + _.cloneDeep(this.templates) ); } @@ -229,39 +254,39 @@ class ServerlessFunction { return _this._create(); } }) - .then(function() { + .then(function() { - // Save all nested endpoints - if (options && options.deep) { - return BbPromise.try(function () { - return _this.endpoints; - }) - .each(function(endpoint) { - return endpoint.save(); - }) - } - }) - .then(function() { + // Save all nested endpoints + if (options && options.deep) { + return BbPromise.try(function () { + return _this.endpoints; + }) + .each(function(endpoint) { + return endpoint.save(); + }) + } + }) + .then(function() { - // If templates, save templates - if (_this.templates && Object.keys(_this.templates).length) { - return SUtils.writeFile(path.join(_this._config.fullPath, 's-templates.json'), _this.templates); - } - }) - .then(function() { + // If templates, save templates + if (_this.templates && Object.keys(_this.templates).length) { + return SUtils.writeFile(path.join(_this._config.fullPath, 's-templates.json'), _this.templates); + } + }) + .then(function() { - let clone = _this.get(); + let clone = _this.get(); - // Strip properties - if (clone.templates) delete clone.templates; + // Strip properties + if (clone.templates) delete clone.templates; - // Write file - return SUtils.writeFile(path.join(_this._config.fullPath, 's-function.json'), - JSON.stringify(clone, null, 2)); - }) - .then(function() { - return _this; - }) + // Write file + return SUtils.writeFile(path.join(_this._config.fullPath, 's-function.json'), + JSON.stringify(clone, null, 2)); + }) + .then(function() { + return _this; + }) } /** @@ -279,16 +304,16 @@ class ServerlessFunction { // Runtime: nodejs writeDeferred.push( - fs.mkdirSync(_this._config.fullPath), - SUtils.writeFile(path.join(_this._config.fullPath, 'event.json'), '{}') + fs.mkdirSync(_this._config.fullPath), + SUtils.writeFile(path.join(_this._config.fullPath, 'event.json'), '{}') ); if (_this.getRuntime() === 'nodejs') { writeDeferred.push( - SUtils.writeFile(path.join(_this._config.fullPath, 'handler.js'), fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'nodejs', 'handler.js'))) + SUtils.writeFile(path.join(_this._config.fullPath, 'handler.js'), fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'nodejs', 'handler.js'))) ) } else if (_this.getRuntime() === 'python2.7') { writeDeferred.push( - SUtils.writeFile(path.join(_this._config.fullPath, 'handler.py'), fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'python2.7', 'handler.py'))) + SUtils.writeFile(path.join(_this._config.fullPath, 'handler.py'), fs.readFileSync(path.join(_this._S.config.serverlessPath, 'templates', 'python2.7', 'handler.py'))) ) } return BbPromise.all(writeDeferred); diff --git a/lib/utils/index.js b/lib/utils/index.js index 3999646b8..3b507f3a1 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -616,11 +616,9 @@ exports.populate = function(meta, templates, data, stage, region) { // Sanitize: Remove nested properties. DO NOT populate these. Rely on calling those classes getPopulated methods instead. if (data.components) delete data.components; - if (data.modules) delete data.modules; if (data.functions) delete data.functions; if (data.endpoints) delete data.endpoints; - // Populate templates traverse(data).forEach(function (val) { diff --git a/tests/all.js b/tests/all.js index bed6fffd9..b5774d0db 100644 --- a/tests/all.js +++ b/tests/all.js @@ -11,10 +11,10 @@ describe('All Tests', function() { after(function() {}); require('./tests/classes/ServerlessStateTest'); - //require('./tests/classes/ServerlessProjectTest'); - //require('./tests/classes/ServerlessComponentTest'); - //require('./tests/classes/ServerlessFunctionTest'); - //require('./tests/classes/ServerlessEndpointTest'); + require('./tests/classes/ServerlessProjectTest'); + require('./tests/classes/ServerlessComponentTest'); + require('./tests/classes/ServerlessFunctionTest'); + require('./tests/classes/ServerlessEndpointTest'); //require('./tests/actions/TestPluginCustom'); //require('./tests/actions/TestDefaultActionHook'); //require('./tests/actions/StageCreate'); diff --git a/tests/test-prj/nodejscomponent/function0/s-function.json b/tests/test-prj/nodejscomponent/function0/s-function.json index 45d738187..4ac0e5b7b 100644 --- a/tests/test-prj/nodejscomponent/function0/s-function.json +++ b/tests/test-prj/nodejscomponent/function0/s-function.json @@ -14,8 +14,8 @@ "method": "GET", "authorizationType": "${endpointVariable}", "apiKeyRequired": false, - "requestParameters": "$${endpointTemplate}", - "requestTemplates": "$${apiRequestTemplate}", + "requestParameters": {}, + "requestTemplates": {}, "responses": { "default": { "statusCode": "200", diff --git a/tests/tests/classes/ServerlessComponentTest.js b/tests/tests/classes/ServerlessComponentTest.js index 8083bc1e4..310dfba31 100644 --- a/tests/tests/classes/ServerlessComponentTest.js +++ b/tests/tests/classes/ServerlessComponentTest.js @@ -35,7 +35,7 @@ describe('Test Serverless Component Class', function() { // Instantiate Class instance = new serverless.classes.Component(serverless, { - component: 'nodejscomponent' + sPath: 'nodejscomponent' }); done(); @@ -92,7 +92,7 @@ describe('Test Serverless Component Class', function() { it('Create new and save', function(done) { let component = new serverless.classes.Component(serverless, { - component: 'nodejscomponent' + sPath: 'nodejscomponent' }); component.save() diff --git a/tests/tests/classes/ServerlessEndpointTest.js b/tests/tests/classes/ServerlessEndpointTest.js index 79739cd08..a1f3e0052 100644 --- a/tests/tests/classes/ServerlessEndpointTest.js +++ b/tests/tests/classes/ServerlessEndpointTest.js @@ -116,7 +116,13 @@ describe('Test Serverless Endpoint Class', function() { it('Get function', function() { let func = instance.getFunction(); assert.instanceOf(func, serverless.classes.Function); - assert.equal(func.name, instance._config.function); + assert.equal(true, instance._config.sPath.indexOf(func._config.sPath) !== -1) + }); + + it('Get component', function() { + let comp = instance.getComponent(); + assert.instanceOf(comp, serverless.classes.Component); + assert.equal(true, instance._config.sPath.indexOf(comp._config.sPath) !== -1) }); }); }); diff --git a/tests/tests/classes/ServerlessFunctionTest.js b/tests/tests/classes/ServerlessFunctionTest.js index f0ce3862e..e13a2863e 100644 --- a/tests/tests/classes/ServerlessFunctionTest.js +++ b/tests/tests/classes/ServerlessFunctionTest.js @@ -34,9 +34,7 @@ describe('Test Serverless Function Class', function() { // Instantiate Class instance = new serverless.classes.Function(serverless, { - component: 'nodejscomponent', - module: 'group1', - function: 'function1' + sPath: 'nodejscomponent/group1/function1' }); done(); @@ -93,9 +91,7 @@ describe('Test Serverless Function Class', function() { it('Create new and save', function(done) { let func = new serverless.classes.Function(serverless, { - component: 'nodejscomponent', - module: 'group1', - function: 'function4' + sPath: 'nodejscomponent/group1/function1' }); func.save() @@ -109,11 +105,5 @@ describe('Test Serverless Function Class', function() { done(e); }); }); - - it('Get module', function() { - let module = instance.getModule(); - assert.instanceOf(module, serverless.classes.Module); - assert.equal(module.name, instance._config.module); - }); }); }); diff --git a/tests/tests/classes/ServerlessProjectTest.js b/tests/tests/classes/ServerlessProjectTest.js index 0f8bf31d6..09ea8785e 100644 --- a/tests/tests/classes/ServerlessProjectTest.js +++ b/tests/tests/classes/ServerlessProjectTest.js @@ -70,21 +70,21 @@ describe('Test Serverless Project Class', function() { // We've set a template in the project that gets extended at the module level and function level, check it: // Project template - assert.equal(true, typeof data.components.nodejscomponent.modules.module1.functions.function1.endpoints[0].requestTemplates['application/json'].httpMethod !== 'undefined'); + assert.equal(true, typeof data.components.nodejscomponent.functions['nodejscomponent/group1/function1'].endpoints[0].requestTemplates['application/json'].httpMethod !== 'undefined'); // Component template - assert.equal(true, typeof data.components.nodejscomponent.modules.module1.functions.function1.endpoints[0].requestTemplates['application/json'].headerParams !== 'undefined'); + assert.equal(true, typeof data.components.nodejscomponent.functions['nodejscomponent/group1/function1'].endpoints[0].requestTemplates['application/json'].headerParams !== 'undefined'); // Module template - assert.equal(true, typeof data.components.nodejscomponent.modules.module1.functions.function1.endpoints[0].requestTemplates['application/json'].queryParams !== 'undefined'); + assert.equal(true, typeof data.components.nodejscomponent.functions['nodejscomponent/group1/function1'].endpoints[0].requestTemplates['application/json'].queryParams !== 'undefined'); // Test subjective template inheritance // These functions have their own s-templates.json files which give them the same template, with one different property // Function1 template - assert.equal(true, data.components.nodejscomponent.modules.module1.functions.function1.endpoints[0].requestTemplates['application/json'].pathParams === "$input.path('$.id1')"); + assert.equal(true, data.components.nodejscomponent.functions['nodejscomponent/group1/function1'].endpoints[0].requestTemplates['application/json'].pathParams === "$input.path('$.id1')"); // Function2 template - assert.equal(true, data.components.nodejscomponent.modules.module1.functions.function2.endpoints[0].requestTemplates['application/json'].pathParams === "$input.path('$.id2')"); + assert.equal(true, data.components.nodejscomponent.functions['nodejscomponent/group1/function2'].endpoints[0].requestTemplates['application/json'].pathParams === "$input.path('$.id2')"); // Function3 template - s-templates.json left undefined - assert.equal(true, typeof data.components.nodejscomponent.modules.module1.functions.function3.endpoints[0].requestTemplates['application/json'].pathParams === 'undefined'); + assert.equal(true, typeof data.components.nodejscomponent.functions['nodejscomponent/group1/function3'].endpoints[0].requestTemplates['application/json'].pathParams === 'undefined'); done(); }); diff --git a/tests/tests/classes/ServerlessStateTest.js b/tests/tests/classes/ServerlessStateTest.js index 8b06b58eb..e59d94143 100644 --- a/tests/tests/classes/ServerlessStateTest.js +++ b/tests/tests/classes/ServerlessStateTest.js @@ -105,12 +105,14 @@ describe('Test Serverless State Class', function() { done(); }); - //it('Get resources (populated)', function(done) { - // let resources = instance.getResources({ populate: true, stage: config.stage, region: config.region }); - // assert.equal(true, JSON.stringify(resources).indexOf('$${') == -1); - // assert.equal(true, JSON.stringify(resources).indexOf('${') == -1); - // done(); - //}); + it('Get resources (populated)', function(done) { + let resources = instance.getResources({ + populate: true, stage: config.stage, region: config.region + }); + assert.equal(true, JSON.stringify(resources).indexOf('$${') == -1); + assert.equal(true, JSON.stringify(resources).indexOf('${') == -1); + done(); + }); it('Get stages', function(done) { let stages = instance.getStages();