Merge pull request #1369 from ethereum/tests-logic

Tests logic
pull/1/head
yann300 6 years ago committed by GitHub
commit 03777aa43e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/app.js
  2. 1
      src/app/files/fileManager.js
  3. 6
      src/app/panels/file-panel.js
  4. 72
      src/app/tabs/styles/test-tab-styles.js
  5. 119
      src/app/tabs/test-tab.js
  6. 20
      src/app/ui/styles-guide/style-guide.js

@ -474,6 +474,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
self._components.filePanel = new FilePanel() self._components.filePanel = new FilePanel()
self._view.leftpanel.appendChild(self._components.filePanel.render()) self._view.leftpanel.appendChild(self._components.filePanel.render())
self._components.filePanel.event.register('resize', delta => self._adjustLayout('left', delta)) self._components.filePanel.event.register('resize', delta => self._adjustLayout('left', delta))
registry.put({api: self._components.filePanel, name: 'filepanel'})
// ----------------- Renderer ----------------- // ----------------- Renderer -----------------
var renderer = new Renderer() var renderer = new Renderer()

@ -154,6 +154,7 @@ class FileManager {
} }
fileProviderOf (file) { fileProviderOf (file) {
if (!file) return null
var provider = file.match(/[^/]*/) var provider = file.match(/[^/]*/)
if (provider !== null && this._deps.filesProviders[provider[0]]) { if (provider !== null && this._deps.filesProviders[provider[0]]) {
return this._deps.filesProviders[provider[0]] return this._deps.filesProviders[provider[0]]

@ -249,7 +249,11 @@ function filepanel (localRegistry) {
if (!self._deps.fileProviders['browser'].set(newName, '')) { if (!self._deps.fileProviders['browser'].set(newName, '')) {
modalDialogCustom.alert('Failed to create file ' + newName) modalDialogCustom.alert('Failed to create file ' + newName)
} else { } else {
self._deps.fileManager.switchFile(self._deps.fileProviders['browser'].type + '/' + newName) var file = self._deps.fileProviders['browser'].type + '/' + newName
self._deps.fileManager.switchFile(file)
if (file.includes('_test.sol')) {
self.event.trigger('newTestFileCreated', [file])
}
} }
}) })
}, null, true) }, null, true)

@ -3,53 +3,51 @@ var styleGuide = require('../../ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser() var styles = styleGuide.chooser()
var css = csjs` var css = csjs`
.opts_li { .testTabView {}
display: block; .infoBox {
font-weight: bold; ${styles.rightPanel.testTab.box_listTests};
color: ${styles.rightPanel.text_Teriary}; margin: 2%;
} }
.opts_li.active { .tests {}
color: ${styles.rightPanel.text_Primary}; .testList {
${styles.rightPanel.testTab.box_listTests};
line-height: 2em;
display: flex;
flex-direction: column;
margin: 2%;
} }
.opts_li:hover { .container {
color: ${styles.rightPanel.icon_HoverColor_TogglePanel}; ${styles.rightPanel.testTab.box_listTests};
margin: 2%;
padding-bottom: 5%;
} }
.solIcon { .outputTitle {
margin-left: 10px; font-weight: bold;
margin-right: 30px; margin: 10px 0;
display: flex;
align-self: center;
height: 29px;
width: 20px;
background-color: ${styles.colors.transparent};
} }
a { .summaryTitle {
color: ${styles.rightPanel.text_link}; font-weight: bold;
} }
#optionViews > div { .testPass {
display: none; background-color: ${styles.rightPanel.testTab.color_testPass};
} }
#optionViews .pre { .testLog {
word-wrap: break-word; margin-bottom: 1%;
background-color: ${styles.rightPanel.BackgroundColor_Pre}; border-radius: 4px;
border-radius: 3px; padding: 1% 1% 1% 5%;
display: inline-block;
padding: 0 0.6em;
} }
#optionViews .hide { .testFailure {
display: none; background-color: ${styles.rightPanel.testTab.color_testFail};
} }
.infoBox { .testFailureSummary {
${styles.infoTextBox} color: ${styles.appProperties.errorText_Color};
margin-bottom: 1em;
} }
.textBox { .buttons {
${styles.textBoxL} ${styles.rightPanel.testTab.box_listTests};
margin-bottom: 1em; margin: 2%;
} }
.icon { .runButton {
height: 70%; ${styles.rightPanel.testTab.button_runTests};
margin-right: 2%;
} }
` `

