mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-13 08:21:09 +00:00
Add test fixtures for the revive WASM version (#160)
This commit is contained in:
committed by
GitHub
parent
8ffe072fee
commit
b78b2b2af9
+63
-39
@@ -1,63 +1,87 @@
|
|||||||
const { test, expect } = require('@playwright/test');
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
const validCompilerInput = {
|
function loadFixture(fixture) {
|
||||||
language: 'Solidity',
|
const fixturePath = path.resolve(__dirname, `../fixtures/${fixture}`);
|
||||||
sources: {
|
return JSON.parse(fs.readFileSync(fixturePath, 'utf-8'));
|
||||||
'MyContract.sol': {
|
}
|
||||||
content: `
|
|
||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.0;
|
|
||||||
contract MyContract {
|
|
||||||
function greet() public pure returns (string memory) {
|
|
||||||
return "Hello";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
optimizer: {
|
|
||||||
enabled: true,
|
|
||||||
runs: 200,
|
|
||||||
},
|
|
||||||
outputSelection: {
|
|
||||||
'*': {
|
|
||||||
'*': ['abi', 'evm.bytecode'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function runWorker(page, input) {
|
async function runWorker(page, input) {
|
||||||
return await page.evaluate((input) => {
|
return await page.evaluate((input) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const worker = new Worker('worker.js'); // Path to your worker.js file
|
const worker = new Worker('worker.js');
|
||||||
worker.postMessage(JSON.stringify(input));
|
worker.postMessage(JSON.stringify(input));
|
||||||
|
|
||||||
worker.onmessage = (event) => {
|
worker.onmessage = (event) => {
|
||||||
resolve(event.data.output);
|
resolve(event.data.output);
|
||||||
worker.terminate(); // Clean up the worker
|
worker.terminate();
|
||||||
};
|
};
|
||||||
|
|
||||||
worker.onerror = (error) => {
|
worker.onerror = (error) => {
|
||||||
reject(error.message || error); // Provide error message for clarity
|
reject(error.message || error);
|
||||||
worker.terminate(); // Clean up the worker
|
worker.terminate();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, input); // Pass the input as an argument to the function
|
}, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
test('Test browser', async ({ page }) => {
|
test('should successfully compile valid Solidity code in browser', async ({ page }) => {
|
||||||
await page.goto("http://127.0.0.1:8080");
|
await page.goto("http://127.0.0.1:8080");
|
||||||
await page.setContent("");
|
await page.setContent("");
|
||||||
|
const standardInput = loadFixture('storage.json')
|
||||||
const result = await runWorker(page, validCompilerInput);
|
const result = await runWorker(page, standardInput);
|
||||||
|
|
||||||
expect(typeof result).toBe('string');
|
expect(typeof result).toBe('string');
|
||||||
let output = JSON.parse(result);
|
let output = JSON.parse(result);
|
||||||
expect(output).toHaveProperty('contracts');
|
expect(output).toHaveProperty('contracts');
|
||||||
expect(output.contracts['MyContract.sol']).toHaveProperty('MyContract');
|
expect(output.contracts['fixtures/storage.sol']).toHaveProperty('Storage');
|
||||||
expect(output.contracts['MyContract.sol'].MyContract).toHaveProperty('abi');
|
expect(output.contracts['fixtures/storage.sol'].Storage).toHaveProperty('abi');
|
||||||
expect(output.contracts['MyContract.sol'].MyContract).toHaveProperty('evm');
|
expect(output.contracts['fixtures/storage.sol'].Storage).toHaveProperty('evm');
|
||||||
expect(output.contracts['MyContract.sol'].MyContract.evm).toHaveProperty('bytecode');
|
expect(output.contracts['fixtures/storage.sol'].Storage.evm).toHaveProperty('bytecode');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should successfully compile large valid Solidity code in browser', async ({ page }) => {
|
||||||
|
await page.goto("http://127.0.0.1:8080");
|
||||||
|
await page.setContent("");
|
||||||
|
const standardInput = loadFixture('token.json')
|
||||||
|
const result = await runWorker(page, standardInput);
|
||||||
|
|
||||||
|
expect(typeof result).toBe('string');
|
||||||
|
let output = JSON.parse(result);
|
||||||
|
expect(output).toHaveProperty('contracts');
|
||||||
|
expect(output.contracts['fixtures/token.sol']).toHaveProperty('MyToken');
|
||||||
|
expect(output.contracts['fixtures/token.sol'].MyToken).toHaveProperty('abi');
|
||||||
|
expect(output.contracts['fixtures/token.sol'].MyToken).toHaveProperty('evm');
|
||||||
|
expect(output.contracts['fixtures/token.sol'].MyToken.evm).toHaveProperty('bytecode');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should throw an error for invalid Solidity code in browser', async ({ page }) => {
|
||||||
|
await page.goto("http://127.0.0.1:8080");
|
||||||
|
await page.setContent("");
|
||||||
|
const standardInput = loadFixture('invalid_contract_content.json')
|
||||||
|
const result = await runWorker(page, standardInput);
|
||||||
|
|
||||||
|
expect(typeof result).toBe('string');
|
||||||
|
let output = JSON.parse(result);
|
||||||
|
expect(output).toHaveProperty('errors');
|
||||||
|
expect(Array.isArray(output.errors)).toBeTruthy(); // Check if it's an array
|
||||||
|
expect(output.errors.length).toBeGreaterThan(0);
|
||||||
|
expect(output.errors[0]).toHaveProperty('type');
|
||||||
|
expect(output.errors[0].type).toContain('ParserError');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return not found error for missing imports in browser', async ({page}) => {
|
||||||
|
await page.goto("http://127.0.0.1:8080");
|
||||||
|
await page.setContent("");
|
||||||
|
const standardInput = loadFixture('missing_import.json')
|
||||||
|
const result = await runWorker(page, standardInput);
|
||||||
|
|
||||||
|
expect(typeof result).toBe('string');
|
||||||
|
let output = JSON.parse(result);
|
||||||
|
expect(output).toHaveProperty('errors');
|
||||||
|
expect(Array.isArray(output.errors)).toBeTruthy(); // Check if it's an array
|
||||||
|
expect(output.errors.length).toBeGreaterThan(0);
|
||||||
|
expect(output.errors[0]).toHaveProperty('message');
|
||||||
|
expect(output.errors[0].message).toContain('Source "nonexistent/console.sol" not found');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"language": "Solidity",
|
||||||
|
"sources": {
|
||||||
|
"fixtures/storage.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\nimport \"nonexistent/console.sol\";\ncontract MyContract { function greet() public pure returns (string memory) { return \"Hello\" // Missing semicolon }}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"optimizer": {
|
||||||
|
"enabled": true,
|
||||||
|
"runs": 200
|
||||||
|
},
|
||||||
|
"outputSelection": {
|
||||||
|
"*": {
|
||||||
|
"*": [
|
||||||
|
"abi"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"language": "Solidity",
|
||||||
|
"sources": {
|
||||||
|
"fixtures/storage.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\nimport \"nonexistent/console.sol\";\ncontract MyContract { function f() public { } }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"optimizer": {
|
||||||
|
"enabled": true,
|
||||||
|
"runs": 200
|
||||||
|
},
|
||||||
|
"outputSelection": {
|
||||||
|
"*": {
|
||||||
|
"*": [
|
||||||
|
"abi"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"language": "Solidity",
|
||||||
|
"sources": {
|
||||||
|
"fixtures/storage.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.8.2 <0.9.0;\ncontract Storage {\n uint256 number;\n function store(uint256 num) public { number = num; }\n function retrieve() public view returns (uint256){ return number; }\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"optimizer": {
|
||||||
|
"enabled": true,
|
||||||
|
"runs": 200
|
||||||
|
},
|
||||||
|
"outputSelection": {
|
||||||
|
"*": {
|
||||||
|
"*": [
|
||||||
|
"abi"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
+2
-2
@@ -8,8 +8,8 @@
|
|||||||
"fetch:soljson": "wget https://binaries.soliditylang.org/wasm/soljson-v0.8.28+commit.7893614a.js -O ./examples/web/soljson.js",
|
"fetch:soljson": "wget https://binaries.soliditylang.org/wasm/soljson-v0.8.28+commit.7893614a.js -O ./examples/web/soljson.js",
|
||||||
"example:web": "npm run fetch:soljson && http-server ./examples/web/",
|
"example:web": "npm run fetch:soljson && http-server ./examples/web/",
|
||||||
"example:node": "node ./examples/node/run_revive.js",
|
"example:node": "node ./examples/node/run_revive.js",
|
||||||
"test:node": "mocha --timeout 20000 ./tests",
|
"test:node": "mocha --timeout 60000 ./tests",
|
||||||
"test:bun": "bun test --timeout 20000 node.test",
|
"test:bun": "bun test --timeout 60000 node.test",
|
||||||
"test:all": "npm run test:node && npm run test:bun"
|
"test:all": "npm run test:node && npm run test:bun"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ module.exports = defineConfig({
|
|||||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
},
|
},
|
||||||
|
timeout: 120000,
|
||||||
/* Configure projects for major browsers */
|
/* Configure projects for major browsers */
|
||||||
projects: [
|
projects: [
|
||||||
{
|
{
|
||||||
|
|||||||
+38
-70
@@ -1,68 +1,52 @@
|
|||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { compile } from '../examples/node/revive.js';
|
import { compile } from '../examples/node/revive.js';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
const validCompilerInput = {
|
function loadFixture(fixture) {
|
||||||
language: 'Solidity',
|
const fixturePath = path.resolve(__dirname, `../fixtures/${fixture}`);
|
||||||
sources: {
|
return JSON.parse(fs.readFileSync(fixturePath, 'utf-8'));
|
||||||
'MyContract.sol': {
|
}
|
||||||
content: `
|
|
||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.0;
|
|
||||||
contract MyContract {
|
|
||||||
function greet() public pure returns (string memory) {
|
|
||||||
return "Hello";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
optimizer: {
|
|
||||||
enabled: true,
|
|
||||||
runs: 200,
|
|
||||||
},
|
|
||||||
outputSelection: {
|
|
||||||
'*': {
|
|
||||||
'*': ['abi', 'evm.bytecode'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Compile Function Tests', function () {
|
describe('Compile Function Tests', function () {
|
||||||
it('should successfully compile valid Solidity code', async function () {
|
it('should successfully compile valid Solidity code', async function () {
|
||||||
const result = await compile(validCompilerInput);
|
const standardInput = loadFixture('storage.json')
|
||||||
|
|
||||||
// Ensure result contains compiled contract
|
const result = await compile(standardInput);
|
||||||
expect(result).to.be.a('string');
|
expect(result).to.be.a('string');
|
||||||
const output = JSON.parse(result);
|
const output = JSON.parse(result);
|
||||||
expect(output).to.have.property('contracts');
|
expect(output).to.have.property('contracts');
|
||||||
expect(output.contracts['MyContract.sol']).to.have.property('MyContract');
|
expect(output.contracts['fixtures/storage.sol']).to.have.property('Storage');
|
||||||
expect(output.contracts['MyContract.sol'].MyContract).to.have.property('abi');
|
expect(output.contracts['fixtures/storage.sol'].Storage).to.have.property('abi');
|
||||||
expect(output.contracts['MyContract.sol'].MyContract).to.have.property('evm');
|
expect(output.contracts['fixtures/storage.sol'].Storage).to.have.property('evm');
|
||||||
expect(output.contracts['MyContract.sol'].MyContract.evm).to.have.property('bytecode');
|
expect(output.contracts['fixtures/storage.sol'].Storage.evm).to.have.property('bytecode');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error for invalid Solidity code', async function () {
|
if (typeof globalThis.Bun == 'undefined') {
|
||||||
const invalidCompilerInput = {
|
// Running this test with Bun on a Linux host causes:
|
||||||
...validCompilerInput,
|
// RuntimeError: Out of bounds memory access (evaluating 'getWasmTableEntry(index)(a1, a2, a3, a4, a5)')
|
||||||
sources: {
|
// Once this issue is resolved, the test will be re-enabled.
|
||||||
'MyContract.sol': {
|
it('should successfully compile large Solidity code', async function () {
|
||||||
content: `
|
const standardInput = loadFixture('token.json')
|
||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.0;
|
|
||||||
import "nonexistent/console.sol";
|
|
||||||
contract MyContract {
|
|
||||||
function greet() public pure returns (string memory) {
|
|
||||||
return "Hello" // Missing semicolon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await compile(invalidCompilerInput);
|
const result = await compile(standardInput);
|
||||||
|
expect(result).to.be.a('string');
|
||||||
|
const output = JSON.parse(result);
|
||||||
|
expect(output).to.have.property('contracts');
|
||||||
|
expect(output.contracts['fixtures/token.sol']).to.have.property('MyToken');
|
||||||
|
expect(output.contracts['fixtures/token.sol'].MyToken).to.have.property('abi');
|
||||||
|
expect(output.contracts['fixtures/token.sol'].MyToken).to.have.property('evm');
|
||||||
|
expect(output.contracts['fixtures/token.sol'].MyToken.evm).to.have.property('bytecode');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should throw an error for invalid Solidity code', async function () {
|
||||||
|
const standardInput = loadFixture('invalid_contract_content.json')
|
||||||
|
|
||||||
|
const result = await compile(standardInput);
|
||||||
expect(result).to.be.a('string');
|
expect(result).to.be.a('string');
|
||||||
const output = JSON.parse(result);
|
const output = JSON.parse(result);
|
||||||
expect(output).to.have.property('errors');
|
expect(output).to.have.property('errors');
|
||||||
@@ -73,25 +57,9 @@ describe('Compile Function Tests', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return not found error for missing imports', async function () {
|
it('should return not found error for missing imports', async function () {
|
||||||
const compilerInputWithImport = {
|
const standardInput = loadFixture('missing_import.json')
|
||||||
...validCompilerInput,
|
|
||||||
sources: {
|
|
||||||
'MyContract.sol': {
|
|
||||||
content: `
|
|
||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.0;
|
|
||||||
import "nonexistent/console.sol";
|
|
||||||
contract MyContract {
|
|
||||||
function greet() public pure returns (string memory) {
|
|
||||||
return "Hello";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = await compile(compilerInputWithImport);
|
const result = await compile(standardInput);
|
||||||
const output = JSON.parse(result);
|
const output = JSON.parse(result);
|
||||||
expect(output).to.have.property('errors');
|
expect(output).to.have.property('errors');
|
||||||
expect(output.errors).to.be.an('array');
|
expect(output.errors).to.be.an('array');
|
||||||
|
|||||||
Reference in New Issue
Block a user