Merge branch 'master' into clear_storage

pull/2191/head
bunsenstraat 3 years ago committed by GitHub
commit 9f08918fe7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      apps/remix-ide-e2e/nightwatch.ts
  2. 2
      apps/remix-ide-e2e/src/checkGroupTests.js
  3. 23
      apps/remix-ide-e2e/src/commands/openFile.ts
  4. 2
      apps/remix-ide-e2e/src/select_tests.sh
  5. 195
      apps/remix-ide-e2e/src/tests/stress.editor.ts
  6. 342
      apps/remix-ide-e2e/src/tests/stressEditor.test.ts
  7. 8
      apps/remix-ide-e2e/src/tests/url.test.ts
  8. 2
      apps/remix-ide/ci/browser_test.sh
  9. 2
      apps/remix-ide/ci/browser_tests_plugin_api.sh
  10. 8
      apps/remix-ide/src/app/files/fileManager.ts
  11. 9
      apps/remix-ide/src/app/files/fileProvider.js
  12. 8
      apps/remix-ide/src/app/files/workspaceFileProvider.js
  13. 9
      apps/remix-ide/src/app/panels/tab-proxy.js
  14. 2
      libs/remix-ui/vertical-icons-panel/src/lib/components/Icon.tsx
  15. 21
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  16. 2
      package.json

