CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openzeppelin--test-helpers

JavaScript testing helpers for Ethereum smart contract development with assertions, event verification, balance tracking, and time manipulation.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

constants-utilities.mddocs/

Constants and Utilities

Common Ethereum constants and utility functions for conversions, interface IDs, and transaction sending. Essential building blocks for smart contract testing.

Capabilities

Ethereum Constants

Common constants used in Ethereum smart contract development.

const constants = {
  /**
   * Zero address - commonly used as null address
   * @type {string}
   */
  ZERO_ADDRESS: '0x0000000000000000000000000000000000000000',
  
  /**
   * Zero bytes32 value - commonly used as null bytes32
   * @type {string}
   */
  ZERO_BYTES32: '0x0000000000000000000000000000000000000000000000000000000000000000',
  
  /**
   * Maximum uint256 value (2^256 - 1)
   * @type {BN}
   */
  MAX_UINT256: BN,
  
  /**
   * Maximum int256 value (2^255 - 1)
   * @type {BN}
   */
  MAX_INT256: BN,
  
  /**
   * Minimum int256 value (-2^255)
   * @type {BN}
   */
  MIN_INT256: BN,
};

Usage Examples:

const { constants, expectRevert } = require('@openzeppelin/test-helpers');

// Test zero address validation
await expectRevert(
  token.transfer(constants.ZERO_ADDRESS, 100),
  'ERC20: transfer to the zero address'
);

// Test maximum values
await token.approve(spender, constants.MAX_UINT256);

// Test with zero bytes32
await myContract.setData(constants.ZERO_BYTES32);

Ether Conversion

Convert ether amounts to wei for precise calculations.

/**
 * Convert ether amount to wei as BigNumber
 * @param {string|number} n - Amount in ether
 * @returns {BN} - Amount in wei as BigNumber
 */
function ether(n);

Usage Examples:

const { ether, BN } = require('@openzeppelin/test-helpers');

// Convert ether to wei
const oneEther = ether('1');
console.log(oneEther.toString()); // "1000000000000000000"

// Use in transactions
await contract.deposit({ value: ether('0.5') });

// Compare with BN
const halfEther = new BN('500000000000000000');
expect(ether('0.5')).to.be.bignumber.equal(halfEther);

// Use in calculations
const totalValue = ether('1.5').add(ether('2.3'));
expect(totalValue).to.be.bignumber.equal(ether('3.8'));

Interface ID Generation

Generate interface IDs for ERC165 and ERC1820 standards.

/**
 * Generate ERC165 interface ID from function signatures
 * @param {string[]} functionSignatures - Array of function signature strings
 * @returns {string} - 4-byte interface ID as hex string
 */
function makeInterfaceId.ERC165(functionSignatures = []);

/**
 * Generate ERC1820 interface hash from interface name
 * @param {string} interfaceName - Name of the interface
 * @returns {string} - 32-byte interface hash as hex string
 */
function makeInterfaceId.ERC1820(interfaceName);

Usage Examples:

const { makeInterfaceId } = require('@openzeppelin/test-helpers');

// Generate ERC165 interface ID for ERC721
const ERC721InterfaceId = makeInterfaceId.ERC165([
  'balanceOf(address)',
  'ownerOf(uint256)',
  'approve(address,uint256)',
  'getApproved(uint256)',
  'setApprovalForAll(address,bool)',
  'isApprovedForAll(address,address)',
  'transferFrom(address,address,uint256)',
  'safeTransferFrom(address,address,uint256)',
  'safeTransferFrom(address,address,uint256,bytes)',
]);

console.log('ERC721 Interface ID:', ERC721InterfaceId); // "0x80ac58cd"

// Test interface support
const supportsInterface = await nft.supportsInterface(ERC721InterfaceId);
expect(supportsInterface).to.equal(true);

// Generate ERC1820 interface hash
const ERC777TokensRecipientHash = makeInterfaceId.ERC1820('ERC777TokensRecipient');
console.log('ERC777TokensRecipient Hash:', ERC777TokensRecipientHash);

Transaction Sending Utilities

Low-level transaction sending utilities for custom scenarios.

/**
 * Send ether from one address to another
 * @param {string} from - Sender address
 * @param {string} to - Recipient address
 * @param {BN|string|number} value - Amount to send in wei
 * @returns {Promise<TransactionReceipt>} - Transaction receipt
 */
