Merge pull request #1229 from ethereum/test-tab

add test-tab (wip)
pull/1/head
yann300 7 years ago committed by GitHub
commit ac4c407a44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .gitignore
  2. 3
      package.json
  3. 12
      src/app.js
  4. 8
      src/app/files/fileManager.js
  5. 4
      src/app/panels/righthand-panel.js
  6. 56
      src/app/tabs/styles/test-tab-styles.js
  7. 106
      src/app/tabs/test-tab.js

2
.gitignore vendored

@ -9,3 +9,5 @@ package-lock.json
remix
.DS_Store
contracts
TODO
.tern-port

@ -39,6 +39,7 @@
"remix-core": "latest",
"remix-lib": "latest",
"remix-solidity": "latest",
"remix-tests": "latest",
"remixd": "git+https://github.com/ethereum/remixd.git",
"request": "^2.83.0",
"rimraf": "^2.6.1",
@ -52,7 +53,7 @@
"web3": "^0.18.0",
"webworkify": "^1.2.1",
"yo-yo": "^1.2.2",
"yo-yoify": "^3.1.0"
"yo-yoify": "^3.7.3"
},
"dependencies": {
"http-server": "0.9.0",

@ -6,6 +6,7 @@ var yo = require('yo-yo')
var async = require('async')
var request = require('request')
var remixLib = require('remix-lib')
var remixTests = require('remix-tests')
var EventManager = remixLib.EventManager
var UniversalDApp = require('./universal-dapp.js')
@ -251,7 +252,9 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
},
(error, content, cleanUrl, type, url) => {
if (!error) {
filesProviders[type].addReadOnly(cleanUrl, content, url)
if (filesProviders[type]) {
filesProviders[type].addReadOnly(cleanUrl, content, url)
}
cb(null, content)
} else {
cb(error)
@ -260,6 +263,9 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
}
function importFileCb (url, filecb) {
if (url.indexOf('/remix_tests.sol') !== -1) {
return filecb(null, remixTests.assertLibCode)
}
var provider = fileManager.fileProviderOf(url)
if (provider) {
provider.exists(url, (error, exist) => {
@ -723,6 +729,10 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
// ---------------- Righthand-panel --------------------
var rhpAPI = {
importFileCb: importFileCb,
filesFromPath: (path, cb) => {
fileManager.filesFromPath(path, cb)
},
newAccount: (pass, cb) => {
udapp.newAccount(pass, cb)
},

@ -155,6 +155,14 @@ class FileManager {
}
}
filesFromPath (path, cb) {
var provider = this.fileProviderOf(path)
if (provider) {
return provider.resolveDirectory(path, (error, filesTree) => { cb(error, filesTree) })
}
cb(`provider for path ${path} not found`)
}
fileProviderOf (file) {
var provider = file.match(/[^/]*/)
if (provider !== null && this.opt.filesProviders[provider[0]]) {

@ -9,6 +9,7 @@ var AnalysisTab = require('../tabs/analysis-tab')
var DebuggerTab = require('../tabs/debugger-tab')
var SupportTab = require('../tabs/support-tab')
var PluginTab = require('../tabs/plugin-tab')
var TestTab = require('../tabs/test-tab')
var PluginManager = require('../plugin/pluginManager')
var css = require('./styles/righthand-panel-styles')
@ -54,12 +55,15 @@ function RighthandPanel (appAPI = {}, events = {}, opts = {}) {
optionViews.appendChild(debuggerTab.render())
var supportTab = new SupportTab(appAPI, events, opts)
optionViews.appendChild(supportTab.render())
var testTab = new TestTab(appAPI, events, opts)
optionViews.appendChild(testTab.render())
this._view.tabbedMenu.addTab('Compile', 'compileView', optionViews.querySelector('#compileTabView'))
this._view.tabbedMenu.addTab('Run', 'runView', optionViews.querySelector('#runTabView'))
this._view.tabbedMenu.addTab('Settings', 'settingsView', optionViews.querySelector('#settingsView'))
this._view.tabbedMenu.addTab('Analysis', 'staticanalysisView', optionViews.querySelector('#staticanalysisView'))
this._view.tabbedMenu.addTab('Debugger', 'debugView', optionViews.querySelector('#debugView'))
this._view.tabbedMenu.addTab('Support', 'supportView', optionViews.querySelector('#supportView'))
this._view.tabbedMenu.addTab('Test', 'testView', optionViews.querySelector('#testView'))
this._view.tabbedMenu.selectTabByTitle('Compile')
self.pluginManager = new PluginManager(opts.pluginAPI, events)

@ -0,0 +1,56 @@
var csjs = require('csjs-inject')
var styleGuide = require('../../ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser()
var css = csjs`
.opts_li {
display: block;
font-weight: bold;
color: ${styles.rightPanel.text_Teriary};
}
.opts_li.active {
color: ${styles.rightPanel.text_Primary};
}
.opts_li:hover {
color: ${styles.rightPanel.icon_HoverColor_TogglePanel};
}
.solIcon {
margin-left: 10px;
margin-right: 30px;
display: flex;
align-self: center;
height: 29px;
width: 20px;
background-color: ${styles.colors.transparent};
}
a {
color: ${styles.rightPanel.text_link};
}
#optionViews > div {
display: none;
}
#optionViews .pre {
word-wrap: break-word;
background-color: ${styles.rightPanel.BackgroundColor_Pre};
border-radius: 3px;
display: inline-block;
padding: 0 0.6em;
}
#optionViews .hide {
display: none;
}
.infoBox {
${styles.infoTextBox}
margin-bottom: 1em;
}
.textBox {
${styles.textBoxL}
margin-bottom: 1em;
}
.icon {
height: 70%;
margin-right: 2%;
}
`
module.exports = css

@ -0,0 +1,106 @@
var yo = require('yo-yo')
var async = require('async')
var css = require('./styles/test-tab-styles')
var remixTests = require('remix-tests')
function append (container, txt) {
let child = yo`<div>${txt}</div>`
container.appendChild(child)
}
function testTabView (api) {
var container = yo`<div class="tests" id="tests"></div>`
let testCallback = function (result) {
if (result.type === 'contract') {
append(container, '\n ' + result.value)
} else if (result.type === 'testPass') {
append(container, '\t✓ ' + result.value)
} else if (result.type === 'testFailure') {
append(container, '\t✘ ' + result.value)
}
}
let resultsCallback = function (_err, result, cb) {
// total stats for the test
// result.passingNum
// result.failureNum
// result.timePassed
cb()
}
let updateFinalResult = function (_err, result) {
if (result.totalPassing > 0) {
append(container, (' ' + result.totalPassing + ' passing ') + ('(' + result.totalTime + 's)'))
}
if (result.totalFailing > 0) {
append(container, (' ' + result.totalFailing + ' failing'))
}
result.errors.forEach((error, index) => {
append(container, ' ' + (index + 1) + ') ' + error.context + ' ' + error.value)
append(container, '')
append(container, ('\t error: ' + error.message))
})
}
function runTest (testFilePath, callback) {
var provider = api.fileProviderOf(testFilePath)
provider.get(testFilePath, (error, content) => {
if (!error) {
var runningTest = {}
runningTest[testFilePath] = { content }
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result)
callback(error)
}, api.importFileCb)
}
})
}
let runTests = function () {
container.innerHTML = ''
var path = api.currentPath()
var tests = []
api.filesFromPath(path, (error, files) => {
if (!error) {
for (var file in files) {
if (/.(_test.sol)$/.exec(file)) tests.push(path + file)
}
async.eachOfSeries(tests, (value, key, callback) => { runTest(value, callback) })
}
})
}
return yo`
<div class="${css.testTabView} "id="testView">
<div>
<div class="${css.infoBox}">
</div>
</div>
<div class="${css.testList}">
<p><button onclick=${runTests}>Run Tests</button></p>
${container}
</div>
</div>
`
}
function testTab (api = {}, events = {}, opts = {}) {
let el = testTabView(api)
let gitterIsLoaded = false
events.app.register('tabChanged', (tabName) => {
if (tabName !== 'test' || gitterIsLoaded) {
return
}
yo.update(el, testTabView(api))
el.style.display = 'block'
gitterIsLoaded = true
})
return { render () { return el } }
}
module.exports = testTab
Loading…
Cancel
Save