Skip to content

Commit

Permalink
Add tests for the Revive WASM version (#147)
Browse files Browse the repository at this point in the history
  • Loading branch information
smiasojed authored Jan 10, 2025
1 parent f49d145 commit d7d60da
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 18 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/build-revive-wasm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ env:
CARGO_TERM_COLOR: always
REVIVE_WASM_INSTALL_DIR: ${{ github.workspace }}/target/wasm32-unknown-emscripten/release
EMSCRIPTEN_VERSION: 3.1.64
BUN_VERSION: 1.1.43

jobs:
build-revive-wasm:
Expand Down Expand Up @@ -77,3 +78,51 @@ jobs:
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.js
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.wasm
retention-days: 1

test-revive-wasm:
needs: build-revive-wasm
strategy:
matrix:
os: ['ubuntu-24.04', 'macos-14', 'windows-2022']
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- name: Create Target Directory
run: mkdir -p ${{ env.REVIVE_WASM_INSTALL_DIR }}

- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: revive-wasm
path: ${{ env.REVIVE_WASM_INSTALL_DIR }}

- name: Set Up Node.js
uses: actions/setup-node@v3
with:
node-version: '20'

- name: Install Bun on Windows
if: runner.os == 'Windows'
run: |
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
scoop install bun@${{ env.BUN_VERSION }}
Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
- name: Install Bun on macOS and Linux
if: runner.os != 'Windows'
run: |
curl -fsSL https://bun.sh/install | bash -s bun-v${{ env.BUN_VERSION }}
echo "$HOME/.bun/bin" >> $GITHUB_PATH
- name: Confirm Installations
run: |
node --version
bun --version
- name: Test revive
run: |
echo "Running tests for ${{ matrix.os }}"
npm install
npm run test:wasm
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: install format test test-solidity test-cli test-integration test-workspace clean docs docs-build
.PHONY: install format test test-solidity test-cli test-integration test-workspace test-wasm clean docs docs-build

RUSTFLAGS_EMSCRIPTEN := \
-C link-arg=-sEXPORTED_FUNCTIONS=_main,_free,_malloc \
Expand All @@ -25,9 +25,11 @@ install-bin:
install-npm:
npm install && npm fund

install-wasm:
install-wasm: install-npm
RUSTFLAGS='$(RUSTFLAGS_EMSCRIPTEN)' cargo build --target wasm32-unknown-emscripten -p revive-solidity --release --no-default-features
npm install

test-wasm: install-wasm
npm run test:wasm

# install-revive: Build and install to the directory specified in REVIVE_INSTALL_DIR
ifeq ($(origin REVIVE_INSTALL_DIR), undefined)
Expand Down
32 changes: 32 additions & 0 deletions js/examples/node/revive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const soljson = require('solc/soljson');
const createRevive = require('./resolc.js');

async function compile(standardJsonInput) {
if (!standardJsonInput) {
throw new Error('Input JSON for the Solidity compiler is required.');
}

// Initialize the compiler
const compiler = createRevive();
compiler.soljson = soljson;

// Provide input to the compiler
compiler.writeToStdin(JSON.stringify(standardJsonInput));

// Run the compiler
compiler.callMain(['--standard-json']);

// Collect output
const stdout = compiler.readFromStdout();
const stderr = compiler.readFromStderr();

// Check for errors and throw if stderr exists
if (stderr) {
throw new Error(`Compilation failed: ${stderr}`);
}

// Return the output if no errors
return stdout;
}

module.exports = { compile };
15 changes: 3 additions & 12 deletions js/examples/node/run_revive.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const soljson = require('solc/soljson');
const createRevive = require('./resolc.js');
const { compile } = require('./revive.js');

const compilerStandardJsonInput = {
language: 'Solidity',
Expand Down Expand Up @@ -30,16 +29,8 @@ const compilerStandardJsonInput = {
};

async function runCompiler() {
const m = createRevive();
m.soljson = soljson;

// Set input data for stdin
m.writeToStdin(JSON.stringify(compilerStandardJsonInput));

// Compile the Solidity source code
let x = m.callMain(['--standard-json']);
console.log("Stdout: " + m.readFromStdout());
console.error("Stderr: " + m.readFromStderr());
let output = await compile(compilerStandardJsonInput)
console.log("Output: " + output);
}

runCompiler().catch(err => {
Expand Down
9 changes: 7 additions & 2 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
"scripts": {
"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:node": "node ./examples/node/run_revive.js"
"example:node": "node ./examples/node/run_revive.js",
"test:node": "mocha --timeout 10000 ./tests",
"test:bun": "bun test",
"test:all": "npm run test:node && npm run test:bun"
},
"devDependencies": {
"http-server": "^14.1.1"
"chai": "^5.1.2",
"http-server": "^14.1.1",
"mocha": "^11.0.1"
}
}
102 changes: 102 additions & 0 deletions js/tests/node.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { expect } from 'chai';
import { compile } from '../examples/node/revive.js';

const validCompilerInput = {
language: 'Solidity',
sources: {
'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 () {
it('should successfully compile valid Solidity code', async function () {
const result = await compile(validCompilerInput);

// Ensure result contains compiled contract
expect(result).to.be.a('string');
const output = JSON.parse(result);
expect(output).to.have.property('contracts');
expect(output.contracts['MyContract.sol']).to.have.property('MyContract');
expect(output.contracts['MyContract.sol'].MyContract).to.have.property('abi');
expect(output.contracts['MyContract.sol'].MyContract).to.have.property('evm');
expect(output.contracts['MyContract.sol'].MyContract.evm).to.have.property('bytecode');
});

it('should throw an error for invalid Solidity code', async function () {
const invalidCompilerInput = {
...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" // Missing semicolon
}
}
`,
},
},
};

const result = await compile(invalidCompilerInput);
expect(result).to.be.a('string');
const output = JSON.parse(result);
expect(output).to.have.property('errors');
expect(output.errors).to.be.an('array');
expect(output.errors.length).to.be.greaterThan(0);
expect(output.errors[0].type).to.exist;
expect(output.errors[0].type).to.contain("ParserError");
});

it('should return not found error for missing imports', async function () {
const compilerInputWithImport = {
...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 output = JSON.parse(result);
expect(output).to.have.property('errors');
expect(output.errors).to.be.an('array');
expect(output.errors.length).to.be.greaterThan(0);
expect(output.errors[0].message).to.exist;
expect(output.errors[0].message).to.include('Source "nonexistent/console.sol" not found');
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": true,
"scripts": {
"test:cli": "npm run test -w crates/solidity/src/tests/cli-tests",
"test:revive": "npm run example:node -w js"
"test:wasm": "npm run test:all -w js"
},
"workspaces": [
"crates/solidity/src/tests/cli-tests",
Expand Down

0 comments on commit d7d60da

Please sign in to comment.