GithubHelp home page GithubHelp logo

sarvex / prb-test Goto Github PK

View Code? Open in Web Editor NEW

This project forked from paulrberg/prb-test

0.0 1.0 0.0 2.6 MB

Modern collection of testing assertions and logging utilities for Solidity

License: MIT License

Solidity 100.00%

prb-test's Introduction

PRBTest Github Actions Coverage Foundry License: MIT

PRBTest is a modern collection of testing assertions and logging utilities for Solidity, and is meant to be a drop-in replacement for DSTest.

  • Feature-packed: assertions for equalities, inequalities, approximate equalities, numerical comparisons, and more
  • Type-rich: every assertion has overloads for address, bytes, bytes32, int256, string and uint256
  • Versioned releases so that you don't accidentally pull the latest version and break your test suites
  • Meant to be used with Foundry, but can also be used with Hardhat
  • Complementary to Forge Std
  • Designed for Solidity >=0.8.0
  • Thoroughly tested

Install

Foundry

First, run the install step:

forge install --no-commit PaulRBerg/prb-test@v0

Your .gitmodules file should now contain the following entry:

[submodule "lib/prb-test"]
  branch = "v0"
  path = "lib/prb-test"
  url = "https://github.com/PaulRBerg/prb-test"

Finally, add this to your remappings.txt file:

@prb/test/=lib/prb-test/src/

Node.js

pnpm add @prb/test
# or
npm install @prb/test

Template

If you're starting a project from scratch, the easiest way to install PRBTest is to use my Foundry template, since it comes pre-configured with PRBTest.

Usage

Once installed, all you need to do is import PRBTest and inherit from it in your test contract. PRBTest comes with a pre-instantiated cheatcodes environment accessible via the vm property. It also has support for logs.

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

import { PRBTest } from "@prb/test/PRBTest.sol";

contract MyTest is PRBTest {
  function testExample() external {
    vm.warp(block.timestamp + 100);
    emit Log("Hello World");
    assertTrue(true);
  }
}

Assertions

All assertions have overloads with an additional err argument, so that you can pass custom error messages.

Name Argument Types
assertTrue bool
assertFalse bool
assertEq address, bytes, bytes32, int256, string, uint256 and their array equivalents
assertNotEq address, bytes, bytes32, int256, string, uint256 and their array equivalents
assertAlmostEq int256 and uint256
assertGt int256 and uint256
assertGte int256 and uint256
assertLt int256 and uint256
assertLte int256 and uint256
assertContains address[], bytes32[], int256[], string[], and uint256[]

Forge Std

PRBTest can be used alongside all testing utilities from forge-std, except for their Test contract.

Here's an example for how to use PRBTest with StdCheats and stdError:

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

import { PRBTest } from "@prb/test/PRBTest.sol";
import { StdCheats } from "forge-std/StdCheats.sol";
import { stdError } from "forge-std/Test.sol";

contract MyTest is PRBTest, StdCheats {
  function testArithmeticOverflow() external {
    uint256 a = type(uint256).max;
    uint256 b = 1;
    vm.expectRevert(stdError.arithmeticError);
    a + b;
  }
}

Why Choose PRBTest Over DSTest?

DSTest is great. I have used it for a while, and I like it a lot. But, with time, I slowly came to realize that there's a lot of room for improvement.

1. Missing Features and Tests

DSTest is incomplete. Some commonly needed assertions, like equality assertions for arrays, assertEq(bool,bool) and assertNotEq, are missing from DSTest. PRBTest fills these gaps, and then some.

Also, the DSTest testing assertions are not themselves tested. Whereas the PRBTest testing assertions are tested, and in fact they are quite thoroughly tested. All other things being equal, this should give you more confidence that your tests do what you intend them to do.

2. No Release Versioning

DSTest doesn't version its releases, which makes it difficult to future-proof consumer repos. It's quite easy to accidentally update your git submodules and thus break your test suites. For some users, this is a real pain.

PRBTest is versioned via tags and branches and all changes are tracked in a CHANGELOG file. I maintain redundant branches for each release because git submodules don't support tags.

I will strive to follow the semver versioning scheme, though I won't do this before the v1.0 release, and it might not always be feasible.

3. Path Dependence

As one of the maintainers of DSTest said here, updating DSTest is painful to orchestrate. The reasons for this are twofold:

  1. Every DappTools project uses it as a git submodule.
  2. DSTest releases have not been versioned.

So any significant change in DSTest might wreak havoc downstream.

This issue has led to a "balkanization" of DSTest forks and extensions. See, for instance, Solmate's DSTestPlus and Forge Std's Test. Also see the discussions in this PR, in which the PR author ended up making the PR against forge-std rather than ds-test because he feared that his PR won't be merged.

4. Lack of Backward Compatibility with Node.js

It is my firm conviction that Foundry is the future of Ethereum smart contract development. Solidity code is best tested in Solidity itself.

But, due to various historical reasons, the Ethereum ecosystem has for a long time relied upon JavaScript for testing smart contracts. Refactoring a code base from Hardhat or Truffle to Foundry takes time, and it may not always be possible to do it in one fell swoop. Thus, to ensure backward compatibility, PRBTest is available as a Node.js package in the npm package registry.

For more details about this, see this discussion here.

Contributing

Feel free to dive in! Open an issue, start a discussion or submit a PR.

Pre Requisites

You will need the following software on your machine:

In addition, familiarity with Solidity is requisite.

Set Up

Clone this repository including submodules:

$ git clone --recurse-submodules -j8 [email protected]:PaulRBerg/prb-test.git

Then, inside the project's directory, run this to install the Node.js dependencies:

$ pnpm install

Now you can start making changes.

Syntax Highlighting

You will need the following VSCode extensions:

Acknowledgements

These contracts were inspired by or directly modified from the following sources:

License

This project is licensed under MIT.

prb-test's People

Contributors

paulrberg avatar sambacha avatar jaycenhorton avatar kyscott18 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.