Skip to content

Commit

Permalink
Merge pull request #1369 from ethereum/tests-logic
Browse files Browse the repository at this point in the history
Tests logic
  • Loading branch information
yann300 authored Jul 18, 2018
2 parents 8288bf2 + 9afb294 commit 03777aa
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 94 deletions.
1 change: 1 addition & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
self._components.filePanel = new FilePanel()
self._view.leftpanel.appendChild(self._components.filePanel.render())
self._components.filePanel.event.register('resize', delta => self._adjustLayout('left', delta))
registry.put({api: self._components.filePanel, name: 'filepanel'})

// ----------------- Renderer -----------------
var renderer = new Renderer()
Expand Down
1 change: 1 addition & 0 deletions src/app/files/fileManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ class FileManager {
}

fileProviderOf (file) {
if (!file) return null
var provider = file.match(/[^/]*/)
if (provider !== null && this._deps.filesProviders[provider[0]]) {
return this._deps.filesProviders[provider[0]]
Expand Down
6 changes: 5 additions & 1 deletion src/app/panels/file-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,11 @@ function filepanel (localRegistry) {
if (!self._deps.fileProviders['browser'].set(newName, '')) {
modalDialogCustom.alert('Failed to create file ' + newName)
} 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)
Expand Down
94 changes: 46 additions & 48 deletions src/app/tabs/styles/test-tab-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,52 @@ 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%;
}
.testTabView {}
.infoBox {
${styles.rightPanel.testTab.box_listTests};
margin: 2%;
}
.tests {}
.testList {
${styles.rightPanel.testTab.box_listTests};
line-height: 2em;
display: flex;
flex-direction: column;
margin: 2%;
}
.container {
${styles.rightPanel.testTab.box_listTests};
margin: 2%;
padding-bottom: 5%;
}
.outputTitle {
font-weight: bold;
margin: 10px 0;
}
.summaryTitle {
font-weight: bold;
}
.testPass {
background-color: ${styles.rightPanel.testTab.color_testPass};
}
.testLog {
margin-bottom: 1%;
border-radius: 4px;
padding: 1% 1% 1% 5%;
}
.testFailure {
background-color: ${styles.rightPanel.testTab.color_testFail};
}
.testFailureSummary {
color: ${styles.appProperties.errorText_Color};
}
.buttons {
${styles.rightPanel.testTab.box_listTests};
margin: 2%;
}
.runButton {
${styles.rightPanel.testTab.button_runTests};
}
`

module.exports = css
125 changes: 80 additions & 45 deletions src/app/tabs/test-tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,101 +13,136 @@ module.exports = class TestTab {
// dependencies
self._deps = {
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._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 () {
var self = this
var container = yo`<div class="tests" id="tests"></div>`

function append (container, txt) {
let child = yo`<div>${txt}</div>`
container.appendChild(child)
}
const self = this
var testsOutput = yo`<div class=${css.container} hidden='true' id="tests"></div>`
var testsSummary = yo`<div class=${css.container} hidden='true' id="tests"></div>`
self.data.allTests = getTests(self)
self.data.selectedTests = [...self.data.allTests]

let testCallback = function (result) {
var testCallback = function (result) {
testsOutput.hidden = false
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') {
append(container, '\t✓ ' + result.value)
testsOutput.appendChild(yo`<div class='${css.testPass} ${css.testLog}'>✓ (${result.value})</div>`)
} 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
// result.passingNum
// result.failureNum
// result.timePassed
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) {
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) {
append(container, (' ' + result.totalFailing + ' failing'))
testsSummary.appendChild(yo`<div>${result.totalFailing} failing</div>`)
testsSummary.appendChild(yo`<br>`)
}

result.errors.forEach((error, index) => {
append(container, ' ' + (index + 1) + ') ' + error.context + ' ' + error.value)
append(container, '')
append(container, ('\t error: ' + error.message))
testsSummary.appendChild(yo`<div>${error.context} - ${error.value} </div>`)
testsSummary.appendChild(yo`<div class=${css.testFailureSummary} >error: ${error.message}</div>`)
testsSummary.appendChild(yo`<br>`)
})
}

function runTest (testFilePath, provider, callback) {
provider.get(testFilePath, (error, content) => {
function runTest (testFilePath, callback) {
self._deps.fileManager.fileProviderOf(testFilePath).get(testFilePath, (error, content) => {
if (!error) {
var runningTest = {}
runningTest[testFilePath] = { content }
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result)
updateFinalResult(error, result, testFilePath)
callback(error)
}, (url, cb) => { this._deps.app.importFileCb(url, cb) })
}, (url, cb) => { self._deps.app.importFileCb(url, cb) })
}
})
}

let runTests = function () {
container.innerHTML = ''
var path = this._deps.fileManager.currentPath()
var provider = this._deps.fileManager.fileProviderOf(path)
function getTests (self) {
var path = self._deps.fileManager.currentPath()
var provider = self._deps.fileManager.fileProviderOf(path)
var tests = []
self._deps.fileManager.filesFromPath(path, (error, files) => {
if (!error) {
for (var file in files) {
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`
<div class="${css.testTabView} "id="testView">
<div>
<div class="${css.infoBox}">
</div>
<div class="${css.testTabView}" id="testView">
<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 class="${css.testList}">
<p><button onclick=${runTests}>Run Tests</button></p>
${container}
<div class="${css.tests}">
<div class=${css.testList}>${listTests()}</div>
<div class=${css.buttons}>
<div class=${css.runButton} onclick=${runTests}>Run Tests</div>
</div>
${testsOutput}
${testsSummary}
</div>
</div>
`
if (!self._view.el) self._view.el = el
return el
}
}
20 changes: 20 additions & 0 deletions src/app/ui/styles-guide/style-guide.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
::::::::::::::: */
Expand Down

0 comments on commit 03777aa

Please sign in to comment.