mirror of
https://github.com/embarklabs/embark.git
synced 2025-01-11 14:24:24 +00:00
feat(@embark/test-runner): make modules configurable per test
Make storage, ens and communication configurable per test Tested ENS and it works like a charm
This commit is contained in:
parent
9648aaf4b1
commit
63ab21ee81
@ -2,7 +2,9 @@ module.exports = {
|
||||
"default": {
|
||||
"enabled": true,
|
||||
"available_providers": ["ens"],
|
||||
"provider": "ens",
|
||||
"provider": "ens"
|
||||
},
|
||||
development: {
|
||||
"register": {
|
||||
"rootDomain": "embark.eth",
|
||||
"subdomains": {
|
||||
@ -11,8 +13,5 @@ module.exports = {
|
||||
"MyToken2": "$MyToken2"
|
||||
}
|
||||
}
|
||||
},
|
||||
test: {
|
||||
enabled: true
|
||||
}
|
||||
};
|
||||
|
@ -4,6 +4,12 @@ const SimpleStorage = require('Embark/contracts/SimpleStorage');
|
||||
const EmbarkJS = require('Embark/EmbarkJS');
|
||||
|
||||
config({
|
||||
namesystem: {
|
||||
enabled: true,
|
||||
register: {
|
||||
"rootDomain": "test.eth"
|
||||
}
|
||||
},
|
||||
contracts: {
|
||||
deploy: {
|
||||
"SimpleStorage": {
|
||||
@ -14,12 +20,12 @@ config({
|
||||
});
|
||||
|
||||
describe("EmbarkJS functions", function() {
|
||||
it('should have access to ENS functions', async function() {
|
||||
const rootAddress = await EmbarkJS.Names.resolve('embark.eth');
|
||||
it('should have access to ENS functions and registered test.eth', async function() {
|
||||
const rootAddress = await EmbarkJS.Names.resolve('test.eth');
|
||||
assert.strictEqual(rootAddress, web3.eth.defaultAccount);
|
||||
|
||||
const rootName = await EmbarkJS.Names.lookup(rootAddress);
|
||||
assert.strictEqual(rootName, 'embark.eth');
|
||||
assert.strictEqual(rootName, 'test.eth');
|
||||
});
|
||||
|
||||
it('should have access to Storage functions', async function() {
|
||||
|
@ -5,6 +5,15 @@ const MyToken2 = require('Embark/contracts/MyToken2');
|
||||
const EmbarkJS = require('Embark/EmbarkJS');
|
||||
|
||||
config({
|
||||
namesystem: {
|
||||
"register": {
|
||||
"rootDomain": "embark.eth",
|
||||
"subdomains": {
|
||||
"mytoken": "$MyToken",
|
||||
"MyToken2": "$MyToken2"
|
||||
}
|
||||
}
|
||||
},
|
||||
contracts: {
|
||||
deploy: {
|
||||
"Token": {
|
||||
|
@ -67,28 +67,39 @@ class ENS {
|
||||
this.logger = embark.logger;
|
||||
this.events = embark.events;
|
||||
this.fs = embark.fs;
|
||||
this.namesConfig = embark.config.namesystemConfig;
|
||||
this.config = embark.config;
|
||||
this.enabled = false;
|
||||
this.registration = this.namesConfig.register || {};
|
||||
this.embark = embark;
|
||||
this.ensConfig = ensConfig;
|
||||
this.configured = false;
|
||||
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, dappArtifacts.symlinkDir);
|
||||
this.consoleCmdsRegistered = false;
|
||||
this.eventsRegistered = false;
|
||||
|
||||
this.events.setCommandHandler("ens:resolve", this.ensResolve.bind(this));
|
||||
this.events.setCommandHandler("ens:isENSName", this.isENSName.bind(this));
|
||||
|
||||
if (this.namesConfig === {} ||
|
||||
this.namesConfig.enabled !== true ||
|
||||
this.namesConfig.available_providers.indexOf('ens') < 0) {
|
||||
return;
|
||||
this.embark.events.setCommandHandler("module:namesystem:reset", (cb) => {
|
||||
this.reset();
|
||||
this.init(cb);
|
||||
});
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init(cb = () => {}) {
|
||||
if (this.config.namesystemConfig === {} ||
|
||||
this.config.namesystemConfig.enabled !== true ||
|
||||
!this.config.namesystemConfig.available_providers ||
|
||||
this.config.namesystemConfig.available_providers.indexOf('ens') < 0) {
|
||||
return cb();
|
||||
}
|
||||
this.enabled = true;
|
||||
this.doSetENSProvider = this.namesConfig.provider === 'ens';
|
||||
this.doSetENSProvider = this.config.namesystemConfig.provider === 'ens';
|
||||
|
||||
this.addENSToEmbarkJS();
|
||||
this.registerEvents();
|
||||
this.registerConsoleCommands();
|
||||
this.addENSToEmbarkJS(cb);
|
||||
}
|
||||
|
||||
reset() {
|
||||
@ -96,6 +107,10 @@ class ENS {
|
||||
}
|
||||
|
||||
registerConsoleCommands() {
|
||||
if (this.consoleCmdsRegistered) {
|
||||
return;
|
||||
}
|
||||
this.consoleCmdsRegistered = true;
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'resolve [name]',
|
||||
description: __('Resolves an ENS name'),
|
||||
@ -138,6 +153,10 @@ class ENS {
|
||||
}
|
||||
|
||||
registerEvents() {
|
||||
if (this.eventsRegistered) {
|
||||
return;
|
||||
}
|
||||
this.eventsRegistered = true;
|
||||
this.embark.registerActionForEvent("deploy:beforeAll", this.configureContractsAndRegister.bind(this));
|
||||
this.events.on('blockchain:reseted', this.reset.bind(this));
|
||||
this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this));
|
||||
@ -147,7 +166,7 @@ class ENS {
|
||||
getEnsConfig(cb) {
|
||||
cb({
|
||||
env: this.env,
|
||||
registration: this.registration,
|
||||
registration: this.config.namesystemConfig.register,
|
||||
registryAbi: this.ensConfig.ENSRegistry.abiDefinition,
|
||||
registryAddress: this.ensConfig.ENSRegistry.deployedAddress,
|
||||
registrarAbi: this.ensConfig.FIFSRegistrar.abiDefinition,
|
||||
@ -166,7 +185,7 @@ class ENS {
|
||||
|
||||
self.events.request('blockchain:networkId', (networkId) => {
|
||||
const isKnownNetwork = Boolean(ENS_CONTRACTS_CONFIG[networkId]);
|
||||
const shouldRegisterSubdomain = self.registration && self.registration.subdomains && Object.keys(self.registration.subdomains).length;
|
||||
const shouldRegisterSubdomain = self.config.namesystemConfig.register && self.config.namesystemConfig.register.subdomains && Object.keys(self.config.namesystemConfig.register.subdomains).length;
|
||||
if (isKnownNetwork || !shouldRegisterSubdomain) {
|
||||
return cb();
|
||||
}
|
||||
@ -248,8 +267,8 @@ class ENS {
|
||||
registerConfigDomains(config, cb) {
|
||||
|
||||
this.events.request("blockchain:defaultAccount:get", (defaultAccount) => {
|
||||
async.each(Object.keys(this.registration.subdomains), (subDomainName, eachCb) => {
|
||||
const address = this.registration.subdomains[subDomainName];
|
||||
async.each(Object.keys(this.config.namesystemConfig.register.subdomains), (subDomainName, eachCb) => {
|
||||
const address = this.config.namesystemConfig.register.subdomains[subDomainName];
|
||||
const directivesRegExp = new RegExp(/\$(\w+\[?\d?\]?)/g);
|
||||
|
||||
|
||||
@ -281,13 +300,13 @@ class ENS {
|
||||
}
|
||||
|
||||
safeRegisterSubDomain(subDomainName, address, defaultAccount, callback) {
|
||||
this.ensResolve(`${subDomainName}.${this.registration.rootDomain}`, (error, currentAddress) => {
|
||||
this.ensResolve(`${subDomainName}.${this.config.namesystemConfig.register.rootDomain}`, (error, currentAddress) => {
|
||||
if (currentAddress && currentAddress.toLowerCase() === address.toLowerCase()) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (error && error !== NOT_REGISTERED_ERROR) {
|
||||
this.logger.error(__('Error resolving %s', `${subDomainName}.${this.registration.rootDomain}`));
|
||||
this.logger.error(__('Error resolving %s', `${subDomainName}.${this.config.namesystemConfig.register.rootDomain}`));
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
@ -299,7 +318,7 @@ class ENS {
|
||||
registerSubDomain(defaultAccount, subDomainName, reverseNode, address, secureSend, cb) {
|
||||
this.events.request("blockchain:get", (web3) => {
|
||||
ENSFunctions.registerSubDomain(web3, this.ensContract, this.registrarContract, this.resolverContract, defaultAccount,
|
||||
subDomainName, this.registration.rootDomain, reverseNode, address, this.logger, secureSend, cb, namehash);
|
||||
subDomainName, this.config.namesystemConfig.register.rootDomain, reverseNode, address, this.logger, secureSend, cb, namehash);
|
||||
});
|
||||
}
|
||||
|
||||
@ -363,27 +382,30 @@ class ENS {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({name: `${req.body.subdomain}.${self.registration.rootDomain}`, address: req.body.address});
|
||||
res.send({name: `${req.body.subdomain}.${self.config.namesystemConfig.register.rootDomain}`, address: req.body.address});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
addENSToEmbarkJS() {
|
||||
addENSToEmbarkJS(cb) {
|
||||
this.events.request('version:downloadIfNeeded', 'eth-ens-namehash', (err, location) => {
|
||||
if (err) {
|
||||
this.logger.error(__('Error downloading NameHash'));
|
||||
return this.logger.error(err.message || err);
|
||||
this.logger.error(err.message || err);
|
||||
return cb();
|
||||
}
|
||||
|
||||
this.events.request('code-generator:ready', () => {
|
||||
this.events.request('code-generator:symlink:generate', location, 'eth-ens-namehash', (err) => {
|
||||
if (err) {
|
||||
this.logger.error(__('Error creating a symlink to eth-ens-namehash'));
|
||||
return this.logger.error(err.message || err);
|
||||
this.logger.error(err.message || err);
|
||||
return cb();
|
||||
}
|
||||
this.events.emit('runcode:register', 'namehash', require('eth-ens-namehash'), () => {
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -430,6 +452,7 @@ class ENS {
|
||||
if (self.configured) {
|
||||
return cb();
|
||||
}
|
||||
const registration = this.config.namesystemConfig.register;
|
||||
|
||||
async.waterfall([
|
||||
function getNetworkId(next) {
|
||||
@ -454,19 +477,19 @@ class ENS {
|
||||
});
|
||||
},
|
||||
function checkRootNode(next) {
|
||||
if (!self.registration || !self.registration.rootDomain) {
|
||||
if (!registration || !registration.rootDomain) {
|
||||
return next(NO_REGISTRATION);
|
||||
}
|
||||
if (!self.isENSName(self.registration.rootDomain)) {
|
||||
if (!self.isENSName(registration.rootDomain)) {
|
||||
|
||||
return next(__('Invalid domain name: {{name}}\nValid extensions are: {{extenstions}}',
|
||||
{name: self.registration.rootDomain, extenstions: ENS_WHITELIST.join(', ')}));
|
||||
{name: registration.rootDomain, extenstions: ENS_WHITELIST.join(', ')}));
|
||||
}
|
||||
next();
|
||||
},
|
||||
function registrar(next) {
|
||||
const registryAddress = self.ensConfig.ENSRegistry.deployedAddress;
|
||||
const rootNode = namehash.hash(self.registration.rootDomain);
|
||||
const rootNode = namehash.hash(registration.rootDomain);
|
||||
const contract = self.ensConfig.FIFSRegistrar;
|
||||
contract.args = [registryAddress, rootNode];
|
||||
|
||||
@ -518,7 +541,7 @@ class ENS {
|
||||
self.resolverContract = result[2];
|
||||
const web3 = result[3];
|
||||
|
||||
const rootNode = namehash.hash(self.registration.rootDomain);
|
||||
const rootNode = namehash.hash(registration.rootDomain);
|
||||
var reverseNode = namehash.hash(web3.eth.defaultAccount.toLowerCase().substr(2) + reverseAddrSuffix);
|
||||
const owner = await self.ensContract.methods.owner(rootNode).call();
|
||||
|
||||
@ -550,7 +573,7 @@ class ENS {
|
||||
}, false);
|
||||
}).then(() => {
|
||||
// Set name of the reverse node to the root domain
|
||||
return secureSend(web3, self.resolverContract.methods.setName(reverseNode, self.registration.rootDomain), {
|
||||
return secureSend(web3, self.resolverContract.methods.setName(reverseNode, registration.rootDomain), {
|
||||
from: web3.eth.defaultAccount,
|
||||
gas: ENS_GAS_PRICE
|
||||
}, false);
|
||||
|
@ -4,7 +4,6 @@ import * as async from 'async';
|
||||
class Storage {
|
||||
constructor(embark, options){
|
||||
this.embark = embark;
|
||||
this.storageConfig = embark.config.storageConfig;
|
||||
this.plugins = options.plugins;
|
||||
this.ready = false;
|
||||
|
||||
@ -15,22 +14,24 @@ class Storage {
|
||||
this.embark.events.once("module:storage:ready", cb);
|
||||
});
|
||||
|
||||
if (!this.storageConfig.enabled) {
|
||||
this.embark.events.setCommandHandler("module:storage:reset", (cb) => {
|
||||
this.ready = false;
|
||||
this.addSetProviders(cb);
|
||||
});
|
||||
|
||||
if (!embark.config.storageConfig.enabled) {
|
||||
this.ready = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleUploadCommand();
|
||||
this.addSetProviders(() => {
|
||||
this.ready = true;
|
||||
this.embark.events.emit("module:storage:ready");
|
||||
});
|
||||
this.addSetProviders(() => {});
|
||||
}
|
||||
|
||||
handleUploadCommand() {
|
||||
const self = this;
|
||||
this.embark.events.setCommandHandler('storage:upload', (cb) => {
|
||||
let platform = self.storageConfig.upload.provider;
|
||||
let platform = this.embark.config.storageConfig.upload.provider;
|
||||
|
||||
let uploadCmds = self.plugins.getPluginsProperty('uploadCmds', 'uploadCmds');
|
||||
for (let uploadCmd of uploadCmds) {
|
||||
@ -44,7 +45,7 @@ class Storage {
|
||||
}
|
||||
|
||||
addSetProviders(cb) {
|
||||
let code = `\nEmbarkJS.Storage.setProviders(${JSON.stringify(this.storageConfig.dappConnection || [])}, {web3});`;
|
||||
let code = `\nEmbarkJS.Storage.setProviders(${JSON.stringify(this.embark.config.storageConfig.dappConnection || [])}, {web3});`;
|
||||
|
||||
let shouldInit = (storageConfig) => {
|
||||
return storageConfig.enabled;
|
||||
@ -75,7 +76,10 @@ class Storage {
|
||||
// in the case where the storage process is too slow when starting up we
|
||||
// execute ourselves the setProviders because the console provider init
|
||||
// was already executed
|
||||
this.embark.events.request('runcode:eval', `if (Object.keys(EmbarkJS.Storage.Providers).length) { ${code} }`, cb, true);
|
||||
this.embark.events.request('runcode:eval', `if (Object.keys(EmbarkJS.Storage.Providers).length) { ${code} }`, () => {
|
||||
this.ready = true;
|
||||
this.embark.events.emit("module:storage:ready");
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { __ } from 'embark-i18n';
|
||||
import { deconstructUrl, prepareContractsConfig, buildUrl } from 'embark-utils';
|
||||
import deepEqual from 'deep-equal';
|
||||
|
||||
const async = require('async');
|
||||
const web3Utils = require('web3-utils');
|
||||
@ -24,7 +25,11 @@ class Test {
|
||||
this.accounts = [];
|
||||
this.embarkjs = {};
|
||||
this.dappPath = options.dappPath;
|
||||
this.accounts = [];
|
||||
this.moduleConfigs = {
|
||||
namesystem: {},
|
||||
storage: {},
|
||||
communication: {}
|
||||
};
|
||||
|
||||
this.events.setCommandHandler("blockchain:provider:contract:accounts:get", cb => {
|
||||
this.events.request("blockchain:getAccounts", cb);
|
||||
@ -168,6 +173,26 @@ class Test {
|
||||
});
|
||||
}
|
||||
|
||||
checkModuleConfigs(options, callback) {
|
||||
const self = this;
|
||||
const restartModules = [];
|
||||
|
||||
Object.keys(this.moduleConfigs).forEach(moduleName => {
|
||||
options[moduleName] = options[moduleName] || {};
|
||||
if (!deepEqual(options[moduleName], this.moduleConfigs[moduleName])) {
|
||||
restartModules.push(function (paraCb) {
|
||||
self.events.request(`config:${moduleName}Config:set`, options[moduleName], true, () => {
|
||||
self.events.request(`module:${moduleName}:reset`, paraCb);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async.parallel(restartModules, (err, _result) => {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
config(options, callback) {
|
||||
const self = this;
|
||||
self.needConfig = false;
|
||||
@ -198,6 +223,9 @@ class Test {
|
||||
function checkDeploymentOpts(next) {
|
||||
self.checkDeploymentOptions(options, next);
|
||||
},
|
||||
function checkModuleConfigs(next) {
|
||||
self.checkModuleConfigs(options, next);
|
||||
},
|
||||
function prepareContracts(next) {
|
||||
if (!self.firstDeployment || !self.options.coverage) {
|
||||
return next();
|
||||
|
@ -32,11 +32,12 @@ const PACKAGE = require('../../../package.json');
|
||||
const embark5ChangesUrl = 'https://...';
|
||||
|
||||
var Config = function(options) {
|
||||
const self = this;
|
||||
this.env = options.env || 'default';
|
||||
this.blockchainConfig = {};
|
||||
this.contractsConfig = {};
|
||||
this.pipelineConfig = {};
|
||||
this.namesystemConfig = {};
|
||||
this.communicationConfig = {};
|
||||
this.webServerConfig = options.webServerConfig;
|
||||
this.chainTracker = {};
|
||||
this.assetFiles = {};
|
||||
@ -53,51 +54,65 @@ var Config = function(options) {
|
||||
this.shownNoAccountConfigMsg = false; // flag to ensure "no account config" message is only displayed once to the user
|
||||
this.corsParts = [];
|
||||
this.providerUrl = null;
|
||||
|
||||
this.registerEvents();
|
||||
};
|
||||
|
||||
Config.prototype.setConfig = function(configName, newConfig, recursive, cb) {
|
||||
if (typeof recursive === 'function') {
|
||||
cb = recursive;
|
||||
recursive = false;
|
||||
}
|
||||
if (recursive) {
|
||||
this[configName] = recursiveMerge(this[configName], newConfig);
|
||||
} else {
|
||||
this[configName] = newConfig;
|
||||
}
|
||||
cb();
|
||||
};
|
||||
|
||||
Config.prototype.registerEvents = function() {
|
||||
this.events.setCommandHandler("config:cors:add", (url) => {
|
||||
this.corsParts.push(url);
|
||||
this._updateBlockchainCors();
|
||||
});
|
||||
|
||||
self.events.setCommandHandler("config:contractsConfig", (cb) => {
|
||||
cb(self.contractsConfig);
|
||||
this.events.setCommandHandler("config:contractsConfig", (cb) => {
|
||||
cb(this.contractsConfig);
|
||||
});
|
||||
|
||||
self.events.setCommandHandler("config:contractsConfig:set", (config, cb) => {
|
||||
self.contractsConfig = config;
|
||||
cb();
|
||||
});
|
||||
this.events.setCommandHandler("config:contractsConfig:set", this.setConfig.bind(this, 'contractsConfig'));
|
||||
this.events.setCommandHandler("config:blockchainConfig:set", this.setConfig.bind(this, 'blockchainConfig'));
|
||||
this.events.setCommandHandler("config:storageConfig:set", this.setConfig.bind(this, 'storageConfig'));
|
||||
this.events.setCommandHandler("config:namesystemConfig:set", this.setConfig.bind(this, 'namesystemConfig'));
|
||||
this.events.setCommandHandler("config:communicationConfig:set", this.setConfig.bind(this, 'communicationConfig'));
|
||||
|
||||
self.events.setCommandHandler("config:blockchainConfig:set", (config, cb) => {
|
||||
self.blockchainConfig = config;
|
||||
cb();
|
||||
});
|
||||
|
||||
self.events.setCommandHandler("config:contractsFiles", (cb) => {
|
||||
cb(self.contractsFiles);
|
||||
this.events.setCommandHandler("config:contractsFiles", (cb) => {
|
||||
cb(this.contractsFiles);
|
||||
});
|
||||
|
||||
// TODO: refactor this so reading the file can be done with a normal resolver or something that takes advantage of the plugin api
|
||||
self.events.setCommandHandler("config:contractsFiles:add", (filename, resolver) => {
|
||||
this.events.setCommandHandler("config:contractsFiles:add", (filename, resolver) => {
|
||||
resolver = resolver || function(callback) {
|
||||
callback(fs.readFileSync(filename).toString());
|
||||
};
|
||||
self.contractsFiles.push(new File({path: filename, originalPath: filename, type: Types.custom, resolver}));
|
||||
this.contractsFiles.push(new File({path: filename, originalPath: filename, type: Types.custom, resolver}));
|
||||
});
|
||||
|
||||
self.events.setCommandHandler("config:contractsFiles:reset", (cb) => {
|
||||
self.contractsFiles.forEach((file) => {
|
||||
this.events.setCommandHandler("config:contractsFiles:reset", (cb) => {
|
||||
this.contractsFiles.forEach((file) => {
|
||||
if(file.path.includes(".embark")) {
|
||||
fs.removeSync(file.path);
|
||||
}
|
||||
self.contractsFiles = self.contractsFiles.filter((contractFile) => contractFile.path !== file.path);
|
||||
this.contractsFiles = this.contractsFiles.filter((contractFile) => contractFile.path !== file.path);
|
||||
});
|
||||
cb();
|
||||
});
|
||||
|
||||
self.events.on('file-remove', (fileType, removedPath) => {
|
||||
this.events.on('file-remove', (fileType, removedPath) => {
|
||||
if(fileType !== 'contract') return;
|
||||
const normalizedPath = path.normalize(removedPath);
|
||||
self.contractsFiles = self.contractsFiles.filter(file => path.normalize(file.path) !== normalizedPath);
|
||||
this.contractsFiles = this.contractsFiles.filter(file => path.normalize(file.path) !== normalizedPath);
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user