Skip to content

Instantly share code, notes, and snippets.

@rumkin
Last active February 28, 2020 05:59
Show Gist options
  • Save rumkin/9729b6531a3589b10897f98f548c74f1 to your computer and use it in GitHub Desktop.
Save rumkin/9729b6531a3589b10897f98f548c74f1 to your computer and use it in GitHub Desktop.
Use TestUp with EVM in JS

Run EVM tests with TestUp

This is short explanation of how tests scripts and helpers might look.

evm.spec.js

import {initEvm, checkpoint} from './helpers';

export default ({describe, it, use, each}) => {
  describe('Subject', () => {
    // Initialize VM and put it into test context
    use(initEvm({
      accounts: {
        alice: {balance: '1 eth'},
        bob: {balance: 0},
      },
    }))
    
    // Make each test to add a checkpoint and to rollback
    each(checkpoint)
    
    // Run test and change the state
    it('test', async (test, ctx) => {
        const {alice, bob} = ctx.accounts

        await alice.transfer('0.5 eth', bob)
        const balance = await bob.getBalance('eth')

        assert.equal(balance, '5', 'Balance is 5')
      
        test.end()
    })
    
    // Run test with initial state, where Alice has 5 ethers and Bob has zero.
    it('test', async (test, ctx) => {
        const {alice, bob} = ctx.accounts

        const aliceBalance = await alice.getBalance('eth')
        const bobBalance = await bob.getBalance('eth')

        assert.equal(aliceBalance, '5', 'Alice balance is 5')
        assert.equal(bobBalance, '0', 'Bob balance is 0')
      
        test.end()
    })
  })
}

helpers.js

// Initialize EVM with a given params
export function initEvm(params) {
  async function (ctx, next) {
    const {evmModule} = ctx.specOpts
    const {default: VM, StateManager} = await import(evmModule)
    
    const state = new StateManager()
    const evm = await VM.create({state})
    
    const accounts = await createAccountsSomeHow(evm, params)
    
    // Put to context new vaalues `evm`, `state` and `accounts`.
    // This call equals to Object.assign(Object.create(ctx), {evm, state, accounts})
    await next({
      evm,
      state,
      accounts,
    })
  }
}

// Add checkpoint and rollback after test end
export async function checkpoint(ctx, next) {
  const {evm} = ctx
  const state = evm.pStateManager
  try {
    await state.checkpoint()
    await next()
  }
  finally {
    await state.rollback()
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment