testTabLogic

pull/1862/head
Aniket-Engg 3 years ago committed by Aniket
parent 63f3ed61cb
commit 93af567fa9
  1. 95
      apps/remix-ide/src/app/tabs/test-tab.js
  2. 3
      apps/remix-ide/src/app/tabs/testTab/testTab.js
  3. 140
      libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts
  4. 7
      libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx

@ -587,21 +587,6 @@ module.exports = class TestTab extends ViewPlugin {
})
}
handleCreateFolder () {
this.inputPath.value = this.trimTestDirInput(this.inputPath.value)
let path = removeMultipleSlashes(this.inputPath.value)
if (path !== '/') path = removeTrailingSlashes(path)
if (this.inputPath.value === '') this.inputPath.value = this.defaultPath
this.inputPath.value = path
this.testTabLogic.generateTestFolder(this.inputPath.value)
this.createTestFolder.disabled = true
this.updateGenerateFileAction().disabled = false
this.testTabLogic.setCurrentPath(this.inputPath.value)
this.updateRunAction()
this.updateForNewCurrent()
this.uiPathList.appendChild(yo`<option>${this.inputPath.value}</option>`)
}
clearResults () {
yo.update(this.resultStatistics, yo`<span></span>`)
this.call('editor', 'clearAnnotations')
@ -642,25 +627,6 @@ module.exports = class TestTab extends ViewPlugin {
runBtn.setAttribute('disabled', 'disabled')
}
updateGenerateFileAction () {
const el = yo`
<button
class="btn border w-50"
data-id="testTabGenerateTestFile"
title="Generate sample test file."
onclick="${this.testTabLogic.generateTestFile.bind(this.testTabLogic)}"
>
Generate
</button>
`
if (!this.generateFileActionElement) {
this.generateFileActionElement = el
} else {
yo.update(this.generateFileActionElement, el)
}
return this.generateFileActionElement
}
updateRunAction (currentFile) {
const el = yo`
<button id="runTestsTabRunAction" title="Run tests" data-id="testTabRunTestsTabRunAction" class="w-50 btn btn-primary" onclick="${() => this.runTests()}">
@ -734,17 +700,6 @@ module.exports = class TestTab extends ViewPlugin {
return yo`<span class='text-info h6'>Progress: ${ready} finished (of ${this.runningTestsNumber})</span>`
}
updateDirList (path) {
for (const o of this.uiPathList.querySelectorAll('option')) o.remove()
this.testTabLogic.dirList(path).then((options) => {
options.forEach((path) => this.uiPathList.appendChild(yo`<option>${path}</option>`))
})
}
trimTestDirInput (input) {
if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/')
else return input.trim()
}
pathAdded (text) {
for (const option of this.uiPathList.querySelectorAll('option')) {
@ -753,54 +708,6 @@ module.exports = class TestTab extends ViewPlugin {
return false
}
async handleTestDirInput (e) {
let testDirInput = this.trimTestDirInput(this.inputPath.value)
testDirInput = removeMultipleSlashes(testDirInput)
if (testDirInput !== '/') testDirInput = removeTrailingSlashes(testDirInput)
if (e.key === 'Enter') {
this.inputPath.value = testDirInput
if (await this.testTabLogic.pathExists(testDirInput)) {
this.testTabLogic.setCurrentPath(testDirInput)
this.updateForNewCurrent()
return
}
}
if (testDirInput) {
if (testDirInput.endsWith('/') && testDirInput !== '/') {
testDirInput = removeTrailingSlashes(testDirInput)
if (this.testTabLogic.currentPath === testDirInput.substr(0, testDirInput.length - 1)) {
this.createTestFolder.disabled = true
this.updateGenerateFileAction().disabled = true
}
this.updateDirList(testDirInput)
} else {
// If there is no matching folder in the workspace with entered text, enable Create button
if (await this.testTabLogic.pathExists(testDirInput)) {
this.createTestFolder.disabled = true
this.updateGenerateFileAction().disabled = false
} else {
// Enable Create button
this.createTestFolder.disabled = false
// Disable Generate button because dir does not exist
this.updateGenerateFileAction().disabled = true
}
}
} else {
this.updateDirList('/')
}
}
async handleEnter (e) {
this.inputPath.value = removeMultipleSlashes(this.trimTestDirInput(this.inputPath.value))
if (this.createTestFolder.disabled) {
if (await this.testTabLogic.pathExists(this.inputPath.value)) {
this.testTabLogic.setCurrentPath(this.inputPath.value)
this.updateForNewCurrent()
}
}
}
render () {
console.log('render--->')
this.onActivationInternal()
@ -811,7 +718,7 @@ module.exports = class TestTab extends ViewPlugin {
renderComponent () {
console.log('renderComponent-start-->')
ReactDOM.render(
<SolidityUnitTesting testTab={this} testTabLogic={this.testTabLogic} helper={helper} />
<SolidityUnitTesting testTab={this} helper={helper} />
, this.element)
console.log('renderComponent-end-->')
}

@ -4,6 +4,7 @@ const remixPath = require('path')
class TestTabLogic {
constructor (fileManager) {
console.log('Inside TestTabLogic constructor---fileManager--->', fileManager)
this.fileManager = fileManager
this.currentPath = '/tests'
}
@ -33,6 +34,8 @@ class TestTabLogic {
}
generateTestFile () {
console.log('Inside generateTestFile-1-')
console.log('Inside generateTestFile---fileManager--->', this.fileManager)
let fileName = this.fileManager.currentFile()
const hasCurrent = !!fileName && this.fileManager.currentFile().split('.').pop().toLowerCase() === 'sol'
if (!hasCurrent) fileName = this.currentPath + '/newFile.sol'

@ -0,0 +1,140 @@
// const modalDialogCustom = require('../../ui/modal-dialog-custom')
const remixPath = require('path')
export class TestTabLogic {
fileManager
currentPath
helper
constructor (fileManager: any, helper: any) {
console.log('Inside TestTabLogic constructor--from SUT-fileManager--->', fileManager)
this.fileManager = fileManager
this.helper = helper
this.currentPath = '/tests'
}
setCurrentPath (path: string) {
if (path.indexOf('/') === 0) return
this.currentPath = this.helper.removeMultipleSlashes(this.helper.removeTrailingSlashes(path))
}
generateTestFolder (path:string) {
// Todo move this check to File Manager after refactoring
// Checking to ignore the value which contains only whitespaces
if (!path || !(/\S/.test(path))) return
path = this.helper.removeMultipleSlashes(path)
const fileProvider = this.fileManager.fileProviderOf(path.split('/')[0])
fileProvider.exists(path).then((res: any) => {
if (!res) fileProvider.createDir(path)
})
}
async pathExists (path: string) {
// Checking to ignore the value which contains only whitespaces
if (!path || !(/\S/.test(path))) return
const fileProvider = this.fileManager.fileProviderOf(path.split('/')[0])
const res = await fileProvider.exists(path, (e: any, res: any) => { return res })
return res
}
generateTestFile () {
console.log('Inside generateTestFile-1SUT-')
console.log('Inside generateTestFile---fileManager-SUT-->', this.fileManager)
let fileName = this.fileManager.currentFile()
const hasCurrent = !!fileName && this.fileManager.currentFile().split('.').pop().toLowerCase() === 'sol'
if (!hasCurrent) fileName = this.currentPath + '/newFile.sol'
const fileProvider = this.fileManager.fileProviderOf(this.currentPath)
if (!fileProvider) return
const splittedFileName = fileName.split('/')
const fileNameToImport = (!hasCurrent) ? fileName : this.currentPath + '/' + splittedFileName[splittedFileName.length - 1]
this.helper.createNonClashingNameWithPrefix(fileNameToImport, fileProvider, '_test', (error: any, newFile: any) => {
// if (error) return modalDialogCustom.alert('Failed to create file. ' + newFile + ' ' + error)
// if (!fileProvider.set(newFile, this.generateTestContractSample(hasCurrent, fileName))) return modalDialogCustom.alert('Failed to create test file ' + newFile)
this.fileManager.open(newFile)
this.fileManager.syncEditor(newFile)
})
}
dirList (path:string) {
return this.fileManager.dirList(path)
}
isRemixDActive () {
return this.fileManager.isRemixDActive()
}
async getTests (cb: any) {
if (!this.currentPath) return cb(null, [])
const provider = this.fileManager.fileProviderOf(this.currentPath)
if (!provider) return cb(null, [])
const tests = []
let files = []
try {
if (await this.fileManager.exists(this.currentPath)) files = await this.fileManager.readdir(this.currentPath)
} catch (e: any) {
cb(e.message)
}
for (var file in files) {
const filepath = provider && provider.type ? provider.type + '/' + file : file
if (/.(_test.sol)$/.exec(file)) tests.push(filepath)
}
cb(null, tests, this.currentPath)
}
// @todo(#2758): If currently selected file is compiled and compilation result is available,
// 'contractName' should be <compiledContractName> + '_testSuite'
generateTestContractSample (hasCurrent: any, fileToImport: any, contractName = 'testSuite') {
let relative = remixPath.relative(this.currentPath, remixPath.dirname(fileToImport))
if (relative === '') relative = '.'
const comment = hasCurrent ? `import "${relative}/${remixPath.basename(fileToImport)}";` : '// <import file to test>'
return `// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
// This import is automatically injected by Remix
import "remix_tests.sol";
// This import is required to use custom transaction context
// Although it may fail compilation in 'Solidity Compiler' plugin
// But it will work fine in 'Solidity Unit Testing' plugin
import "remix_accounts.sol";
${comment}
// File name has to end with '_test.sol', this file can contain more than one testSuite contracts
contract ${contractName} {
/// 'beforeAll' runs before all other tests
/// More special functions are: 'beforeEach', 'beforeAll', 'afterEach' & 'afterAll'
function beforeAll() public {
// <instantiate contract>
Assert.equal(uint(1), uint(1), "1 should be equal to 1");
}
function checkSuccess() public {
// Use 'Assert' methods: https://remix-ide.readthedocs.io/en/latest/assert_library.html
Assert.ok(2 == 2, 'should be true');
Assert.greaterThan(uint(2), uint(1), "2 should be greater than to 1");
Assert.lesserThan(uint(2), uint(3), "2 should be lesser than to 3");
}
function checkSuccess2() public pure returns (bool) {
// Use the return value (true or false) to test the contract
return true;
}
function checkFailure() public {
Assert.notEqual(uint(1), uint(1), "1 should not be equal to 1");
}
/// Custom Transaction Context: https://remix-ide.readthedocs.io/en/latest/unittesting.html#customization
/// #sender: account-1
/// #value: 100
function checkSenderAndValue() public payable {
// account index varies 0-9, value is in wei
Assert.equal(msg.sender, TestsAccounts.getAccount(1), "Invalid sender");
Assert.equal(msg.value, 100, "Invalid value");
}
}
`
}
}

@ -1,4 +1,5 @@
import React, { useState, useRef, useEffect } from 'react' // eslint-disable-line
import { TestTabLogic } from './logic/testTabLogic'
import './css/style.css'
@ -7,7 +8,9 @@ export interface SolidityUnitTestingProps {}
export const SolidityUnitTesting = (props: any) => {
const {helper, testTab, testTabLogic} = props
const {helper, testTab} = props
const testTabLogic = new TestTabLogic(testTab.fileManager, helper)
const [defaultPath, setDefaultPath] = useState('tests')
const [disableCreateButton, setDisableCreateButton] = useState(true)
@ -290,7 +293,7 @@ export const SolidityUnitTesting = (props: any) => {
data-id="testTabGenerateTestFile"
title="Generate sample test file."
disabled={disableGenerateButton}
onClick={testTabLogic.generateTestFile}
onClick={testTabLogic.generateTestFile.bind(testTabLogic)}
>
Generate
</button>

Loading…
Cancel
Save