async function send.ether(from, to, value);

/**
 * Send a transaction to call a contract function
 * @param {ContractInstance} target - Contract instance to call
 * @param {string} name - Function name to call
 * @param {string} argsTypes - Comma-separated argument types
 * @param {any[]} argsValues - Array of argument values
 * @param {object} opts - Transaction options (from, gas, etc.)
 * @returns {Promise<TransactionReceipt>} - Transaction receipt
 */
async function send.transaction(target, name, argsTypes, argsValues, opts = {});

Usage Examples:

const { send, ether } = require('@openzeppelin/test-helpers');

// Send ether between accounts
await send.ether(sender, recipient, ether('1'));

// Call contract function with encoded parameters
await send.transaction(
  myContract,
  'transfer',
  'address,uint256',
  [recipient, ether('100')],
  { from: sender }
);

// Advanced transaction with custom gas
await send.transaction(
  complexContract,
  'complexFunction',
  'uint256[],string,bool',
  [[1, 2, 3], 'hello', true],
  { from: sender, gas: 200000 }
);

Practical Examples

Testing ERC165 Interface Support

const { makeInterfaceId } = require('@openzeppelin/test-helpers');

contract('MyNFT', function () {
  it('should support required interfaces', async function () {
    // ERC165
    const ERC165InterfaceId = makeInterfaceId.ERC165(['supportsInterface(bytes4)']);
    expect(await this.nft.supportsInterface(ERC165InterfaceId)).to.equal(true);
    
    // ERC721
    const ERC721InterfaceId = makeInterfaceId.ERC165([
      'balanceOf(address)',
      'ownerOf(uint256)',
      'approve(address,uint256)',
      'getApproved(uint256)',
      'setApprovalForAll(address,bool)',
      'isApprovedForAll(address,address)',
      'transferFrom(address,address,uint256)',
      'safeTransferFrom(address,address,uint256)',
      'safeTransferFrom(address,address,uint256,bytes)',
    ]);
    expect(await this.nft.supportsInterface(ERC721InterfaceId)).to.equal(true);
  });
});

Testing with Maximum Values

const { constants, expectRevert, ether } = require('@openzeppelin/test-helpers');

contract('Token', function ([owner, user]) {
  it('should handle maximum approvals', async function () {
    // Approve maximum amount
    await this.token.approve(user, constants.MAX_UINT256, { from: owner });
    
    const allowance = await this.token.allowance(owner, user);
    expect(allowance).to.be.bignumber.equal(constants.MAX_UINT256);
  });
  
  it('should reject zero address operations', async function () {
    await expectRevert(
      this.token.transfer(constants.ZERO_ADDRESS, ether('1')),
      'ERC20: transfer to the zero address'
    );
    
    await expectRevert(
      this.token.approve(constants.ZERO_ADDRESS, ether('1')),
      'ERC20: approve to the zero address'
    );
  });
});

Custom Transaction Scenarios

const { send, ether, expectEvent } = require('@openzeppelin/test-helpers');

contract('PaymentSplitter', function ([owner, beneficiary1, beneficiary2]) {
  it('should handle direct ether transfers', async function () {
    // Send ether directly to contract
    const receipt = await send.ether(
      owner,
      this.splitter.address,
      ether('1')
    );
    
    // Check for payment received event
    await expectEvent.inTransaction(
      receipt.transactionHash,
      this.splitter,
      'PaymentReceived',
      { from: owner, amount: ether('1') }
    );
  });
});

Constants Reference

Numeric Constants

// All constants are BigNumber instances
constants.MAX_UINT256.toString();  // "115792089237316195423570985008687907853269984665640564039457584007913129639935"
constants.MAX_INT256.toString();   // "57896044618658097711785492504343953926634992332820282019728792003956564819967"
constants.MIN_INT256.toString();   // "-57896044618658097711785492504343953926634992332820282019728792003956564819968"

String Constants

constants.ZERO_ADDRESS;  // "0x0000000000000000000000000000000000000000"
constants.ZERO_BYTES32;  // "0x0000000000000000000000000000000000000000000000000000000000000000"

Install with Tessl CLI

npx tessl i tessl/npm-openzeppelin--test-helpers

docs

advanced-features.md

balance-tracking.md

constants-utilities.md

event-testing.md

index.md

revert-testing.md

time-manipulation.md

tile.json