From 1141577cf1b1423c5030cdf56d3b5c65657d3489 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 4 Jan 2022 18:20:33 +0530 Subject: [PATCH 01/16] types in SUT component --- .../solidity-unit-testing/.eslintrc.json | 3 - .../src/lib/solidity-unit-testing.tsx | 58 ++++++++++--------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/libs/remix-ui/solidity-unit-testing/.eslintrc.json b/libs/remix-ui/solidity-unit-testing/.eslintrc.json index 5e100bf955..50e59482cf 100644 --- a/libs/remix-ui/solidity-unit-testing/.eslintrc.json +++ b/libs/remix-ui/solidity-unit-testing/.eslintrc.json @@ -1,9 +1,6 @@ { "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"], "ignorePatterns": ["!**/*"], - "rules": { - "@typescript-eslint/no-explicit-any": "off" - }, "overrides": [ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx index 0e791fd0ec..1c71951f42 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx +++ b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx @@ -21,42 +21,42 @@ export const SolidityUnitTesting = (props: Record) => { const { helper, testTab, initialPath } = props const { testTabLogic } = testTab - const [toasterMsg, setToasterMsg] = useState('') + const [toasterMsg, setToasterMsg] = useState('') - const [disableCreateButton, setDisableCreateButton] = useState(true) - const [disableGenerateButton, setDisableGenerateButton] = useState(false) - const [disableStopButton, setDisableStopButton] = useState(true) - const [disableRunButton, setDisableRunButton] = useState(false) - const [runButtonTitle, setRunButtonTitle] = useState('Run tests') - const [stopButtonLabel, setStopButtonLabel] = useState('Stop') + const [disableCreateButton, setDisableCreateButton] = useState(true) + const [disableGenerateButton, setDisableGenerateButton] = useState(false) + const [disableStopButton, setDisableStopButton] = useState(true) + const [disableRunButton, setDisableRunButton] = useState(false) + const [runButtonTitle, setRunButtonTitle] = useState('Run tests') + const [stopButtonLabel, setStopButtonLabel] = useState('Stop') - const [checkSelectAll, setCheckSelectAll] = useState(true) + const [checkSelectAll, setCheckSelectAll] = useState(true) const [testsOutput, setTestsOutput] = useState([]) - const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true) - const [progressBarHidden, setProgressBarHidden] = useState(true) - const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState(true) + const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true) + const [progressBarHidden, setProgressBarHidden] = useState(true) + const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState(true) let [testFiles, setTestFiles] = useState([]) // eslint-disable-line - const [pathOptions, setPathOptions] = useState(['']) + const [pathOptions, setPathOptions] = useState(['']) - const [inputPathValue, setInputPathValue] = useState('tests') + const [inputPathValue, setInputPathValue] = useState('tests') - let [readyTestsNumber, setReadyTestsNumber] = useState(0) // eslint-disable-line - let [runningTestsNumber, setRunningTestsNumber] = useState(0) // eslint-disable-line + let [readyTestsNumber, setReadyTestsNumber] = useState(0) // eslint-disable-line + let [runningTestsNumber, setRunningTestsNumber] = useState(0) // eslint-disable-line - const hasBeenStopped = useRef(false) - const isDebugging = useRef(false) - const allTests: any = useRef([]) - const selectedTests: any = useRef([]) - const currentErrors: any = useRef([]) + const hasBeenStopped = useRef(false) + const isDebugging = useRef(false) + const allTests = useRef([]) + const selectedTests = useRef([]) + const currentErrors:any = useRef([]) const defaultPath = 'tests' let areTestsRunning = false - let runningTestFileName: any - const filesContent: any = {} - const testsResultByFilename: Record = {} + let runningTestFileName: string + const filesContent: Record> = {} + const testsResultByFilename: Record>> = {} const trimTestDirInput = (input: string) => { if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/') @@ -71,7 +71,7 @@ export const SolidityUnitTesting = (props: Record) => { setTestsExecutionStoppedErrorHidden(true) } - const updateForNewCurrent = async (file = null) => { + const updateForNewCurrent = async (file: string | null = null) => { // Ensure that when someone clicks on compilation error and that opens a new file // Test result, which is compilation error in this case, is not cleared if (currentErrors.current) { @@ -90,6 +90,8 @@ export const SolidityUnitTesting = (props: Record) => { const tests = await testTabLogic.getTests() allTests.current = tests selectedTests.current = [...allTests.current] + console.log('allTests----->', allTests.current) + console.log('selectedTests----->', selectedTests.current) updateTestFileList() if (!areTestsRunning) await updateRunAction(file) } catch (e: any) { @@ -132,12 +134,13 @@ export const SolidityUnitTesting = (props: Record) => { }) testTab.fileManager.events.on('noFileSelected', () => { }) // eslint-disable-line - testTab.fileManager.events.on('currentFileChanged', async (file: any, provider: any) => await updateForNewCurrent(file)) + testTab.fileManager.events.on('currentFileChanged', async (file: string, provider: any) => await updateForNewCurrent(file)) }, []) // eslint-disable-line const updateDirList = (path: string) => { testTabLogic.dirList(path).then((options: any) => { + console.log('options in testDir List--->', options) setPathOptions(options) }) } @@ -214,7 +217,7 @@ export const SolidityUnitTesting = (props: Record) => { return fileName ? fileName.replace(/\//g, '_').replace(/\./g, '_') + testSuite : fileName } - const startDebug = async (txHash: any, web3: any) => { + const startDebug = async (txHash: string, web3: any) => { isDebugging.current = true if (!await testTab.appManager.isActive('debugger')) await testTab.appManager.activatePlugin('debugger') testTab.call('menuicons', 'select', 'debugger') @@ -223,6 +226,7 @@ export const SolidityUnitTesting = (props: Record) => { const printHHLogs = (logsArr: any, testName: any) => { let finalLogs = `${testName}:\n` + console.log('logsArr======>', logsArr) for (const log of logsArr) { let formattedLog // Hardhat implements the same formatting options that can be found in Node.js' console.log, @@ -262,7 +266,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const renderContract = (filename: any, contract: any, index: number, withoutLabel = false) => { + const renderContract = (filename: string, contract: string|null, index: number, withoutLabel = false) => { if (withoutLabel) { const contractCard: any = (
From 9587489d59aadc4383d3578121701761c687278e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 4 Jan 2022 18:36:22 +0530 Subject: [PATCH 02/16] TestResultInterface --- .../src/lib/solidity-unit-testing.tsx | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx index 1c71951f42..5ece8f8686 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx +++ b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx @@ -16,6 +16,23 @@ interface TestObject { checked: boolean } +export interface TestResultInterface { + type: string + value: any + time?: number + context?: string + errMsg?: string + filename: string + assertMethod?: string + returned?: string | number + expected?: string | number + location?: string + hhLogs?: [] + web3?: any + debugTxHash?: string + rendered?: boolean +} + export const SolidityUnitTesting = (props: Record) => { const { helper, testTab, initialPath } = props @@ -139,8 +156,7 @@ export const SolidityUnitTesting = (props: Record) => { }, []) // eslint-disable-line const updateDirList = (path: string) => { - testTabLogic.dirList(path).then((options: any) => { - console.log('options in testDir List--->', options) + testTabLogic.dirList(path).then((options: string[]) => { setPathOptions(options) }) } @@ -213,7 +229,7 @@ export const SolidityUnitTesting = (props: Record) => { setPathOptions(pathOptions) } - const cleanFileName = (fileName: any, testSuite: any) => { + const cleanFileName = (fileName: string, testSuite: string) => { return fileName ? fileName.replace(/\//g, '_').replace(/\./g, '_') + testSuite : fileName } @@ -224,9 +240,8 @@ export const SolidityUnitTesting = (props: Record) => { testTab.call('debugger', 'debug', txHash, web3) } - const printHHLogs = (logsArr: any, testName: any) => { + const printHHLogs = (logsArr: Record[], testName: string) => { let finalLogs = `${testName}:\n` - console.log('logsArr======>', logsArr) for (const log of logsArr) { let formattedLog // Hardhat implements the same formatting options that can be found in Node.js' console.log, @@ -307,8 +322,8 @@ export const SolidityUnitTesting = (props: Record) => { }) } - const renderTests = (tests: any, contract: any, filename: any) => { - const index = tests.findIndex((test: any) => test.type === 'testFailure') + const renderTests = (tests: TestResultInterface[], contract: string, filename: string) => { + const index = tests.findIndex((test: TestResultInterface) => test.type === 'testFailure') // show filename and contract renderContract(filename, contract, index) // show tests @@ -346,7 +361,7 @@ export const SolidityUnitTesting = (props: Record) => { const testFailCard1: any = (
highlightLocation(test.location, test.filename)} + onClick={() => { if(test.location) highlightLocation(test.location, test.filename)}} >
✘ {test.value} @@ -363,7 +378,7 @@ export const SolidityUnitTesting = (props: Record) => { const testFailCard2: any = (
highlightLocation(test.location, test.filename)} + onClick={() => { if(test.location) highlightLocation(test.location, test.filename)}} >
✘ {test.value} @@ -400,7 +415,7 @@ export const SolidityUnitTesting = (props: Record) => { for (const contract of contracts) { if (contract && contract !== 'summary' && contract !== 'errors') { runningTestFileName = cleanFileName(filename, contract) - const tests = fileTestsResult[contract] + const tests = fileTestsResult[contract] as TestResultInterface[] if (tests?.length) { renderTests(tests, contract, filename) } else { @@ -441,7 +456,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const testCallback = (result: any) => { + const testCallback = (result: Record) => { if (result.filename) { if (!testsResultByFilename[result.filename]) { testsResultByFilename[result.filename] = {} From 646d34f9cf2fcf4888f1c8a5e46e5d6cb2bbf0a8 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 5 Jan 2022 13:07:12 +0530 Subject: [PATCH 03/16] more types --- .../src/lib/solidity-unit-testing.tsx | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx index 5ece8f8686..32341f6981 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx +++ b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx @@ -16,7 +16,7 @@ interface TestObject { checked: boolean } -export interface TestResultInterface { +interface TestResultInterface { type: string value: any time?: number @@ -33,6 +33,13 @@ export interface TestResultInterface { rendered?: boolean } +interface FinalResult { + totalPassing: number, + totalFailing: number, + totalTime: any, + errors: any[], +} + export const SolidityUnitTesting = (props: Record) => { const { helper, testTab, initialPath } = props @@ -107,8 +114,6 @@ export const SolidityUnitTesting = (props: Record) => { const tests = await testTabLogic.getTests() allTests.current = tests selectedTests.current = [...allTests.current] - console.log('allTests----->', allTests.current) - console.log('selectedTests----->', selectedTests.current) updateTestFileList() if (!areTestsRunning) await updateRunAction(file) } catch (e: any) { @@ -482,7 +487,7 @@ export const SolidityUnitTesting = (props: Record) => { cb() } - const updateFinalResult = (_errors: any, result: any, filename: any) => { + const updateFinalResult = (_errors: any, result: FinalResult|null, filename: string) => { ++readyTestsNumber setReadyTestsNumber(readyTestsNumber) if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) { @@ -519,14 +524,14 @@ export const SolidityUnitTesting = (props: Record) => { } } - const runTest = (testFilePath: any, callback: any) => { + const runTest = (testFilePath: string, callback: any) => { isDebugging.current = false if (hasBeenStopped.current) { - updateFinalResult(null, null, null) + updateFinalResult(null, null, testFilePath) return } - testTab.fileManager.readFile(testFilePath).then((content: any) => { - const runningTests: any = {} + testTab.fileManager.readFile(testFilePath).then((content: string) => { + const runningTests: Record> = {} runningTests[testFilePath] = { content } filesContent[testFilePath] = { content } const { currentVersion, evmVersion, optimize, runs, isUrl } = testTab.compileTab.getCurrentCompilerConfig() @@ -538,14 +543,14 @@ export const SolidityUnitTesting = (props: Record) => { usingWorker: canUseWorker(currentVersion), runs } - const deployCb = async (file: any, contractAddress: any) => { + const deployCb = async (file: string, contractAddress: string) => { const compilerData = await testTab.call('compilerArtefacts', 'getCompilerAbstract', file) await testTab.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilerData) } testTab.testRunner.runTestSources( runningTests, compilerConfig, - (result: any) => testCallback(result), + (result: Record) => testCallback(result), (_err: any, result: any, cb: any) => resultsCallback(_err, result, cb), deployCb, (error: any, result: any) => { @@ -555,7 +560,7 @@ export const SolidityUnitTesting = (props: Record) => { return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: any) => cb(error.message)) }, { testFilePath } ) - }).catch((error: any) => { + }).catch((error: Error) => { console.log(error) if (error) return // eslint-disable-line }) @@ -571,11 +576,11 @@ export const SolidityUnitTesting = (props: Record) => { setDisableStopButton(false) clearResults() setProgressBarHidden(false) - const tests = selectedTests.current + const tests: string[] = selectedTests.current if (!tests || !tests.length) return else setProgressBarHidden(false) _paq.push(['trackEvent', 'solidityUnitTesting', 'runTests']) - eachOfSeries(tests, (value: any, key: any, callback: any) => { + eachOfSeries(tests, (value: string, key: string, callback: any) => { if (hasBeenStopped.current) return runTest(value, callback) }) @@ -605,7 +610,7 @@ export const SolidityUnitTesting = (props: Record) => { return selectedTestsList.map(testFileObj => testFileObj.fileName) } - const toggleCheckbox = (eChecked: any, index: any) => { + const toggleCheckbox = (eChecked: boolean, index: number) => { testFiles[index].checked = eChecked setTestFiles(testFiles) selectedTests.current = getCurrentSelectedTests() @@ -637,7 +642,7 @@ export const SolidityUnitTesting = (props: Record) => { const updateTestFileList = () => { if (allTests.current?.length) { - testFiles = allTests.current.map((testFile: any) => { return { 'fileName': testFile, 'checked': true } }) + testFiles = allTests.current.map((testFile: string) => { return { 'fileName': testFile, 'checked': true } }) setCheckSelectAll(true) } else @@ -723,7 +728,7 @@ export const SolidityUnitTesting = (props: Record) => { />
-
{testFiles?.length ? testFiles.map((testFileObj: any, index) => { +
{testFiles?.length ? testFiles.map((testFileObj: TestObject, index) => { const elemId = `singleTest${testFileObj.fileName}` return (
From 66411da78de8c1f163ede1f21ec7968664bcbbb2 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 5 Jan 2022 13:21:36 +0530 Subject: [PATCH 04/16] ReactElement --- .../src/lib/solidity-unit-testing.tsx | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx index 32341f6981..c10b1b0c6a 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx +++ b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react' // eslint-disable-line +import React, { useState, useRef, useEffect, ReactElement } from 'react' // eslint-disable-line import { eachOfSeries } from 'async' // eslint-disable-line import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity' import { Renderer } from '@remix-ui/renderer' // eslint-disable-line @@ -55,7 +55,7 @@ export const SolidityUnitTesting = (props: Record) => { const [stopButtonLabel, setStopButtonLabel] = useState('Stop') const [checkSelectAll, setCheckSelectAll] = useState(true) - const [testsOutput, setTestsOutput] = useState([]) + const [testsOutput, setTestsOutput] = useState([]) const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true) const [progressBarHidden, setProgressBarHidden] = useState(true) @@ -288,7 +288,7 @@ export const SolidityUnitTesting = (props: Record) => { const renderContract = (filename: string, contract: string|null, index: number, withoutLabel = false) => { if (withoutLabel) { - const contractCard: any = ( + const contractCard: ReactElement = (
{contract ? contract : ''} ({filename})
@@ -315,13 +315,13 @@ export const SolidityUnitTesting = (props: Record) => {
) } // show contract and file name with label - const ContractCard: any = ( + const ContractCard: ReactElement = (
{label}{contract} ({filename})
) setTestsOutput(prevCards => { - const index = prevCards.findIndex((card: any) => card.props.id === runningTestFileName) + const index = prevCards.findIndex((card: ReactElement) => card.props.id === runningTestFileName) prevCards[index] = ContractCard return prevCards }) @@ -345,7 +345,7 @@ export const SolidityUnitTesting = (props: Record) => { } if (test.type === 'testPass') { if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) - const testPassCard: any = ( + const testPassCard: ReactElement = (
) => { } else if (test.type === 'testFailure') { if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) if (!test.assertMethod) { - const testFailCard1: any = (
{ if(test.location) highlightLocation(test.location, test.filename)}} @@ -380,7 +380,7 @@ export const SolidityUnitTesting = (props: Record) => { const preposition = test.assertMethod === 'equal' || test.assertMethod === 'notEqual' ? 'to' : '' const method = test.assertMethod === 'ok' ? '' : test.assertMethod const expected = test.assertMethod === 'ok' ? '\'true\'' : test.expected - const testFailCard2: any = (
{ if(test.location) highlightLocation(test.location, test.filename)}} @@ -431,17 +431,17 @@ export const SolidityUnitTesting = (props: Record) => { const errors = fileTestsResult['errors'] if (errors && errors.errors) { errors.errors.forEach((err: any) => { - const errorCard: any = + const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) }) } else if (errors && Array.isArray(errors) && (errors[0].message || errors[0].formattedMessage)) { errors.forEach((err) => { - const errorCard: any = + const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) }) } else if (errors && !errors.errors && !Array.isArray(errors)) { // To track error like this: https://github.com/ethereum/remix/pull/1438 - const errorCard: any = + const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) } } @@ -449,7 +449,7 @@ export const SolidityUnitTesting = (props: Record) => { // show summary const testSummary = fileTestsResult['summary'] if (testSummary && testSummary.filename && !testSummary.rendered) { - const summaryCard: any = (
+ const summaryCard: ReactElement = (
Result for {testSummary.filename} Passed: {testSummary.passed} Failed: {testSummary.failed} @@ -556,8 +556,8 @@ export const SolidityUnitTesting = (props: Record) => { (error: any, result: any) => { updateFinalResult(error, result, testFilePath) callback(error) - }, (url: any, cb: any) => { - return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: any) => cb(error.message)) + }, (url: string, cb: any) => { + return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: Error) => cb(error.message)) }, { testFilePath } ) }).catch((error: Error) => { From 80f30f94f7b557593575d8985e1689ac6c98020e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 5 Jan 2022 13:29:21 +0530 Subject: [PATCH 05/16] testTabLogic linting fix --- .../src/lib/logic/testTabLogic.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts b/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts index 6b42bc128a..6e1af409a4 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts +++ b/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts @@ -5,6 +5,7 @@ export class TestTabLogic { fileManager currentPath helper + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor (fileManager: any, helper: any) { this.fileManager = fileManager this.helper = helper @@ -26,7 +27,7 @@ export class TestTabLogic { 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) => { + fileProvider.exists(path).then((res: boolean) => { if (!res) fileProvider.createDir(path) }) } @@ -35,11 +36,12 @@ export class TestTabLogic { // 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 }) + const res = await fileProvider.exists(path, (e: Error, res: boolean) => { return res }) return res } - generateTestFile (errorCb: any) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + generateTestFile (errorCb:any) { let fileName = this.fileManager.currentFile() const hasCurrent = !!fileName && this.fileManager.currentFile().split('.').pop().toLowerCase() === 'sol' if (!hasCurrent) fileName = this.currentPath + '/newFile.sol' @@ -47,7 +49,7 @@ export class TestTabLogic { 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) => { + this.helper.createNonClashingNameWithPrefix(fileNameToImport, fileProvider, '_test', (error: Error, newFile: string) => { if (error) return errorCb('Failed to create file. ' + newFile + ' ' + error) const isFileCreated = fileProvider.set(newFile, this.generateTestContractSample(hasCurrent, fileName)) if (!isFileCreated) return errorCb('Failed to create test file ' + newFile) @@ -72,7 +74,7 @@ export class TestTabLogic { let files = [] try { if (await this.fileManager.exists(this.currentPath)) files = await this.fileManager.readdir(this.currentPath) - } catch (e: any) { + } catch (e: any) { // eslint-disable-line @typescript-eslint/no-explicit-any throw e.message } for (const file in files) { @@ -84,7 +86,7 @@ export class TestTabLogic { // @todo(#2758): If currently selected file is compiled and compilation result is available, // 'contractName' should be + '_testSuite' - generateTestContractSample (hasCurrent: any, fileToImport: any, contractName = 'testSuite') { + generateTestContractSample (hasCurrent: boolean, fileToImport: string, contractName = 'testSuite') { let relative = remixPath.relative(this.currentPath, remixPath.dirname(fileToImport)) if (relative === '') relative = '.' const comment = hasCurrent ? `import "${relative}/${remixPath.basename(fileToImport)}";` : '// ' From 3dc300f73f90d5514b23737bf40d4fd7f2c13c1d Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 5 Jan 2022 13:51:21 +0530 Subject: [PATCH 06/16] disable specific linting rule --- .../src/lib/solidity-unit-testing.tsx | 60 +++++++++---------- package.json | 2 +- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx index c10b1b0c6a..6cb5bc3820 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx +++ b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx @@ -1,15 +1,13 @@ import React, { useState, useRef, useEffect, ReactElement } from 'react' // eslint-disable-line import { eachOfSeries } from 'async' // eslint-disable-line +import type Web3 from 'web3' import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity' import { Renderer } from '@remix-ui/renderer' // eslint-disable-line import { Toaster } from '@remix-ui/toaster' // eslint-disable-line import { format } from 'util' import './css/style.css' -const _paq = (window as any)._paq = (window as any)._paq || [] // eslint-disable-line - -/* eslint-disable-next-line */ -export interface SolidityUnitTestingProps { } +const _paq = (window as any)._paq = (window as any)._paq || [] // eslint-disable-line @typescript-eslint/no-explicit-any interface TestObject { fileName: string @@ -18,7 +16,7 @@ interface TestObject { interface TestResultInterface { type: string - value: any + value: any // eslint-disable-line @typescript-eslint/no-explicit-any time?: number context?: string errMsg?: string @@ -28,7 +26,7 @@ interface TestResultInterface { expected?: string | number location?: string hhLogs?: [] - web3?: any + web3?: Web3 debugTxHash?: string rendered?: boolean } @@ -36,11 +34,11 @@ interface TestResultInterface { interface FinalResult { totalPassing: number, totalFailing: number, - totalTime: any, - errors: any[], + totalTime: any, // eslint-disable-line @typescript-eslint/no-explicit-any + errors: any[], // eslint-disable-line @typescript-eslint/no-explicit-any } -export const SolidityUnitTesting = (props: Record) => { +export const SolidityUnitTesting = (props: Record) => { // eslint-disable-line @typescript-eslint/no-explicit-any const { helper, testTab, initialPath } = props const { testTabLogic } = testTab @@ -73,14 +71,14 @@ export const SolidityUnitTesting = (props: Record) => { const isDebugging = useRef(false) const allTests = useRef([]) const selectedTests = useRef([]) - const currentErrors:any = useRef([]) + const currentErrors:any = useRef([]) // eslint-disable-line @typescript-eslint/no-explicit-any const defaultPath = 'tests' let areTestsRunning = false let runningTestFileName: string const filesContent: Record> = {} - const testsResultByFilename: Record>> = {} + const testsResultByFilename: Record>> = {} // eslint-disable-line @typescript-eslint/no-explicit-any const trimTestDirInput = (input: string) => { if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/') @@ -116,7 +114,7 @@ export const SolidityUnitTesting = (props: Record) => { selectedTests.current = [...allTests.current] updateTestFileList() if (!areTestsRunning) await updateRunAction(file) - } catch (e: any) { + } catch (e: any) { // eslint-disable-line @typescript-eslint/no-explicit-any console.log(e) setToasterMsg(e) } @@ -156,7 +154,7 @@ export const SolidityUnitTesting = (props: Record) => { }) testTab.fileManager.events.on('noFileSelected', () => { }) // eslint-disable-line - testTab.fileManager.events.on('currentFileChanged', async (file: string, provider: any) => await updateForNewCurrent(file)) + testTab.fileManager.events.on('currentFileChanged', async (file: string) => await updateForNewCurrent(file)) }, []) // eslint-disable-line @@ -166,7 +164,7 @@ export const SolidityUnitTesting = (props: Record) => { }) } - const handleTestDirInput = async (e: any) => { + const handleTestDirInput = async (e: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any let testDirInput = trimTestDirInput(e.target.value) testDirInput = helper.removeMultipleSlashes(testDirInput) if (testDirInput !== '/') testDirInput = helper.removeTrailingSlashes(testDirInput) @@ -207,7 +205,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const handleEnter = async (e: any) => { + const handleEnter = async (e: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any let inputPath = e.target.value inputPath = helper.removeMultipleSlashes(trimTestDirInput(inputPath)) setInputPathValue(inputPath) @@ -238,14 +236,14 @@ export const SolidityUnitTesting = (props: Record) => { return fileName ? fileName.replace(/\//g, '_').replace(/\./g, '_') + testSuite : fileName } - const startDebug = async (txHash: string, web3: any) => { + const startDebug = async (txHash: string, web3: Web3) => { isDebugging.current = true if (!await testTab.appManager.isActive('debugger')) await testTab.appManager.activatePlugin('debugger') testTab.call('menuicons', 'select', 'debugger') testTab.call('debugger', 'debug', txHash, web3) } - const printHHLogs = (logsArr: Record[], testName: string) => { + const printHHLogs = (logsArr: Record[], testName: string) => { // eslint-disable-line @typescript-eslint/no-explicit-any let finalLogs = `${testName}:\n` for (const log of logsArr) { let formattedLog @@ -430,7 +428,7 @@ export const SolidityUnitTesting = (props: Record) => { } else if (contract === 'errors' && fileTestsResult['errors']) { const errors = fileTestsResult['errors'] if (errors && errors.errors) { - errors.errors.forEach((err: any) => { + errors.errors.forEach((err: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) }) @@ -461,7 +459,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const testCallback = (result: Record) => { + const testCallback = (result: Record) => { // eslint-disable-line @typescript-eslint/no-explicit-any if (result.filename) { if (!testsResultByFilename[result.filename]) { testsResultByFilename[result.filename] = {} @@ -479,7 +477,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const resultsCallback = (_err: any, result: any, cb: any) => { + const resultsCallback = (_err: any, result: any, cb: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any // total stats for the test // result.passingNum // result.failureNum @@ -487,7 +485,7 @@ export const SolidityUnitTesting = (props: Record) => { cb() } - const updateFinalResult = (_errors: any, result: FinalResult|null, filename: string) => { + const updateFinalResult = (_errors: any, result: FinalResult|null, filename: string) => { // eslint-disable-line @typescript-eslint/no-explicit-any ++readyTestsNumber setReadyTestsNumber(readyTestsNumber) if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) { @@ -524,7 +522,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const runTest = (testFilePath: string, callback: any) => { + const runTest = (testFilePath: string, callback: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any isDebugging.current = false if (hasBeenStopped.current) { updateFinalResult(null, null, testFilePath) @@ -550,14 +548,14 @@ export const SolidityUnitTesting = (props: Record) => { testTab.testRunner.runTestSources( runningTests, compilerConfig, - (result: Record) => testCallback(result), - (_err: any, result: any, cb: any) => resultsCallback(_err, result, cb), + (result: Record) => testCallback(result), // eslint-disable-line @typescript-eslint/no-explicit-any + (_err: any, result: any, cb: any) => resultsCallback(_err, result, cb), // eslint-disable-line @typescript-eslint/no-explicit-any deployCb, - (error: any, result: any) => { + (error: any, result: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any updateFinalResult(error, result, testFilePath) callback(error) - }, (url: string, cb: any) => { - return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: Error) => cb(error.message)) + }, (url: string, cb: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any + return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: Error) => cb(error.message)) // eslint-disable-line @typescript-eslint/no-explicit-any }, { testFilePath } ) }).catch((error: Error) => { @@ -580,13 +578,13 @@ export const SolidityUnitTesting = (props: Record) => { if (!tests || !tests.length) return else setProgressBarHidden(false) _paq.push(['trackEvent', 'solidityUnitTesting', 'runTests']) - eachOfSeries(tests, (value: string, key: string, callback: any) => { + eachOfSeries(tests, (value: string, key: string, callback: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any if (hasBeenStopped.current) return runTest(value, callback) }) } - const updateRunAction = async (currentFile: any = null) => { + const updateRunAction = async (currentFile: any = null) => { // eslint-disable-line @typescript-eslint/no-explicit-any const isSolidityActive = await testTab.appManager.isActive('solidity') if (!isSolidityActive || !selectedTests.current?.length) { // setDisableRunButton(true) @@ -627,7 +625,7 @@ export const SolidityUnitTesting = (props: Record) => { } else setCheckSelectAll(false) } - const checkAll = (event: any) => { + const checkAll = (event: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any testFiles.forEach((testFileObj) => testFileObj.checked = event.target.checked) setTestFiles(testFiles) setCheckSelectAll(event.target.checked) @@ -698,7 +696,7 @@ export const SolidityUnitTesting = (props: Record) => { title="Generate sample test file." disabled={disableGenerateButton} onClick={async () => { - testTabLogic.generateTestFile((err:any) => { if (err) setToasterMsg(err)}) + testTabLogic.generateTestFile((err:any) => { if (err) setToasterMsg(err)}) // eslint-disable-line @typescript-eslint/no-explicit-any await updateForNewCurrent() }} > diff --git a/package.json b/package.json index a32a38bdb3..03e89015e9 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs", From 53c6c9684e2c82d9688ed17423015082e2a40db7 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 5 Jan 2022 17:56:29 +0100 Subject: [PATCH 07/16] handle cancels & hide --- apps/remix-ide/src/app/panels/file-panel.js | 2 +- .../remixd-handle.tsx} | 143 +++++++++--------- apps/remix-ide/tsconfig.json | 1 + libs/remix-ui/app/src/index.ts | 1 + .../components/modals/dialogViewPlugin.tsx | 1 - .../src/lib/remix-app/context/provider.tsx | 4 +- .../app/src/lib/remix-app/interface/index.ts | 1 + .../app/src/lib/remix-app/reducer/modals.ts | 6 +- .../src/lib/remix-ui-modal-dialog.tsx | 14 +- 9 files changed, 91 insertions(+), 82 deletions(-) rename apps/remix-ide/src/app/{files/remixd-handle.js => plugins/remixd-handle.tsx} (56%) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 142ff4296e..47e40a2f5f 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -5,7 +5,7 @@ import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' import { FileSystemProvider } from '@remix-ui/workspace' // eslint-disable-line import Registry from '../state/registry' -const { RemixdHandle } = require('../files/remixd-handle.js') +import { RemixdHandle } from '../plugins/remixd-handle' const { GitHandle } = require('../files/git-handle.js') const { HardhatHandle } = require('../files/hardhat-handle.js') const { SlitherHandle } = require('../files/slither-handle.js') diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/plugins/remixd-handle.tsx similarity index 56% rename from apps/remix-ide/src/app/files/remixd-handle.js rename to apps/remix-ide/src/app/plugins/remixd-handle.tsx index be6997574d..3b6d27c815 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/plugins/remixd-handle.tsx @@ -1,24 +1,13 @@ +/* eslint-disable no-unused-vars */ +import React, { useRef, useState, useEffect } from 'react' // eslint-disable-line import isElectron from 'is-electron' import { WebsocketPlugin } from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' import { version as remixdVersion } from '../../../../../libs/remixd/package.json' -var yo = require('yo-yo') -var modalDialog = require('../ui/modaldialog') -var modalDialogCustom = require('../ui/modal-dialog-custom') -var copyToClipboard = require('../ui/copy-to-clipboard') +import { PluginManager } from '@remixproject/engine' +import { AppModal, AlertModal } from '@remix-ui/app' +import { CopyToClipboard } from '@remix-ui/clipboard' -var csjs = require('csjs-inject') - -var css = csjs` - .dialog { - display: flex; - flex-direction: column; - } - .dialogParagraph { - margin-bottom: 2em; - word-break: break-word; - } -` const LOCALHOST = ' - connect to localhost - ' const profile = { @@ -32,29 +21,37 @@ const profile = { version: packageJson.version } +enum State { + ok, + cancel, + new +} + export class RemixdHandle extends WebsocketPlugin { + localhostProvider: any + appManager: PluginManager + state: State constructor (localhostProvider, appManager) { super(profile) this.localhostProvider = localhostProvider this.appManager = appManager } - deactivate () { + async deactivate () { if (super.socket) super.deactivate() // this.appManager.deactivatePlugin('git') // plugin call doesn't work.. see issue https://github.com/ethereum/remix-plugin/issues/342 - if (this.appManager.actives.includes('hardhat')) this.appManager.deactivatePlugin('hardhat') - if (this.appManager.actives.includes('slither')) this.appManager.deactivatePlugin('slither') + if (this.appManager.isActive('hardhat')) this.appManager.deactivatePlugin('hardhat') + if (this.appManager.isActive('slither')) this.appManager.deactivatePlugin('slither') this.localhostProvider.close((error) => { if (error) console.log(error) }) } - activate () { - this.connectToLocalhost() + async activate () { + await this.connectToLocalhost() } async canceled () { - // await this.appManager.deactivatePlugin('git') // plugin call doesn't work.. see issue https://github.com/ethereum/remix-plugin/issues/342 await this.appManager.deactivatePlugin('remixd') } @@ -65,23 +62,25 @@ export class RemixdHandle extends WebsocketPlugin { * @param {String} txHash - hash of the transaction */ async connectToLocalhost () { - const connection = (error) => { + const connection = (error?:any) => { if (error) { console.log(error) - modalDialogCustom.alert( - 'Cannot connect to the remixd daemon. ' + - 'Please make sure you have the remixd running in the background.' - ) + const alert:AlertModal = { + id: 'connectionAlert', + message: 'Cannot connect to the remixd daemon. Please make sure you have the remixd running in the background.' + } + this.call('modal', 'alert', alert) this.canceled() } else { const intervalId = setInterval(() => { if (!this.socket || (this.socket && this.socket.readyState === 3)) { // 3 means connection closed clearInterval(intervalId) console.log(error) - modalDialogCustom.alert( - 'Connection to remixd terminated. ' + - 'Please make sure remixd is still running in the background.' - ) + const alert:AlertModal = { + id: 'connectionAlert', + message: 'Connection to remixd terminated.Please make sure remixd is still running in the background.' + } + this.call('modal', 'alert', alert) this.canceled() } }, 3000) @@ -96,34 +95,38 @@ export class RemixdHandle extends WebsocketPlugin { this.deactivate() } else if (!isElectron()) { // warn the user only if he/she is in the browser context - modalDialog( - 'Connect to localhost', - remixdDialog(), - { - label: 'Connect', - fn: () => { - try { - this.localhostProvider.preInit() - super.activate() - setTimeout(() => { - if (!this.socket || (this.socket && this.socket.readyState === 3)) { // 3 means connection closed - connection(new Error('Connection with daemon failed.')) - } else { - connection() - } - }, 3000) - } catch (error) { - connection(error) - } + this.state = State.new + const mod:AppModal = { + id: 'remixdConnect', + title: 'Connect to localhost', + message: remixdDialog(), + okFn: () => { + this.state = State.ok + try { + this.localhostProvider.preInit() + super.activate() + setTimeout(() => { + if (!this.socket || (this.socket && this.socket.readyState === 3)) { // 3 means connection closed + connection(new Error('Connection with daemon failed.')) + } else { + connection() + } + }, 3000) + } catch (error) { + connection(error) } }, - { - label: 'Cancel', - fn: () => { - this.canceled() - } + cancelFn: async () => { + this.state = State.cancel + await this.canceled() + }, + okLabel: 'Connect', + cancelLabel: 'Cancel', + hideFn: async () => { + if (this.state === State.new) await this.canceled() } - ) + } + await this.call('modal', 'modal', mod) } else { try { super.activate() @@ -137,31 +140,31 @@ export class RemixdHandle extends WebsocketPlugin { function remixdDialog () { const commandText = 'remixd -s -u ' - return yo` -
-
- Access your local file system from Remix IDE using Remixd NPM package.

+ return (<> +
+
+ Access your local file system from Remix IDE using Remixd NPM package.

Remixd needs to be running in the background to load the files in localhost workspace. For more info, please check the Remixd tutorial.
-
+
If you are just looking for the remixd command, here it is: -

${commandText} - ${copyToClipboard(() => commandText)} +



${commandText} +
-
+
When connected, a session will be started between ${window.location.origin} and your local file system at ws://127.0.0.1:65520. - The shared folder will be in the "File Explorers" workspace named "localhost". + The shared folder will be in the "File Explorers" workspace named "localhost".
Read more about other Remixd ports usage
-
+
This feature is still in Alpha. We recommend to keep a backup of the shared folder.
-
-
+
+
Before using, make sure remixd version is latest i.e. ${remixdVersion} -
Read here how to update it +

Read here how to update it
- ` + ) } diff --git a/apps/remix-ide/tsconfig.json b/apps/remix-ide/tsconfig.json index b3e2e7d0ca..052537730e 100644 --- a/apps/remix-ide/tsconfig.json +++ b/apps/remix-ide/tsconfig.json @@ -7,6 +7,7 @@ "allowSyntheticDefaultImports": true, "types": ["node", "jest"], "module": "es6", + "resolveJsonModule": true }, "files": [ "../../node_modules/@nrwl/react/typings/cssmodule.d.ts", diff --git a/libs/remix-ui/app/src/index.ts b/libs/remix-ui/app/src/index.ts index 00999a2115..e00682a41b 100644 --- a/libs/remix-ui/app/src/index.ts +++ b/libs/remix-ui/app/src/index.ts @@ -2,3 +2,4 @@ export { default as RemixApp } from './lib/remix-app/remix-app' export { dispatchModalContext } from './lib/remix-app/context/context' export { ModalProvider } from './lib/remix-app/context/provider' export { AppModal } from './lib/remix-app/interface/index' +export { AlertModal } from './lib/remix-app/interface/index' diff --git a/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx b/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx index 248527075e..d5610de56c 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx @@ -7,7 +7,6 @@ const DialogViewPlugin = () => { const app = useContext(AppContext) useEffect(() => { - console.log(modal, app) app.modal.setDispatcher({ modal, alert, toast }) }, []) return <> diff --git a/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx b/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx index cc25c381fd..73a3a97305 100644 --- a/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx @@ -10,10 +10,10 @@ export const ModalProvider = ({ children = [], reducer = modalReducer, initialSt const [{ modals, toasters, focusModal, focusToaster }, dispatch] = useReducer(reducer, initialState) const modal = (data: AppModal) => { - const { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType, defaultValue } = data + const { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType, defaultValue, hideFn } = data dispatch({ type: modalActionTypes.setModal, - payload: { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue } + payload: { id, title, message, okLabel, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue, hideFn } }) } diff --git a/libs/remix-ui/app/src/lib/remix-app/interface/index.ts b/libs/remix-ui/app/src/lib/remix-app/interface/index.ts index feb7c5761f..dcfcd7a1eb 100644 --- a/libs/remix-ui/app/src/lib/remix-app/interface/index.ts +++ b/libs/remix-ui/app/src/lib/remix-app/interface/index.ts @@ -12,6 +12,7 @@ export interface AppModal { cancelFn: () => void, modalType?: ModalTypes, defaultValue?: string + hideFn?: () => void } export interface AlertModal { diff --git a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts index 951b547f16..cf202585f4 100644 --- a/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts +++ b/libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts @@ -18,7 +18,8 @@ export const modalReducer = (state: ModalState = ModalInitialState, action: Moda cancelLabel: modalList[0].cancelLabel, cancelFn: modalList[0].cancelFn, modalType: modalList[0].modalType, - defaultValue: modalList[0].defaultValue + defaultValue: modalList[0].defaultValue, + hideFn: modalList[0].hideFn } modalList = modalList.slice() @@ -28,6 +29,9 @@ export const modalReducer = (state: ModalState = ModalInitialState, action: Moda return { ...state, modals: modalList } } case modalActionTypes.handleHideModal: + if (state.focusModal.hideFn) { + state.focusModal.hideFn() + } state.focusModal = { ...state.focusModal, hide: true, message: null } return { ...state } diff --git a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx index bd3a07cf00..524caaad62 100644 --- a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx +++ b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx @@ -12,12 +12,15 @@ export const ModalDialog = (props: ModalDialogProps) => { const [state, setState] = useState({ toggleBtn: true }) + const calledHideFunctionOnce = useRef() const modal = useRef(null) const handleHide = () => { - props.handleHide() + if (!calledHideFunctionOnce.current) { props.handleHide() } + calledHideFunctionOnce.current = true } useEffect(() => { + calledHideFunctionOnce.current = props.hide modal.current.focus() }, [props.hide]) @@ -32,12 +35,9 @@ export const ModalDialog = (props: ModalDialogProps) => { } if (modal.current) { modal.current.addEventListener('blur', handleBlur) - - return () => { - if (modal.current) { - modal.current.removeEventListener('blur', handleBlur) - } - } + } + return () => { + modal.current.removeEventListener('blur', handleBlur) } }, [modal.current]) From cd4322cb0244dc601e8722667eb505ade5965138 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 5 Jan 2022 18:09:16 +0100 Subject: [PATCH 08/16] fix test --- apps/remix-ide-e2e/src/tests/remixd.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/remixd.test.ts b/apps/remix-ide-e2e/src/tests/remixd.test.ts index 38f66665c0..0781733b99 100644 --- a/apps/remix-ide-e2e/src/tests/remixd.test.ts +++ b/apps/remix-ide-e2e/src/tests/remixd.test.ts @@ -125,9 +125,9 @@ function startRemixd (browser: NightwatchBrowser) { .clickLaunchIcon('filePanel') .clickLaunchIcon('pluginManager') .scrollAndClick('#pluginManager *[data-id="pluginManagerComponentActivateButtonremixd"]') - .waitForElementVisible('#modal-footer-ok', 2000) + .waitForElementVisible('*[data-id="remixdConnect-modal-footer-ok-react"]', 2000) .pause(2000) - .click('#modal-footer-ok') + .click('*[data-id="remixdConnect-modal-footer-ok-react"]') // .click('*[data-id="workspacesModalDialog-modal-footer-ok-react"]') } From 9c64e04eeb234de69a99fe9c334bfa9f5a5725df Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 4 Jan 2022 13:59:53 +0530 Subject: [PATCH 09/16] do not merge files for localhost workspace --- libs/remix-ui/workspace/src/lib/reducers/workspace.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index e046892df9..1f1d60ae0e 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -674,8 +674,6 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s } else { if (payload.path === state.mode || payload.path === '/') { let files = normalize(payload.fileTree, payload.path, payload.type) - - files = _.merge(files, state[state.mode].files[state.mode]) if (deletePath) delete files[deletePath] return { [state.mode]: files } } else { From 935106b0fa63d2b6dcd062414c945f5328587eaf Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 4 Jan 2022 14:10:21 +0530 Subject: [PATCH 10/16] linting fix --- libs/remix-ui/workspace/src/lib/reducers/workspace.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index 1f1d60ae0e..46b8b47f53 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -673,7 +673,7 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s } } else { if (payload.path === state.mode || payload.path === '/') { - let files = normalize(payload.fileTree, payload.path, payload.type) + const files = normalize(payload.fileTree, payload.path, payload.type) if (deletePath) delete files[deletePath] return { [state.mode]: files } } else { From ae53207148d636475abef21853a3d35f5b934423 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 5 Jan 2022 20:45:18 +0530 Subject: [PATCH 11/16] fix remixd initial load --- libs/remix-ui/workspace/src/lib/reducers/workspace.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index 46b8b47f53..613c1db3b7 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -672,8 +672,12 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s return files } } else { - if (payload.path === state.mode || payload.path === '/') { - const files = normalize(payload.fileTree, payload.path, payload.type) + if (payload.path === '/') { + let files = normalize(payload.fileTree, payload.path, payload.type) + return { [state.mode]: files } + } else if (payload.path === state.mode) { + let files = normalize(payload.fileTree, payload.path, payload.type) + files = _.merge(files, state[state.mode].files[state.mode]) if (deletePath) delete files[deletePath] return { [state.mode]: files } } else { From bd080f4169f11d716b9f12c97e1523b13d295907 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 5 Jan 2022 20:57:51 +0530 Subject: [PATCH 12/16] linting fix --- libs/remix-ui/workspace/src/lib/reducers/workspace.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index 613c1db3b7..ef769f5c5b 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -673,7 +673,7 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s } } else { if (payload.path === '/') { - let files = normalize(payload.fileTree, payload.path, payload.type) + const files = normalize(payload.fileTree, payload.path, payload.type) return { [state.mode]: files } } else if (payload.path === state.mode) { let files = normalize(payload.fileTree, payload.path, payload.type) From ad68b9c2dff64db30e80ca4ef237ace6de61e647 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 6 Jan 2022 13:37:50 +0530 Subject: [PATCH 13/16] resolve remix-tests libs with Localhost workspace --- libs/remix-core-plugin/src/lib/compiler-content-imports.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts index 8c243e37a8..7eab9205ce 100644 --- a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts +++ b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts @@ -146,6 +146,8 @@ export class CompilerImports extends Plugin { const splitted = /([^/]+)\/(.*)$/g.exec(url) const possiblePaths = ['localhost/installed_contracts/' + url] + // pick remix-tests library contracts from '.deps' + if (url.startsWith('remix_')) possiblePaths.push('localhost/.deps/remix-tests/' + url) if (splitted) possiblePaths.push('localhost/installed_contracts/' + splitted[1] + '/contracts/' + splitted[2]) possiblePaths.push('localhost/node_modules/' + url) if (splitted) possiblePaths.push('localhost/node_modules/' + splitted[1] + '/contracts/' + splitted[2]) From fb35fd47eac9e1d233b6f6cc8b038a267259b99a Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Thu, 6 Jan 2022 10:15:44 +0100 Subject: [PATCH 14/16] flaky test --- apps/remix-ide-e2e/src/tests/importFromGithub.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts b/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts index 036d9ceae9..6bdd0b4b0c 100644 --- a/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts +++ b/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts @@ -48,8 +48,8 @@ module.exports = { 'Import From Github For Valid URL': function (browser: NightwatchBrowser) { browser .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) - .clickLaunchIcon('settings') - .clickLaunchIcon('filePanel') + .clickLaunchIcon('settings').pause(1000) + .clickLaunchIcon('filePanel').pause(1000) .scrollAndClick('*[data-id="landingPageImportFromGitHubButton"]') .waitForElementVisible('*[data-id="homeTabModalDialogCustomPromptText"]') .clearValue('*[data-id="homeTabModalDialogCustomPromptText"]') From 09ab718607622c3e408c516c21c31669370abed9 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Thu, 6 Jan 2022 10:24:57 +0100 Subject: [PATCH 15/16] flaky fix --- apps/remix-ide-e2e/src/tests/importFromGithub.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts b/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts index 6bdd0b4b0c..bbf57ca3db 100644 --- a/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts +++ b/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts @@ -31,8 +31,6 @@ module.exports = { 'Display Error Message For Invalid GitHub URL Modal': function (browser: NightwatchBrowser) { browser .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) - .clickLaunchIcon('settings') - .clickLaunchIcon('filePanel') .scrollAndClick('*[data-id="landingPageImportFromGitHubButton"]') .waitForElementVisible('input[data-id="homeTabModalDialogCustomPromptText"]') .execute(() => { @@ -48,8 +46,6 @@ module.exports = { 'Import From Github For Valid URL': function (browser: NightwatchBrowser) { browser .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) - .clickLaunchIcon('settings').pause(1000) - .clickLaunchIcon('filePanel').pause(1000) .scrollAndClick('*[data-id="landingPageImportFromGitHubButton"]') .waitForElementVisible('*[data-id="homeTabModalDialogCustomPromptText"]') .clearValue('*[data-id="homeTabModalDialogCustomPromptText"]') From af88443a3faac1582314568b1d0556cce7db5a44 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Thu, 6 Jan 2022 11:23:37 +0100 Subject: [PATCH 16/16] fix alerts --- .../files/{fileManager.js => fileManager.ts} | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) rename apps/remix-ide/src/app/files/{fileManager.js => fileManager.ts} (94%) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.ts similarity index 94% rename from apps/remix-ide/src/app/files/fileManager.js rename to apps/remix-ide/src/app/files/fileManager.ts index c526f36600..3fa571df83 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -5,9 +5,9 @@ import async from 'async' import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' -const EventEmitter = require('events') +import { EventEmitter } from 'events' +import { RemixAppManager } from '../../../../../libs/remix-ui/plugin-manager/src/types' const toaster = require('../ui/tooltip') -const modalDialogCustom = require('../ui/modal-dialog-custom') const helper = require('../../lib/helper.js') /* @@ -37,6 +37,18 @@ const createError = (err) => { } class FileManager extends Plugin { + mode: string + openedFiles: any + events: EventEmitter + editor: any + _components: any + appManager: RemixAppManager + _deps: any + getCurrentFile: () => any + getFile: (path: any) => Promise + getFolder: (path: any) => Promise + setFile: (path: any, data: any) => Promise + switchFile: (path: any) => Promise constructor (editor, appManager) { super(profile) this.mode = 'browser' @@ -70,7 +82,7 @@ class FileManager extends Plugin { * @param {string} path path of the file/directory * @param {string} message message to display if path doesn't exist. */ - async _handleExists (path, message) { + async _handleExists (path: string, message?:string) { const exists = await this.exists(path) if (!exists) { @@ -96,7 +108,7 @@ class FileManager extends Plugin { * @param {string} path path of the file/directory * @param {string} message message to display if path is not a directory. */ - async _handleIsDir (path, message) { + async _handleIsDir (path: string, message?: string) { const isDir = await this.isDirectory(path) if (!isDir) { @@ -305,13 +317,19 @@ class FileManager extends Plugin { if (isFile) { if (newPathExists) { - modalDialogCustom.alert('File already exists.') + this.call('modal', 'alert', { + id: 'fileManagerAlert', + message: 'File already exists' + }) return } return provider.rename(oldPath, newPath, false) } else { if (newPathExists) { - modalDialogCustom.alert('Folder already exists.') + this.call('modal', 'alert', { + id: 'fileManagerAlert', + message: 'Directory already exists' + }) return } return provider.rename(oldPath, newPath, true) @@ -612,7 +630,7 @@ class FileManager extends Plugin { this.events.emit('noFileSelected') } - async openFile (file) { + async openFile (file?: string) { if (!file) { this.emit('noFileSelected') this.events.emit('noFileSelected') @@ -639,7 +657,7 @@ class FileManager extends Plugin { // TODO: Only keep `this.emit` (issue#2210) this.emit('currentFileChanged', file) this.events.emit('currentFileChanged', file) - resolve() + resolve(true) } }) }) @@ -698,7 +716,7 @@ class FileManager extends Plugin { dirPaths.push(item) resolve(dirPaths) } - return new Promise((resolve, reject) => { resolve() }) + return new Promise((resolve, reject) => { resolve(true) }) }) Promise.all(promises).then(() => { resolve(dirPaths) }) }) @@ -760,9 +778,15 @@ class FileManager extends Plugin { helper.createNonClashingName(file, self._deps.filesProviders[fileProvider], (error, name) => { if (error) { - modalDialogCustom.alert('Unexpected error loading the file ' + error) + this.call('modal', 'alert', { + id: 'fileManagerAlert', + message: 'Unexpected error loading file ' + file + ': ' + error + }) } else if (helper.checkSpecialChars(name)) { - modalDialogCustom.alert('Special characters are not allowed') + this.call('modal', 'alert', { + id: 'fileManagerAlert', + message: 'Special characters are not allowed in file names.' + }) } else { try { self._deps.filesProviders[fileProvider].set(name, filesSet[file].content)