diff --git a/remix-tests/src/compiler.ts b/remix-tests/src/compiler.ts index ae48a8c097..3d9b297479 100644 --- a/remix-tests/src/compiler.ts +++ b/remix-tests/src/compiler.ts @@ -21,6 +21,32 @@ function writeTestAccountsContract (accounts: string[]) { return testAccountContract.replace('>accounts<', body) } +function processFile(filePath: string, sources: any, isRoot: boolean = false) { + try{ + const importRegEx = /import ['"](.+?)['"];/g; + let group: any =''; + if(filePath.includes('tests.sol') || filePath.includes('remix_tests.sol') || filePath.includes('remix_accounts.sol') || Object.keys(sources).includes(filePath)) + return + + let content = fs.readFileSync(filePath, { encoding: 'utf-8' }); + const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm + if (isRoot && filePath.indexOf('_test.sol') > 0 && regexIndexOf(content, s) < 0) { + const includeTestLibs = '\nimport \'remix_tests.sol\';\n' + content = includeTestLibs.concat(content) + } + sources[filePath] = {content}; + importRegEx.exec(''); // Resetting state of RegEx + while (group = importRegEx.exec(content)) { + const importedFile = group[1]; + const importedFilePath = path.join(path.dirname(filePath), importedFile); + processFile(importedFilePath, sources) + } + } + catch(error){ + throw error; + } + }; + const userAgent = (typeof (navigator) !== 'undefined') && navigator.userAgent ? navigator.userAgent.toLowerCase() : '-' const isBrowser = !(typeof (window) === 'undefined' || userAgent.indexOf(' electron/') > -1) @@ -34,26 +60,23 @@ export function compileFileOrFiles(filename: string, isDirectory: boolean, opts: 'remix_accounts.sol': { content: writeTestAccountsContract(accounts) } } const filepath = (isDirectory ? filename : path.dirname(filename)) - // TODO: for now assumes filepath dir contains all tests, later all this - // should be replaced with remix's & browser solidity compiler code - - // This logic is wrong - // We should only look into current file if a full file name with path is given - // We should only walk through directory if a directory name is passed try { - // walkSync only if it is a directory - fs.walkSync(filepath, (foundpath: string) => { - // only process .sol files - if (foundpath.split('.').pop() === 'sol') { - let c = fs.readFileSync(foundpath).toString() - const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm - let includeTestLibs = '\nimport \'remix_tests.sol\';\n' - if (foundpath.indexOf('_test.sol') > 0 && regexIndexOf(c, s) < 0) { - c = includeTestLibs.concat(c) - } - sources[foundpath] = { content: c } + if(!isDirectory && fs.existsSync(filename)) { + if (filename.split('.').pop() === 'sol') { + processFile(filename, sources, true) + } else { + throw new Error('Not a solidity file') } - }) + } else { + // walkSync only if it is a directory + fs.walkSync(filepath, (foundpath: string) => { + // only process .sol files + if (foundpath.split('.').pop() === 'sol') { + processFile(foundpath, sources, true) + } + }) + } + } catch (e) { throw e } finally { diff --git a/remix-tests/tests/examples_5/contract/simple_storage.sol b/remix-tests/tests/examples_5/contract/simple_storage.sol new file mode 100644 index 0000000000..745fe39605 --- /dev/null +++ b/remix-tests/tests/examples_5/contract/simple_storage.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.5.0; + +import "../../examples_4/SafeMath.sol"; +import "../lib/EvenOdd.sol"; + +contract SimpleStorage is EvenOdd{ + using SafeMath for uint256; + uint public storedData; + + constructor() public { + storedData = 100; + } + + function set(uint x) public { + storedData = x; + } + + function get() public view returns (uint retVal) { + return storedData; + } + +} diff --git a/remix-tests/tests/examples_5/lib/EvenOdd.sol b/remix-tests/tests/examples_5/lib/EvenOdd.sol new file mode 100644 index 0000000000..f5847ee481 --- /dev/null +++ b/remix-tests/tests/examples_5/lib/EvenOdd.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.5.0; + +contract EvenOdd { + + /** + * @dev Tells whether a number is even or odd + * @param num Number to check + */ + + function check(int num) public pure returns (string memory){ + if(num % 2 == 0) + return "EVEN"; + return "ODD"; + } +} \ No newline at end of file diff --git a/remix-tests/tests/examples_5/test/simple_storage_test.sol b/remix-tests/tests/examples_5/test/simple_storage_test.sol new file mode 100644 index 0000000000..00be3f627e --- /dev/null +++ b/remix-tests/tests/examples_5/test/simple_storage_test.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.5.0; +import "./../contract/simple_storage.sol"; + +contract StorageResolveTest { + SimpleStorage foo; + + function beforeAll() public { + foo = new SimpleStorage(); + } + + function initialValueShouldBe100() public returns (bool) { + return Assert.equal(foo.get(), 100, "initial value is not correct"); + } + + //Test imported contract functions + function checkIfEven() public returns (bool) { + return Assert.equal(foo.check(10), 'EVEN', "value is odd"); + } + + function checkIfOdd() public returns (bool) { + return Assert.equal(foo.check(11), 'ODD', "value is even"); + } + +} diff --git a/remix-tests/tests/testRunner.ts b/remix-tests/tests/testRunner.ts index 1ee893578e..ba79ca8b54 100644 --- a/remix-tests/tests/testRunner.ts +++ b/remix-tests/tests/testRunner.ts @@ -183,6 +183,33 @@ describe('testRunner', () => { }) }) + // Test multiple directory import in test contract + describe('test multiple directory import in test contract', function () { + let filename = 'tests/examples_5/test/simple_storage_test.sol' + + before(function (done) { + compileAndDeploy(filename, (_err, compilationData, contracts, accounts) => { + runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], { accounts }, testCallback, resultsCallback(done)) + }) + }) + + after(() => { tests = [] }) + + it('should 3 passing tests', function () { + assert.equal(results.passingNum, 3) + }) + + it('should return 4 messages', function () { + deepEqualExcluding(tests, [ + { type: 'accountList', value: accounts }, + { type: 'contract', value: 'StorageResolveTest', filename: 'tests/examples_5/test/simple_storage_test.sol' }, + { type: 'testPass', value: 'Initial value should be100', context: 'StorageResolveTest' }, + { type: 'testPass', value: 'Check if odd', context: 'StorageResolveTest' }, + { type: 'testPass', value: 'Check if even', context: 'StorageResolveTest' } + ], ['time']) + }) + }) + //Test signed/unsigned integer weight describe('test number weight', function () { let filename = 'tests/number/number_test.sol'