From b56da0ad3ea8835d56d023888f2ff491f8fa6ecb Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Mon, 9 Jan 2017 15:10:32 +0000 Subject: [PATCH 01/43] init webpack bundler --- package.json | 4 +- .../package-server-script/bundle/index.js | 54 +++++++++++++++++++ src/cli/domain/package-server-script/index.js | 42 +++------------ 3 files changed, 65 insertions(+), 35 deletions(-) create mode 100644 src/cli/domain/package-server-script/bundle/index.js diff --git a/package.json b/package.json index d38352e16..8b7598490 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "fs-extra": "0.30.0", "handlebars": "4.0.5", "jade": "1.11.0", + "memory-fs": "^0.4.1", "minimal-request": "2.2.0", "multer": "0.1.4", "nice-cache": "0.0.5", @@ -78,6 +79,7 @@ "targz": "1.0.1", "uglify-js": "2.6.4", "underscore": "1.8.3", - "watch": "0.19.1" + "watch": "0.19.1", + "webpack": "^2.2.0-rc.3" } } diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js new file mode 100644 index 000000000..f21010440 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -0,0 +1,54 @@ +var console = require('console'); +var webpack = require("webpack"); +var path = require('path'); +var MemoryFS = require('memory-fs'); + +var memoryFs = new MemoryFS(); + +function bundle(serverContent, fileName, callBack) { + memoryFs.writeFileSync(path.join('/', fileName), serverContent); + + var webpackConfig = { + entry: path.join('/', fileName), + output: { + path: "/build", + filename: fileName + } + }; + + var compiler = webpack(webpackConfig); + + compiler.inputFileSystem = memoryFs; + compiler.resolvers.normal.fileSystem = compiler.inputFileSystem; + compiler.resolvers.context.fileSystem = compiler.inputFileSystem; + compiler.outputFileSystem = memoryFs; + + compiler.run(function(err, stats){ + if (err) { + console.error(err.stack || err); + if (err.details) { + console.error(err.details); + } + return; + } + + var info = stats.toJson(); + + if (stats.hasErrors()) { + console.error(info.errors); + } + if (stats.hasWarnings()) { + console.warn(info.warnings) + } + + console.log(stats.toString({ + chunks: false, + colors: true + })); + + var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); + callBack(serverContentBundled); + }); +} + +module.exports = bundle diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index 4b474fc72..c11876c06 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -1,48 +1,22 @@ 'use strict'; -var format = require('stringformat'); var fs = require('fs-extra'); var path = require('path'); - -var CONST_MAX_ITERATIONS = require('../../../resources/settings').maxLoopIterations; var hashBuilder = require('../../../utils/hash-builder'); -var strings = require('../../../resources'); - -var getSandBoxedJs = require('./getSandBoxedJs'); -var getLocalDependencies = require('./getLocalDependencies')(fs, path); -var missingDependencies = require('./missingDependencies'); - +var bundle = require('./bundle'); module.exports = function(params, callback){ var dataPath = path.join(params.componentPath, params.ocOptions.files.data); var fileName = 'server.js'; - var wrappedRequires; - var sandboxedJs; var serverContent = fs.readFileSync(dataPath).toString(); - try { - wrappedRequires = getLocalDependencies(params.componentPath, serverContent, params.ocOptions.files.data); - } catch(e){ - return callback(e); - } - - var missingDeps = missingDependencies(wrappedRequires.modules, params.dependencies); - - if(missingDeps.length > 0){ - return callback(new Error(format(strings.errors.cli.SERVERJS_DEPENDENCY_NOT_DECLARED, JSON.stringify(missingDeps)))); - } - - try { - sandboxedJs = getSandBoxedJs(wrappedRequires.files, serverContent, params.ocOptions.files.data, CONST_MAX_ITERATIONS); - } catch(e){ - return callback(e); - } - - fs.writeFile(path.join(params.publishPath, fileName), sandboxedJs, function(err, res){ - callback(err, { - type: 'node.js', - hashKey: hashBuilder.fromString(sandboxedJs), - src: fileName + bundle(serverContent, fileName, function(bundledServer){ + fs.writeFile(path.join(params.publishPath, fileName), bundledServer, function(err, res){ + callback(err, { + type: 'node.js', + hashKey: hashBuilder.fromString(bundledServer), + src: fileName + }); }); }); }; From f39644bda5df3354b816b844e685aafe8c9623b7 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Mon, 9 Jan 2017 16:07:19 +0000 Subject: [PATCH 02/43] memory-fs only for compiler.outputFileSystem --- src/cli/domain/package-server-script/bundle/index.js | 12 ++++++------ src/cli/domain/package-server-script/index.js | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index f21010440..7a8c390c1 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -5,11 +5,11 @@ var MemoryFS = require('memory-fs'); var memoryFs = new MemoryFS(); -function bundle(serverContent, fileName, callBack) { - memoryFs.writeFileSync(path.join('/', fileName), serverContent); +function bundle(dataPath, fileName, callBack) { + // memoryFs.writeFileSync(path.join('/', fileName), serverContent); var webpackConfig = { - entry: path.join('/', fileName), + entry: dataPath, output: { path: "/build", filename: fileName @@ -18,9 +18,9 @@ function bundle(serverContent, fileName, callBack) { var compiler = webpack(webpackConfig); - compiler.inputFileSystem = memoryFs; - compiler.resolvers.normal.fileSystem = compiler.inputFileSystem; - compiler.resolvers.context.fileSystem = compiler.inputFileSystem; + // compiler.inputFileSystem = memoryFs; + // compiler.resolvers.normal.fileSystem = compiler.inputFileSystem; + // compiler.resolvers.context.fileSystem = compiler.inputFileSystem; compiler.outputFileSystem = memoryFs; compiler.run(function(err, stats){ diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index c11876c06..88a39de6c 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -8,9 +8,9 @@ var bundle = require('./bundle'); module.exports = function(params, callback){ var dataPath = path.join(params.componentPath, params.ocOptions.files.data); var fileName = 'server.js'; - var serverContent = fs.readFileSync(dataPath).toString(); + // var serverContent = fs.readFileSync(dataPath).toString(); - bundle(serverContent, fileName, function(bundledServer){ + bundle(dataPath, fileName, function(bundledServer){ fs.writeFile(path.join(params.publishPath, fileName), bundledServer, function(err, res){ callback(err, { type: 'node.js', From d7be7b5bd70c020e6241efde1af64335859bf116 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 10:28:04 +0000 Subject: [PATCH 03/43] initial test --- package.json | 1 + test/unit/cli-domain-package-server-script.js | 288 -------------- .../cli-domain-package-server-script.js | 355 ++++++++++++++++++ 3 files changed, 356 insertions(+), 288 deletions(-) delete mode 100644 test/unit/cli-domain-package-server-script.js create mode 100644 test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js diff --git a/package.json b/package.json index 8b7598490..34233bc80 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "load-grunt-tasks": "^3.5.2", "mocha": "^3.0.2", "phantomjs-prebuilt": "^2.1.12", + "rimraf": "^2.5.4", "semver-sort": "0.0.4", "sinon": "^1.17.5" }, diff --git a/test/unit/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script.js deleted file mode 100644 index fc366859a..000000000 --- a/test/unit/cli-domain-package-server-script.js +++ /dev/null @@ -1,288 +0,0 @@ -'use strict'; - -var expect = require('chai').expect; -var injectr = require('injectr'); -var path = require('path'); -var sinon = require('sinon'); -var uglifyJs = require('uglify-js'); -var _ = require('underscore'); - -var fsMock, - packageServerScript; - -var initialise = function(fs){ - - fsMock = _.extend({ - existsSync: sinon.stub().returns(true), - readFileSync: sinon.stub().returns('file content'), - readJsonSync: sinon.stub().returns({ content: true }), - writeFile: sinon.stub().yields(null, 'ok') - }, fs || {}); - - packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { - 'fs-extra': fsMock, - path: { - extname: path.extname, - join: path.join, - resolve: function(){ - return _.toArray(arguments).join('/'); - } - } - }); -}; - -describe('cli : domain : package-server-script', function(){ - - describe('when packaging component\'s server.js', function(){ - - describe('when component implements not-valid javascript', function(){ - - var error, - serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'myserver.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should throw an error with error details', function(){ - expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); - }); - }); - - describe('when component does not require any json', function(){ - - var result, - serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - result = r; - done(); - }); - }); - - it('should save compiled data provider', function(){ - expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); - }); - - it('should return hash for script', function(){ - expect(result.hashKey).not.be.empty; - }); - }); - - describe('when component requires a json', function(){ - - var requiredJson = { hello: 'world' }, - serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; - - beforeEach(function(done){ - - initialise({ - readFileSync: sinon.stub().returns(serverjs), - readJsonSync: sinon.stub().returns(requiredJson) - }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, done); - }); - - it('should save compiled and minified data provider encapsulating json content', function(){ - var written = fsMock.writeFile.args[0][1]; - - expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' - + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' - + 'module.exports.data=function(e,r){return r(null,{})};'); - }); - }); - - describe('when component requires an npm module', function(){ - - var error, - serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should throw an error when the dependency is not present in the package.json', function(){ - expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); - }); - }); - - describe('when component requires a relative path from an npm module', function(){ - - var error, - serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should throw an error when the dependency is not present in the package.json', function(){ - expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); - }); - }); - - describe('when component requires a js file', function(){ - - var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', - error; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should not package component and respond with error', function(){ - expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); - }); - }); - - describe('when component requires a file without extension that is not found as json', function(){ - - var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', - error; - - beforeEach(function(done){ - - initialise({ - readFileSync: sinon.stub().returns(serverjs), - existsSync: sinon.stub().returns(false) - }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should not package component and respond with error', function(){ - expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); - }); - }); - - describe('when component code includes a loop', function(){ - - var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' - + 'while(true){ x = 234; } ' - + 'for(var i=1e12;;){ y = 546; }' - + 'do { z = 342; } while(true);' - + 'return cb(null,data); };', - result; - - beforeEach(function(done){ - - initialise({ - readFileSync: sinon.stub().returns(serverjs), - existsSync: sinon.stub().returns(false) - }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - result = r; - done(); - }); - }); - - it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ - expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); - }); - - it('should wrap the for loop with an iterator limit', function(){ - expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); - }); - - it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ - expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); - }); - }); - }); -}); diff --git a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js new file mode 100644 index 000000000..39577f7cc --- /dev/null +++ b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -0,0 +1,355 @@ +'use strict'; + +var expect = require('chai').expect; +var rimraf = require('rimraf'); +var fs = require('fs'); +var path = require('path'); +var packageServerScript = require('../../../src/cli/domain/package-server-script/index.js'); +var hashBuilder = require('../../../src/utils/hash-builder'); + +var serverName = 'server.js'; +var componentName = 'component'; +var componentPath = path.resolve(__dirname, componentName); + +describe('cli : domain : package-server-script', function(){ + beforeEach(function(done){ + if(!fs.existsSync(componentPath)) { + fs.mkdirSync(componentPath) + fs.mkdirSync(path.resolve(componentPath, '_package')) + } + done(); + }); + + afterEach(function(done){ + if(fs.existsSync(componentPath)) { + rimraf.sync(componentPath); + } + done(); + }); + + describe('when packaging component\'s server.js', function(){ + describe('when component does not require any json', function(){ + var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + done(); + }); + + it('should save compiled data provider', function(done){ + var publishPath = path.resolve(componentPath, '_package'); + + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath + }, + function(err, res){ + if (err) throw err + expect(res.type).to.equal('node.js') + expect(res.src).to.equal('server.js') + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}) + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)) + done(); + } + ) + }) + }) + }); +}) + + +// OLD SPEC +// ====================================== + +// var expect = require('chai').expect; +// var injectr = require('injectr'); +// var path = require('path'); +// var sinon = require('sinon'); +// var uglifyJs = require('uglify-js'); +// var _ = require('underscore'); + +// var fsMock, +// packageServerScript; + +// var initialise = function(fs){ + +// fsMock = _.extend({ +// existsSync: sinon.stub().returns(true), +// readFileSync: sinon.stub().returns('file content'), +// readJsonSync: sinon.stub().returns({ content: true }), +// writeFile: sinon.stub().yields(null, 'ok') +// }, fs || {}); + +// packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { +// 'fs-extra': fsMock, +// path: { +// extname: path.extname, +// join: path.join, +// resolve: function(){ +// return _.toArray(arguments).join('/'); +// } +// } +// }); +// }; + +// describe.skip('cli : domain : package-server-script', function(){ + +// describe('when packaging component\'s server.js', function(){ + +// describe('when component implements not-valid javascript', function(){ + +// var error; +// var serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'myserver.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should throw an error with error details', function(){ +// expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); +// }); +// }); + +// describe('when component does not require any json', function(){ + +// var result, +// serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// result = r; +// done(); +// }); +// }); + +// it('should save compiled data provider', function(){ +// expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); +// }); + +// it('should return hash for script', function(){ +// expect(result.hashKey).not.be.empty; +// }); +// }); + +// describe('when component requires a json', function(){ + +// var requiredJson = { hello: 'world' }, +// serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// readJsonSync: sinon.stub().returns(requiredJson) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, done); +// }); + +// it('should save compiled and minified data provider encapsulating json content', function(){ +// var written = fsMock.writeFile.args[0][1]; + +// expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' +// + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' +// + 'module.exports.data=function(e,r){return r(null,{})};'); +// }); +// }); + +// describe('when component requires an npm module', function(){ + +// var error, +// serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should throw an error when the dependency is not present in the package.json', function(){ +// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); +// }); +// }); + +// describe('when component requires a relative path from an npm module', function(){ + +// var error, +// serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should throw an error when the dependency is not present in the package.json', function(){ +// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); +// }); +// }); + +// describe('when component requires a js file', function(){ + +// var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', +// error; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should not package component and respond with error', function(){ +// expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); +// }); +// }); + +// describe('when component requires a file without extension that is not found as json', function(){ + +// var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', +// error; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// existsSync: sinon.stub().returns(false) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should not package component and respond with error', function(){ +// expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); +// }); +// }); + +// describe('when component code includes a loop', function(){ + +// var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' +// + 'while(true){ x = 234; } ' +// + 'for(var i=1e12;;){ y = 546; }' +// + 'do { z = 342; } while(true);' +// + 'return cb(null,data); };', +// result; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// existsSync: sinon.stub().returns(false) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// result = r; +// done(); +// }); +// }); + +// it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); +// }); + +// it('should wrap the for loop with an iterator limit', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); +// }); + +// it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); +// }); +// }); +// }); +// }); From 7faf403b3b55e26776be797ffa9386db6c93d247 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 11:06:13 +0000 Subject: [PATCH 04/43] passing down compiler errors --- .../package-server-script/bundle/index.js | 9 +++------ src/cli/domain/package-server-script/index.js | 18 +++++++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 7a8c390c1..c76af63ab 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -6,7 +6,6 @@ var MemoryFS = require('memory-fs'); var memoryFs = new MemoryFS(); function bundle(dataPath, fileName, callBack) { - // memoryFs.writeFileSync(path.join('/', fileName), serverContent); var webpackConfig = { entry: dataPath, @@ -17,13 +16,10 @@ function bundle(dataPath, fileName, callBack) { }; var compiler = webpack(webpackConfig); - - // compiler.inputFileSystem = memoryFs; - // compiler.resolvers.normal.fileSystem = compiler.inputFileSystem; - // compiler.resolvers.context.fileSystem = compiler.inputFileSystem; compiler.outputFileSystem = memoryFs; compiler.run(function(err, stats){ + var error = err; if (err) { console.error(err.stack || err); if (err.details) { @@ -35,6 +31,7 @@ function bundle(dataPath, fileName, callBack) { var info = stats.toJson(); if (stats.hasErrors()) { + error = info.errors; console.error(info.errors); } if (stats.hasWarnings()) { @@ -47,7 +44,7 @@ function bundle(dataPath, fileName, callBack) { })); var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); - callBack(serverContentBundled); + callBack(error, serverContentBundled); }); } diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index 88a39de6c..e67617b8d 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -10,13 +10,17 @@ module.exports = function(params, callback){ var fileName = 'server.js'; // var serverContent = fs.readFileSync(dataPath).toString(); - bundle(dataPath, fileName, function(bundledServer){ - fs.writeFile(path.join(params.publishPath, fileName), bundledServer, function(err, res){ - callback(err, { - type: 'node.js', - hashKey: hashBuilder.fromString(bundledServer), - src: fileName + bundle(dataPath, fileName, function(err, bundledServer){ + if (err) { + callback(err) + } else { + fs.writeFile(path.join(params.publishPath, fileName), bundledServer, function(err, res){ + callback(err, { + type: 'node.js', + hashKey: hashBuilder.fromString(bundledServer), + src: fileName + }); }); - }); + } }); }; From 8ffe4cfb6045503b67ec0ecef117dab7fb99c08f Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 11:06:57 +0000 Subject: [PATCH 05/43] testing compiler errors --- .../cli-domain-package-server-script.js | 37 +++++++-- .../component/_package/server.js | 76 +++++++++++++++++++ .../component/server.js | 3 + 3 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 test/unit/cli-domain-package-server-script/component/_package/server.js create mode 100644 test/unit/cli-domain-package-server-script/component/server.js diff --git a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js index 39577f7cc..9e8f99eb7 100644 --- a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -10,6 +10,7 @@ var hashBuilder = require('../../../src/utils/hash-builder'); var serverName = 'server.js'; var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); +var publishPath = path.resolve(componentPath, '_package'); describe('cli : domain : package-server-script', function(){ beforeEach(function(done){ @@ -22,7 +23,7 @@ describe('cli : domain : package-server-script', function(){ afterEach(function(done){ if(fs.existsSync(componentPath)) { - rimraf.sync(componentPath); + // rimraf.sync(componentPath); } done(); }); @@ -37,8 +38,6 @@ describe('cli : domain : package-server-script', function(){ }); it('should save compiled data provider', function(done){ - var publishPath = path.resolve(componentPath, '_package'); - packageServerScript( { componentPath: componentPath, @@ -58,8 +57,36 @@ describe('cli : domain : package-server-script', function(){ done(); } ) - }) - }) + }); + }); + + describe.only('when component implements not-valid javascript', function(){ + var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + done(); + }); + + it('should throw an error with error details', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath + }, + function(err, res){ + expect(err.toString().match(/Unexpected token \(3:19\)/)).to.be.ok; + done(); + } + ) + }); + }); + }); }) diff --git a/test/unit/cli-domain-package-server-script/component/_package/server.js b/test/unit/cli-domain-package-server-script/component/_package/server.js new file mode 100644 index 000000000..87768eb79 --- /dev/null +++ b/test/unit/cli-domain-package-server-script/component/_package/server.js @@ -0,0 +1,76 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports) { + +throw new Error("Module parse failed: /Users/nbalestra/dev/oc/test/unit/cli-domain-package-server-script/component/server.js Unexpected token (3:19)\nYou may need an appropriate loader to handle this file type.\n| var data=require('request');\n| module.exports.data=function(context,cb){\n| return cb(null,data; };"); + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/test/unit/cli-domain-package-server-script/component/server.js b/test/unit/cli-domain-package-server-script/component/server.js new file mode 100644 index 000000000..6e2a2e2c3 --- /dev/null +++ b/test/unit/cli-domain-package-server-script/component/server.js @@ -0,0 +1,3 @@ +var data=require('request'); +module.exports.data=function(context,cb){ +return cb(null,data; }; \ No newline at end of file From de55e7860c85186ebb589bb5e1ee529a3ad7ea14 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 11:25:47 +0000 Subject: [PATCH 06/43] moved integration test to /integration --- .../cli-domain-package-server-script.js | 3 +- .../component/_package/server.js | 2 +- .../component/server.js | 0 test/unit/cli-domain-package-server-script.js | 287 ++++++++++++++++++ 4 files changed, 290 insertions(+), 2 deletions(-) rename test/{unit => integration}/cli-domain-package-server-script/cli-domain-package-server-script.js (99%) rename test/{unit => integration}/cli-domain-package-server-script/component/_package/server.js (88%) rename test/{unit => integration}/cli-domain-package-server-script/component/server.js (100%) create mode 100644 test/unit/cli-domain-package-server-script.js diff --git a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js similarity index 99% rename from test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js rename to test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 9e8f99eb7..da5a32ff2 100644 --- a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -60,7 +60,7 @@ describe('cli : domain : package-server-script', function(){ }); }); - describe.only('when component implements not-valid javascript', function(){ + describe('when component implements not-valid javascript', function(){ var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; beforeEach(function(done){ @@ -87,6 +87,7 @@ describe('cli : domain : package-server-script', function(){ }); }); + }); }) diff --git a/test/unit/cli-domain-package-server-script/component/_package/server.js b/test/integration/cli-domain-package-server-script/component/_package/server.js similarity index 88% rename from test/unit/cli-domain-package-server-script/component/_package/server.js rename to test/integration/cli-domain-package-server-script/component/_package/server.js index 87768eb79..b4408d782 100644 --- a/test/unit/cli-domain-package-server-script/component/_package/server.js +++ b/test/integration/cli-domain-package-server-script/component/_package/server.js @@ -70,7 +70,7 @@ /* 0 */ /***/ function(module, exports) { -throw new Error("Module parse failed: /Users/nbalestra/dev/oc/test/unit/cli-domain-package-server-script/component/server.js Unexpected token (3:19)\nYou may need an appropriate loader to handle this file type.\n| var data=require('request');\n| module.exports.data=function(context,cb){\n| return cb(null,data; };"); +module.exports.data=function(context,cb){return cb(null, {name:'John'}); }; /***/ } /******/ ]); \ No newline at end of file diff --git a/test/unit/cli-domain-package-server-script/component/server.js b/test/integration/cli-domain-package-server-script/component/server.js similarity index 100% rename from test/unit/cli-domain-package-server-script/component/server.js rename to test/integration/cli-domain-package-server-script/component/server.js diff --git a/test/unit/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script.js new file mode 100644 index 000000000..6b47282c4 --- /dev/null +++ b/test/unit/cli-domain-package-server-script.js @@ -0,0 +1,287 @@ +var expect = require('chai').expect; +var injectr = require('injectr'); +var path = require('path'); +var sinon = require('sinon'); +var uglifyJs = require('uglify-js'); +var _ = require('underscore'); + +var fsMock, + packageServerScript; + +var initialise = function(fs){ + + fsMock = _.extend({ + existsSync: sinon.stub().returns(true), + readFileSync: sinon.stub().returns('file content'), + readJsonSync: sinon.stub().returns({ content: true }), + writeFile: sinon.stub().yields(null, 'ok') + }, fs || {}); + + packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { + 'fs-extra': fsMock, + path: { + extname: path.extname, + join: path.join, + resolve: function(){ + return _.toArray(arguments).join('/'); + } + } + }); +}; + +// SKIPPED FOR NOW, NEED TO BE FIXED +describe.skip('cli : domain : package-server-script', function(){ + + describe('when packaging component\'s server.js', function(){ + + describe('when component implements not-valid javascript', function(){ + + var error; + var serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; + + beforeEach(function(done){ + + initialise({ readFileSync: sinon.stub().returns(serverjs) }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'myserver.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + error = e; + done(); + }); + }); + + it('should throw an error with error details', function(){ + expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); + }); + }); + + describe('when component does not require any json', function(){ + + var result, + serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; + + beforeEach(function(done){ + + initialise({ readFileSync: sinon.stub().returns(serverjs) }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + result = r; + done(); + }); + }); + + it('should save compiled data provider', function(){ + expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); + }); + + it('should return hash for script', function(){ + expect(result.hashKey).not.be.empty; + }); + }); + + describe('when component requires a json', function(){ + + var requiredJson = { hello: 'world' }, + serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; + + beforeEach(function(done){ + + initialise({ + readFileSync: sinon.stub().returns(serverjs), + readJsonSync: sinon.stub().returns(requiredJson) + }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, done); + }); + + it('should save compiled and minified data provider encapsulating json content', function(){ + var written = fsMock.writeFile.args[0][1]; + + expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' + + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' + + 'module.exports.data=function(e,r){return r(null,{})};'); + }); + }); + + describe('when component requires an npm module', function(){ + + var error, + serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; + + beforeEach(function(done){ + + initialise({ readFileSync: sinon.stub().returns(serverjs) }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + error = e; + done(); + }); + }); + + it('should throw an error when the dependency is not present in the package.json', function(){ + expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); + }); + }); + + describe('when component requires a relative path from an npm module', function(){ + + var error, + serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; + + beforeEach(function(done){ + + initialise({ readFileSync: sinon.stub().returns(serverjs) }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + error = e; + done(); + }); + }); + + it('should throw an error when the dependency is not present in the package.json', function(){ + expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); + }); + }); + + describe('when component requires a js file', function(){ + + var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', + error; + + beforeEach(function(done){ + + initialise({ readFileSync: sinon.stub().returns(serverjs) }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + error = e; + done(); + }); + }); + + it('should not package component and respond with error', function(){ + expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); + }); + }); + + describe('when component requires a file without extension that is not found as json', function(){ + + var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', + error; + + beforeEach(function(done){ + + initialise({ + readFileSync: sinon.stub().returns(serverjs), + existsSync: sinon.stub().returns(false) + }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + error = e; + done(); + }); + }); + + it('should not package component and respond with error', function(){ + expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); + }); + }); + + describe('when component code includes a loop', function(){ + + var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' + + 'while(true){ x = 234; } ' + + 'for(var i=1e12;;){ y = 546; }' + + 'do { z = 342; } while(true);' + + 'return cb(null,data); };', + result; + + beforeEach(function(done){ + + initialise({ + readFileSync: sinon.stub().returns(serverjs), + existsSync: sinon.stub().returns(false) + }); + + packageServerScript({ + componentPath: '/path/to/component/', + ocOptions: { + files: { + data: 'server.js' + } + }, + publishPath: '/path/to/component/_package/' + }, function(e, r){ + result = r; + done(); + }); + }); + + it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ + expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); + }); + + it('should wrap the for loop with an iterator limit', function(){ + expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); + }); + + it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ + expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); + }); + }); + }); +}); From abb5f830df8670ec80586c6485eda75a04544810 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 13:45:42 +0000 Subject: [PATCH 07/43] drop rimraf -> fs-extra --- package.json | 1 - .../cli-domain-package-server-script.js | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 34233bc80..8b7598490 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "load-grunt-tasks": "^3.5.2", "mocha": "^3.0.2", "phantomjs-prebuilt": "^2.1.12", - "rimraf": "^2.5.4", "semver-sort": "0.0.4", "sinon": "^1.17.5" }, diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index da5a32ff2..85275631e 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -1,8 +1,7 @@ 'use strict'; var expect = require('chai').expect; -var rimraf = require('rimraf'); -var fs = require('fs'); +var fs = require('fs-extra'); var path = require('path'); var packageServerScript = require('../../../src/cli/domain/package-server-script/index.js'); var hashBuilder = require('../../../src/utils/hash-builder'); @@ -23,7 +22,7 @@ describe('cli : domain : package-server-script', function(){ afterEach(function(done){ if(fs.existsSync(componentPath)) { - // rimraf.sync(componentPath); + fs.removeSync(componentPath); } done(); }); From e2689925d5dc298030176ebfa0ed535df063fc8a Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 15:53:31 +0000 Subject: [PATCH 08/43] babel-loader && preset-env --- package.json | 3 ++ .../package-server-script/bundle/index.js | 40 ++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 8b7598490..493b37341 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,9 @@ "accept-language-parser": "1.1.2", "async": "1.5.2", "aws-sdk": "2.6.11", + "babel-core": "^6.21.0", + "babel-loader": "^6.2.10", + "babel-preset-env": "^1.1.7", "clean-css": "3.4.18", "colors": "1.1.2", "dependency-graph": "0.5.0", diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index c76af63ab..f709a0d4c 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -12,6 +12,21 @@ function bundle(dataPath, fileName, callBack) { output: { path: "/build", filename: fileName + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: [ + path.resolve(dataPath, "_package"), + path.resolve(dataPath, "node_modules") + ], + loader: "babel-loader", + options: { + presets: [["env", {"targets": {"node": "current"}}]] + } + } + ] } }; @@ -19,28 +34,23 @@ function bundle(dataPath, fileName, callBack) { compiler.outputFileSystem = memoryFs; compiler.run(function(err, stats){ + + // handleFatalError var error = err; - if (err) { - console.error(err.stack || err); - if (err.details) { - console.error(err.details); - } - return; - } + if (error) return callBack(error); var info = stats.toJson(); - if (stats.hasErrors()) { - error = info.errors; - console.error(info.errors); - } - if (stats.hasWarnings()) { - console.warn(info.warnings) - } + // handleSoftErrors + if (stats.hasErrors()) error = info.errors; + // handleWarnings + if (stats.hasWarnings()) error = info.warnings; console.log(stats.toString({ chunks: false, - colors: true + colors: true, + version: false, + hash: false })); var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); From 18e6ce7ded05e59dd1659bf6ddf6f9005007c03b Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 15:54:48 +0000 Subject: [PATCH 09/43] integration test wip --- .../cli-domain-package-server-script.js | 4 +- .../component/_package/server.js | 76 ------------------- .../component/server.js | 3 - 3 files changed, 3 insertions(+), 80 deletions(-) delete mode 100644 test/integration/cli-domain-package-server-script/component/_package/server.js delete mode 100644 test/integration/cli-domain-package-server-script/component/server.js diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 85275631e..8b50428cb 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -28,7 +28,9 @@ describe('cli : domain : package-server-script', function(){ }); describe('when packaging component\'s server.js', function(){ + this.timeout(10000); describe('when component does not require any json', function(){ + var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' beforeEach(function(done){ @@ -79,7 +81,7 @@ describe('cli : domain : package-server-script', function(){ publishPath: publishPath }, function(err, res){ - expect(err.toString().match(/Unexpected token \(3:19\)/)).to.be.ok; + expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; done(); } ) diff --git a/test/integration/cli-domain-package-server-script/component/_package/server.js b/test/integration/cli-domain-package-server-script/component/_package/server.js deleted file mode 100644 index b4408d782..000000000 --- a/test/integration/cli-domain-package-server-script/component/_package/server.js +++ /dev/null @@ -1,76 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // The require function -/******/ function __webpack_require__(moduleId) { - -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; - -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.l = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; - -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; - -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; - -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports) { - -module.exports.data=function(context,cb){return cb(null, {name:'John'}); }; - -/***/ } -/******/ ]); \ No newline at end of file diff --git a/test/integration/cli-domain-package-server-script/component/server.js b/test/integration/cli-domain-package-server-script/component/server.js deleted file mode 100644 index 6e2a2e2c3..000000000 --- a/test/integration/cli-domain-package-server-script/component/server.js +++ /dev/null @@ -1,3 +0,0 @@ -var data=require('request'); -module.exports.data=function(context,cb){ -return cb(null,data; }; \ No newline at end of file From 99b4b8432b019eb307b253e6b68d11a2253298c8 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 16:58:30 +0000 Subject: [PATCH 10/43] bundler options --- .../package-server-script/bundle/index.js | 22 +++++++++++++------ src/cli/domain/package-server-script/index.js | 2 +- .../cli-domain-package-server-script.js | 7 ++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index f709a0d4c..778d31342 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -5,7 +5,20 @@ var MemoryFS = require('memory-fs'); var memoryFs = new MemoryFS(); -function bundle(dataPath, fileName, callBack) { +function bundle(dataPath, fileName, options, callBack) { + + if (typeof options === 'function') { + callBack = options; + options = { + stats: { + chunks: false, + colors: true, + version: false, + hash: false + } + } + } + var webpackConfig = { entry: dataPath, @@ -46,12 +59,7 @@ function bundle(dataPath, fileName, callBack) { // handleWarnings if (stats.hasWarnings()) error = info.warnings; - console.log(stats.toString({ - chunks: false, - colors: true, - version: false, - hash: false - })); + console.log(stats.toString(options.stats)); var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); callBack(error, serverContentBundled); diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index e67617b8d..09d0d972a 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -10,7 +10,7 @@ module.exports = function(params, callback){ var fileName = 'server.js'; // var serverContent = fs.readFileSync(dataPath).toString(); - bundle(dataPath, fileName, function(err, bundledServer){ + bundle(dataPath, fileName, params.bundler, function(err, bundledServer){ if (err) { callback(err) } else { diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 8b50428cb..32b6a5554 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -10,6 +10,7 @@ var serverName = 'server.js'; var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); var publishPath = path.resolve(componentPath, '_package'); +var bundlerOptions = { stats: "errors-only" } describe('cli : domain : package-server-script', function(){ beforeEach(function(done){ @@ -47,7 +48,8 @@ describe('cli : domain : package-server-script', function(){ data: serverName } }, - publishPath: publishPath + publishPath: publishPath, + bundler: bundlerOptions }, function(err, res){ if (err) throw err @@ -78,7 +80,8 @@ describe('cli : domain : package-server-script', function(){ data: serverName } }, - publishPath: publishPath + publishPath: publishPath, + bundler: bundlerOptions }, function(err, res){ expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; From 5dc00601259fb451f01fe0a15c390984f9324237 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 17:34:09 +0000 Subject: [PATCH 11/43] es6 example integration test --- .../cli-domain-package-server-script.js | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 32b6a5554..5867d7e74 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -23,7 +23,7 @@ describe('cli : domain : package-server-script', function(){ afterEach(function(done){ if(fs.existsSync(componentPath)) { - fs.removeSync(componentPath); + // fs.removeSync(componentPath); } done(); }); @@ -31,7 +31,6 @@ describe('cli : domain : package-server-script', function(){ describe('when packaging component\'s server.js', function(){ this.timeout(10000); describe('when component does not require any json', function(){ - var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' beforeEach(function(done){ @@ -91,6 +90,35 @@ describe('cli : domain : package-server-script', function(){ }); }); + describe.only('when component uses es2015 javascript syntax', function(){ + var serverContent = 'const {first, last} = {first: "John", last: "Doe"};\nexport const data = (context,cb) => cb(null, context, first, last)'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + done(); + }); + + it('should throw an error with error details', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + bundler: bundlerOptions + }, + function(err, res){ + console.log(res) + // expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; + done(); + } + ) + }); + }); + }); }) From f5d80b3fd08b272512880ef6bb2ae9492a1174bf Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 18:01:06 +0000 Subject: [PATCH 12/43] cleanup --- .../package-server-script/bundle/index.js | 30 ++++++++----- src/cli/domain/package-server-script/index.js | 2 +- .../cli-domain-package-server-script.js | 43 ++++++++++--------- test/unit/cli-domain-package-server-script.js | 2 + 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 778d31342..1abb59a37 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -1,5 +1,7 @@ +'use strict'; + var console = require('console'); -var webpack = require("webpack"); +var webpack = require('webpack'); var path = require('path'); var MemoryFS = require('memory-fs'); @@ -16,14 +18,14 @@ function bundle(dataPath, fileName, options, callBack) { version: false, hash: false } - } + }; } var webpackConfig = { entry: dataPath, output: { - path: "/build", + path: '/build', filename: fileName }, module: { @@ -31,12 +33,12 @@ function bundle(dataPath, fileName, options, callBack) { { test: /\.js$/, exclude: [ - path.resolve(dataPath, "_package"), - path.resolve(dataPath, "node_modules") + path.resolve(dataPath, '_package'), + path.resolve(dataPath, 'node_modules') ], - loader: "babel-loader", + loader: 'babel-loader', options: { - presets: [["env", {"targets": {"node": "current"}}]] + presets: [['env', {'targets': {'node': 'current'}}]] } } ] @@ -50,14 +52,20 @@ function bundle(dataPath, fileName, options, callBack) { // handleFatalError var error = err; - if (error) return callBack(error); + if (error) { + return callBack(error); + } var info = stats.toJson(); // handleSoftErrors - if (stats.hasErrors()) error = info.errors; + if (stats.hasErrors()) { + error = info.errors; + } // handleWarnings - if (stats.hasWarnings()) error = info.warnings; + if (stats.hasWarnings()) { + error = info.warnings; + } console.log(stats.toString(options.stats)); @@ -66,4 +74,4 @@ function bundle(dataPath, fileName, options, callBack) { }); } -module.exports = bundle +module.exports = bundle; diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index 09d0d972a..193ac44f5 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -12,7 +12,7 @@ module.exports = function(params, callback){ bundle(dataPath, fileName, params.bundler, function(err, bundledServer){ if (err) { - callback(err) + return callback(err); } else { fs.writeFile(path.join(params.publishPath, fileName), bundledServer, function(err, res){ callback(err, { diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 5867d7e74..76a07e6ba 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -10,31 +10,32 @@ var serverName = 'server.js'; var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); var publishPath = path.resolve(componentPath, '_package'); -var bundlerOptions = { stats: "errors-only" } +var bundlerOptions = { stats: 'errors-only' }; describe('cli : domain : package-server-script', function(){ beforeEach(function(done){ if(!fs.existsSync(componentPath)) { - fs.mkdirSync(componentPath) - fs.mkdirSync(path.resolve(componentPath, '_package')) + fs.mkdirSync(componentPath); + fs.mkdirSync(path.resolve(componentPath, '_package')); } done(); }); afterEach(function(done){ if(fs.existsSync(componentPath)) { - // fs.removeSync(componentPath); + fs.removeSync(componentPath); } done(); }); describe('when packaging component\'s server.js', function(){ this.timeout(10000); + describe('when component does not require any json', function(){ - var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' + var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); @@ -51,14 +52,16 @@ describe('cli : domain : package-server-script', function(){ bundler: bundlerOptions }, function(err, res){ - if (err) throw err - expect(res.type).to.equal('node.js') - expect(res.src).to.equal('server.js') - var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}) - expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)) + if (err) { + throw err; + } + expect(res.type).to.equal('node.js'); + expect(res.src).to.equal('server.js'); + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); done(); } - ) + ); }); }); @@ -66,7 +69,7 @@ describe('cli : domain : package-server-script', function(){ var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); @@ -86,15 +89,15 @@ describe('cli : domain : package-server-script', function(){ expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; done(); } - ) + ); }); }); - describe.only('when component uses es2015 javascript syntax', function(){ + describe('when component uses es2015 javascript syntax', function(){ var serverContent = 'const {first, last} = {first: "John", last: "Doe"};\nexport const data = (context,cb) => cb(null, context, first, last)'; beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); @@ -111,17 +114,17 @@ describe('cli : domain : package-server-script', function(){ bundler: bundlerOptions }, function(err, res){ - console.log(res) + console.log(res); // expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; done(); } - ) + ); }); }); }); -}) +}); // OLD SPEC @@ -400,7 +403,7 @@ describe('cli : domain : package-server-script', function(){ // }); // it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); // }); // it('should wrap the for loop with an iterator limit', function(){ diff --git a/test/unit/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script.js index 6b47282c4..61fb8938f 100644 --- a/test/unit/cli-domain-package-server-script.js +++ b/test/unit/cli-domain-package-server-script.js @@ -1,3 +1,5 @@ +'use strict'; + var expect = require('chai').expect; var injectr = require('injectr'); var path = require('path'); From 8a717029a65b9a083aa33a71009971c266963872 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 02:08:40 +0000 Subject: [PATCH 13/43] webpack1 --- npm-shrinkwrap.json | 25 +++++++++++++++++++ package.json | 10 ++++---- .../package-server-script/bundle/index.js | 21 +++++++++------- .../cli-domain-package-server-script.js | 6 +++-- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 83bf7693c..c31c95910 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -90,6 +90,21 @@ } } }, + "babel-core": { + "version": "6.21.0", + "from": "babel-core@6.21.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.21.0.tgz" + }, + "babel-loader": { + "version": "6.21.0", + "from": "babel-loader@6.2.10", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.2.10.tgz" + }, + "babel-preset-env": { + "version": "1.1.8", + "from": "babel-preset-env@1.1.8", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.1.8.tgz" + }, "clean-css": { "version": "3.4.18", "from": "clean-css@3.4.18", @@ -1412,6 +1427,11 @@ } } }, + "memory-fs": { + "version": "0.4.1", + "from": "memory-fs@0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz" + }, "minimal-request": { "version": "2.2.0", "from": "minimal-request@2.2.0", @@ -3423,6 +3443,11 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" } } + }, + "webpack": { + "version": "1.14.0", + "from": "webpack@1.14.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.14.0.tgz" } } } diff --git a/package.json b/package.json index 493b37341..cdb5313e1 100644 --- a/package.json +++ b/package.json @@ -52,9 +52,9 @@ "accept-language-parser": "1.1.2", "async": "1.5.2", "aws-sdk": "2.6.11", - "babel-core": "^6.21.0", - "babel-loader": "^6.2.10", - "babel-preset-env": "^1.1.7", + "babel-core": "6.21.0", + "babel-loader": "6.2.10", + "babel-preset-env": "1.1.8", "clean-css": "3.4.18", "colors": "1.1.2", "dependency-graph": "0.5.0", @@ -65,7 +65,7 @@ "fs-extra": "0.30.0", "handlebars": "4.0.5", "jade": "1.11.0", - "memory-fs": "^0.4.1", + "memory-fs": "0.4.1", "minimal-request": "2.2.0", "multer": "0.1.4", "nice-cache": "0.0.5", @@ -83,6 +83,6 @@ "uglify-js": "2.6.4", "underscore": "1.8.3", "watch": "0.19.1", - "webpack": "^2.2.0-rc.3" + "webpack": "1.14.0" } } diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 1abb59a37..1217d8d07 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -29,16 +29,19 @@ function bundle(dataPath, fileName, options, callBack) { filename: fileName }, module: { - rules: [ + loaders: [ { - test: /\.js$/, - exclude: [ - path.resolve(dataPath, '_package'), - path.resolve(dataPath, 'node_modules') - ], - loader: 'babel-loader', - options: { - presets: [['env', {'targets': {'node': 'current'}}]] + test: /\.jsx?$/, + exclude: /node_modules/, + loader: 'babel', + query: { + 'presets': [ + ['env', { + 'targets': { + 'node': 'current' + } + }] + ] } } ] diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 76a07e6ba..29ce4e105 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -10,7 +10,9 @@ var serverName = 'server.js'; var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); var publishPath = path.resolve(componentPath, '_package'); -var bundlerOptions = { stats: 'errors-only' }; +var bundlerOptions = { + stats: 'none' +}; describe('cli : domain : package-server-script', function(){ beforeEach(function(done){ @@ -114,7 +116,7 @@ describe('cli : domain : package-server-script', function(){ bundler: bundlerOptions }, function(err, res){ - console.log(res); + // console.log(res); // expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; done(); } From a1db0555ebad81ffc4057031cc4e653fc6d3dc8c Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 02:32:00 +0000 Subject: [PATCH 14/43] uglify and optimize plugins --- .../domain/package-server-script/bundle/index.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 1217d8d07..f1793786a 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -1,3 +1,4 @@ +/*jshint camelcase:false */ 'use strict'; var console = require('console'); @@ -28,6 +29,18 @@ function bundle(dataPath, fileName, options, callBack) { path: '/build', filename: fileName }, + plugins: [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false, + screw_ie8: true + } + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + }) + ], module: { loaders: [ { From c0d9c6bc51bee6e7cec31846449b10eb88b7c503 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 04:19:31 +0000 Subject: [PATCH 15/43] added config module --- .../package-server-script/bundle/index.js | 56 +++++-------------- .../bundle/webpack.server.config.js | 44 +++++++++++++++ .../package-server-script/bundle/wrapLoops.js | 22 ++++++++ .../getSandBoxedJs/wrapLoops.js | 24 -------- 4 files changed, 79 insertions(+), 67 deletions(-) create mode 100644 src/cli/domain/package-server-script/bundle/webpack.server.config.js create mode 100644 src/cli/domain/package-server-script/bundle/wrapLoops.js delete mode 100644 src/cli/domain/package-server-script/getSandBoxedJs/wrapLoops.js diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index f1793786a..94c0b9115 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -1,15 +1,15 @@ /*jshint camelcase:false */ 'use strict'; - +var _ = require('underscore'); +var config = require('./webpack.server.config'); var console = require('console'); -var webpack = require('webpack'); -var path = require('path'); var MemoryFS = require('memory-fs'); +var path = require('path'); +var webpack = require('webpack'); var memoryFs = new MemoryFS(); function bundle(dataPath, fileName, options, callBack) { - if (typeof options === 'function') { callBack = options; options = { @@ -22,50 +22,21 @@ function bundle(dataPath, fileName, options, callBack) { }; } - - var webpackConfig = { - entry: dataPath, - output: { - path: '/build', - filename: fileName + var webpackConfig = _.extend( + { + entry: dataPath, + output: { + path: '/build', + filename: fileName + } }, - plugins: [ - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.optimize.UglifyJsPlugin({ - compressor: { - warnings: false, - screw_ie8: true - } - }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) - }) - ], - module: { - loaders: [ - { - test: /\.jsx?$/, - exclude: /node_modules/, - loader: 'babel', - query: { - 'presets': [ - ['env', { - 'targets': { - 'node': 'current' - } - }] - ] - } - } - ] - } - }; + config + ); var compiler = webpack(webpackConfig); compiler.outputFileSystem = memoryFs; compiler.run(function(err, stats){ - // handleFatalError var error = err; if (error) { @@ -73,7 +44,6 @@ function bundle(dataPath, fileName, options, callBack) { } var info = stats.toJson(); - // handleSoftErrors if (stats.hasErrors()) { error = info.errors; diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js new file mode 100644 index 000000000..438d307b5 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/webpack.server.config.js @@ -0,0 +1,44 @@ +/*jshint camelcase:false */ +'use strict'; +var webpack = require('webpack'); + +var config = { + module: { + loaders: [ + { + test: /\.json$/, + loader: 'json-loader', + exclude: /node_modules/ + }, + { + test: /\.jsx?$/, + exclude: /node_modules/, + loader: 'babel-loader', + query: { + 'presets': [ + ['env', { + 'targets': { + 'node': 0.10 + } + }] + ] + } + } + ] + }, + plugins: [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false, + screw_ie8: true + }, + sourceMap: false + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + }) + ] +}; + +module.exports = config; diff --git a/src/cli/domain/package-server-script/bundle/wrapLoops.js b/src/cli/domain/package-server-script/bundle/wrapLoops.js new file mode 100644 index 000000000..37cc10500 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/wrapLoops.js @@ -0,0 +1,22 @@ +'use strict'; +var CONST_MAX_ITERATIONS = 10000; + +var wrapLoops = function(node){ + var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; + + if(loopKeywords.indexOf(node.type) > -1){ + node.update('{ var __ITER = ' + CONST_MAX_ITERATIONS + ';' + + node.source() + '}'); + } + + if(!node.parent){ + return; + } + + if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement') { + node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum allowed iterations"); } ' + + node.source() + ' __ITER--; }'); + } +}; + +module.exports = wrapLoops; diff --git a/src/cli/domain/package-server-script/getSandBoxedJs/wrapLoops.js b/src/cli/domain/package-server-script/getSandBoxedJs/wrapLoops.js deleted file mode 100644 index dd09cd206..000000000 --- a/src/cli/domain/package-server-script/getSandBoxedJs/wrapLoops.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -var falafel = require('falafel'); - -var wrapLoops = function(code, CONST_MAX_ITERATIONS){ - var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; - return falafel(code, function (node) { - if(loopKeywords.indexOf(node.type) > -1){ - node.update('{ var __ITER = ' + CONST_MAX_ITERATIONS + ';' - + node.source() + '}'); - } - - if(!node.parent){ - return; - } - - if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement'){ - node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum allowed iterations"); } ' - + node.source() + ' __ITER--; }'); - } - }).toString(); -}; - -module.exports = wrapLoops; From d80bfa2720f9c33f091858a7e707c264055d8629 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 13:02:23 +0000 Subject: [PATCH 16/43] libraryTarget=commonjs2, externals=regex, added json-loader & integration test --- npm-shrinkwrap.json | 5 +++ package.json | 1 + .../package-server-script/bundle/index.js | 3 +- .../bundle/webpack.server.config.js | 7 +-- .../cli-domain-package-server-script.js | 44 +++++++++++++++++-- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index c31c95910..3e3406c80 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1427,6 +1427,11 @@ } } }, + "json-loader": { + "version": "0.5.4", + "from": "json-loader@0.5.4", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.4.tgz" + }, "memory-fs": { "version": "0.4.1", "from": "memory-fs@0.4.1", diff --git a/package.json b/package.json index cdb5313e1..e5f699ef9 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "fs-extra": "0.30.0", "handlebars": "4.0.5", "jade": "1.11.0", + "json-loader": "0.5.4", "memory-fs": "0.4.1", "minimal-request": "2.2.0", "multer": "0.1.4", diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 94c0b9115..4ceb4ffcd 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -27,7 +27,8 @@ function bundle(dataPath, fileName, options, callBack) { entry: dataPath, output: { path: '/build', - filename: fileName + filename: fileName, + libraryTarget: 'commonjs2' } }, config diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js index 438d307b5..6a05cfa85 100644 --- a/src/cli/domain/package-server-script/bundle/webpack.server.config.js +++ b/src/cli/domain/package-server-script/bundle/webpack.server.config.js @@ -4,14 +4,15 @@ var webpack = require('webpack'); var config = { module: { + externals: /^[a-z@][a-z\-\/0-9]+$/, loaders: [ { test: /\.json$/, - loader: 'json-loader', - exclude: /node_modules/ + exclude: /node_modules/, + loader: 'json-loader' }, { - test: /\.jsx?$/, + test: /\.js?$/, exclude: /node_modules/, loader: 'babel-loader', query: { diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 29ce4e105..13d3275e2 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -11,7 +11,7 @@ var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); var publishPath = path.resolve(componentPath, '_package'); var bundlerOptions = { - stats: 'none' + stats: 'errors-only' }; describe('cli : domain : package-server-script', function(){ @@ -31,9 +31,9 @@ describe('cli : domain : package-server-script', function(){ }); describe('when packaging component\'s server.js', function(){ - this.timeout(10000); + this.timeout(15000); - describe('when component does not require any json', function(){ + describe('when component does not require any module', function(){ var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; beforeEach(function(done){ @@ -103,7 +103,7 @@ describe('cli : domain : package-server-script', function(){ done(); }); - it('should throw an error with error details', function(done){ + it('should transpile it to es2015 through Babel', function(done){ packageServerScript( { componentPath: componentPath, @@ -116,6 +116,7 @@ describe('cli : domain : package-server-script', function(){ bundler: bundlerOptions }, function(err, res){ + // check for const and arrow function being removed/replaced // console.log(res); // expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; done(); @@ -124,6 +125,41 @@ describe('cli : domain : package-server-script', function(){ }); }); + describe('when component require a json file', function(){ + var user = {first: 'John',last:'Doe'}; + var jsonContent = JSON.stringify(user); + var serverContent = 'var user = require(\'./user\');\nmodule.exports.data=function(){return user.first;};'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, 'user.json'), jsonContent); + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should save compiled and minified data provider encapsulating json content', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + bundler: bundlerOptions + }, + function(err, res){ + var name = user.first; + var bundle = require(path.resolve(publishPath, res.src)); + expect(bundle.data()).to.be.equal(name); + done(); + } + ); + }); + }); + + + }); }); From c24d0398b9ecf600c3045cb09cd00d8118f5d756 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 16:34:39 +0000 Subject: [PATCH 17/43] wrap while/do/for;; loops with an iterator limit --- npm-shrinkwrap.json | 30 +------ package.json | 2 +- .../bundle/webpack.server.config.js | 27 +++--- .../package-server-script/bundle/wrapLoops.js | 20 +++-- src/cli/domain/package-server-script/index.js | 1 - .../cli-domain-package-server-script.js | 89 ++++++++++++++++++- 6 files changed, 120 insertions(+), 49 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 3e3406c80..fd3c809f2 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -835,32 +835,10 @@ } } }, - "falafel": { - "version": "1.2.0", - "from": "falafel@1.2.0", - "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz", - "dependencies": { - "acorn": { - "version": "1.2.2", - "from": "acorn@>=1.0.3 <2.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz" - }, - "foreach": { - "version": "2.0.5", - "from": "foreach@>=2.0.5 <3.0.0", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "object-keys": { - "version": "1.0.9", - "from": "object-keys@>=1.0.6 <2.0.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.9.tgz" - } - } + "falafel-loader": { + "version": "0.0.3", + "from": "falafel-loader@0.0.3", + "resolved": "https://registry.npmjs.org/falafel-loader/-/falafel-loader-0.0.3.tgz" }, "form-data": { "version": "0.1.4", diff --git a/package.json b/package.json index e5f699ef9..448e74b5e 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "dependency-graph": "0.5.0", "detective": "4.3.1", "express": "3.21.2", - "falafel": "1.2.0", + "falafel-loader": "0.0.3", "form-data": "0.1.4", "fs-extra": "0.30.0", "handlebars": "4.0.5", diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js index 6a05cfa85..29cce45a4 100644 --- a/src/cli/domain/package-server-script/bundle/webpack.server.config.js +++ b/src/cli/domain/package-server-script/bundle/webpack.server.config.js @@ -1,6 +1,7 @@ /*jshint camelcase:false */ 'use strict'; var webpack = require('webpack'); +var wrapLoops = require('./wrapLoops'); var config = { module: { @@ -14,16 +15,19 @@ var config = { { test: /\.js?$/, exclude: /node_modules/, - loader: 'babel-loader', - query: { - 'presets': [ - ['env', { - 'targets': { - 'node': 0.10 - } - }] - ] - } + loaders: [ + 'falafel-loader', + 'babel-loader?' + JSON.stringify({ + cacheDirectory: true, + 'presets': [ + ['env', { + 'targets': { + 'node': 0.10 + } + }] + ] + }) + ], } ] }, @@ -39,7 +43,8 @@ var config = { new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }) - ] + ], + falafel: wrapLoops }; module.exports = config; diff --git a/src/cli/domain/package-server-script/bundle/wrapLoops.js b/src/cli/domain/package-server-script/bundle/wrapLoops.js index 37cc10500..f0320fb78 100644 --- a/src/cli/domain/package-server-script/bundle/wrapLoops.js +++ b/src/cli/domain/package-server-script/bundle/wrapLoops.js @@ -1,21 +1,27 @@ 'use strict'; -var CONST_MAX_ITERATIONS = 10000; -var wrapLoops = function(node){ +var CONST_MAX_ITERATIONS = require('../../../../resources/settings').maxLoopIterations; + +var wrapLoops = function (node) { var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; if(loopKeywords.indexOf(node.type) > -1){ - node.update('{ var __ITER = ' + CONST_MAX_ITERATIONS + ';' - + node.source() + '}'); + node.update( + 'var __ITER = ' + CONST_MAX_ITERATIONS + ';\n' + + node.source() + ); } if(!node.parent){ return; } - if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement') { - node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum allowed iterations"); } ' - + node.source() + ' __ITER--; }'); + if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement'){ + node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum ' + + 'allowed iterations"); } ' + + node.source().substr(1).slice(0, -1) + + ' __ITER--; }' + ); } }; diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index 193ac44f5..c2634917a 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -8,7 +8,6 @@ var bundle = require('./bundle'); module.exports = function(params, callback){ var dataPath = path.join(params.componentPath, params.ocOptions.files.data); var fileName = 'server.js'; - // var serverContent = fs.readFileSync(dataPath).toString(); bundle(dataPath, fileName, params.bundler, function(err, bundledServer){ if (err) { diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 13d3275e2..0a18b8204 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -11,7 +11,7 @@ var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); var publishPath = path.resolve(componentPath, '_package'); var bundlerOptions = { - stats: 'errors-only' + stats: 'none' }; describe('cli : domain : package-server-script', function(){ @@ -34,7 +34,7 @@ describe('cli : domain : package-server-script', function(){ this.timeout(15000); describe('when component does not require any module', function(){ - var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; + var serverContent = 'module.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); @@ -96,7 +96,7 @@ describe('cli : domain : package-server-script', function(){ }); describe('when component uses es2015 javascript syntax', function(){ - var serverContent = 'const {first, last} = {first: "John", last: "Doe"};\nexport const data = (context,cb) => cb(null, context, first, last)'; + var serverContent = 'const {first, last} = {first: "John", last: "Doe"};\nconst data = (context,cb) => cb(null, context, first, last)\nexport {data}'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); @@ -158,6 +158,89 @@ describe('cli : domain : package-server-script', function(){ }); }); + describe.only('when component code includes a loop', function(){ + var serverContent = 'module.exports.data=function(context,cb){ var x,y,z;' + + 'while(true){ x = 234; }' + + 'for(var i=1e12;;){ y = 546; }' + + 'do { z = 342; } while(true);' + + '}'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should wrap while/do/for;; loops with an iterator limit', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + bundler: bundlerOptions + }, + function(err, res){ + if (err) { + throw err; + } + // expect(res.type).to.equal('node.js'); + // expect(res.src).to.equal('server.js'); + // var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + // expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); + done(); + } + ); + }); + }); + + + +// describe('when component code includes a loop', function(){ + +// var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' +// + 'while(true){ x = 234; } ' +// + 'for(var i=1e12;;){ y = 546; }' +// + 'do { z = 342; } while(true);' +// + 'return cb(null,data); };', +// result; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// existsSync: sinon.stub().returns(false) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// result = r; +// done(); +// }); +// }); + +// it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); +// }); + +// it('should wrap the for loop with an iterator limit', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); +// }); + +// it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); +// }); +// }); + From 4a17d9a553f878f088e433b15a914acebffe7b93 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 12 Jan 2017 13:06:54 +0000 Subject: [PATCH 18/43] structure/internaAPIi refactor --- .../config/externalDependenciesHandlers.js | 35 +++++++++++ .../bundle/config/index.js | 59 +++++++++++++++++++ .../bundle/{ => config}/wrapLoops.js | 7 +-- .../package-server-script/bundle/index.js | 39 +++--------- .../bundle/webpack.server.config.js | 50 ---------------- src/cli/domain/package-server-script/index.js | 26 ++++++-- .../cli-domain-package-server-script.js | 50 +++++++++++++--- 7 files changed, 168 insertions(+), 98 deletions(-) create mode 100644 src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js create mode 100644 src/cli/domain/package-server-script/bundle/config/index.js rename src/cli/domain/package-server-script/bundle/{ => config}/wrapLoops.js (78%) delete mode 100644 src/cli/domain/package-server-script/bundle/webpack.server.config.js diff --git a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js new file mode 100644 index 000000000..1fca92761 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js @@ -0,0 +1,35 @@ +/* + * External Dependencies handler for webpack + * Returns an array with handlers to indicates dependencies that should not be + * bundled by webPack but instead remain requested by the resulting bundle. + * For more info http://webpack.github.io/docs/configuration.html#externals + * +*/ +'use strict'; + +var _ = require('underscore'); + + +module.exports = function externalDependenciesHandlers(dependencies){ + dependencies = dependencies || {} + + var missingExternalDependecy = function(dep, dependencies) { + return !_.contains(_.keys(dependencies), dep); + } + + return [ + function(context, request, callback) { + console.log(request) + if (/^[a-z@][a-z\-\/0-9]+$/.test(request)) { + if(missingExternalDependecy(request, dependencies)) { + console.log('BOOM, ' + request + ' doesnt exist on package.json') + } else { + console.log('coool') + } + + } + callback() + }, + /^[a-z@][a-z\-\/0-9]+$/ + ] +}; diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js new file mode 100644 index 000000000..9878679d4 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -0,0 +1,59 @@ +/*jshint camelcase:false */ +'use strict'; + +var webpack = require('webpack'); +var wrapLoops = require('./wrapLoops'); +var externalDependenciesHandlers = require('./externalDependenciesHandlers'); + + +module.exports = function webpackConfigGenerator(params){ + return { + entry: params.dataPath, + output: { + path: '/build', + filename: params.fileName, + libraryTarget: 'commonjs2' + }, + externals: externalDependenciesHandlers(params.dependencies), + module: { + loaders: [ + { + test: /\.json$/, + exclude: /node_modules/, + loader: 'json-loader' + }, + { + test: /\.js?$/, + exclude: /node_modules/, + loaders: [ + 'falafel-loader', + 'babel-loader?' + JSON.stringify({ + cacheDirectory: false, + 'presets': [ + ['env', { + 'targets': { + 'node': 0.10 + } + }] + ] + }) + ], + } + ] + }, + plugins: [ + new webpack.optimize.OccurenceOrderPlugin(), + // new webpack.optimize.UglifyJsPlugin({ + // compressor: { + // warnings: false, + // screw_ie8: true + // }, + // sourceMap: false + // }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + }) + ], + falafel: wrapLoops + }; +}; diff --git a/src/cli/domain/package-server-script/bundle/wrapLoops.js b/src/cli/domain/package-server-script/bundle/config/wrapLoops.js similarity index 78% rename from src/cli/domain/package-server-script/bundle/wrapLoops.js rename to src/cli/domain/package-server-script/bundle/config/wrapLoops.js index f0320fb78..cea8d2b3a 100644 --- a/src/cli/domain/package-server-script/bundle/wrapLoops.js +++ b/src/cli/domain/package-server-script/bundle/config/wrapLoops.js @@ -1,8 +1,9 @@ 'use strict'; -var CONST_MAX_ITERATIONS = require('../../../../resources/settings').maxLoopIterations; -var wrapLoops = function (node) { +var CONST_MAX_ITERATIONS = require('../../../../../resources/settings').maxLoopIterations; + +module.exports = function wrapLoops(node){ var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; if(loopKeywords.indexOf(node.type) > -1){ @@ -24,5 +25,3 @@ var wrapLoops = function (node) { ); } }; - -module.exports = wrapLoops; diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 4ceb4ffcd..b6559b0ab 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -1,7 +1,7 @@ /*jshint camelcase:false */ 'use strict'; var _ = require('underscore'); -var config = require('./webpack.server.config'); +var webpackConfig = require('./config'); var console = require('console'); var MemoryFS = require('memory-fs'); var path = require('path'); @@ -9,32 +9,9 @@ var webpack = require('webpack'); var memoryFs = new MemoryFS(); -function bundle(dataPath, fileName, options, callBack) { - if (typeof options === 'function') { - callBack = options; - options = { - stats: { - chunks: false, - colors: true, - version: false, - hash: false - } - }; - } - - var webpackConfig = _.extend( - { - entry: dataPath, - output: { - path: '/build', - filename: fileName, - libraryTarget: 'commonjs2' - } - }, - config - ); - - var compiler = webpack(webpackConfig); +module.exports = function bundle(params, callBack) { + var config = webpackConfig(params) + var compiler = webpack(config); compiler.outputFileSystem = memoryFs; compiler.run(function(err, stats){ @@ -47,18 +24,16 @@ function bundle(dataPath, fileName, options, callBack) { var info = stats.toJson(); // handleSoftErrors if (stats.hasErrors()) { - error = info.errors; + error = info.errors.toString(); } // handleWarnings if (stats.hasWarnings()) { - error = info.warnings; + error = info.warnings.toString(); } - console.log(stats.toString(options.stats)); + console.log(stats.toString('normal')); var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); callBack(error, serverContentBundled); }); } - -module.exports = bundle; diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js deleted file mode 100644 index 29cce45a4..000000000 --- a/src/cli/domain/package-server-script/bundle/webpack.server.config.js +++ /dev/null @@ -1,50 +0,0 @@ -/*jshint camelcase:false */ -'use strict'; -var webpack = require('webpack'); -var wrapLoops = require('./wrapLoops'); - -var config = { - module: { - externals: /^[a-z@][a-z\-\/0-9]+$/, - loaders: [ - { - test: /\.json$/, - exclude: /node_modules/, - loader: 'json-loader' - }, - { - test: /\.js?$/, - exclude: /node_modules/, - loaders: [ - 'falafel-loader', - 'babel-loader?' + JSON.stringify({ - cacheDirectory: true, - 'presets': [ - ['env', { - 'targets': { - 'node': 0.10 - } - }] - ] - }) - ], - } - ] - }, - plugins: [ - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.optimize.UglifyJsPlugin({ - compressor: { - warnings: false, - screw_ie8: true - }, - sourceMap: false - }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) - }) - ], - falafel: wrapLoops -}; - -module.exports = config; diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index c2634917a..cb84f1572 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -5,15 +5,31 @@ var path = require('path'); var hashBuilder = require('../../../utils/hash-builder'); var bundle = require('./bundle'); -module.exports = function(params, callback){ - var dataPath = path.join(params.componentPath, params.ocOptions.files.data); - var fileName = 'server.js'; +var webpackDefaults = { + stats: { + chunks: false, + colors: true, + version: false, + hash: false + } +}; + +module.exports = function packageServerScript(params, callback){ + var fileName = 'server.js' + var publishPath = params.publishPath; + + var bundleParams = { + webpack: params.webpack || webpackDefaults, + dependencies: params.dependencies || {}, + fileName: fileName, + dataPath: path.join(params.componentPath, params.ocOptions.files.data) + }; - bundle(dataPath, fileName, params.bundler, function(err, bundledServer){ + bundle(bundleParams, function(err, bundledServer){ if (err) { return callback(err); } else { - fs.writeFile(path.join(params.publishPath, fileName), bundledServer, function(err, res){ + fs.writeFile(path.join(publishPath, fileName), bundledServer, function(err, res){ callback(err, { type: 'node.js', hashKey: hashBuilder.fromString(bundledServer), diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 0a18b8204..ce0a60bcd 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -10,7 +10,7 @@ var serverName = 'server.js'; var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); var publishPath = path.resolve(componentPath, '_package'); -var bundlerOptions = { +var webpackOptions = { stats: 'none' }; @@ -51,7 +51,7 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - bundler: bundlerOptions + webpack: webpackOptions }, function(err, res){ if (err) { @@ -67,6 +67,42 @@ describe('cli : domain : package-server-script', function(){ }); }); + + describe.only('when component does require a module', function(){ + var serverContent = 'var _=require(\'underscore\');\nmodule.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should save compiled data provider', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions + }, + function(err, res){ + if (err) { + console.log(err); + done(err); + } + expect(res.type).to.equal('node.js'); + expect(res.src).to.equal('server.js'); + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); + done(); + } + ); + }); + }); + describe('when component implements not-valid javascript', function(){ var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; @@ -85,7 +121,7 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - bundler: bundlerOptions + webpack: webpackOptions }, function(err, res){ expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; @@ -113,7 +149,7 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - bundler: bundlerOptions + webpack: webpackOptions }, function(err, res){ // check for const and arrow function being removed/replaced @@ -146,7 +182,7 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - bundler: bundlerOptions + webpack: webpackOptions }, function(err, res){ var name = user.first; @@ -158,7 +194,7 @@ describe('cli : domain : package-server-script', function(){ }); }); - describe.only('when component code includes a loop', function(){ + describe('when component code includes a loop', function(){ var serverContent = 'module.exports.data=function(context,cb){ var x,y,z;' + 'while(true){ x = 234; }' + 'for(var i=1e12;;){ y = 546; }' @@ -180,7 +216,7 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - bundler: bundlerOptions + webpack: webpackOptions }, function(err, res){ if (err) { From d0d1574da4d0e1d2f71ebdb15ff5d4e988984355 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 12 Jan 2017 14:25:40 +0000 Subject: [PATCH 19/43] fix webpack error handling propagation --- .../domain/package-server-script/bundle/index.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index b6559b0ab..b4b0d907c 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -14,9 +14,11 @@ module.exports = function bundle(params, callBack) { var compiler = webpack(config); compiler.outputFileSystem = memoryFs; - compiler.run(function(err, stats){ + compiler.run(function(error, stats){ + var sofError; + var warning; + // handleFatalError - var error = err; if (error) { return callBack(error); } @@ -24,16 +26,17 @@ module.exports = function bundle(params, callBack) { var info = stats.toJson(); // handleSoftErrors if (stats.hasErrors()) { - error = info.errors.toString(); + sofError = info.errors.toString(); + return callBack(sofError); } // handleWarnings if (stats.hasWarnings()) { - error = info.warnings.toString(); + warning = info.warnings.toString(); } - console.log(stats.toString('normal')); + console.log(stats.toString(params.webpack.stats)); var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); - callBack(error, serverContentBundled); + callBack(warning, serverContentBundled); }); } From 46af301e2bf2e86ea874726ecf28aaca53d3fc7c Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 12 Jan 2017 15:27:14 +0000 Subject: [PATCH 20/43] handling relative paths from npm module requires --- .../config/externalDependenciesHandlers.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js index 1fca92761..4f0e08328 100644 --- a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js +++ b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js @@ -6,30 +6,33 @@ * */ 'use strict'; - +var format = require('stringformat'); var _ = require('underscore'); +var strings = require('../../../../../resources'); module.exports = function externalDependenciesHandlers(dependencies){ - dependencies = dependencies || {} + var deps = dependencies || {} var missingExternalDependecy = function(dep, dependencies) { return !_.contains(_.keys(dependencies), dep); } return [ - function(context, request, callback) { - console.log(request) - if (/^[a-z@][a-z\-\/0-9]+$/.test(request)) { - if(missingExternalDependecy(request, dependencies)) { - console.log('BOOM, ' + request + ' doesnt exist on package.json') - } else { - console.log('coool') + function(context, req, callback) { + if (/^[a-z@][a-z\-\/0-9]+$/.test(req)) { + var dependencyName = req; + if (/\//g.test(dependencyName)) { + dependencyName = dependencyName.substring(0, dependencyName.indexOf("/")); + } + if (missingExternalDependecy(dependencyName, deps)) { + return callback(new Error(format(strings.errors.cli.SERVERJS_DEPENDENCY_NOT_DECLARED, JSON.stringify(dependencyName)))); } - } callback() }, /^[a-z@][a-z\-\/0-9]+$/ ] }; + + From 2aeeb800370064eb01084bef645a814cd8f30ca3 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 12 Jan 2017 16:31:49 +0000 Subject: [PATCH 21/43] integration tests --- .../config/externalDependenciesHandlers.js | 10 +- .../bundle/config/index.js | 16 +- .../bundle/config/wrapLoops.js | 2 +- .../package-server-script/bundle/index.js | 4 +- src/cli/domain/package-server-script/index.js | 2 +- .../cli-domain-package-server-script.js | 580 ++++++------------ 6 files changed, 209 insertions(+), 405 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js index 4f0e08328..839524de9 100644 --- a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js +++ b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js @@ -12,27 +12,27 @@ var strings = require('../../../../../resources'); module.exports = function externalDependenciesHandlers(dependencies){ - var deps = dependencies || {} + var deps = dependencies || {}; var missingExternalDependecy = function(dep, dependencies) { return !_.contains(_.keys(dependencies), dep); - } + }; return [ function(context, req, callback) { if (/^[a-z@][a-z\-\/0-9]+$/.test(req)) { var dependencyName = req; if (/\//g.test(dependencyName)) { - dependencyName = dependencyName.substring(0, dependencyName.indexOf("/")); + dependencyName = dependencyName.substring(0, dependencyName.indexOf('/')); } if (missingExternalDependecy(dependencyName, deps)) { return callback(new Error(format(strings.errors.cli.SERVERJS_DEPENDENCY_NOT_DECLARED, JSON.stringify(dependencyName)))); } } - callback() + callback(); }, /^[a-z@][a-z\-\/0-9]+$/ - ] + ]; }; diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js index 9878679d4..d368bcc66 100644 --- a/src/cli/domain/package-server-script/bundle/config/index.js +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -28,7 +28,7 @@ module.exports = function webpackConfigGenerator(params){ loaders: [ 'falafel-loader', 'babel-loader?' + JSON.stringify({ - cacheDirectory: false, + cacheDirectory: true, 'presets': [ ['env', { 'targets': { @@ -43,13 +43,13 @@ module.exports = function webpackConfigGenerator(params){ }, plugins: [ new webpack.optimize.OccurenceOrderPlugin(), - // new webpack.optimize.UglifyJsPlugin({ - // compressor: { - // warnings: false, - // screw_ie8: true - // }, - // sourceMap: false - // }), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false, + screw_ie8: true + }, + sourceMap: false + }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }) diff --git a/src/cli/domain/package-server-script/bundle/config/wrapLoops.js b/src/cli/domain/package-server-script/bundle/config/wrapLoops.js index cea8d2b3a..377b5d174 100644 --- a/src/cli/domain/package-server-script/bundle/config/wrapLoops.js +++ b/src/cli/domain/package-server-script/bundle/config/wrapLoops.js @@ -18,7 +18,7 @@ module.exports = function wrapLoops(node){ } if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement'){ - node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum ' + node.update('{ if(__ITER <=0){ throw new Error("Loop exceeded maximum ' + 'allowed iterations"); } ' + node.source().substr(1).slice(0, -1) + ' __ITER--; }' diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index b4b0d907c..8773fb815 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -10,7 +10,7 @@ var webpack = require('webpack'); var memoryFs = new MemoryFS(); module.exports = function bundle(params, callBack) { - var config = webpackConfig(params) + var config = webpackConfig(params); var compiler = webpack(config); compiler.outputFileSystem = memoryFs; @@ -39,4 +39,4 @@ module.exports = function bundle(params, callBack) { var serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); callBack(warning, serverContentBundled); }); -} +}; diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index cb84f1572..63c39f12a 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -15,7 +15,7 @@ var webpackDefaults = { }; module.exports = function packageServerScript(params, callback){ - var fileName = 'server.js' + var fileName = 'server.js'; var publishPath = params.publishPath; var bundleParams = { diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index ce0a60bcd..8ce94527f 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -33,15 +33,49 @@ describe('cli : domain : package-server-script', function(){ describe('when packaging component\'s server.js', function(){ this.timeout(15000); - describe('when component does not require any module', function(){ - var serverContent = 'module.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; + + describe('when component implements not-valid javascript', function(){ + var serverContent = '\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); - it('should save compiled data provider', function(done){ + it('should throw an error with error details', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions + }, + function(err, res){ + try { + expect(err.toString()).to.contain.contain('Unexpected token, expected , (3:19)'); + return done(); + } catch(e) { + return done(e); + } + return done('error'); + } + ); + }); + }); + + describe('when component does not require any json', function(){ + var serverContent = '\nmodule.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should save compiled data provider and return a hash for the script', function(done){ packageServerScript( { componentPath: componentPath, @@ -55,21 +89,70 @@ describe('cli : domain : package-server-script', function(){ }, function(err, res){ if (err) { - throw err; + return done(err); + } + try { + expect(res.type).to.equal('node.js'); + expect(res.src).to.equal('server.js'); + + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); + return done(); + } catch(e) { + return done(e); } - expect(res.type).to.equal('node.js'); - expect(res.src).to.equal('server.js'); - var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); - expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); - done(); } ); }); }); + describe('when component require a json file', function(){ + var user = {first: 'John',last:'Doe'}; + var jsonContent = JSON.stringify(user); + var serverContent = 'var user = require(\'./user\');\nmodule.exports.data=function(){return user.first;};'; - describe.only('when component does require a module', function(){ - var serverContent = 'var _=require(\'underscore\');\nmodule.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, 'user.json'), jsonContent); + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should save compiled and minified data provider encapsulating json content', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions + }, + function(err, res){ + if (err) { + return done(err); + } + try { + var name = user.first; + var bundle = require(path.resolve(publishPath, res.src)); + expect(bundle.data()).to.be.equal(name); + + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(compiledContent).to.not.contain('user'); + return done(); + } catch(e) { + return done(e); + } + } + ); + }); + }); + + describe('when component does require an npm module', function(){ + var serverContent = 'var _ =require(\'underscore\');' + + '\nvar user = {name:\'John\'};\nmodule.exports.data=function(context,cb){' + + '\nreturn cb(null, _.has(user, \'name\'));\n};'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); @@ -77,6 +160,8 @@ describe('cli : domain : package-server-script', function(){ }); it('should save compiled data provider', function(done){ + var dependencies = {underscore: '1.8.3'}; + packageServerScript( { componentPath: componentPath, @@ -86,32 +171,67 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - webpack: webpackOptions + webpack: webpackOptions, + dependencies: dependencies }, function(err, res){ if (err) { - console.log(err); - done(err); + return done(err); + } + try { + expect(res.type).to.equal('node.js'); + expect(res.src).to.equal('server.js'); + + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); + return done(); + } catch(e) { + return done(e); } - expect(res.type).to.equal('node.js'); - expect(res.src).to.equal('server.js'); - var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); - expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); - done(); } ); }); + + describe('end required depenencies is not present in the package.json', function(){ + it('should throw an error with details', function(done){ + var dependencies = {lodash: '1.0.0'}; + + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions, + dependencies: dependencies + }, + function(err, res){ + try { + expect(/Missing depenencies drom package.json => \"underscore\"/ig.test(err)); + return done(); + } catch(e) { + return done(e); + } + } + ); + }); + }); }); - describe('when component implements not-valid javascript', function(){ - var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; + describe('when component does require a relative path from an npm module', function(){ + var serverContent = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); - it('should throw an error with error details', function(done){ + it('should throw an error when the dependency is not present in the package.json', function(done){ + var dependencies = {'react': '15.4.2'}; + packageServerScript( { componentPath: componentPath, @@ -121,25 +241,32 @@ describe('cli : domain : package-server-script', function(){ } }, publishPath: publishPath, - webpack: webpackOptions + webpack: webpackOptions, + dependencies: dependencies }, function(err, res){ - expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; - done(); + try { + expect(err.toString()).to.contain('Missing dependencies from package.json => \"react-dom\"'); + return done(); + } catch(e) { + return done(e); + } } ); }); }); - describe('when component uses es2015 javascript syntax', function(){ - var serverContent = 'const {first, last} = {first: "John", last: "Doe"};\nconst data = (context,cb) => cb(null, context, first, last)\nexport {data}'; + describe('when component require a local js module', function(){ + var jsContent = 'var user = {first: \'John\',last:\'Doe\'};\nmodule.exports = user'; + var serverContent = 'var user = require(\'./user\');\nmodule.exports.data=function(){return user.first;};'; beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, 'user.js'), jsContent); fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); - it('should transpile it to es2015 through Babel', function(done){ + it('should save compiled data provider encapsulating js module content', function(done){ packageServerScript( { componentPath: componentPath, @@ -152,27 +279,31 @@ describe('cli : domain : package-server-script', function(){ webpack: webpackOptions }, function(err, res){ - // check for const and arrow function being removed/replaced - // console.log(res); - // expect(err.toString().match(/Unexpected token,.*\(3:19\)/)).to.be.ok; - done(); + if (err) { + return done(err); + } + try { + var name = 'John'; + var bundle = require(path.resolve(publishPath, res.src)); + expect(bundle.data()).to.be.equal(name); + return done(); + } catch(e) { + return done(e); + } } ); }); }); - describe('when component require a json file', function(){ - var user = {first: 'John',last:'Doe'}; - var jsonContent = JSON.stringify(user); - var serverContent = 'var user = require(\'./user\');\nmodule.exports.data=function(){return user.first;};'; + describe('when component uses es2015 javascript syntax', function(){ + var serverContent = 'const {first, last} = {first: "John", last: "Doe"};\nconst data = (context,cb) => cb(null, first, last)\nexport {data}'; beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, 'user.json'), jsonContent); fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); done(); }); - it('should save compiled and minified data provider encapsulating json content', function(done){ + it('should transpile it to es2015 through Babel', function(done){ packageServerScript( { componentPath: componentPath, @@ -185,10 +316,19 @@ describe('cli : domain : package-server-script', function(){ webpack: webpackOptions }, function(err, res){ - var name = user.first; - var bundle = require(path.resolve(publishPath, res.src)); - expect(bundle.data()).to.be.equal(name); - done(); + if (err) { + return done(err); + } + try { + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(compiledContent).to.not.contain('=>'); + expect(compiledContent).to.not.contain('const'); + expect(compiledContent).to.contain('var'); + expect(compiledContent).to.contain('function'); + return done(); + } catch(e) { + return done(e); + } } ); }); @@ -220,356 +360,20 @@ describe('cli : domain : package-server-script', function(){ }, function(err, res){ if (err) { - throw err; + return done(err); + } + try { + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(compiledContent).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); + expect(compiledContent).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); + expect(compiledContent).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); + done(); + } catch(e) { + return done(); } - // expect(res.type).to.equal('node.js'); - // expect(res.src).to.equal('server.js'); - // var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); - // expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); - done(); } ); }); }); - - - -// describe('when component code includes a loop', function(){ - -// var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' -// + 'while(true){ x = 234; } ' -// + 'for(var i=1e12;;){ y = 546; }' -// + 'do { z = 342; } while(true);' -// + 'return cb(null,data); };', -// result; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// existsSync: sinon.stub().returns(false) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// result = r; -// done(); -// }); -// }); - -// it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); -// }); - -// it('should wrap the for loop with an iterator limit', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); -// }); - -// it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); -// }); -// }); - - - - }); }); - - -// OLD SPEC -// ====================================== - -// var expect = require('chai').expect; -// var injectr = require('injectr'); -// var path = require('path'); -// var sinon = require('sinon'); -// var uglifyJs = require('uglify-js'); -// var _ = require('underscore'); - -// var fsMock, -// packageServerScript; - -// var initialise = function(fs){ - -// fsMock = _.extend({ -// existsSync: sinon.stub().returns(true), -// readFileSync: sinon.stub().returns('file content'), -// readJsonSync: sinon.stub().returns({ content: true }), -// writeFile: sinon.stub().yields(null, 'ok') -// }, fs || {}); - -// packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { -// 'fs-extra': fsMock, -// path: { -// extname: path.extname, -// join: path.join, -// resolve: function(){ -// return _.toArray(arguments).join('/'); -// } -// } -// }); -// }; - -// describe.skip('cli : domain : package-server-script', function(){ - -// describe('when packaging component\'s server.js', function(){ - -// describe('when component implements not-valid javascript', function(){ - -// var error; -// var serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'myserver.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should throw an error with error details', function(){ -// expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); -// }); -// }); - -// describe('when component does not require any json', function(){ - -// var result, -// serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// result = r; -// done(); -// }); -// }); - -// it('should save compiled data provider', function(){ -// expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); -// }); - -// it('should return hash for script', function(){ -// expect(result.hashKey).not.be.empty; -// }); -// }); - -// describe('when component requires a json', function(){ - -// var requiredJson = { hello: 'world' }, -// serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// readJsonSync: sinon.stub().returns(requiredJson) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, done); -// }); - -// it('should save compiled and minified data provider encapsulating json content', function(){ -// var written = fsMock.writeFile.args[0][1]; - -// expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' -// + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' -// + 'module.exports.data=function(e,r){return r(null,{})};'); -// }); -// }); - -// describe('when component requires an npm module', function(){ - -// var error, -// serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should throw an error when the dependency is not present in the package.json', function(){ -// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); -// }); -// }); - -// describe('when component requires a relative path from an npm module', function(){ - -// var error, -// serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should throw an error when the dependency is not present in the package.json', function(){ -// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); -// }); -// }); - -// describe('when component requires a js file', function(){ - -// var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', -// error; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should not package component and respond with error', function(){ -// expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); -// }); -// }); - -// describe('when component requires a file without extension that is not found as json', function(){ - -// var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', -// error; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// existsSync: sinon.stub().returns(false) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should not package component and respond with error', function(){ -// expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); -// }); -// }); - -// describe('when component code includes a loop', function(){ - -// var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' -// + 'while(true){ x = 234; } ' -// + 'for(var i=1e12;;){ y = 546; }' -// + 'do { z = 342; } while(true);' -// + 'return cb(null,data); };', -// result; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// existsSync: sinon.stub().returns(false) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// result = r; -// done(); -// }); -// }); - -// it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); -// }); - -// it('should wrap the for loop with an iterator limit', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); -// }); - -// it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); -// }); -// }); -// }); -// }); From 3ca88c78c5daab206ff59d56adad4c2dff62a9f8 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Fri, 13 Jan 2017 12:14:06 +0000 Subject: [PATCH 22/43] clean legacy code --- .../domain/package-server-script/compress.js | 18 ------- .../getLocalDependencies.js | 47 ------------------- .../getSandBoxedJs/index.js | 21 --------- .../missingDependencies.js | 11 ----- 4 files changed, 97 deletions(-) delete mode 100644 src/cli/domain/package-server-script/compress.js delete mode 100644 src/cli/domain/package-server-script/getLocalDependencies.js delete mode 100644 src/cli/domain/package-server-script/getSandBoxedJs/index.js delete mode 100644 src/cli/domain/package-server-script/missingDependencies.js diff --git a/src/cli/domain/package-server-script/compress.js b/src/cli/domain/package-server-script/compress.js deleted file mode 100644 index ab334560b..000000000 --- a/src/cli/domain/package-server-script/compress.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -var uglifyJs = require('uglify-js'); -var format = require('stringformat'); -var strings = require('../../../resources'); - -var compress = function(code, fileName){ - try { - return uglifyJs.minify(code, { fromString: true }).code; - } catch (e){ - if(!!e.line && !!e.col){ - throw new Error(format(strings.errors.cli.SERVERJS_PARSING_ERROR, fileName, e.line, e.col, e.message)); - } - throw e; - } -}; - -module.exports = compress; diff --git a/src/cli/domain/package-server-script/getLocalDependencies.js b/src/cli/domain/package-server-script/getLocalDependencies.js deleted file mode 100644 index f89040564..000000000 --- a/src/cli/domain/package-server-script/getLocalDependencies.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -var detective = require('detective'); -var requirePackageName = require('require-package-name'); -var format = require('stringformat'); -var _ = require('underscore'); -var strings = require('../../../resources'); -var compress = require('./compress'); - -var isLocalFile = function(f){ - return _.first(f) === '/' || _.first(f) === '.'; -}; - -var getRequiredContent = function(componentPath, required, fs, path){ - var ext = path.extname(required).toLowerCase(); - if(ext === ''){ - required += '.json'; - } else if(ext !== '.json'){ - throw new Error(strings.errors.cli.SERVERJS_REQUIRE_JS_NOT_ALLOWED); - } - - var requiredPath = path.resolve(componentPath, required); - if(!fs.existsSync(requiredPath)){ - throw new Error(format(strings.errors.cli.SERVERJS_REQUIRE_JSON_NOT_FOUND, required)); - } - - return fs.readJsonSync(requiredPath); -}; - -var getLocalDependencies = function(fs, path, componentPath, serverContent, fileName){ - var requires = { files: {}, modules: [] }; - var localRequires = detective(compress(serverContent, fileName)); - - _.forEach(localRequires, function(required){ - if(isLocalFile(required)) { - requires.files[required] = getRequiredContent(componentPath, required, fs, path); - } else { - var packageName = requirePackageName(required); - requires.modules.push(packageName); - } - }); - return requires; -}; - -module.exports = function(fs, path){ - return getLocalDependencies.bind(null, fs, path); -}; diff --git a/src/cli/domain/package-server-script/getSandBoxedJs/index.js b/src/cli/domain/package-server-script/getSandBoxedJs/index.js deleted file mode 100644 index b1dc96862..000000000 --- a/src/cli/domain/package-server-script/getSandBoxedJs/index.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -var _ = require('underscore'); -var wrapLoops = require('./wrapLoops'); -var compress = require('../compress'); - - -var getSandBoxedJs = function(wrappedRequires, serverContent, fileName, maxLoopIterations){ - if(_.keys(wrappedRequires).length > 0){ - serverContent = 'var __sandboxedRequire = require, ' + - ' __localRequires=' + JSON.stringify(wrappedRequires) + ';' + - 'require=function(x){' + - ' return __localRequires[x] ? __localRequires[x] : __sandboxedRequire(x);' + - '};' + - '\n' + serverContent; - } - - return compress(wrapLoops(serverContent, maxLoopIterations), fileName); -}; - -module.exports = getSandBoxedJs; diff --git a/src/cli/domain/package-server-script/missingDependencies.js b/src/cli/domain/package-server-script/missingDependencies.js deleted file mode 100644 index 8d3cb0699..000000000 --- a/src/cli/domain/package-server-script/missingDependencies.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -var _ = require('underscore'); - -var missingDependencies = function(requires, dependencies){ - return _.filter(requires, function(dep){ - return !_.contains(_.keys(dependencies), dep); - }); -}; - -module.exports = missingDependencies; From 7e1cbdc94ec646c2aef3250c7c25f4f536e0b447 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Fri, 13 Jan 2017 17:48:34 +0000 Subject: [PATCH 23/43] unit tests --- .../config/externalDependenciesHandlers.js | 4 +- .../bundle/config/index.js | 2 +- .../bundle/config/wrapLoops.js | 2 +- .../cli-domain-package-server-script.js | 43 +-- test/unit/cli-domain-package-server-script.js | 319 ++++-------------- 5 files changed, 103 insertions(+), 267 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js index 839524de9..c15eacec2 100644 --- a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js +++ b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js @@ -20,7 +20,7 @@ module.exports = function externalDependenciesHandlers(dependencies){ return [ function(context, req, callback) { - if (/^[a-z@][a-z\-\/0-9]+$/.test(req)) { + if (/^[a-z@][a-z\-\/0-9]+$/i.test(req)) { var dependencyName = req; if (/\//g.test(dependencyName)) { dependencyName = dependencyName.substring(0, dependencyName.indexOf('/')); @@ -31,7 +31,7 @@ module.exports = function externalDependenciesHandlers(dependencies){ } callback(); }, - /^[a-z@][a-z\-\/0-9]+$/ + /^[a-z@][a-z\-\/0-9]+$/i ]; }; diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js index d368bcc66..61ae2f9cc 100644 --- a/src/cli/domain/package-server-script/bundle/config/index.js +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -51,7 +51,7 @@ module.exports = function webpackConfigGenerator(params){ sourceMap: false }), new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + 'process.env.NODE_ENV': JSON.stringify('production') }) ], falafel: wrapLoops diff --git a/src/cli/domain/package-server-script/bundle/config/wrapLoops.js b/src/cli/domain/package-server-script/bundle/config/wrapLoops.js index 377b5d174..8c5a08749 100644 --- a/src/cli/domain/package-server-script/bundle/config/wrapLoops.js +++ b/src/cli/domain/package-server-script/bundle/config/wrapLoops.js @@ -8,7 +8,7 @@ module.exports = function wrapLoops(node){ if(loopKeywords.indexOf(node.type) > -1){ node.update( - 'var __ITER = ' + CONST_MAX_ITERATIONS + ';\n' + 'var __ITER = ' + CONST_MAX_ITERATIONS + ';' + node.source() ); } diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 8ce94527f..2ae493273 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -43,27 +43,32 @@ describe('cli : domain : package-server-script', function(){ }); it('should throw an error with error details', function(done){ - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } + try { + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions }, - publishPath: publishPath, - webpack: webpackOptions - }, - function(err, res){ - try { - expect(err.toString()).to.contain.contain('Unexpected token, expected , (3:19)'); - return done(); - } catch(e) { - return done(e); + function(err, res){ + try { + expect(err.toString()).to.contain.contain('Unexpected token, expected , (3:19)'); + return done(); + } catch(e) { + return done(e); + } + return done('error'); } - return done('error'); - } - ); + ); + } catch (e) { + expect(e).to.contain.contain('Unexpected token, expected , (3:19)'); + done(); + } }); }); diff --git a/test/unit/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script.js index 61fb8938f..870978683 100644 --- a/test/unit/cli-domain-package-server-script.js +++ b/test/unit/cli-domain-package-server-script.js @@ -6,283 +6,114 @@ var path = require('path'); var sinon = require('sinon'); var uglifyJs = require('uglify-js'); var _ = require('underscore'); +var falafelLoader = require('falafel-loader'); -var fsMock, - packageServerScript; +var externalDependenciesHandlers = + require('../../src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers'); +var wrapLoops = + require('../../src/cli/domain/package-server-script/bundle/config/wrapLoops'); +var webpackConfigGenerator = + require('../../src/cli/domain/package-server-script/bundle/config'); -var initialise = function(fs){ - fsMock = _.extend({ - existsSync: sinon.stub().returns(true), - readFileSync: sinon.stub().returns('file content'), - readJsonSync: sinon.stub().returns({ content: true }), - writeFile: sinon.stub().yields(null, 'ok') - }, fs || {}); +describe('cli : domain : package-server-script ', function(){ - packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { - 'fs-extra': fsMock, - path: { - extname: path.extname, - join: path.join, - resolve: function(){ - return _.toArray(arguments).join('/'); - } - } - }); -}; - -// SKIPPED FOR NOW, NEED TO BE FIXED -describe.skip('cli : domain : package-server-script', function(){ - - describe('when packaging component\'s server.js', function(){ - - describe('when component implements not-valid javascript', function(){ - - var error; - var serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'myserver.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should throw an error with error details', function(){ - expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); - }); - }); - - describe('when component does not require any json', function(){ - - var result, - serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - result = r; - done(); - }); - }); + describe('bundle/config/externalDependenciesHandlers when configured with a dependencies hash', function(){ + var handler = externalDependenciesHandlers({lodash: '4.17.14'}); - it('should save compiled data provider', function(){ - expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); - }); - - it('should return hash for script', function(){ - expect(result.hashKey).not.be.empty; - }); + it('should return an array containing a function and a regular expression ', function(){ + expect(handler).to.be.an('array'); + expect(handler.length).to.be.equal(2); + expect(handler[1] instanceof RegExp).to.be.true; + expect(handler[0]).to.be.a('function'); }); - describe('when component requires a json', function(){ - - var requiredJson = { hello: 'world' }, - serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; - - beforeEach(function(done){ - - initialise({ - readFileSync: sinon.stub().returns(serverjs), - readJsonSync: sinon.stub().returns(requiredJson) - }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, done); + describe('its regular expression', function(){ + var regex = handler[1]; + it('should match npm module names', function() { + expect(regex.test('lodash')).to.be.true; + expect(regex.test('lodash/fp/curryN')).to.be.true; + expect(regex.test('@cycle/xstream-run')).to.be.true; }); - - it('should save compiled and minified data provider encapsulating json content', function(){ - var written = fsMock.writeFile.args[0][1]; - - expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' - + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' - + 'module.exports.data=function(e,r){return r(null,{})};'); + it('should not match local modules', function() { + expect(regex.test('/myModule')).to.be.false; + expect(regex.test('./myModule')).to.be.false; }); }); - describe('when component requires an npm module', function(){ - - var error, - serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; + describe('its function', function() { + var missingDephandler = handler[0]; + it('should return an error if a specific npm-module is missing from the given dependencies', function(done) { + missingDephandler('_', 'underscore', function(err){ + expect(err.toString()).to.be.equal('Error: Missing dependencies from package.json => \"underscore\"'); done(); }); }); - - it('should throw an error when the dependency is not present in the package.json', function(){ - expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); - }); - }); - - describe('when component requires a relative path from an npm module', function(){ - - var error, - serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); - - it('should throw an error when the dependency is not present in the package.json', function(){ - expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); - }); - }); - - describe('when component requires a js file', function(){ - - var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', - error; - - beforeEach(function(done){ - - initialise({ readFileSync: sinon.stub().returns(serverjs) }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); + it('should invoke the callback with no arguments if module is not missing from the given dependencies', function(done) { + missingDephandler('_', 'lodash', function(err){ + expect(err).to.be.an('undefined'); + return done(); }); }); - - it('should not package component and respond with error', function(){ - expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); - }); }); + }); - describe('when component requires a file without extension that is not found as json', function(){ - - var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', - error; - - beforeEach(function(done){ - - initialise({ - readFileSync: sinon.stub().returns(serverjs), - existsSync: sinon.stub().returns(false) - }); - - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - error = e; - done(); - }); - }); + describe('bundle/config/wrapLoops', function (){ - it('should not package component and respond with error', function(){ - expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); - }); + it('should be a function with arity 1', function() { + expect(wrapLoops).to.be.a('function'); + expect(wrapLoops.length).to.be.equal(1); }); describe('when component code includes a loop', function(){ + var mockFalafel = function(){ + this.options = { + falafel: wrapLoops + }; + this.cacheable = function(){}; + this.loader = falafelLoader; + }; + var falafel = new mockFalafel(); var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' - + 'while(true){ x = 234; } ' - + 'for(var i=1e12;;){ y = 546; }' - + 'do { z = 342; } while(true);' - + 'return cb(null,data); };', - result; + + 'while(true){ x = 234; } ' + + 'for(var i=1e12;;){ y = 546; }' + + 'do { z = 342; } while(true);' + + 'return cb(null,data); };'; - beforeEach(function(done){ + var result = falafel.loader(serverjs); - initialise({ - readFileSync: sinon.stub().returns(serverjs), - existsSync: sinon.stub().returns(false) - }); + it('should wrap the while loop with an iterator limit', function() { + expect(result).to.contain('var x,y,z;var __ITER = 1000000000;while(true){ if(__ITER <=0)' + + '{ throw new Error("Loop exceeded maximum allowed iterations"); } x = 234; __ITER--; }'); + }); - packageServerScript({ - componentPath: '/path/to/component/', - ocOptions: { - files: { - data: 'server.js' - } - }, - publishPath: '/path/to/component/_package/' - }, function(e, r){ - result = r; - done(); - }); + it('should wrap the for loop with an iterator limit', function(){ + expect(result).to.contain('for(var i=1e12;;){ if(__ITER <=0)' + + '{ throw new Error("Loop exceeded maximum allowed iterations"); } y = 546; __ITER--; }'); }); - it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ - expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); + it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ + expect(result).to.contain('var __ITER = 1000000000;do { if(__ITER <=0)' + + '{ throw new Error("Loop exceeded maximum allowed iterations"); } z = 342; __ITER--; } while(true)'); }); + }); + }); - it('should wrap the for loop with an iterator limit', function(){ - expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); + describe('bundle/config', function(){ + + describe('when configured', function(){ + var config = webpackConfigGenerator({ + webpack: { stats: 'none' }, + dependencies: {}, + fileName: 'server.js', + dataPath: '/Users/nbalestra/dev/oc/test/integration/cli-domain-package-server-script/component/server.js' }); - it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ - expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); + it('should return a proper confifuration options for webpack', function(){ + expect(config.entry).to.be.equal('/Users/nbalestra/dev/oc/test/integration/cli-domain-package-server-script/component/server.js'); + expect(config.output.filename).to.be.equal('server.js'); + expect(config.externals).to.be.an('array'); }); }); }); From af9b87f9f254e2418c8499279c2b15030e1521dc Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Mon, 16 Jan 2017 16:36:40 +0000 Subject: [PATCH 24/43] resolveLoader --- .../domain/package-server-script/bundle/config/index.js | 9 ++++++--- .../cli-domain-package-server-script.js | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js index 61ae2f9cc..9248e3e67 100644 --- a/src/cli/domain/package-server-script/bundle/config/index.js +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -2,10 +2,10 @@ 'use strict'; var webpack = require('webpack'); +var path = require('path'); var wrapLoops = require('./wrapLoops'); var externalDependenciesHandlers = require('./externalDependenciesHandlers'); - module.exports = function webpackConfigGenerator(params){ return { entry: params.dataPath, @@ -30,7 +30,7 @@ module.exports = function webpackConfigGenerator(params){ 'babel-loader?' + JSON.stringify({ cacheDirectory: true, 'presets': [ - ['env', { + [require.resolve('babel-preset-env'), { 'targets': { 'node': 0.10 } @@ -54,6 +54,9 @@ module.exports = function webpackConfigGenerator(params){ 'process.env.NODE_ENV': JSON.stringify('production') }) ], - falafel: wrapLoops + falafel: wrapLoops, + resolveLoader: { + root: path.resolve(__dirname, '../../../../../../node_modules') + } }; }; diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 2ae493273..77c612049 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -67,7 +67,7 @@ describe('cli : domain : package-server-script', function(){ ); } catch (e) { expect(e).to.contain.contain('Unexpected token, expected , (3:19)'); - done(); + return done(); } }); }); From 89aafd34c222af1c3c8c78a7b4c5924c8214a18c Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 17 Jan 2017 09:00:10 +0000 Subject: [PATCH 25/43] tests --- .../cli-domain-package-server-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 77c612049..43897467b 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -340,7 +340,7 @@ describe('cli : domain : package-server-script', function(){ }); describe('when component code includes a loop', function(){ - var serverContent = 'module.exports.data=function(context,cb){ var x,y,z;' + var serverContent = 'module.exports.data=function(context,cb){ var x,y,z;' + 'while(true){ x = 234; }' + 'for(var i=1e12;;){ y = 546; }' + 'do { z = 342; } while(true);' From 1bb52c7bdeb7a6a1935000c124deedc76a07823c Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 10:28:04 +0000 Subject: [PATCH 26/43] initial test --- package.json | 1 + .../cli-domain-package-server-script.js | 355 ++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js diff --git a/package.json b/package.json index 448e74b5e..564df6599 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "load-grunt-tasks": "^3.5.2", "mocha": "^3.0.2", "phantomjs-prebuilt": "^2.1.12", + "rimraf": "^2.5.4", "semver-sort": "0.0.4", "sinon": "^1.17.5" }, diff --git a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js new file mode 100644 index 000000000..39577f7cc --- /dev/null +++ b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -0,0 +1,355 @@ +'use strict'; + +var expect = require('chai').expect; +var rimraf = require('rimraf'); +var fs = require('fs'); +var path = require('path'); +var packageServerScript = require('../../../src/cli/domain/package-server-script/index.js'); +var hashBuilder = require('../../../src/utils/hash-builder'); + +var serverName = 'server.js'; +var componentName = 'component'; +var componentPath = path.resolve(__dirname, componentName); + +describe('cli : domain : package-server-script', function(){ + beforeEach(function(done){ + if(!fs.existsSync(componentPath)) { + fs.mkdirSync(componentPath) + fs.mkdirSync(path.resolve(componentPath, '_package')) + } + done(); + }); + + afterEach(function(done){ + if(fs.existsSync(componentPath)) { + rimraf.sync(componentPath); + } + done(); + }); + + describe('when packaging component\'s server.js', function(){ + describe('when component does not require any json', function(){ + var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + done(); + }); + + it('should save compiled data provider', function(done){ + var publishPath = path.resolve(componentPath, '_package'); + + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath + }, + function(err, res){ + if (err) throw err + expect(res.type).to.equal('node.js') + expect(res.src).to.equal('server.js') + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}) + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)) + done(); + } + ) + }) + }) + }); +}) + + +// OLD SPEC +// ====================================== + +// var expect = require('chai').expect; +// var injectr = require('injectr'); +// var path = require('path'); +// var sinon = require('sinon'); +// var uglifyJs = require('uglify-js'); +// var _ = require('underscore'); + +// var fsMock, +// packageServerScript; + +// var initialise = function(fs){ + +// fsMock = _.extend({ +// existsSync: sinon.stub().returns(true), +// readFileSync: sinon.stub().returns('file content'), +// readJsonSync: sinon.stub().returns({ content: true }), +// writeFile: sinon.stub().yields(null, 'ok') +// }, fs || {}); + +// packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { +// 'fs-extra': fsMock, +// path: { +// extname: path.extname, +// join: path.join, +// resolve: function(){ +// return _.toArray(arguments).join('/'); +// } +// } +// }); +// }; + +// describe.skip('cli : domain : package-server-script', function(){ + +// describe('when packaging component\'s server.js', function(){ + +// describe('when component implements not-valid javascript', function(){ + +// var error; +// var serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'myserver.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should throw an error with error details', function(){ +// expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); +// }); +// }); + +// describe('when component does not require any json', function(){ + +// var result, +// serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// result = r; +// done(); +// }); +// }); + +// it('should save compiled data provider', function(){ +// expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); +// }); + +// it('should return hash for script', function(){ +// expect(result.hashKey).not.be.empty; +// }); +// }); + +// describe('when component requires a json', function(){ + +// var requiredJson = { hello: 'world' }, +// serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// readJsonSync: sinon.stub().returns(requiredJson) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, done); +// }); + +// it('should save compiled and minified data provider encapsulating json content', function(){ +// var written = fsMock.writeFile.args[0][1]; + +// expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' +// + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' +// + 'module.exports.data=function(e,r){return r(null,{})};'); +// }); +// }); + +// describe('when component requires an npm module', function(){ + +// var error, +// serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should throw an error when the dependency is not present in the package.json', function(){ +// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); +// }); +// }); + +// describe('when component requires a relative path from an npm module', function(){ + +// var error, +// serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should throw an error when the dependency is not present in the package.json', function(){ +// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); +// }); +// }); + +// describe('when component requires a js file', function(){ + +// var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', +// error; + +// beforeEach(function(done){ + +// initialise({ readFileSync: sinon.stub().returns(serverjs) }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should not package component and respond with error', function(){ +// expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); +// }); +// }); + +// describe('when component requires a file without extension that is not found as json', function(){ + +// var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', +// error; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// existsSync: sinon.stub().returns(false) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// error = e; +// done(); +// }); +// }); + +// it('should not package component and respond with error', function(){ +// expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); +// }); +// }); + +// describe('when component code includes a loop', function(){ + +// var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' +// + 'while(true){ x = 234; } ' +// + 'for(var i=1e12;;){ y = 546; }' +// + 'do { z = 342; } while(true);' +// + 'return cb(null,data); };', +// result; + +// beforeEach(function(done){ + +// initialise({ +// readFileSync: sinon.stub().returns(serverjs), +// existsSync: sinon.stub().returns(false) +// }); + +// packageServerScript({ +// componentPath: '/path/to/component/', +// ocOptions: { +// files: { +// data: 'server.js' +// } +// }, +// publishPath: '/path/to/component/_package/' +// }, function(e, r){ +// result = r; +// done(); +// }); +// }); + +// it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); +// }); + +// it('should wrap the for loop with an iterator limit', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); +// }); + +// it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ +// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); +// }); +// }); +// }); +// }); From fd0c275a7649b77afa361433890f96d0844b876d Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 11:06:57 +0000 Subject: [PATCH 27/43] testing compiler errors --- .../cli-domain-package-server-script.js | 37 +++++++-- .../component/_package/server.js | 76 +++++++++++++++++++ .../component/server.js | 3 + 3 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 test/unit/cli-domain-package-server-script/component/_package/server.js create mode 100644 test/unit/cli-domain-package-server-script/component/server.js diff --git a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js index 39577f7cc..9e8f99eb7 100644 --- a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -10,6 +10,7 @@ var hashBuilder = require('../../../src/utils/hash-builder'); var serverName = 'server.js'; var componentName = 'component'; var componentPath = path.resolve(__dirname, componentName); +var publishPath = path.resolve(componentPath, '_package'); describe('cli : domain : package-server-script', function(){ beforeEach(function(done){ @@ -22,7 +23,7 @@ describe('cli : domain : package-server-script', function(){ afterEach(function(done){ if(fs.existsSync(componentPath)) { - rimraf.sync(componentPath); + // rimraf.sync(componentPath); } done(); }); @@ -37,8 +38,6 @@ describe('cli : domain : package-server-script', function(){ }); it('should save compiled data provider', function(done){ - var publishPath = path.resolve(componentPath, '_package'); - packageServerScript( { componentPath: componentPath, @@ -58,8 +57,36 @@ describe('cli : domain : package-server-script', function(){ done(); } ) - }) - }) + }); + }); + + describe.only('when component implements not-valid javascript', function(){ + var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) + done(); + }); + + it('should throw an error with error details', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath + }, + function(err, res){ + expect(err.toString().match(/Unexpected token \(3:19\)/)).to.be.ok; + done(); + } + ) + }); + }); + }); }) diff --git a/test/unit/cli-domain-package-server-script/component/_package/server.js b/test/unit/cli-domain-package-server-script/component/_package/server.js new file mode 100644 index 000000000..87768eb79 --- /dev/null +++ b/test/unit/cli-domain-package-server-script/component/_package/server.js @@ -0,0 +1,76 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.l = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; + +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; + +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; + +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports) { + +throw new Error("Module parse failed: /Users/nbalestra/dev/oc/test/unit/cli-domain-package-server-script/component/server.js Unexpected token (3:19)\nYou may need an appropriate loader to handle this file type.\n| var data=require('request');\n| module.exports.data=function(context,cb){\n| return cb(null,data; };"); + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/test/unit/cli-domain-package-server-script/component/server.js b/test/unit/cli-domain-package-server-script/component/server.js new file mode 100644 index 000000000..6e2a2e2c3 --- /dev/null +++ b/test/unit/cli-domain-package-server-script/component/server.js @@ -0,0 +1,3 @@ +var data=require('request'); +module.exports.data=function(context,cb){ +return cb(null,data; }; \ No newline at end of file From 17ef3b36e949f87361cb13896fbde483f5105141 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 11:25:47 +0000 Subject: [PATCH 28/43] moved integration test to /integration --- .../component/_package/server.js | 2 +- .../component/server.js | 0 .../cli-domain-package-server-script.js | 382 ------------------ 3 files changed, 1 insertion(+), 383 deletions(-) rename test/{unit => integration}/cli-domain-package-server-script/component/_package/server.js (88%) rename test/{unit => integration}/cli-domain-package-server-script/component/server.js (100%) delete mode 100644 test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js diff --git a/test/unit/cli-domain-package-server-script/component/_package/server.js b/test/integration/cli-domain-package-server-script/component/_package/server.js similarity index 88% rename from test/unit/cli-domain-package-server-script/component/_package/server.js rename to test/integration/cli-domain-package-server-script/component/_package/server.js index 87768eb79..b4408d782 100644 --- a/test/unit/cli-domain-package-server-script/component/_package/server.js +++ b/test/integration/cli-domain-package-server-script/component/_package/server.js @@ -70,7 +70,7 @@ /* 0 */ /***/ function(module, exports) { -throw new Error("Module parse failed: /Users/nbalestra/dev/oc/test/unit/cli-domain-package-server-script/component/server.js Unexpected token (3:19)\nYou may need an appropriate loader to handle this file type.\n| var data=require('request');\n| module.exports.data=function(context,cb){\n| return cb(null,data; };"); +module.exports.data=function(context,cb){return cb(null, {name:'John'}); }; /***/ } /******/ ]); \ No newline at end of file diff --git a/test/unit/cli-domain-package-server-script/component/server.js b/test/integration/cli-domain-package-server-script/component/server.js similarity index 100% rename from test/unit/cli-domain-package-server-script/component/server.js rename to test/integration/cli-domain-package-server-script/component/server.js diff --git a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js deleted file mode 100644 index 9e8f99eb7..000000000 --- a/test/unit/cli-domain-package-server-script/cli-domain-package-server-script.js +++ /dev/null @@ -1,382 +0,0 @@ -'use strict'; - -var expect = require('chai').expect; -var rimraf = require('rimraf'); -var fs = require('fs'); -var path = require('path'); -var packageServerScript = require('../../../src/cli/domain/package-server-script/index.js'); -var hashBuilder = require('../../../src/utils/hash-builder'); - -var serverName = 'server.js'; -var componentName = 'component'; -var componentPath = path.resolve(__dirname, componentName); -var publishPath = path.resolve(componentPath, '_package'); - -describe('cli : domain : package-server-script', function(){ - beforeEach(function(done){ - if(!fs.existsSync(componentPath)) { - fs.mkdirSync(componentPath) - fs.mkdirSync(path.resolve(componentPath, '_package')) - } - done(); - }); - - afterEach(function(done){ - if(fs.existsSync(componentPath)) { - // rimraf.sync(componentPath); - } - done(); - }); - - describe('when packaging component\'s server.js', function(){ - describe('when component does not require any json', function(){ - var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' - - beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) - done(); - }); - - it('should save compiled data provider', function(done){ - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } - }, - publishPath: publishPath - }, - function(err, res){ - if (err) throw err - expect(res.type).to.equal('node.js') - expect(res.src).to.equal('server.js') - var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}) - expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)) - done(); - } - ) - }); - }); - - describe.only('when component implements not-valid javascript', function(){ - var serverContent = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; - - beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent) - done(); - }); - - it('should throw an error with error details', function(done){ - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } - }, - publishPath: publishPath - }, - function(err, res){ - expect(err.toString().match(/Unexpected token \(3:19\)/)).to.be.ok; - done(); - } - ) - }); - }); - - }); -}) - - -// OLD SPEC -// ====================================== - -// var expect = require('chai').expect; -// var injectr = require('injectr'); -// var path = require('path'); -// var sinon = require('sinon'); -// var uglifyJs = require('uglify-js'); -// var _ = require('underscore'); - -// var fsMock, -// packageServerScript; - -// var initialise = function(fs){ - -// fsMock = _.extend({ -// existsSync: sinon.stub().returns(true), -// readFileSync: sinon.stub().returns('file content'), -// readJsonSync: sinon.stub().returns({ content: true }), -// writeFile: sinon.stub().yields(null, 'ok') -// }, fs || {}); - -// packageServerScript = injectr('../../src/cli/domain/package-server-script/index.js', { -// 'fs-extra': fsMock, -// path: { -// extname: path.extname, -// join: path.join, -// resolve: function(){ -// return _.toArray(arguments).join('/'); -// } -// } -// }); -// }; - -// describe.skip('cli : domain : package-server-script', function(){ - -// describe('when packaging component\'s server.js', function(){ - -// describe('when component implements not-valid javascript', function(){ - -// var error; -// var serverjs = 'var data=require(\'request\');\nmodule.exports.data=function(context,cb){\nreturn cb(null,data; };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'myserver.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should throw an error with error details', function(){ -// expect(error.toString()).to.equal('Error: Javascript error found in myserver.js [3,19]: SyntaxError: Unexpected token punc «;», expected punc «,»]'); -// }); -// }); - -// describe('when component does not require any json', function(){ - -// var result, -// serverjs = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// result = r; -// done(); -// }); -// }); - -// it('should save compiled data provider', function(){ -// expect(fsMock.writeFile.args[0][1]).to.equal('module.exports.data=function(n,e){return e(null,{name:"John"})};'); -// }); - -// it('should return hash for script', function(){ -// expect(result.hashKey).not.be.empty; -// }); -// }); - -// describe('when component requires a json', function(){ - -// var requiredJson = { hello: 'world' }, -// serverjs = 'var data = require(\'./someJson\'); module.exports.data=function(context,cb){return cb(null,{}); };'; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// readJsonSync: sinon.stub().returns(requiredJson) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, done); -// }); - -// it('should save compiled and minified data provider encapsulating json content', function(){ -// var written = fsMock.writeFile.args[0][1]; - -// expect(written).to.contain('var __sandboxedRequire=require,__localRequires={"./someJson":{hello:"world"}};' -// + 'require=function(e){return __localRequires[e]?__localRequires[e]:__sandboxedRequire(e)};var data=require("./someJson");' -// + 'module.exports.data=function(e,r){return r(null,{})};'); -// }); -// }); - -// describe('when component requires an npm module', function(){ - -// var error, -// serverjs = 'var data=require(\'request\');module.exports.data=function(context,cb){return cb(null,data); };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should throw an error when the dependency is not present in the package.json', function(){ -// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["request"]'); -// }); -// }); - -// describe('when component requires a relative path from an npm module', function(){ - -// var error, -// serverjs = 'var data=require(\'react-dom/server\');module.exports.data=function(context,cb){return cb(null,data); };'; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should throw an error when the dependency is not present in the package.json', function(){ -// expect(error.toString()).to.equal('Error: Missing dependencies from package.json => ["react-dom"]'); -// }); -// }); - -// describe('when component requires a js file', function(){ - -// var serverjs = 'var data=require(\'./hi.js\');module.exports.data=function(context,cb){return cb(null,data); };', -// error; - -// beforeEach(function(done){ - -// initialise({ readFileSync: sinon.stub().returns(serverjs) }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should not package component and respond with error', function(){ -// expect(error.toString()).to.equal('Error: Requiring local js files is not allowed. Keep it small.'); -// }); -// }); - -// describe('when component requires a file without extension that is not found as json', function(){ - -// var serverjs = 'var data=require(\'./hi\');module.exports.data=function(context,cb){return cb(null,data); };', -// error; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// existsSync: sinon.stub().returns(false) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// error = e; -// done(); -// }); -// }); - -// it('should not package component and respond with error', function(){ -// expect(error.toString()).to.equal('Error: ./hi.json not found. Only json files are require-able.'); -// }); -// }); - -// describe('when component code includes a loop', function(){ - -// var serverjs = 'module.exports.data=function(context,cb){ var x,y,z;' -// + 'while(true){ x = 234; } ' -// + 'for(var i=1e12;;){ y = 546; }' -// + 'do { z = 342; } while(true);' -// + 'return cb(null,data); };', -// result; - -// beforeEach(function(done){ - -// initialise({ -// readFileSync: sinon.stub().returns(serverjs), -// existsSync: sinon.stub().returns(false) -// }); - -// packageServerScript({ -// componentPath: '/path/to/component/', -// ocOptions: { -// files: { -// data: 'server.js' -// } -// }, -// publishPath: '/path/to/component/_package/' -// }, function(e, r){ -// result = r; -// done(); -// }); -// }); - -// it('should wrap the while loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var r,a,t,i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");r=234,i--}'); -// }); - -// it('should wrap the for loop with an iterator limit', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");a=546,i--}'); -// }); - -// it('should wrap the do loop with an iterator limit (and convert it to a for loop)', function(){ -// expect(fsMock.writeFile.firstCall.args[1]).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); -// }); -// }); -// }); -// }); From afdb51e1801efb57bc9fa493df5a919e002d7570 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 13:45:42 +0000 Subject: [PATCH 29/43] drop rimraf -> fs-extra --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 564df6599..448e74b5e 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "load-grunt-tasks": "^3.5.2", "mocha": "^3.0.2", "phantomjs-prebuilt": "^2.1.12", - "rimraf": "^2.5.4", "semver-sort": "0.0.4", "sinon": "^1.17.5" }, From c312a54aaac7bbcedb2a069d9f003685475bb744 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 15:54:48 +0000 Subject: [PATCH 30/43] integration test wip --- .../component/_package/server.js | 76 ------------------- .../component/server.js | 3 - 2 files changed, 79 deletions(-) delete mode 100644 test/integration/cli-domain-package-server-script/component/_package/server.js delete mode 100644 test/integration/cli-domain-package-server-script/component/server.js diff --git a/test/integration/cli-domain-package-server-script/component/_package/server.js b/test/integration/cli-domain-package-server-script/component/_package/server.js deleted file mode 100644 index b4408d782..000000000 --- a/test/integration/cli-domain-package-server-script/component/_package/server.js +++ /dev/null @@ -1,76 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // The require function -/******/ function __webpack_require__(moduleId) { - -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; - -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.l = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; - -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; - -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; - -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports) { - -module.exports.data=function(context,cb){return cb(null, {name:'John'}); }; - -/***/ } -/******/ ]); \ No newline at end of file diff --git a/test/integration/cli-domain-package-server-script/component/server.js b/test/integration/cli-domain-package-server-script/component/server.js deleted file mode 100644 index 6e2a2e2c3..000000000 --- a/test/integration/cli-domain-package-server-script/component/server.js +++ /dev/null @@ -1,3 +0,0 @@ -var data=require('request'); -module.exports.data=function(context,cb){ -return cb(null,data; }; \ No newline at end of file From d97575c01447dc06412f26a282e6fc7b091629d5 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 17:34:09 +0000 Subject: [PATCH 31/43] es6 example integration test --- .../cli-domain-package-server-script.js | 88 +------------------ 1 file changed, 2 insertions(+), 86 deletions(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 43897467b..8ea4062a5 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -25,7 +25,7 @@ describe('cli : domain : package-server-script', function(){ afterEach(function(done){ if(fs.existsSync(componentPath)) { - fs.removeSync(componentPath); + // fs.removeSync(componentPath); } done(); }); @@ -73,91 +73,7 @@ describe('cli : domain : package-server-script', function(){ }); describe('when component does not require any json', function(){ - var serverContent = '\nmodule.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; - - beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); - done(); - }); - - it('should save compiled data provider and return a hash for the script', function(done){ - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } - }, - publishPath: publishPath, - webpack: webpackOptions - }, - function(err, res){ - if (err) { - return done(err); - } - try { - expect(res.type).to.equal('node.js'); - expect(res.src).to.equal('server.js'); - - var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); - expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); - return done(); - } catch(e) { - return done(e); - } - } - ); - }); - }); - - describe('when component require a json file', function(){ - var user = {first: 'John',last:'Doe'}; - var jsonContent = JSON.stringify(user); - var serverContent = 'var user = require(\'./user\');\nmodule.exports.data=function(){return user.first;};'; - - beforeEach(function(done){ - fs.writeFileSync(path.resolve(componentPath, 'user.json'), jsonContent); - fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); - done(); - }); - - it('should save compiled and minified data provider encapsulating json content', function(done){ - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } - }, - publishPath: publishPath, - webpack: webpackOptions - }, - function(err, res){ - if (err) { - return done(err); - } - try { - var name = user.first; - var bundle = require(path.resolve(publishPath, res.src)); - expect(bundle.data()).to.be.equal(name); - - var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); - expect(compiledContent).to.not.contain('user'); - return done(); - } catch(e) { - return done(e); - } - } - ); - }); - }); - - describe('when component does require an npm module', function(){ - var serverContent = 'var _ =require(\'underscore\');' - + '\nvar user = {name:\'John\'};\nmodule.exports.data=function(context,cb){' - + '\nreturn cb(null, _.has(user, \'name\'));\n};'; + var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); From 494a8b1aa991c3c7f5a30db5964a6d4b7ec3ce2e Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Tue, 10 Jan 2017 18:01:06 +0000 Subject: [PATCH 32/43] cleanup --- .../cli-domain-package-server-script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 8ea4062a5..fea488a95 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -25,7 +25,7 @@ describe('cli : domain : package-server-script', function(){ afterEach(function(done){ if(fs.existsSync(componentPath)) { - // fs.removeSync(componentPath); + fs.removeSync(componentPath); } done(); }); @@ -73,7 +73,7 @@ describe('cli : domain : package-server-script', function(){ }); describe('when component does not require any json', function(){ - var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };' + var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); From 0b491bb60a4e12facbf115f78aa5a965b2fe5296 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 04:19:31 +0000 Subject: [PATCH 33/43] added config module --- .../bundle/webpack.server.config.js | 44 +++++++++++++++++++ .../package-server-script/bundle/wrapLoops.js | 22 ++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/cli/domain/package-server-script/bundle/webpack.server.config.js create mode 100644 src/cli/domain/package-server-script/bundle/wrapLoops.js diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js new file mode 100644 index 000000000..438d307b5 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/webpack.server.config.js @@ -0,0 +1,44 @@ +/*jshint camelcase:false */ +'use strict'; +var webpack = require('webpack'); + +var config = { + module: { + loaders: [ + { + test: /\.json$/, + loader: 'json-loader', + exclude: /node_modules/ + }, + { + test: /\.jsx?$/, + exclude: /node_modules/, + loader: 'babel-loader', + query: { + 'presets': [ + ['env', { + 'targets': { + 'node': 0.10 + } + }] + ] + } + } + ] + }, + plugins: [ + new webpack.optimize.OccurenceOrderPlugin(), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false, + screw_ie8: true + }, + sourceMap: false + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + }) + ] +}; + +module.exports = config; diff --git a/src/cli/domain/package-server-script/bundle/wrapLoops.js b/src/cli/domain/package-server-script/bundle/wrapLoops.js new file mode 100644 index 000000000..37cc10500 --- /dev/null +++ b/src/cli/domain/package-server-script/bundle/wrapLoops.js @@ -0,0 +1,22 @@ +'use strict'; +var CONST_MAX_ITERATIONS = 10000; + +var wrapLoops = function(node){ + var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; + + if(loopKeywords.indexOf(node.type) > -1){ + node.update('{ var __ITER = ' + CONST_MAX_ITERATIONS + ';' + + node.source() + '}'); + } + + if(!node.parent){ + return; + } + + if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement') { + node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum allowed iterations"); } ' + + node.source() + ' __ITER--; }'); + } +}; + +module.exports = wrapLoops; From 4939afd7d75e6d4694c39dba3b95ef5dd9b5ae06 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 13:02:23 +0000 Subject: [PATCH 34/43] libraryTarget=commonjs2, externals=regex, added json-loader & integration test --- .../package-server-script/bundle/webpack.server.config.js | 7 ++++--- .../cli-domain-package-server-script.js | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js index 438d307b5..6a05cfa85 100644 --- a/src/cli/domain/package-server-script/bundle/webpack.server.config.js +++ b/src/cli/domain/package-server-script/bundle/webpack.server.config.js @@ -4,14 +4,15 @@ var webpack = require('webpack'); var config = { module: { + externals: /^[a-z@][a-z\-\/0-9]+$/, loaders: [ { test: /\.json$/, - loader: 'json-loader', - exclude: /node_modules/ + exclude: /node_modules/, + loader: 'json-loader' }, { - test: /\.jsx?$/, + test: /\.js?$/, exclude: /node_modules/, loader: 'babel-loader', query: { diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index fea488a95..4f18989dd 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -72,7 +72,7 @@ describe('cli : domain : package-server-script', function(){ }); }); - describe('when component does not require any json', function(){ + describe('when component does not require any module', function(){ var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; beforeEach(function(done){ @@ -187,7 +187,7 @@ describe('cli : domain : package-server-script', function(){ done(); }); - it('should save compiled data provider encapsulating js module content', function(done){ + it('should transpile it to es2015 through Babel', function(done){ packageServerScript( { componentPath: componentPath, From 818f58a5a906be7f0fba5732851b318810cd622e Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 11 Jan 2017 16:34:39 +0000 Subject: [PATCH 35/43] wrap while/do/for;; loops with an iterator limit --- .../bundle/webpack.server.config.js | 27 +++++++++++-------- .../package-server-script/bundle/wrapLoops.js | 20 +++++++++----- .../cli-domain-package-server-script.js | 2 +- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js index 6a05cfa85..29cce45a4 100644 --- a/src/cli/domain/package-server-script/bundle/webpack.server.config.js +++ b/src/cli/domain/package-server-script/bundle/webpack.server.config.js @@ -1,6 +1,7 @@ /*jshint camelcase:false */ 'use strict'; var webpack = require('webpack'); +var wrapLoops = require('./wrapLoops'); var config = { module: { @@ -14,16 +15,19 @@ var config = { { test: /\.js?$/, exclude: /node_modules/, - loader: 'babel-loader', - query: { - 'presets': [ - ['env', { - 'targets': { - 'node': 0.10 - } - }] - ] - } + loaders: [ + 'falafel-loader', + 'babel-loader?' + JSON.stringify({ + cacheDirectory: true, + 'presets': [ + ['env', { + 'targets': { + 'node': 0.10 + } + }] + ] + }) + ], } ] }, @@ -39,7 +43,8 @@ var config = { new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }) - ] + ], + falafel: wrapLoops }; module.exports = config; diff --git a/src/cli/domain/package-server-script/bundle/wrapLoops.js b/src/cli/domain/package-server-script/bundle/wrapLoops.js index 37cc10500..f0320fb78 100644 --- a/src/cli/domain/package-server-script/bundle/wrapLoops.js +++ b/src/cli/domain/package-server-script/bundle/wrapLoops.js @@ -1,21 +1,27 @@ 'use strict'; -var CONST_MAX_ITERATIONS = 10000; -var wrapLoops = function(node){ +var CONST_MAX_ITERATIONS = require('../../../../resources/settings').maxLoopIterations; + +var wrapLoops = function (node) { var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; if(loopKeywords.indexOf(node.type) > -1){ - node.update('{ var __ITER = ' + CONST_MAX_ITERATIONS + ';' - + node.source() + '}'); + node.update( + 'var __ITER = ' + CONST_MAX_ITERATIONS + ';\n' + + node.source() + ); } if(!node.parent){ return; } - if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement') { - node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum allowed iterations"); } ' - + node.source() + ' __ITER--; }'); + if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement'){ + node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum ' + + 'allowed iterations"); } ' + + node.source().substr(1).slice(0, -1) + + ' __ITER--; }' + ); } }; diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 4f18989dd..4f6ca19a3 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -73,7 +73,7 @@ describe('cli : domain : package-server-script', function(){ }); describe('when component does not require any module', function(){ - var serverContent = 'module.exports.data=function(context,cb){return cb(null, {name:\'John\'}); };'; + var serverContent = 'module.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); From 8944a4766e9dc315c0497b8a5d437400c82a65d0 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 12 Jan 2017 13:06:54 +0000 Subject: [PATCH 36/43] structure/internaAPIi refactor --- .../config/externalDependenciesHandlers.js | 2 - .../bundle/webpack.server.config.js | 50 ------------------- .../package-server-script/bundle/wrapLoops.js | 28 ----------- 3 files changed, 80 deletions(-) delete mode 100644 src/cli/domain/package-server-script/bundle/webpack.server.config.js delete mode 100644 src/cli/domain/package-server-script/bundle/wrapLoops.js diff --git a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js index c15eacec2..f883d65b4 100644 --- a/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js +++ b/src/cli/domain/package-server-script/bundle/config/externalDependenciesHandlers.js @@ -34,5 +34,3 @@ module.exports = function externalDependenciesHandlers(dependencies){ /^[a-z@][a-z\-\/0-9]+$/i ]; }; - - diff --git a/src/cli/domain/package-server-script/bundle/webpack.server.config.js b/src/cli/domain/package-server-script/bundle/webpack.server.config.js deleted file mode 100644 index 29cce45a4..000000000 --- a/src/cli/domain/package-server-script/bundle/webpack.server.config.js +++ /dev/null @@ -1,50 +0,0 @@ -/*jshint camelcase:false */ -'use strict'; -var webpack = require('webpack'); -var wrapLoops = require('./wrapLoops'); - -var config = { - module: { - externals: /^[a-z@][a-z\-\/0-9]+$/, - loaders: [ - { - test: /\.json$/, - exclude: /node_modules/, - loader: 'json-loader' - }, - { - test: /\.js?$/, - exclude: /node_modules/, - loaders: [ - 'falafel-loader', - 'babel-loader?' + JSON.stringify({ - cacheDirectory: true, - 'presets': [ - ['env', { - 'targets': { - 'node': 0.10 - } - }] - ] - }) - ], - } - ] - }, - plugins: [ - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.optimize.UglifyJsPlugin({ - compressor: { - warnings: false, - screw_ie8: true - }, - sourceMap: false - }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) - }) - ], - falafel: wrapLoops -}; - -module.exports = config; diff --git a/src/cli/domain/package-server-script/bundle/wrapLoops.js b/src/cli/domain/package-server-script/bundle/wrapLoops.js deleted file mode 100644 index f0320fb78..000000000 --- a/src/cli/domain/package-server-script/bundle/wrapLoops.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -var CONST_MAX_ITERATIONS = require('../../../../resources/settings').maxLoopIterations; - -var wrapLoops = function (node) { - var loopKeywords = ['WhileStatement', 'ForStatement', 'DoWhileStatement']; - - if(loopKeywords.indexOf(node.type) > -1){ - node.update( - 'var __ITER = ' + CONST_MAX_ITERATIONS + ';\n' - + node.source() - ); - } - - if(!node.parent){ - return; - } - - if(loopKeywords.indexOf(node.parent.type) > -1 && node.type === 'BlockStatement'){ - node.update('{ if(__ITER <=0){ throw new Error("loop exceeded maximum ' - + 'allowed iterations"); } ' - + node.source().substr(1).slice(0, -1) - + ' __ITER--; }' - ); - } -}; - -module.exports = wrapLoops; From 9b3fefe0b86f024d9e630f6b7e0249d87533f63a Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 12 Jan 2017 16:31:49 +0000 Subject: [PATCH 37/43] integration tests --- .../cli-domain-package-server-script.js | 115 +++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 4f6ca19a3..5581f3d53 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -43,6 +43,7 @@ describe('cli : domain : package-server-script', function(){ }); it('should throw an error with error details', function(done){ +<<<<<<< 139682f91d4265cf5a425a2e232c0e52a16f09f9 try { packageServerScript( { @@ -74,6 +75,118 @@ describe('cli : domain : package-server-script', function(){ describe('when component does not require any module', function(){ var serverContent = 'module.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; +======= + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions + }, + function(err, res){ + try { + expect(err.toString()).to.contain.contain('Unexpected token, expected , (3:19)'); + return done(); + } catch(e) { + return done(e); + } + return done('error'); + } + ); + }); + }); + + describe('when component does not require any json', function(){ + var serverContent = '\nmodule.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should save compiled data provider and return a hash for the script', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions + }, + function(err, res){ + if (err) { + return done(err); + } + try { + expect(res.type).to.equal('node.js'); + expect(res.src).to.equal('server.js'); + + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); + return done(); + } catch(e) { + return done(e); + } + } + ); + }); + }); + + describe('when component require a json file', function(){ + var user = {first: 'John',last:'Doe'}; + var jsonContent = JSON.stringify(user); + var serverContent = 'var user = require(\'./user\');\nmodule.exports.data=function(){return user.first;};'; + + beforeEach(function(done){ + fs.writeFileSync(path.resolve(componentPath, 'user.json'), jsonContent); + fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); + done(); + }); + + it('should save compiled and minified data provider encapsulating json content', function(done){ + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions + }, + function(err, res){ + if (err) { + return done(err); + } + try { + var name = user.first; + var bundle = require(path.resolve(publishPath, res.src)); + expect(bundle.data()).to.be.equal(name); + + var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); + expect(compiledContent).to.not.contain('user'); + return done(); + } catch(e) { + return done(e); + } + } + ); + }); + }); + + describe('when component does require an npm module', function(){ + var serverContent = 'var _ =require(\'underscore\');' + + '\nvar user = {name:\'John\'};\nmodule.exports.data=function(context,cb){' + + '\nreturn cb(null, _.has(user, \'name\'));\n};'; +>>>>>>> integration tests beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); @@ -187,7 +300,7 @@ describe('cli : domain : package-server-script', function(){ done(); }); - it('should transpile it to es2015 through Babel', function(done){ + it('should save compiled data provider encapsulating js module content', function(done){ packageServerScript( { componentPath: componentPath, From 366200e6c41cfe4c9abd893d414f0cda7be10761 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Fri, 13 Jan 2017 17:48:34 +0000 Subject: [PATCH 38/43] unit tests --- .../cli-domain-package-server-script.js | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 5581f3d53..c4073a828 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -43,7 +43,6 @@ describe('cli : domain : package-server-script', function(){ }); it('should throw an error with error details', function(done){ -<<<<<<< 139682f91d4265cf5a425a2e232c0e52a16f09f9 try { packageServerScript( { @@ -68,38 +67,11 @@ describe('cli : domain : package-server-script', function(){ ); } catch (e) { expect(e).to.contain.contain('Unexpected token, expected , (3:19)'); - return done(); + done(); } }); }); - describe('when component does not require any module', function(){ - var serverContent = 'module.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; -======= - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } - }, - publishPath: publishPath, - webpack: webpackOptions - }, - function(err, res){ - try { - expect(err.toString()).to.contain.contain('Unexpected token, expected , (3:19)'); - return done(); - } catch(e) { - return done(e); - } - return done('error'); - } - ); - }); - }); - describe('when component does not require any json', function(){ var serverContent = '\nmodule.exports.data=function(context,cb){\nreturn cb(null, {name:\'John\'});\n};'; @@ -186,7 +158,6 @@ describe('cli : domain : package-server-script', function(){ var serverContent = 'var _ =require(\'underscore\');' + '\nvar user = {name:\'John\'};\nmodule.exports.data=function(context,cb){' + '\nreturn cb(null, _.has(user, \'name\'));\n};'; ->>>>>>> integration tests beforeEach(function(done){ fs.writeFileSync(path.resolve(componentPath, serverName), serverContent); From 19477b3098aabda55bc00dfa874a09e9def01567 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Mon, 16 Jan 2017 16:36:40 +0000 Subject: [PATCH 39/43] resolveLoader --- .../cli-domain-package-server-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index c4073a828..43897467b 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -67,7 +67,7 @@ describe('cli : domain : package-server-script', function(){ ); } catch (e) { expect(e).to.contain.contain('Unexpected token, expected , (3:19)'); - done(); + return done(); } }); }); From 2a9cd221208df2d4f874094d1e81c4bb6f279eac Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 18 Jan 2017 10:06:51 +0000 Subject: [PATCH 40/43] added target node for the webpack config --- src/cli/domain/package-server-script/bundle/config/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js index 9248e3e67..f2b9d2e48 100644 --- a/src/cli/domain/package-server-script/bundle/config/index.js +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -9,10 +9,11 @@ var externalDependenciesHandlers = require('./externalDependenciesHandlers'); module.exports = function webpackConfigGenerator(params){ return { entry: params.dataPath, + target: 'node', output: { path: '/build', filename: params.fileName, - libraryTarget: 'commonjs2' + libraryTarget: 'commonjs2', }, externals: externalDependenciesHandlers(params.dependencies), module: { From 41944ce3aa0fb6d8e725d541d65d09ef0d7a2e09 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 18 Jan 2017 11:08:52 +0000 Subject: [PATCH 41/43] tests cleanup --- .../cli-domain-package-server-script.js | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 43897467b..2801bfa65 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -102,9 +102,9 @@ describe('cli : domain : package-server-script', function(){ var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); - return done(); + done(); } catch(e) { - return done(e); + done(e); } } ); @@ -145,9 +145,9 @@ describe('cli : domain : package-server-script', function(){ var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); expect(compiledContent).to.not.contain('user'); - return done(); + done(); } catch(e) { - return done(e); + done(e); } } ); @@ -189,9 +189,9 @@ describe('cli : domain : package-server-script', function(){ var compiledContent = fs.readFileSync(path.resolve(publishPath, res.src), {encoding: 'utf8'}); expect(res.hashKey).to.equal(hashBuilder.fromString(compiledContent)); - return done(); + done(); } catch(e) { - return done(e); + done(e); } } ); @@ -214,12 +214,9 @@ describe('cli : domain : package-server-script', function(){ dependencies: dependencies }, function(err, res){ - try { - expect(/Missing depenencies drom package.json => \"underscore\"/ig.test(err)); - return done(); - } catch(e) { - return done(e); - } + expect(err).to.not.be.null; + expect(err).to.contain('Missing dependencies from package.json => "underscore"'); + done(); } ); }); @@ -250,12 +247,9 @@ describe('cli : domain : package-server-script', function(){ dependencies: dependencies }, function(err, res){ - try { - expect(err.toString()).to.contain('Missing dependencies from package.json => \"react-dom\"'); - return done(); - } catch(e) { - return done(e); - } + expect(err).to.not.be.null; + expect(err.toString()).to.contain('Missing dependencies from package.json => "react-dom"'); + done(); } ); }); @@ -291,9 +285,9 @@ describe('cli : domain : package-server-script', function(){ var name = 'John'; var bundle = require(path.resolve(publishPath, res.src)); expect(bundle.data()).to.be.equal(name); - return done(); + done(); } catch(e) { - return done(e); + done(e); } } ); @@ -330,9 +324,9 @@ describe('cli : domain : package-server-script', function(){ expect(compiledContent).to.not.contain('const'); expect(compiledContent).to.contain('var'); expect(compiledContent).to.contain('function'); - return done(); + done(); } catch(e) { - return done(e); + done(e); } } ); @@ -374,7 +368,7 @@ describe('cli : domain : package-server-script', function(){ expect(compiledContent).to.contain('for(var i=1e9;;){if(i<=0)throw new Error(\"loop exceeded maximum allowed iterations\");t=342,i--}'); done(); } catch(e) { - return done(); + done(); } } ); From dbf47143244b6b991ce805fef567be086bb75b9e Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 18 Jan 2017 16:14:58 +0000 Subject: [PATCH 42/43] rebase --- src/cli/domain/package-server-script/bundle/config/index.js | 2 +- src/cli/domain/package-server-script/bundle/index.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js index f2b9d2e48..6c29bbd54 100644 --- a/src/cli/domain/package-server-script/bundle/config/index.js +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -33,7 +33,7 @@ module.exports = function webpackConfigGenerator(params){ 'presets': [ [require.resolve('babel-preset-env'), { 'targets': { - 'node': 0.10 + 'node': 4 } }] ] diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 8773fb815..0d8e2b45c 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -1,10 +1,8 @@ /*jshint camelcase:false */ 'use strict'; -var _ = require('underscore'); var webpackConfig = require('./config'); var console = require('console'); var MemoryFS = require('memory-fs'); -var path = require('path'); var webpack = require('webpack'); var memoryFs = new MemoryFS(); From 34dc1cec02e2f95ef617136ded1200dddb6a0930 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Fri, 20 Jan 2017 09:41:00 +0000 Subject: [PATCH 43/43] review-fixes --- .../package-server-script/bundle/index.js | 6 +-- src/resources/index.js | 3 -- .../cli-domain-package-server-script.js | 52 ++++++++++++------- test/unit/cli-domain-package-server-script.js | 6 +-- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 0d8e2b45c..bfb183b24 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -13,7 +13,7 @@ module.exports = function bundle(params, callBack) { compiler.outputFileSystem = memoryFs; compiler.run(function(error, stats){ - var sofError; + var softError; var warning; // handleFatalError @@ -24,8 +24,8 @@ module.exports = function bundle(params, callBack) { var info = stats.toJson(); // handleSoftErrors if (stats.hasErrors()) { - sofError = info.errors.toString(); - return callBack(sofError); + softError = info.errors.toString(); + return callBack(softError); } // handleWarnings if (stats.hasWarnings()) { diff --git a/src/resources/index.js b/src/resources/index.js index 6fc851ad3..1d0c4680c 100644 --- a/src/resources/index.js +++ b/src/resources/index.js @@ -80,9 +80,6 @@ module.exports = { PUBLISHING_FAIL: 'An error happened when publishing the component: {0}', REGISTRY_NOT_FOUND: 'oc registries not found. Run "oc registry add "', SERVERJS_DEPENDENCY_NOT_DECLARED: 'Missing dependencies from package.json => {0}', - SERVERJS_PARSING_ERROR: 'Javascript error found in {0} [{1},{2}]: {3}]', - SERVERJS_REQUIRE_JS_NOT_ALLOWED: 'Requiring local js files is not allowed. Keep it small.', - SERVERJS_REQUIRE_JSON_NOT_FOUND: '{0} not found. Only json files are require-able.', TEMPLATE_NOT_FOUND: 'file {0} not found', TEMPLATE_TYPE_NOT_VALID: 'the template is not valid. Allowed values are handlebars and jade' }, diff --git a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js index 2801bfa65..6ed547dd7 100644 --- a/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js +++ b/test/integration/cli-domain-package-server-script/cli-domain-package-server-script.js @@ -122,6 +122,11 @@ describe('cli : domain : package-server-script', function(){ done(); }); + afterEach(function(done){ + require.cache[path.resolve(publishPath, serverName)] = null; + done(); + }); + it('should save compiled and minified data provider encapsulating json content', function(done){ packageServerScript( { @@ -197,7 +202,7 @@ describe('cli : domain : package-server-script', function(){ ); }); - describe('end required depenencies is not present in the package.json', function(){ + describe('and required dependencies are not present in the package.json', function(){ it('should throw an error with details', function(done){ var dependencies = {lodash: '1.0.0'}; @@ -231,27 +236,29 @@ describe('cli : domain : package-server-script', function(){ done(); }); - it('should throw an error when the dependency is not present in the package.json', function(done){ - var dependencies = {'react': '15.4.2'}; + describe('and required dependencies are not present in the package.json', function(){ + it('should throw an error with details', function(done){ + var dependencies = {'react': '15.4.2'}; - packageServerScript( - { - componentPath: componentPath, - ocOptions: { - files: { - data: serverName - } + packageServerScript( + { + componentPath: componentPath, + ocOptions: { + files: { + data: serverName + } + }, + publishPath: publishPath, + webpack: webpackOptions, + dependencies: dependencies }, - publishPath: publishPath, - webpack: webpackOptions, - dependencies: dependencies - }, - function(err, res){ - expect(err).to.not.be.null; - expect(err.toString()).to.contain('Missing dependencies from package.json => "react-dom"'); - done(); - } - ); + function(err, res){ + expect(err).to.not.be.null; + expect(err.toString()).to.contain('Missing dependencies from package.json => "react-dom"'); + done(); + } + ); + }); }); }); @@ -265,6 +272,11 @@ describe('cli : domain : package-server-script', function(){ done(); }); + afterEach(function(done){ + require.cache[path.resolve(publishPath, serverName)] = null; + done(); + }); + it('should save compiled data provider encapsulating js module content', function(done){ packageServerScript( { diff --git a/test/unit/cli-domain-package-server-script.js b/test/unit/cli-domain-package-server-script.js index 870978683..153eef81c 100644 --- a/test/unit/cli-domain-package-server-script.js +++ b/test/unit/cli-domain-package-server-script.js @@ -107,11 +107,11 @@ describe('cli : domain : package-server-script ', function(){ webpack: { stats: 'none' }, dependencies: {}, fileName: 'server.js', - dataPath: '/Users/nbalestra/dev/oc/test/integration/cli-domain-package-server-script/component/server.js' + dataPath: '/path/to/server.js' }); - it('should return a proper confifuration options for webpack', function(){ - expect(config.entry).to.be.equal('/Users/nbalestra/dev/oc/test/integration/cli-domain-package-server-script/component/server.js'); + it('should return a proper configuration options for webpack', function(){ + expect(config.entry).to.be.equal('/path/to/server.js'); expect(config.output.filename).to.be.equal('server.js'); expect(config.externals).to.be.an('array'); });