Merge pull request #487 from ethereum/fix#476

Refactor the recorder and make it a plugin
pull/514/head
yann300 4 years ago committed by GitHub
commit 8dd20d4584
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 71
      apps/remix-ide/src/app/tabs/runTab/model/recorder.js
  2. 60
      apps/remix-ide/src/app/tabs/runTab/recorder.js
  3. 4
      apps/remix-ide/src/app/udapp/run-tab.js

@ -4,7 +4,6 @@ var remixLib = require('@remix-project/remix-lib')
var EventManager = remixLib.EventManager
var format = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper
var helper = require('../../../../lib/helper.js')
/**
* Record transaction as long as the user create them.
@ -12,14 +11,12 @@ var helper = require('../../../../lib/helper.js')
*
*/
class Recorder {
constructor (blockchain, fileManager, config) {
constructor (blockchain) {
var self = this
self.event = new EventManager()
self.blockchain = blockchain
self.data = { _listen: true, _replay: false, journal: [], _createdContracts: {}, _createdContractsReverse: {}, _usedAccounts: {}, _abis: {}, _contractABIReferences: {}, _linkReferences: {} }
this.fileManager = fileManager
this.config = config
this.blockchain.event.register('initiatingTransaction', (timestamp, tx, payLoad) => {
if (tx.useCall) return
var { from, to, value } = tx
@ -279,51 +276,37 @@ class Recorder {
return address
}
runScenario (continueCb, promptCb, alertCb, confirmationCb, logCallBack, cb) {
var currentFile = this.config.get('currentFile')
this.fileManager.fileProviderOf(currentFile).get(currentFile, (error, json) => {
if (error) {
return cb('Invalid Scenario File ' + error)
}
if (!currentFile.match('.json$')) {
return cb('A scenario file is required. Please make sure a scenario file is currently displayed in the editor. The file must be of type JSON. Use the "Save Transactions" Button to generate a new Scenario File.')
}
runScenario (json, continueCb, promptCb, alertCb, confirmationCb, logCallBack, cb) {
if (!json) {
return cb('a json content must be provided')
}
if (typeof json === 'string') {
try {
var obj = JSON.parse(json)
var txArray = obj.transactions || []
var accounts = obj.accounts || []
var options = obj.options || {}
var abis = obj.abis || {}
var linkReferences = obj.linkReferences || {}
json = JSON.parse(json)
} catch (e) {
return cb('Invalid Scenario File, please try again')
}
return cb('A scenario file is required. It must be json formatted')
}
}
if (!txArray.length) {
return
}
try {
var txArray = json.transactions || []
var accounts = json.accounts || []
var options = json.options || {}
var abis = json.abis || {}
var linkReferences = json.linkReferences || {}
} catch (e) {
return cb('Invalid Scenario File. Please try again')
}
this.run(txArray, accounts, options, abis, linkReferences, confirmationCb, continueCb, promptCb, alertCb, logCallBack, (abi, address, contractName) => {
cb(null, abi, address, contractName)
})
})
}
if (!txArray.length) {
return
}
saveScenario (promptCb, cb) {
var txJSON = JSON.stringify(this.getAll(), null, 2)
var path = this.fileManager.currentPath()
promptCb(path, input => {
var fileProvider = this.fileManager.fileProviderOf(path)
if (!fileProvider) return
var newFile = path + '/' + input
helper.createNonClashingName(newFile, fileProvider, (error, newFile) => {
if (error) return cb('Failed to create file. ' + newFile + ' ' + error)
if (!fileProvider.set(newFile, txJSON)) return cb('Failed to create file ' + newFile)
this.fileManager.open(newFile)
})
})
this.run(txArray, accounts, options, abis, linkReferences, confirmationCb, continueCb, promptCb, alertCb, logCallBack, (abi, address, contractName) => {
cb(null, abi, address, contractName)
})
}
}
module.exports = Recorder

@ -1,16 +1,29 @@
var yo = require('yo-yo')
var remixLib = require('@remix-project/remix-lib')
var EventManager = remixLib.EventManager
import { Plugin } from '@remixproject/engine'
var csjs = require('csjs-inject')
var css = require('../styles/run-tab-styles')
import * as packageJson from '../../../../package.json'
var modalDialogCustom = require('../../ui/modal-dialog-custom')
var modalDialog = require('../../ui/modaldialog')
var confirmDialog = require('../../ui/confirmDialog')
class RecorderUI {
var helper = require('../../../lib/helper.js')
const profile = {
name: 'recorder',
methods: ['runScenario'],
version: packageJson.version
}
class RecorderUI extends Plugin {
constructor (blockchain, recorder, logCallBack, config) {
constructor (blockchain, fileManager, recorder, logCallBack, config) {
super(profile)
this.fileManager = fileManager
this.blockchain = blockchain
this.recorder = recorder
this.logCallBack = logCallBack
@ -31,10 +44,16 @@ class RecorderUI {
onclick=${this.triggerRecordButton.bind(this)} title="Save Transactions" aria-hidden="true">
</i>`
this.runButton.onclick = this.runScenario.bind(this)
this.runButton.onclick = () => {
const file = this.config.get('currentFile')
if (!file) return modalDialogCustom.alert('A scenario file has to be selected')
this.runScenario(file)
}
}
runScenario () {
runScenario (file) {
if (!file) return modalDialogCustom.alert('Unable to run scenerio, no specified scenario file')
var continueCb = (error, continueTxExecution, cancelCb) => {
if (error) {
var msg = typeof error !== 'string' ? error.message : error
@ -67,14 +86,16 @@ class RecorderUI {
const confirmationCb = this.getConfirmationCb(modalDialog, confirmDialog)
// TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily
this.recorder.runScenario(continueCb, promptCb, alertCb, confirmationCb, this.logCallBack, (error, abi, address, contractName) => {
if (error) {
return modalDialogCustom.alert(error)
}
this.fileManager.readFile(file).then((json) => {
// TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily
this.recorder.runScenario(json, continueCb, promptCb, alertCb, confirmationCb, this.logCallBack, (error, abi, address, contractName) => {
if (error) {
return modalDialogCustom.alert(error)
}
this.event.trigger('newScenario', [abi, address, contractName])
})
this.event.trigger('newScenario', [abi, address, contractName])
})
}).catch((error) => modalDialogCustom.alert(error))
}
getConfirmationCb (modalDialog, confirmDialog) {
@ -110,7 +131,7 @@ class RecorderUI {
}
triggerRecordButton () {
this.recorder.saveScenario(
this.saveScenario(
(path, cb) => {
modalDialogCustom.prompt('Save transactions as scenario', 'Transactions will be saved in a file under ' + path, 'scenario.json', cb)
},
@ -120,6 +141,21 @@ class RecorderUI {
)
}
saveScenario (promptCb, cb) {
var txJSON = JSON.stringify(this.recorder.getAll(), null, 2)
var path = this.fileManager.currentPath()
promptCb(path, input => {
var fileProvider = this.fileManager.fileProviderOf(path)
if (!fileProvider) return
var newFile = path + '/' + input
helper.createNonClashingName(newFile, fileProvider, (error, newFile) => {
if (error) return cb('Failed to create file. ' + newFile + ' ' + error)
if (!fileProvider.set(newFile, txJSON)) return cb('Failed to create file ' + newFile)
this.fileManager.open(newFile)
})
})
}
}
module.exports = RecorderUI

@ -118,13 +118,13 @@ export class RunTab extends LibraryPlugin {
renderRecorder (udappUI, fileManager, config, logCallback) {
this.recorderCount = yo`<span>0</span>`
const recorder = new Recorder(this.blockchain, fileManager, config)
const recorder = new Recorder(this.blockchain)
recorder.event.register('recorderCountChange', (count) => {
this.recorderCount.innerText = count
})
this.event.register('clearInstance', recorder.clearAll.bind(recorder))
this.recorderInterface = new RecorderUI(this.blockchain, recorder, logCallback, config)
this.recorderInterface = new RecorderUI(this.blockchain, fileManager, recorder, logCallback, config)
this.recorderInterface.event.register('newScenario', (abi, address, contractName) => {
var noInstancesText = this.noInstancesText

Loading…
Cancel
Save