@ -13,39 +13,30 @@ module.exports = class TestTab {
// dependencies // dependencies
self._deps = { self._deps = {
fileManager: self._components.registry.get('filemanager').api, fileManager: self._components.registry.get('filemanager').api,
app: self._components.registry.get('app').api app: self._components.registry.get('app').api,
filePanel: self._components.registry.get('filepanel').api
} }
self.data = {} self.data = {}
self._view.el = self.render()
self._deps.app.event.register('tabChanged', tabName => {
if (tabName !== 'test') return
yo.update(self._view.el, self.render())
self._view.el.style.display = 'block'
})
return { render () { return self._view.el } }
} }
render () { render () {
var self = this const self = this
var container = yo`<div class="tests" id="tests"></div>` var testsOutput = yo`<div class=${css.container} hidden='true' id="tests"></div>`
var testsSummary = yo`<div class=${css.container} hidden='true' id="tests"></div>`
function append (container, txt) { self.data.allTests = getTests(self)
let child = yo`<div>${txt}</div>` self.data.selectedTests = [...self.data.allTests]
container.appendChild(child)
}
let testCallback = function (result) { var testCallback = function (result) {
testsOutput.hidden = false
if (result.type === 'contract') { if (result.type === 'contract') {
append(container, '\n ' + result.value) testsOutput.appendChild(yo`<div class=${css.outputTitle}>${result.filename} (${result.value})</div>`)
} else if (result.type === 'testPass') { } else if (result.type === 'testPass') {
append(container, '\t✓ ' + result.value) testsOutput.appendChild(yo`<div class='${css.testPass} ${css.testLog}'>✓ (${result.value})</div>`)
} else if (result.type === 'testFailure') { } else if (result.type === 'testFailure') {
append(container, '\t✘ ' + result.value) testsOutput.appendChild(yo`<div class='${css.testFailure} ${css.testLog}'>✘ (${result.value})</div>`)
} }
} }
let resultsCallback = function (_err, result, cb) { var resultsCallback = function (_err, result, cb) {
// total stats for the test // total stats for the test
// result.passingNum // result.passingNum
// result.failureNum // result.failureNum
@ -53,61 +44,105 @@ module.exports = class TestTab {
cb() cb()
} }
let updateFinalResult = function (_err, result) { var updateFinalResult = function (_err, result, filename) {
testsSummary.hidden = false
testsSummary.appendChild(yo`<div class=${css.summaryTitle}> ${filename} </div>`)
if (result.totalPassing > 0) { if (result.totalPassing > 0) {
append(container, (' ' + result.totalPassing + ' passing ') + ('(' + result.totalTime + 's)')) testsSummary.appendChild(yo`<div>${result.totalPassing} passing (${result.totalTime}s)</div>`)
testsSummary.appendChild(yo`<br>`)
} }
if (result.totalFailing > 0) { if (result.totalFailing > 0) {
append(container, (' ' + result.totalFailing + ' failing')) testsSummary.appendChild(yo`<div>${result.totalFailing} failing</div>`)
testsSummary.appendChild(yo`<br>`)
} }
result.errors.forEach((error, index) => { result.errors.forEach((error, index) => {
append(container, ' ' + (index + 1) + ') ' + error.context + ' ' + error.value) testsSummary.appendChild(yo`<div>${error.context} - ${error.value} </div>`)
append(container, '') testsSummary.appendChild(yo`<div class=${css.testFailureSummary} >error: ${error.message}</div>`)
append(container, ('\t error: ' + error.message)) testsSummary.appendChild(yo`<br>`)
}) })
} }
function runTest (testFilePath, provider, callback) { function runTest (testFilePath, callback) {
provider.get(testFilePath, (error, content) => { self._deps.fileManager.fileProviderOf(testFilePath).get(testFilePath, (error, content) => {
if (!error) { if (!error) {
var runningTest = {} var runningTest = {}
runningTest[testFilePath] = { content } runningTest[testFilePath] = { content }
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => { remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result) updateFinalResult(error, result, testFilePath)
callback(error) callback(error)
}, (url, cb) => { this._deps.app.importFileCb(url, cb) }) }, (url, cb) => { self._deps.app.importFileCb(url, cb) })
} }
}) })
} }
let runTests = function () { function getTests (self) {
container.innerHTML = '' var path = self._deps.fileManager.currentPath()
var path = this._deps.fileManager.currentPath() var provider = self._deps.fileManager.fileProviderOf(path)
var provider = this._deps.fileManager.fileProviderOf(path)
var tests = [] var tests = []
self._deps.fileManager.filesFromPath(path, (error, files) => { self._deps.fileManager.filesFromPath(path, (error, files) => {
if (!error) { if (!error) {
for (var file in files) { for (var file in files) {
if (/.(_test.sol)$/.exec(file)) tests.push(provider.type + '/' + file) if (/.(_test.sol)$/.exec(file)) tests.push(provider.type + '/' + file)
} }
async.eachOfSeries(tests, (value, key, callback) => { runTest(value, provider, callback) })
} }
}) })
return tests
}
self._deps.filePanel.event.register('newTestFileCreated', file => {
var testList = document.querySelector("[class^='testList']")
var test = yo`<label><input onchange =${(e) => toggleCheckbox(e, file)} type="checkbox" checked="true">${file} </label>`
testList.appendChild(test)
self.data.allTests.push(file)
self.data.selectedTests.push(file)
})
self._deps.fileManager.event.register('currentFileChanged', (file, provider) => {
})
// self._events.filePanel.register('fileRenamed', (oldName, newName, isFolder) => {
// debugger
// self.data.allTests = self.data.allTests.filter(e => e != oldName)
// self.data.selectedTests = self.data.selectedTests.filter(e => e !== oldName)
// if (/.(_test.sol)$/.exec(newName)) self.data.allTests.push(newName)
// })
function listTests () {
var tests = self.data.allTests
return tests.map(test => yo`<label><input onchange =${(e) => toggleCheckbox(e, test)} type="checkbox" checked="true">${test} </label>`)
}
function toggleCheckbox (e, test) {
var selectedTests = self.data.selectedTests
selectedTests = e.target.checked ? [...selectedTests, test] : selectedTests.filter(el => el !== test)
self.data.selectedTests = selectedTests
}
var runTests = function () {
testsOutput.innerHTML = ''
testsSummary.innerHTML = ''
var tests = self.data.selectedTests
async.eachOfSeries(tests, (value, key, callback) => { runTest(value, callback) })
} }
var el = yo` var el = yo`
<div class="${css.testTabView}" id="testView"> <div class="${css.testTabView}" id="testView">
<div>
<div class="${css.infoBox}"> <div class="${css.infoBox}">
Test your smart contract by creating a foo_test.sol file.
Open ballot_test.sol to see the example. For more details, see
How to test smart contracts guide in our documentation.
</div> </div>
<div class="${css.tests}">
<div class=${css.testList}>${listTests()}</div>
<div class=${css.buttons}>
<div class=${css.runButton} onclick=${runTests}>Run Tests</div>
</div> </div>
<div class="${css.testList}"> ${testsOutput}
<p><button onclick=${runTests}>Run Tests</button></p> ${testsSummary}
${container}
</div> </div>
</div> </div>
` `
if (!self._view.el) self._view.el = el
return el return el
} }
} }

@ -654,6 +654,26 @@ function styleGuide () {
}, },
/* ::::::::::::::
TEST TAB
::::::::::::::: */
testTab: {
box_listTests: appProperties.uiElements.solidBorderBox({
BackgroundColor: appProperties.solidBorderBox_BackgroundColor,
BorderColor: appProperties.solidBorderBox_BackgroundColor,
Color: appProperties.solidBorderBox_TextColor
}),
button_runTests: appProperties.uiElements.button({
BackgroundColor: appProperties.primaryButton_BackgroundColor,
BorderColor: appProperties.primaryButton_BorderColor,
Color: appProperties.primaryButton_TextColor
}),
color_testPass: appProperties.success_BackgroundColor,
color_testFail: appProperties.danger_BackgroundColor
},
/* :::::::::::::: /* ::::::::::::::
SETTINGS TAB SETTINGS TAB
::::::::::::::: */ ::::::::::::::: */

Loading…
Cancel
Save