@ -20,15 +20,7 @@ module.exports = {
on_failure: true,
on_error: true
},
desiredCapabilities: {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true,
'moz:firefoxOptions': {
args: ['-headless']
}
},
exclude: ['dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js', 'dist/apps/remix-ide-e2e/src/tests/pluginManager.spec.ts']
exclude: ['dist/apps/remix-ide-e2e/src/tests/runAndDeploy.test.js', 'dist/apps/remix-ide-e2e/src/tests/pluginManager.test.ts']
},
chrome: {

@ -6,7 +6,7 @@ fs.readdirSync(testFolder).forEach(file => {
const content = fs.readFileSync(testFolder + file, 'utf8')
const matches = content.match(/group\d+/g)
if (matches) {
const disabled = content.includes('@disabled')
const disabled = content.includes('\'@disabled\': true') || content.includes('\'@disabled\':true')
if (!disabled) {
console.log(`WARNING ${file} has group tests but is not disabled`)
}

@ -15,13 +15,24 @@ class OpenFile extends EventEmitter {
// click on fileExplorer can toggle it. We go through settings to be sure FE is open
function openFile (browser: NightwatchBrowser, name: string, done: VoidFunction) {
browser.clickLaunchIcon('settings').clickLaunchIcon('filePanel')
.waitForElementVisible('li[data-id="treeViewLitreeViewItem' + name + '"', 60000)
.click('li[data-id="treeViewLitreeViewItem' + name + '"')
.pause(2000)
.perform(() => {
done()
browser.perform((done) => {
browser.isVisible('[data-id="remixIdeSidePanel"]', (result) => {
if (result.value) {
// if side panel is shown, check this is the file panel
browser.element('css selector', '[data-id="verticalIconsKindfilePanel"] img[data-id="selected"]', (result) => {
if (result.status === 0) {
done()
} else browser.clickLaunchIcon('filePanel').perform(done)
})
} else browser.clickLaunchIcon('filePanel').perform(done)
})
})
.waitForElementVisible('li[data-id="treeViewLitreeViewItem' + name + '"', 60000)
.click('li[data-id="treeViewLitreeViewItem' + name + '"')
.pause(2000)
.perform(() => {
done()
})
}
module.exports = OpenFile

@ -26,7 +26,7 @@ do
done
npm run build:e2e
PS3='Select a test or command: '
TESTFILES=( $(grep -IRiL "disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) )
TESTFILES=( $(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) )
# declare -p TESTFILES
TESTFILES+=("list")

@ -1,195 +0,0 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'Should create 10 files, reload, and check if the files are saved': function (browser: NightwatchBrowser) {
const contents = {}
const checkContent = function (i, done) {
const name = 'test_' + i + '.sol'
browser
.openFile(name)
.pause(500)
.getEditorValue((content) => {
browser.assert.ok(content === contents[i])
done()
})
}
browser.clickLaunchIcon('filePanel').perform((done) => {
let contentEditSet = content.slice()
for (let i = 0; i < 10; i++) {
contentEditSet += contentEditSet
contents[i] = contentEditSet
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(contentEditSet)
}
done()
}).pause(10000).refresh()
.perform(done => checkContent(0, done))
.perform(done => checkContent(1, done))
.perform(done => checkContent(2, done))
.perform(done => checkContent(3, done))
.perform(done => checkContent(4, done))
.perform(done => checkContent(5, done))
.perform(done => checkContent(6, done))
.perform(done => checkContent(7, done))
.perform(done => checkContent(8, done))
.perform(done => checkContent(9, done))
.end()
}
}
const content = `
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/**
* @title Ballot
* @dev Implements voting process along with vote delegation|
*/
contract Ballot {
struct Voter {
uint weight; // weight is accumulated by delegation
bool voted; // if true, that person already voted
address delegate; // person delegated to
uint vote; // index of the voted proposal
}
struct Proposal {
// If you can limit the length to a certain number of bytes,
// always use one of bytes1 to bytes32 because they are much cheaper
bytes32 name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
}
address public chairperson;
mapping(address => Voter) public voters;
Proposal[] public proposals;
function () test {
/**
* @dev Create a new ballot to choose one of 'proposalNames'.
* @param proposalNames names of proposals
*/
constructor(bytes32[] memory proposalNames) {
chairperson = msg.sender;
voters[chairperson].weight = 1;
for (uint i = 0; i < proposalNames.length; i++) {
// 'Proposal({...})' creates a temporary
// Proposal object and 'proposals.push(...)'
// appends it to the end of 'proposals'.
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
/**
* @dev Give 'voter' the right to vote on this ballot. May only be called by 'chairperson'.
* @param voter address of voter
*/
function giveRightToVote(address voter) public {
require(
msg.sender == chairperson,
"Only chairperson can give right to vote."
);
require(
!voters[voter].voted,
"The voter already voted."
);
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}
/**
* @dev Delegate your vote to the voter 'to'.
* @param to address to which vote is delegated
*/
function delegate(address to) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted, "You already voted.");
require(to != msg.sender, "Self-delegation is disallowed.");
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;
// We found a loop in the delegation, not allowed.
require(to != msg.sender, "Found loop in delegation.");
}
sender.voted = true;
sender.delegate = to;
Voter storage delegate_ = voters[to];
if (delegate_.voted) {
// If the delegate already voted,
// directly add to the number of votes
proposals[delegate_.vote].voteCount += sender.weight;
} else {
// If the delegate did not vote yet,
// add to her weight.
delegate_.weight += sender.weight;
}
}
/**
* @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'.
* @param proposal index of proposal in the proposals array
*/
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "Has no right to vote");
require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;
// If 'proposal' is out of the range of the array,
// this will throw automatically and revert all
// changes.
proposals[proposal].voteCount += sender.weight;
}
/**
* @dev Computes the winning proposal taking all previous votes into account.
* @return winningProposal_ index of winning proposal in the proposals array
*/
function winningProposal() public view
returns (uint winningProposal_)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
}
/**
* @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then
* @return winnerName_ the name of the winner
*/
function winnerName() public view
returns (bytes32 winnerName_)
{
winnerName_ = proposals[winningProposal()].name;
}
}
`

@ -0,0 +1,342 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
},
'Should create 10 files, reload, and check if the files are saved': function (browser: NightwatchBrowser) {
const contents = {}
const checkContent = (i, done) => {
const name = 'test_' + i + '.sol'
browser
.openFile(name)
.getEditorValue((content) => {
browser.assert.ok(content === contents[i])
browser.assert.ok(content === contents[i])
done()
})
}
const fillContent = (content, mul) => {
let localContent = content
mul = 3 * mul
for (let k = 0 ; k < mul; k++) {
localContent += content
}
return localContent
}
browser.clickLaunchIcon('filePanel')
.perform((done) => {
const i = 0
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 1
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 2
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 3
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 4
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 5
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 6
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 7
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 8
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
}).perform((done) => {
const i = 9
const localContent = fillContent(content, i)
contents[i] = localContent
const name = 'test_' + i + '.sol'
browser.click('[data-id="fileExplorerNewFilecreateNewFile"]')
.waitForElementContainsText('*[data-id$="/blank"]', '', 60000)
.sendKeys('*[data-id$="/blank"] .remixui_items', name)
.sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER)
.getText('.remix_ui_terminal_block', (result) => {
console.log(result)
})
.waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000)
.setEditorValue(localContent)
done()
})
.pause(10000)
.refresh()
.perform(done => checkContent(0, done))
.perform(done => checkContent(1, done))
.perform(done => checkContent(2, done))
.perform(done => checkContent(3, done))
.perform(done => checkContent(4, done))
.perform(done => checkContent(5, done))
.perform(done => checkContent(6, done))
.perform(done => checkContent(7, done))
.perform(done => checkContent(8, done))
.perform(done => checkContent(9, done))
.end()
}
}
const content = `
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/**
* @title Ballot
* @dev Implements voting process along with vote delegation|
*/
contract Ballot {
struct Voter {
uint weight; // weight is accumulated by delegation
bool voted; // if true, that person already voted
address delegate; // person delegated to
uint vote; // index of the voted proposal
}
struct Proposal {
// If you can limit the length to a certain number of bytes,
// always use one of bytes1 to bytes32 because they are much cheaper
bytes32 name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
}
address public chairperson;
mapping(address => Voter) public voters;
Proposal[] public proposals;
function () test {
/**
* @dev Create a new ballot to choose one of 'proposalNames'.
* @param proposalNames names of proposals
*/
constructor(bytes32[] memory proposalNames) {
chairperson = msg.sender;
voters[chairperson].weight = 1;
for (uint i = 0; i < proposalNames.length; i++) {
// 'Proposal({...})' creates a temporary
// Proposal object and 'proposals.push(...)'
// appends it to the end of 'proposals'.
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
/**
* @dev Give 'voter' the right to vote on this ballot. May only be called by 'chairperson'.
* @param voter address of voter
*/
function giveRightToVote(address voter) public {
require(
msg.sender == chairperson,
"Only chairperson can give right to vote."
);
require(
!voters[voter].voted,
"The voter already voted."
);
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}
/**
* @dev Delegate your vote to the voter 'to'.
* @param to address to which vote is delegated
*/
function delegate(address to) public {
Voter storage sender = voters[msg.sender];
require(!sender.voted, "You already voted.");
require(to != msg.sender, "Self-delegation is disallowed.");
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;
// We found a loop in the delegation, not allowed.
require(to != msg.sender, "Found loop in delegation.");
}
sender.voted = true;
sender.delegate = to;
Voter storage delegate_ = voters[to];
if (delegate_.voted) {
// If the delegate already voted,
// directly add to the number of votes
proposals[delegate_.vote].voteCount += sender.weight;
} else {
// If the delegate did not vote yet,
// add to her weight.
delegate_.weight += sender.weight;
}
}
/**
* @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'.
* @param proposal index of proposal in the proposals array
*/
function vote(uint proposal) public {
Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "Has no right to vote");
require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;
// If 'proposal' is out of the range of the array,
// this will throw automatically and revert all
// changes.
proposals[proposal].voteCount += sender.weight;
}
/**
* @dev Computes the winning proposal taking all previous votes into account.
* @return winningProposal_ index of winning proposal in the proposals array
*/
function winningProposal() public view
returns (uint winningProposal_)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
}
/**
* @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then
* @return winnerName_ the name of the winner
*/
function winnerName() public view
returns (bytes32 winnerName_)
{
winnerName_ = proposals[winningProposal()].name;
}
}
`

@ -31,7 +31,7 @@ module.exports = {
.assert.containsText('*[data-id="compilerContainerCompileBtn"]', 'contract-76747f6e19.sol')
.currentWorkspaceIs('code-sample')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(
browser.assert.ok(content && content.indexOf(
'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol') !== -1,
'code has not been loaded')
})
@ -45,7 +45,7 @@ module.exports = {
.pause(5000)
.currentWorkspaceIs('code-sample')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(
browser.assert.ok(content && content.indexOf(
'proposals.length = _numProposals;') !== -1,
'url has not been loaded')
})
@ -59,7 +59,7 @@ module.exports = {
.pause(5000)
.currentWorkspaceIs('code-sample')
.getEditorValue((content) => {
browser.assert.ok(content.indexOf(
browser.assert.ok(content && content.indexOf(
'proposals.length = _numProposals;') !== -1,
'code has not been loaded')
})
@ -108,7 +108,7 @@ module.exports = {
'Should load json files from link passed in remix URL': function (browser: NightwatchBrowser) {
browser
.url('http://localhost:8080/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.6.12+commit.27d51765.js&url=https://raw.githubusercontent.com/EthVM/evm-source-verification/main/contracts/1/0x011e5846975c6463a8c6337eecf3cbf64e328884/input.json')
.url('http://127.0.0.1:8080/#optimize=false&runs=200&evmVersion=null&version=soljson-v0.6.12+commit.27d51765.js&url=https://raw.githubusercontent.com/EthVM/evm-source-verification/main/contracts/1/0x011e5846975c6463a8c6337eecf3cbf64e328884/input.json')
.refresh()
.pause(5000)
.waitForElementPresent('*[data-id="workspacesSelect"] option[value="code-sample"]')

@ -15,7 +15,7 @@ sleep 5
npm run build:e2e
TESTFILES=$(grep -IRiL "disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split )
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=$1 || TEST_EXITCODE=1
done

@ -14,7 +14,7 @@ sleep 5
npm run build:e2e
TESTFILES=$(grep -IRiL "disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split )
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=chrome || TEST_EXITCODE=1
done

@ -272,7 +272,13 @@ class FileManager extends Plugin {
await this._handleIsDir(src, `Cannot copy from ${src}. Path is not a directory.`)
await this._handleExists(dest, `Cannot paste content into ${dest}. Path does not exist.`)
await this._handleIsDir(dest, `Cannot paste content into ${dest}. Path is not directory.`)
await this.inDepthCopy(src, dest)
const provider = this.fileProviderOf(src)
if (provider.isSubDirectory(src, dest)) {
this.call('notification', 'toast', 'File(s) to paste is an ancestor of the destination folder')
} else {
await this.inDepthCopy(src, dest)
}
} catch (e) {
throw new Error(e)
}

@ -3,6 +3,7 @@
import { CompilerImports } from '@remix-project/core-plugin'
const EventManager = require('events')
const remixLib = require('@remix-project/remix-lib')
const pathModule = require('path')
const Storage = remixLib.Storage
class FileProvider {
@ -308,6 +309,14 @@ class FileProvider {
_normalizePath (path) {
return this.type + path
}
isSubDirectory (parent, child) {
if (!parent) return false
if (parent === child) return true
const relative = pathModule.relative(parent, child)
return !!relative && relative.split(pathModule.sep)[0] !== '..'
}
}
module.exports = FileProvider

@ -49,14 +49,6 @@ class WorkspaceFileProvider extends FileProvider {
return ret
}
isSubDirectory (parent, child) {
if (!parent) return false
if (parent === child) return true
const relative = pathModule.relative(parent, child)
return !!relative && relative.split(pathModule.sep)[0] !== '..'
}
resolveDirectory (path, callback) {
super.resolveDirectory(path, (error, files) => {
if (error) return callback(error)

@ -190,15 +190,6 @@ export class TabProxy extends Plugin {
}
renameTab (oldName, newName) {
this.addTab(newName, '', async () => {
await this.fileManager.open(newName)
this.event.emit('openFile', newName)
},
async () => {
await this.fileManager.closeFile(newName)
this.event.emit('closeFile', newName)
this.emit('closeFile', newName)
})
this.removeTab(oldName)
}

@ -100,7 +100,7 @@ const Icon = ({
id={`verticalIconsKind${name}`}
ref={iconRef}
>
<img className={`${theme === 'dark' ? 'invert' : ''} ${theme} remixui_image ${iconRecord.active ? `selected-${theme}`:''}`} src={icon} alt={name} />
<img data-id={iconRecord.active ? `selected`: ''} className={`${theme === 'dark' ? 'invert' : ''} ${theme} remixui_image ${iconRecord.active ? `selected-${theme}`:''}`} src={icon} alt={name} />
<Badge
badgeStatus={badgeStatus}
/>

@ -85,30 +85,35 @@ export const loadWorkspacePreset = async (template: 'gist-template' | 'code-temp
case 'code-template':
// creates a new workspace code-sample and loads code from url params.
try {
let path = ''; let content = ''
let path = ''; let content
if (params.code) {
const hash = bufferToHex(keccakFromString(params.code))
path = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol'
content = atob(params.code)
workspaceProvider.set(path, content)
await workspaceProvider.set(path, content)
}
if (params.url) {
const data = await plugin.call('contentImport', 'resolve', params.url)
path = data.cleanUrl
content = data.content
if (content && typeof content === 'object') {
const standardInput = content as JSONStandardInput
if (standardInput.language && standardInput.language === "Solidity" && standardInput.sources) {
try {
content = JSON.parse(content) as any
if (content.language && content.language === "Solidity" && content.sources) {
const standardInput: JSONStandardInput = content as JSONStandardInput
for (const [fname, source] of Object.entries(standardInput.sources)) {
await workspaceProvider.set(fname, source.content)
}
return Object.keys(standardInput.sources)[0]
} else {
await workspaceProvider.set(path, JSON.stringify(content))
}
return Object.keys(standardInput.sources)[0]
} else {
workspaceProvider.set(path, content)
} catch (e) {
console.log(e)
await workspaceProvider.set(path, content)
}
}
return path

@ -96,7 +96,7 @@
"nightwatch_local_verticalIconscontextmenu": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome",
"nightwatch_local_pluginApi": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/plugin_api_*.js --env=chrome",
"nightwatch_local_migrate_filesystem": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/migrateFileSystem.test.js --env=chrome",
"nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stress.editor.js --env=chromeDesktop",
"nightwatch_local_stress_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/stressEditor.test.js --env=chromeDesktop",
"nightwatch_local_search": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/search.test.js --env=chromeDesktop",
"onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint",
"remixd": "nx build remixd && chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js -s ./apps/remix-ide/contracts --remix-ide http://127.0.0.1:8080",

Loading…
Cancel
Save