From d1762a0fb44b82f10f2ef2def387231c40a4025c Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 13 Oct 2017 20:01:35 -0400 Subject: [PATCH] refactor code generation --- lib/contracts/code_generator.js | 188 ++++-------------- .../code_templates/define-web3-simple.js.ejs | 3 + .../define-when-env-loaded.js.ejs | 7 + .../code_templates/do-when-loaded.js.ejs | 6 + .../code_templates/embarkjs-contract.js.ejs | 1 + .../exec-when-env-loaded.js.ejs | 3 + .../code_templates/exec-when-ready.js.ejs | 3 + .../code_templates/load-manager.js.ejs | 4 + .../code_templates/main-context.js.ejs | 1 + lib/contracts/code_templates/utils.js.ejs | 36 ++++ .../code_templates/vanilla-contract.js.ejs | 3 + .../code_templates/web3-connector.js.ejs | 28 +++ lib/core/runCode.js | 6 +- package.json | 1 + test/code_generator.js | 6 +- 15 files changed, 145 insertions(+), 151 deletions(-) create mode 100644 lib/contracts/code_templates/define-web3-simple.js.ejs create mode 100644 lib/contracts/code_templates/define-when-env-loaded.js.ejs create mode 100644 lib/contracts/code_templates/do-when-loaded.js.ejs create mode 100644 lib/contracts/code_templates/embarkjs-contract.js.ejs create mode 100644 lib/contracts/code_templates/exec-when-env-loaded.js.ejs create mode 100644 lib/contracts/code_templates/exec-when-ready.js.ejs create mode 100644 lib/contracts/code_templates/load-manager.js.ejs create mode 100644 lib/contracts/code_templates/main-context.js.ejs create mode 100644 lib/contracts/code_templates/utils.js.ejs create mode 100644 lib/contracts/code_templates/vanilla-contract.js.ejs create mode 100644 lib/contracts/code_templates/web3-connector.js.ejs diff --git a/lib/contracts/code_generator.js b/lib/contracts/code_generator.js index 54689844..f1dee354 100644 --- a/lib/contracts/code_generator.js +++ b/lib/contracts/code_generator.js @@ -1,3 +1,18 @@ +const ejs = require('ejs'); +const Templates = { + utils: require('./code_templates/utils.js.ejs'), + vanilla_contract: require('./code_templates/vanilla-contract.js.ejs'), + embarkjs_contract: require('./code_templates/embarkjs-contract.js.ejs'), + exec_when_ready: require('./code_templates/exec-when-ready.js.ejs'), + load_manager: require('./code_templates/load-manager.js.ejs'), + define_when_env_loaded: require('./code_templates/define-when-env-loaded.js.ejs'), + main_context: require('./code_templates/main-context.js.ejs'), + define_web3_simple: require('./code_templates/define-web3-simple.js.ejs'), + web3_connector: require('./code_templates/web3-connector.js.ejs'), + do_when_loaded: require('./code_templates/do-when-loaded.js.ejs'), + exec_when_env_loaded: require('./code_templates/exec-when-env-loaded.js.ejs') +} + class CodeGenerator { constructor(options) { this.blockchainConfig = options.blockchainConfig || {}; @@ -51,64 +66,11 @@ class CodeGenerator { return ""; } - result += "\nfunction __reduce(arr, memo, iteratee, cb) {"; - result += "\n if (typeof cb !== 'function') {"; - result += "\n if (typeof memo === 'function' && typeof iteratee === 'function') {"; - result += "\n cb = iteratee;"; - result += "\n iteratee = memo;"; - result += "\n memo = [];"; - result += "\n } else {"; - result += "\n throw new TypeError('expected callback to be a function');"; - result += "\n }"; - result += "\n }"; -result += "\n"; - result += "\n if (!Array.isArray(arr)) {"; - result += "\n cb(new TypeError('expected an array'));"; - result += "\n return;"; - result += "\n }"; -result += "\n"; - result += "\n if (typeof iteratee !== 'function') {"; - result += "\n cb(new TypeError('expected iteratee to be a function'));"; - result += "\n return;"; - result += "\n }"; -result += "\n"; - result += "\n (function next(i, acc) {"; - result += "\n if (i === arr.length) {"; - result += "\n cb(null, acc);"; - result += "\n return;"; - result += "\n }"; -result += "\n"; - result += "\n iteratee(acc, arr[i], function(err, val) {"; - result += "\n if (err) {"; - result += "\n cb(err);"; - result += "\n return;"; - result += "\n }"; - result += "\n next(i + 1, val);"; - result += "\n });"; - result += "\n })(0, memo);"; - result += "\n};"; + result += Templates.utils(); - let mainContext = ""; - if (isDeployment) { - mainContext = "__mainContext."; - result += "\nvar __mainContext = __mainContext || this;"; - } else { - result += "\nvar __mainContext = __mainContext || this;"; - mainContext = "__mainContext."; - } - - result += "\n" + mainContext + "__LoadManager = function() { this.list = []; this.done = false; }"; - result += "\n" + mainContext + "__LoadManager.prototype.execWhenReady = function(cb) { if (this.done) { cb(); } else { this.list.push(cb) } }"; - result += "\n" + mainContext + "__LoadManager.prototype.doFirst = function(todo) { var self = this; todo(function() { self.done = true; self.list.map((x) => x.apply()) }) }"; - result += "\n" + mainContext + "__loadManagerInstance = new " + mainContext + "__LoadManager();"; - - result += "\nvar whenEnvIsLoaded = function(cb) {"; - result += "\n if (typeof document !== 'undefined' && document !== null) {"; - result += "\n document.addEventListener('DOMContentLoaded', cb);"; - result += "\n } else {"; - result += "\n cb();"; - result += "\n }"; - result += "\n}"; + result += Templates.main_context(); + result += Templates.load_manager(); + result += Templates.define_when_env_loaded(); if (this.plugins) { providerPlugins = this.plugins.getPluginsFor('clientWeb3Provider'); @@ -119,50 +81,18 @@ result += "\n"; result += plugin.generateProvider(self) + "\n"; }); } else { - result += "\nwhenEnvIsLoaded(function(){" + mainContext + "__loadManagerInstance.doFirst(function(done) {\n"; - result += "\nif (typeof window !== 'undefined') { window.web3 = undefined; }"; + let web3Load; if (isDeployment) { let connection = "http://" + this.contractsConfig.deployment.host + ":" + this.contractsConfig.deployment.port; - result += '\n\tweb3 = new Web3(new Web3.providers.HttpProvider("' + connection + '"));'; - result += '\n\tdone();'; + web3Load = Templates.define_web3_simple({url: connection, done: 'done();'}); } else { - - let connectionCode = ""; - connectionCode += "\n__reduce(["; - connectionCode += this.contractsConfig.dappConnection.map((x) => '"' + x + '"').join(','); - connectionCode += "], function(prev, value, next) {"; - - connectionCode += "\nif (prev === false) {"; - connectionCode += "\n return next(null, false);"; - connectionCode += "\n}"; - - connectionCode += "\n if (value === '$WEB3' && (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined')) {"; - connectionCode += '\n\tweb3 = new Web3(web3.currentProvider);'; - connectionCode += "\n } else if (value !== '$WEB3' && (typeof Web3 !== 'undefined' && ((typeof web3 === 'undefined') || (typeof web3 !== 'undefined' && (!web3.isConnected || (web3.isConnected && !web3.isConnected())))))) {"; - - connectionCode += "\n\tweb3 = new Web3(new Web3.providers.HttpProvider(value));"; - - connectionCode += "\n}"; - - connectionCode += "\nelse if (value === '$WEB3') {"; - connectionCode += "\n\treturn next(null, '');"; - connectionCode += "\n}"; - - connectionCode += "\nweb3.eth.getAccounts(function(err, account) { if(err) { next(null, true) } else { next(null, false) }})"; - - connectionCode += "\n}, function(err, _result) {"; - connectionCode += "\nweb3.eth.getAccounts(function(err, accounts) {;"; - connectionCode += "\nweb3.eth.defaultAccount = accounts[0];"; - connectionCode += '\ndone();'; - connectionCode += "\n});"; - connectionCode += "\n});"; - - result += connectionCode; + let connectionList = "[" + this.contractsConfig.dappConnection.map((x) => '"' + x + '"').join(',') + "]"; + web3Load = Templates.web3_connector({connectionList: connectionList, done: 'done();'}); } - result += '\n})})'; + result += Templates.do_when_loaded({block: web3Load}); } return result; @@ -179,20 +109,11 @@ result += "\n"; for (let className in this.contractsManager.contracts) { let contract = this.contractsManager.contracts[className]; let abi = JSON.stringify(contract.abiDefinition); - result += "\n" + className + "Abi = " + abi + ";"; - result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);"; - result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');"; + result += Templates.vanilla_contract({className: className, abi: abi, contract: contract}); } return result; } - let mainContext = ""; - if (isDeployment) { - mainContext = "__mainContext."; - } else { - mainContext = "__mainContext."; - } - if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { return ""; } @@ -212,28 +133,16 @@ result += "\n"; let abi = JSON.stringify(contract.abiDefinition); let gasEstimates = JSON.stringify(contract.gasEstimates); - // TODO: refactor this - //result += "\nif (whenEnvIsLoaded === undefined) {"; - //result += "\n var whenEnvIsLoaded = function(cb) {"; - //result += "\n if (typeof document !== 'undefined' && document !== null) {"; - //result += "\n document.addEventListener('DOMContentLoaded', cb);"; - //result += "\n } else {"; - //result += "\n cb();"; - //result += "\n }"; - //result += "\n }"; - //result += "\n}"; + let block = ""; - result += "\n" + mainContext + "__loadManagerInstance.execWhenReady(function() {"; - result += "\nif (typeof window !== 'undefined') { window." + className + " = undefined; }"; if (useEmbarkJS) { let contractAddress = contract.deployedAddress ? ("'" + contract.deployedAddress + "'") : "undefined"; - result += "\n" + mainContext + "" + className + " = new EmbarkJS.Contract({abi: " + abi + ", address: " + contractAddress + ", code: '" + contract.code + "', gasEstimates: " + gasEstimates + "});"; + block += Templates.embarkjs_contract({className: className, abi: abi, contract: contract, contractAddress: contractAddress, gasEstimates: gasEstimates}); } else { - result += "\n" + className + "Abi = " + abi + ";"; - result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);"; - result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');"; + block += Templates.vanilla_contract({className: className, abi: abi, contract: contract}); } - result += '\n});'; + result += Templates.exec_when_ready({block: block}); + } } @@ -247,19 +156,8 @@ result += "\n"; if (!useEmbarkJS || self.storageConfig === {}) return ""; if (self.storageConfig.provider === 'ipfs' && self.storageConfig.enabled === true) { - // TODO: make this more readable - - result += "\nvar whenEnvIsLoaded = function(cb) {"; - result += "\n if (typeof document !== 'undefined' && document !== null) {"; - result += "\n document.addEventListener('DOMContentLoaded', cb);"; - result += "\n } else {"; - result += "\n cb();"; - result += "\n }"; - result += "\n}"; - - result += "\nwhenEnvIsLoaded(function() {\n"; - result += "\nEmbarkJS.Storage.setProvider('" + self.storageConfig.provider + "', {server: '" + self.storageConfig.host + "', port: '" + self.storageConfig.port + "', getUrl: '" + self.storageConfig.getUrl + "'});"; - result += '\n})'; + let block = "\nEmbarkJS.Storage.setProvider('" + self.storageConfig.provider + "', {server: '" + self.storageConfig.host + "', port: '" + self.storageConfig.port + "', getUrl: '" + self.storageConfig.getUrl + "'});"; + result += Templates.define_when_env_loaded({block: block}); } return result; @@ -271,26 +169,20 @@ result += "\n"; if (!useEmbarkJS || self.communicationConfig === {}) return ""; - result += "\nvar whenEnvIsLoaded = function(cb) {"; - result += "\n if (typeof document !== 'undefined' && document !== null) {"; - result += "\n document.addEventListener('DOMContentLoaded', cb);"; - result += "\n } else {"; - result += "\n cb();"; - result += "\n }"; - result += "\n}"; + // TODO: don't repeat this twice; should have 'requirements' generator first + result += Templates.define_when_env_loaded(); + let block; if (self.communicationConfig.provider === 'whisper' && self.communicationConfig.enabled === true) { - result += "\nwhenEnvIsLoaded(function() {\n"; - result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; - result += '\n})'; + block = "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; + result += Templates.define_when_env_loaded({block: block}); } else if (self.communicationConfig.provider === 'orbit' && self.communicationConfig.enabled === true) { - result += "\nwhenEnvIsLoaded(function() {\n"; if (self.communicationConfig.host === undefined && self.communicationConfig.port === undefined) { - result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; + block = "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; } else { - result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});"; + block = "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});"; } - result += '\n})'; + result += Templates.define_when_env_loaded({block: block}); } return result; diff --git a/lib/contracts/code_templates/define-web3-simple.js.ejs b/lib/contracts/code_templates/define-web3-simple.js.ejs new file mode 100644 index 00000000..b6177bfa --- /dev/null +++ b/lib/contracts/code_templates/define-web3-simple.js.ejs @@ -0,0 +1,3 @@ +__mainContext.web3 = undefined; +web3 = new Web3(new Web3.providers.HttpProvider("<%- url -%>'")); +<%- done %> diff --git a/lib/contracts/code_templates/define-when-env-loaded.js.ejs b/lib/contracts/code_templates/define-when-env-loaded.js.ejs new file mode 100644 index 00000000..186bd7e0 --- /dev/null +++ b/lib/contracts/code_templates/define-when-env-loaded.js.ejs @@ -0,0 +1,7 @@ +var whenEnvIsLoaded = function(cb) { + if (typeof document !== 'undefined' && document !== null) { + document.addEventListener('DOMContentLoaded', cb); + } else { + cb(); + } +} diff --git a/lib/contracts/code_templates/do-when-loaded.js.ejs b/lib/contracts/code_templates/do-when-loaded.js.ejs new file mode 100644 index 00000000..7a984f07 --- /dev/null +++ b/lib/contracts/code_templates/do-when-loaded.js.ejs @@ -0,0 +1,6 @@ +whenEnvIsLoaded(function(){ + __mainContext.__loadManagerInstance.doFirst(function(done) { + <%- block %> + }) +}); + diff --git a/lib/contracts/code_templates/embarkjs-contract.js.ejs b/lib/contracts/code_templates/embarkjs-contract.js.ejs new file mode 100644 index 00000000..52e0b441 --- /dev/null +++ b/lib/contracts/code_templates/embarkjs-contract.js.ejs @@ -0,0 +1 @@ +__mainContext.<%- className %> = new EmbarkJS.Contract({abi: <%- abi %>, address: <%- contractAddress %>, code: '<%- contract.code %>', gasEstimates: <%- gasEstimates %>}); diff --git a/lib/contracts/code_templates/exec-when-env-loaded.js.ejs b/lib/contracts/code_templates/exec-when-env-loaded.js.ejs new file mode 100644 index 00000000..4fc2b113 --- /dev/null +++ b/lib/contracts/code_templates/exec-when-env-loaded.js.ejs @@ -0,0 +1,3 @@ +whenEnvIsLoaded(function() { + <%- block %> +}); diff --git a/lib/contracts/code_templates/exec-when-ready.js.ejs b/lib/contracts/code_templates/exec-when-ready.js.ejs new file mode 100644 index 00000000..291ee51f --- /dev/null +++ b/lib/contracts/code_templates/exec-when-ready.js.ejs @@ -0,0 +1,3 @@ +__mainContext.__loadManagerInstance.execWhenReady(function() { + <%- block %> +}); diff --git a/lib/contracts/code_templates/load-manager.js.ejs b/lib/contracts/code_templates/load-manager.js.ejs new file mode 100644 index 00000000..ff9b8259 --- /dev/null +++ b/lib/contracts/code_templates/load-manager.js.ejs @@ -0,0 +1,4 @@ +__mainContext.__LoadManager = function() { this.list = []; this.done = false; } +__mainContext.__LoadManager.prototype.execWhenReady = function(cb) { if (this.done) { cb(); } else { this.list.push(cb) } } +__mainContext.__LoadManager.prototype.doFirst = function(todo) { var self = this; todo(function() { self.done = true; self.list.map((x) => x.apply()) }) } +__mainContext.__loadManagerInstance = new __mainContext.__LoadManager(); diff --git a/lib/contracts/code_templates/main-context.js.ejs b/lib/contracts/code_templates/main-context.js.ejs new file mode 100644 index 00000000..557e62b6 --- /dev/null +++ b/lib/contracts/code_templates/main-context.js.ejs @@ -0,0 +1 @@ +var __mainContext = __mainContext || this; diff --git a/lib/contracts/code_templates/utils.js.ejs b/lib/contracts/code_templates/utils.js.ejs new file mode 100644 index 00000000..b88c7b37 --- /dev/null +++ b/lib/contracts/code_templates/utils.js.ejs @@ -0,0 +1,36 @@ +function __reduce(arr, memo, iteratee, cb) { + if (typeof cb !== 'function') { + if (typeof memo === 'function' && typeof iteratee === 'function') { + cb = iteratee; + iteratee = memo; + memo = []; + } else { + throw new TypeError('expected callback to be a function'); + } + } + + if (!Array.isArray(arr)) { + cb(new TypeError('expected an array')); + return; + } + + if (typeof iteratee !== 'function') { + cb(new TypeError('expected iteratee to be a function')); + return; + } + + (function next(i, acc) { + if (i === arr.length) { + cb(null, acc); + return; + } + + iteratee(acc, arr[i], function(err, val) { + if (err) { + cb(err); + return; + } + next(i + 1, val); + }); + })(0, memo); +}; diff --git a/lib/contracts/code_templates/vanilla-contract.js.ejs b/lib/contracts/code_templates/vanilla-contract.js.ejs new file mode 100644 index 00000000..97c2b396 --- /dev/null +++ b/lib/contracts/code_templates/vanilla-contract.js.ejs @@ -0,0 +1,3 @@ +<%- className %>Abi = <%- abi %>; +<%- className %>Contract = web3.eth.contract(<%- className %>Abi); +<%- className %> = <%= className %>Contract.at('<%- contract.deployedAddress %>'); diff --git a/lib/contracts/code_templates/web3-connector.js.ejs b/lib/contracts/code_templates/web3-connector.js.ejs new file mode 100644 index 00000000..ea97f084 --- /dev/null +++ b/lib/contracts/code_templates/web3-connector.js.ejs @@ -0,0 +1,28 @@ +__mainContext.web3 = undefined; +__reduce(<%- connectionList %>,function(prev, value, next) { + if (prev === false) { + return next(null, false); + } + + if (value === '$WEB3' && (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined')) { + web3 = new Web3(web3.currentProvider); + } else if (value !== '$WEB3' && (typeof Web3 !== 'undefined' && ((typeof web3 === 'undefined') || (typeof web3 !== 'undefined' && (!web3.isConnected || (web3.isConnected && !web3.isConnected())))))) { + + web3 = new Web3(new Web3.providers.HttpProvider(value)); + } else if (value === '$WEB3') { + return next(null, ''); + } + + web3.eth.getAccounts(function(err, account) { + if (err) { + next(null, true) + } else { + next(null, false) + } + }); +}, function(err, _result) { + web3.eth.getAccounts(function(err, accounts) { + web3.eth.defaultAccount = accounts[0]; + <%- done %> + }); +}); diff --git a/lib/core/runCode.js b/lib/core/runCode.js index 9614b912..3a32606b 100644 --- a/lib/core/runCode.js +++ b/lib/core/runCode.js @@ -12,7 +12,11 @@ function doEval(code, _web3) { web3 = _web3; } - return eval(code); // jshint ignore:line + try { + return eval(code); // jshint ignore:line + } catch(e) { + throw new Error(e + "\n" + code); + } } module.exports = { diff --git a/package.json b/package.json index aa3be6c1..ef16a245 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "chokidar": "^1.6.0", "colors": "^1.1.2", "commander": "^2.8.1", + "ejs": "^2.5.7", "ethereumjs-testrpc": "3.9.2", "finalhandler": "^0.5.0", "follow-redirects": "^1.2.4", diff --git a/test/code_generator.js b/test/code_generator.js index 266b45d4..9f5be02d 100644 --- a/test/code_generator.js +++ b/test/code_generator.js @@ -10,9 +10,11 @@ describe('embark.CodeGenerator', function() { let generator = new CodeGenerator({contractsConfig: {"dappConnection": [ "$WEB3", "http://somehost:1234" ] }, contractsManager: {}}); it('should generate code to connect to a provider', function() { - var providerCode = "\nfunction __reduce(arr, memo, iteratee, cb) {\n if (typeof cb !== 'function') {\n if (typeof memo === 'function' && typeof iteratee === 'function') {\n cb = iteratee;\n iteratee = memo;\n memo = [];\n } else {\n throw new TypeError('expected callback to be a function');\n }\n }\n\n if (!Array.isArray(arr)) {\n cb(new TypeError('expected an array'));\n return;\n }\n\n if (typeof iteratee !== 'function') {\n cb(new TypeError('expected iteratee to be a function'));\n return;\n }\n\n (function next(i, acc) {\n if (i === arr.length) {\n cb(null, acc);\n return;\n }\n\n iteratee(acc, arr[i], function(err, val) {\n if (err) {\n cb(err);\n return;\n }\n next(i + 1, val);\n });\n })(0, memo);\n};\nvar __mainContext = __mainContext || this;\n__mainContext.__LoadManager = function() { this.list = []; this.done = false; }\n__mainContext.__LoadManager.prototype.execWhenReady = function(cb) { if (this.done) { cb(); } else { this.list.push(cb) } }\n__mainContext.__LoadManager.prototype.doFirst = function(todo) { var self = this; todo(function() { self.done = true; self.list.map((x) => x.apply()) }) }\n__mainContext.__loadManagerInstance = new __mainContext.__LoadManager();\nvar whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n}\nwhenEnvIsLoaded(function(){__mainContext.__loadManagerInstance.doFirst(function(done) {\n\nif (typeof window !== 'undefined') { window.web3 = undefined; }\n__reduce([\"$WEB3\",\"http://somehost:1234\"], function(prev, value, next) {\nif (prev === false) {\n return next(null, false);\n}\n if (value === '$WEB3' && (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined')) {\n\tweb3 = new Web3(web3.currentProvider);\n } else if (value !== '$WEB3' && (typeof Web3 !== 'undefined' && ((typeof web3 === 'undefined') || (typeof web3 !== 'undefined' && (!web3.isConnected || (web3.isConnected && !web3.isConnected())))))) {\n\tweb3 = new Web3(new Web3.providers.HttpProvider(value));\n}\nelse if (value === '$WEB3') {\n\treturn next(null, '');\n}\nweb3.eth.getAccounts(function(err, account) { if(err) { next(null, true) } else { next(null, false) }})\n}, function(err, _result) {\nweb3.eth.getAccounts(function(err, accounts) {;\nweb3.eth.defaultAccount = accounts[0];\ndone();\n});\n});\n})})"; + var providerCode = "function __reduce(arr, memo, iteratee, cb) {\n if (typeof cb !== 'function') {\n if (typeof memo === 'function' && typeof iteratee === 'function') {\n cb = iteratee;\n iteratee = memo;\n memo = [];\n } else {\n throw new TypeError('expected callback to be a function');\n }\n }\n\n if (!Array.isArray(arr)) {\n cb(new TypeError('expected an array'));\n return;\n }\n\n if (typeof iteratee !== 'function') {\n cb(new TypeError('expected iteratee to be a function'));\n return;\n }\n\n (function next(i, acc) {\n if (i === arr.length) {\n cb(null, acc);\n return;\n }\n\n iteratee(acc, arr[i], function(err, val) {\n if (err) {\n cb(err);\n return;\n }\n next(i + 1, val);\n });\n })(0, memo);\n};\n\nvar __mainContext = __mainContext || this;\n__mainContext.__LoadManager = function() { this.list = []; this.done = false; }\n__mainContext.__LoadManager.prototype.execWhenReady = function(cb) { if (this.done) { cb(); } else { this.list.push(cb) } }\n__mainContext.__LoadManager.prototype.doFirst = function(todo) { var self = this; todo(function() { self.done = true; self.list.map((x) => x.apply()) }) }\n__mainContext.__loadManagerInstance = new __mainContext.__LoadManager();\nvar whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n}\nwhenEnvIsLoaded(function(){__mainContext.__loadManagerInstance.doFirst(function(done) {\n\nif (typeof window !== 'undefined') { window.web3 = undefined; }\n__reduce([\"$WEB3\",\"http://somehost:1234\"], function(prev, value, next) {\nif (prev === false) {\n return next(null, false);\n}\n if (value === '$WEB3' && (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined')) {\n\tweb3 = new Web3(web3.currentProvider);\n } else if (value !== '$WEB3' && (typeof Web3 !== 'undefined' && ((typeof web3 === 'undefined') || (typeof web3 !== 'undefined' && (!web3.isConnected || (web3.isConnected && !web3.isConnected())))))) {\n\tweb3 = new Web3(new Web3.providers.HttpProvider(value));\n}\nelse if (value === '$WEB3') {\n\treturn next(null, '');\n}\nweb3.eth.getAccounts(function(err, account) { if(err) { next(null, true) } else { next(null, false) }})\n}, function(err, _result) {\nweb3.eth.getAccounts(function(err, accounts) {;\nweb3.eth.defaultAccount = accounts[0];\ndone();\n});\n});\n})})"; - assert.equal(generator.generateProvider(), providerCode); + console.log(JSON.stringify(generator.generateProvider())); + + assert.equal(generator.generateProvider().split('\n'), providerCode.split('\n')); }); });