Giter Site home page Giter Site logo

rkalis / truffle-assertions Goto Github PK

View Code? Open in Web Editor NEW
157.0 7.0 20.0 10.81 MB

🛠 Assertions and utilities for testing Ethereum smart contracts with Truffle unit tests

Home Page: https://kalis.me/check-events-solidity-smart-contract-test-truffle/

License: MIT License

JavaScript 100.00%
truffle ethereum web3 events solidity revert

truffle-assertions's Introduction

⚠️ Truffle (and truffle-assertions) has been sunset. It is recommended to move over to Hardhat or Foundry ⚠️

truffle-assertions

Coverage Status NPM Version NPM Monthly Downloads NPM License

This package adds additional assertions that can be used to test Ethereum smart contracts inside Truffle tests.

Installation

truffle-assertions can be installed through npm:

npm install truffle-assertions

Usage

To use this package, import it at the top of the Truffle test file, and use the functions that are documented below.

const truffleAssert = require('truffle-assertions');

Tutorials

I wrote two tutorials on using this library for checking events and asserting reverts inside smart contract tests:

I also gave a two talks that explain a few different use cases of the library:

Exported functions

truffleAssert.eventEmitted(result, eventType[, filter][, message])

The eventEmitted assertion checks that an event with type eventType has been emitted by the transaction with result result. A filter function can be passed along to further specify requirements for the event arguments:

truffleAssert.eventEmitted(result, 'TestEvent', (ev) => {
    return ev.param1 === 10 && ev.param2 === ev.param3;
});

Alternatively, a filter object can be passed in place of a function. If an object is passed, this object will be matched against the event's arguments. This object does not need to include all the event's arguments; only the included ones will be used in the comparison.

truffleAssert.eventEmitted(result, 'TestEvent', { param1: 10, param2: 20 });

When the filter parameter is omitted or set to null, the assertion checks just for event type:

truffleAssert.eventEmitted(result, 'TestEvent');

Optionally, a custom message can be passed to the assertion, which will be displayed alongside the default one:

truffleAssert.eventEmitted(result, 'TestEvent', (ev) => {
    return ev.param1 === 10 && ev.param2 === ev.param3;
}, 'TestEvent should be emitted with correct parameters');

The default messages are

`Event of type ${eventType} was not emitted`
`Event filter for ${eventType} returned no results`

Depending on the reason for the assertion failure. The default message also includes a list of events that were emitted in the passed transaction.


truffleAssert.eventNotEmitted(result, eventType[, filter][, message])

The eventNotEmitted assertion checks that an event with type eventType has not been emitted by the transaction with result result. A filter function can be passed along to further specify requirements for the event arguments:

truffleAssert.eventNotEmitted(result, 'TestEvent', (ev) => {
    return ev.param1 === 10 && ev.param2 === ev.param3;
});

Alternatively, a filter object can be passed in place of a function. If an object is passed, this object will be matched against the event's arguments. This object does not need to include all the event's arguments; only the included ones will be used in the comparison.

truffleAssert.eventNotEmitted(result, 'TestEvent', { param1: 10, param2: 20 });

When the filter parameter is omitted or set to null, the assertion checks just for event type:

truffleAssert.eventNotEmitted(result, 'TestEvent');

Optionally, a custom message can be passed to the assertion, which will be displayed alongside the default one:

truffleAssert.eventNotEmitted(result, 'TestEvent', null, 'TestEvent should not be emitted');

The default messages are

`Event of type ${eventType} was emitted`
`Event filter for ${eventType} returned results`

Depending on the reason for the assertion failure. The default message also includes a list of events that were emitted in the passed transaction.


truffleAssert.prettyPrintEmittedEvents(result)

Pretty prints the full list of events with their parameters, that were emitted in transaction with result result

truffleAssert.prettyPrintEmittedEvents(result);
Events emitted in tx 0x7da28cf2bd52016ee91f10ec711edd8aa2716aac3ed453b0def0af59991d5120:
----------------------------------------------------------------------------------------
TestEvent(testAddress = 0xe04893f0a1bdb132d66b4e7279492fcfe602f0eb, testInt: 10)
----------------------------------------------------------------------------------------

truffleAssert.createTransactionResult(contract, transactionHash)

There can be times where we only have access to a transaction hash, and not to a transaction result object, such as with the deployment of a new contract instance using Contract.new();. In these cases we still want to be able to assert that certain events are or aren't emitted.

truffle-assertions offers the possibility to create a transaction result object from a contract instance and a transaction hash, which can then be used in the other functions that the library offers.

Note: This function assumes that web3 is injected into the tests, which truffle does automatically. If you're not using truffle, you should import web3 manually at the top of your test file.

let contractInstance = await Contract.new();
let result = await truffleAssert.createTransactionResult(contractInstance, contractInstance.transactionHash);

truffleAssert.eventEmitted(result, 'TestEvent');

truffleAssert.passes(asyncFn[, message])

Asserts that the passed async contract function does not fail.

await truffleAssert.passes(
    contractInstance.methodThatShouldPass()
);

Optionally, a custom message can be passed to the assertion, which will be displayed alongside the default one:

await truffleAssert.passes(
    contractInstance.methodThatShouldPass(),
    'This method should not run out of gas'
);

The default message is

`Failed with ${error}`

truffleAssert.fails(asyncFn[, errorType][, reason][, message])

Asserts that the passed async contract function fails with a certain ErrorType and reason.

The different error types are defined as follows:

ErrorType = {
  REVERT: "revert",
  INVALID_OPCODE: "invalid opcode",
  OUT_OF_GAS: "out of gas",
  INVALID_JUMP: "invalid JUMP"
}
await truffleAssert.fails(
    contractInstance.methodThatShouldFail(),
    truffleAssert.ErrorType.OUT_OF_GAS
);

A reason can be passed to the assertion, which functions as an extra filter on the revert reason (note that this is only relevant in the case of revert, not for the other ErrorTypes). This functionality requires at least Truffle v0.5.

await truffleAssert.fails(
    contractInstance.methodThatShouldFail(),
    truffleAssert.ErrorType.REVERT,
    "only owner"
);

If the errorType parameter is omitted or set to null, the function just checks for failure, regardless of cause.

await truffleAssert.fails(contractInstance.methodThatShouldFail());

Optionally, a custom message can be passed to the assertion, which will be displayed alongside the default one:

await truffleAssert.fails(
    contractInstance.methodThatShouldFail(),
    truffleAssert.ErrorType.OUT_OF_GAS,
    null,
    'This method should run out of gas'
);

The default messages are

'Did not fail'
`Expected to fail with ${errorType}, but failed with: ${error}`

truffleAssert.reverts(asyncFn[, reason][, message])

This is an alias for truffleAssert.fails(asyncFn, truffleAssert.ErrorType.REVERT[, reason][, message]).

await truffleAssert.reverts(
    contractInstance.methodThatShouldRevert(),
    "only owner"
);

Related projects

  • truffle-events — 3rd party add-on to this project with 'deep events' support. You can test emitted events in other contracts, provided they are in the same transaction i.e. event A (contract A) and event B (contract B) are produced in the same transaction.

Donations

If you use this library inside your own projects and you would like to support its development, you can donate Ξ to 0x6775f0Ee4E63983501DBE7b0385bF84DBd36D69B.

truffle-assertions's People

Contributors

itsnickbarry avatar leonprou avatar rkalis avatar zanawar avatar zulhfreelancer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

truffle-assertions's Issues

eventEmitted to receive an event object.

Is your feature request related to a problem?
For most of the time I use eventEmitted filter property to check some props of the emitted event. A more concise way can be just to pass an object to compare it with the event.

Describe the solution you'd like
For example I want to check the ERC20 Transfer event. The current form:

truffleAssert.eventEmitted(result, 'TokenCreated', (ev) => {
  return ev.from === from && ev.to === to && ev.tokens === tokens
})

Can be changed to

truffleAssert.eventEmitted(result, 'TokenCreated', {from: from, to: to, tokens: tokens})

Revert reason checking is not strict

Describe the bug
The reason checking doesn't fully check the string 1:1. If the asserted reason is an incomplete subset of the actual reason it will still pass. For instance:

Asserted Reason: "Pausable: pause"
Actual Reason: "Pausable: paused"

This is passed by truffle-assertions. This should have failed because "Pausabled: pause" is not the same as "Pausable: paused".

Example test code

  it('should successfully pause contract', async () => {
    await truffleAssert.passes(instance.pause());
    await truffleAssert.fails(
      instance.splitEth(bob, carol, { sender: alice, value: 2 }),
      truffleAssert.ErrorType.REVERT,
      'Pausable: pause'
    ); // This assertion passes 
  });

  it('should successfully pause contract', async () => {
    await truffleAssert.passes(instance.pause());
    await truffleAssert.fails(
      instance.splitEth(bob, carol, { sender: alice, value: 2 }),
      truffleAssert.ErrorType.REVERT,
      'Pausable: paused'
    ); // This assertion also passes
  });

Expected behavior
Should have failed the assertion

Environment Information
Truffle version: 5.0.21
Web3 version: 1.0.0-beta.37
truffle-assertions version: 0.9.1

Different behavior when running testing against Rinkeby

Describe the Bug
When running truffle v5 javascript tests against Rinkeby it doesn't catch the revert.
When running the tests against Ganache, behavior is as expected.

Error Message

  1) Contract: Bileto
       should not open store for non-owner:
     AssertionError: Expected to fail with by owner, but failed with: StatusError: Transaction: 0x5b4dc57076030dc52c18e15410bccaa1962db7f636204b8222469e888651320d exited with an error (status 0).
     Please check that the transaction:
     - satisfies all conditions set by Solidity `require` statements.
     - does not trigger a Solidity `revert` statement.
      at fails (node_modules/truffle-assertions/index.js:138:13)
      at process.internalTickCallback (internal/process/next_tick.js:77:7)

Test Code

  it("should not open store for non-owner", async () => {
    await truffleAssert.reverts(
      __contract.openStore({
        from: __organizer1
      }),
      "by owner");
  });

Expected Behavior
It should recognize that method reverted and consider the test successful.

Environment Information

  • Truffle version: 5.0.1 (core: 5.0.1)
  • Web3 version: x.x
  • Solidity: 0.5.2 (solc-js)
  • truffle-assertions version: 0.7.2
  • ganache-cli version: 6.2.5 (ganache-core: 2.3.3)

truffle-config.js

    rinkeby: {
      provider: () => new HDWallet(
        metamaskSeedPhrase,
        `https://rinkeby.infura.io/v3/${infuraProjectId}`,
        rinkebyAddressIndex,
        rinkebyNumAddresses),
      network_id: 4,
      skipDryRun: true
    },

Cannot read property 'filter' of undefined

Describe the bug

Maybe a user error but the most simple test fails with an undefined filter error.

Example test code

Bellow is the example code but I guess any contract will do.

const tassert = require('truffle-assertions')
...
contract("Request", async accounts => {
  it("creates fine", async () => {
    let project = await Project.new()
    let request = await Request.new(project.address)
    tassert.eventEmitted(request, 'Foo')
  })
})

Expected behavior

I would expect the assert to fire (or not fire) but not get this TypeError.

 1) Contract: Request
       creates fine with project:
     TypeError: Cannot read property 'filter' of undefined
      at assertEventEmittedFromTxResult (node_modules/truffle-assertions/index.js:61:30)
      at Object.eventEmitted (node_modules/truffle-assertions/index.js:176:5)
      at Context.<anonymous> (test/TestRequest.js:21:13)
      at processTicksAndRejections (internal/process/task_queues.js:89:5)

Environment Information
Truffle version: v5.0.14 (core: 5.0.14)
Web3 version: v1.0.0-beta.37
truffle-assertions version: 0.9.0

Assert nested/internal events

First, thank you for the great package!

I'm trying to assert an event from internal/nested transaction but no success so far.
Providing original tx object results in "AssertionError: Event of type XYZ was not emitted"

Tried also truffleAssert.createTransactionResult() providing instance of child contract and a hash of 'original' tx but no luck

Truffle 5.0, web3 1.0

PS. Truffle sees such an event and displays it in Events emitted during test:

truffle-assertions + truffle-hdwallet-provider + Test.sol > Error: the tx doesn't have the correct nonce

I can not install in this order :

$ npm install [email protected]
$ npm install npm install truffle-assertions

[https://github.com//issues/28]

If I install it the other way round, the installation succeeds
... , but then I get strange errors concerning wrong 'nonce' in my JavaScript based contract test (test/gallery.js) once I add a solidity based test contract (test/TestGallery.sol) when using truffle-hdwallet-provider (tested 1.0.12 and 1.0.14).

Steps to reproduce:

$ truffle develop

Another terminal :

$ npm install npm install truffle-assertions
$ npm install [email protected]
$ truffle test --network truffle_localhost_HDW

testing using web3.version = 1.0.0-beta.37


  TestGallery
    ✓ testAddRetrieve (127ms)

  Contract: Gallery
    ✓ deploys successfully
    1) ...should add an item and return an events with new number of items
    > No events were emitted
    2) ...should retrieve item
    > No events were emitted


  2 passing (6s)
  2 failing

  1) Contract: Gallery
       ...should add an item and return an events with new number of items:
     Error: the tx doesn't have the correct nonce. account has nonce of: 4 tx has nonce of: 20
      at /home/sum/DEV/test_HDWalletProvider_nonce/node_modules/truffle-hdwallet-provider/dist/webpack:/truffle-hdwallet-provider/Users/cruzmolina/Code/truffle-projects/truffle/node_modules/web3-provider-engine/subproviders/provider.js:18:1
      at e.callback [as onreadystatechange] (node_modules/truffle-hdwallet-provider/dist/webpack:/truffle-hdwallet-provider/Users/cruzmolina/Code/truffle-projects/truffle/node_modules/web3-providers-http/src/index.js:96:1)
      at e._a [as dispatchEvent] (node_modules/truffle-hdwallet-provider/dist/webpack:/truffle-hdwallet-provider/Users/cruzmolina/Code/truffle-projects/truffle/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:27:61)
      at e.dispatchEvent [as _setReadyState] (node_modules/truffle-hdwallet-provider/dist/webpack:/truffle-hdwallet-provider/Users/cruzmolina/Code/truffle-projects/truffle/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)
      at e._setReadyState [as _onHttpResponseEnd] (node_modules/truffle-hdwallet-provider/dist/webpack:/truffle-hdwallet-provider/Users/cruzmolina/Code/truffle-projects/truffle/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)
      at IncomingMessage._onHttpResponseEnd (node_modules/truffle-hdwallet-provider/dist/webpack:/truffle-hdwallet-provider/Users/cruzmolina/Code/truffle-projects/truffle/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)
      at endReadableNT (_stream_readable.js:1129:12)
      at process._tickCallback (internal/process/next_tick.js:63:19)

  2) Contract: Gallery
       ...should retrieve item:

      Retrieved url should be identical to stored url.
      + expected - actual

      -https://random.dog/8b28a6b8-2711-47ef-b8b8-fd557464a1ed.jpg

      at Context.it (test/gallery.js:52:10)
      at process._tickCallback (internal/process/next_tick.js:68:7)


versions
¸¸¸
$ truffle version
Truffle v5.0.27 (core: 5.0.27)
Solidity v0.5.0 (solc-js)
Node v10.16.0
Web3.js v1.0.0-beta.37
¸¸¸

code repo
https://github.com/SvenMeyer/test_HDWalletProvider_nonce

AssertionError when an event is emitted

Hi!

Firstly, thanks for this incredibly useful library. It makes my whole testing flow that much more manageable.

I'm running into an issue where the an AssertionError: Event filter for <eventName> returned no results is thrown, when, whilst running the tests, the output is

Events emitted during test:
    ---------------------------
    eventName([args])
    ---------------------------

Is this a bug?

Counting number of emitted events

Multiple people have expressed that they want to be able to count the number of emitted events and assert that they are above/below/at a certain threshold. If there are people with specific requirements for such functionality, let me know in the comments.

Checking event spawned by fallback function

Relayer:

    function relay(address payable recipient, uint amount) public {
        require(amount < address(this).balance, "insufficient funds");
        recipient.transfer(amount);
    }

EthWallet:

    function() external payable {
        // generate an event when receiving Eth
        require(msg.value > 0, "zero deposit");
        emit DepositEvent(msg.sender, msg.value);
    }
    return relay_instance.relay(EthWallet.address, value_out).then(function (result) {
        truffleAssert.prettyPrintEmittedEvents(result);
        //...

There are no events printed, even though (if the test fails) it announces that the event was emitted. I imagine this is because of the fact that the event isn't directly emitted by the Relayer contract.

What is the work around here?

truffleAssert.fails catches non-failure exception

Describe the bug
Run the example code:
await truffleAssert.fails(contractInstance.methodThatShouldFail());

Expected behavior
An assertion/exception to be thrown.

Issue Location

throw new AssertionError(assertionMessage);

Problem exists with line 127.

truffle-assertions/index.js

Lines 124 to 133 in 62cd432

try {
await asyncFn;
const assertionMessage = createAssertionMessage(message, 'Did not fail');
throw new AssertionError(assertionMessage);
} catch (error) {
if (errorType && !error.message.includes(errorType) ||
reason && !error.message.includes(reason)) {
const assertionMessage = createAssertionMessage(message, `Expected to fail with ${errorType}, but failed with: ${error}`);
throw new AssertionError(assertionMessage);
}

The assertion error is thrown within the try/catch block so it is immediately caught. Since errorType wasn't defined, the assertion is ignored and not re-thrown.

Does not work well with solidity-coverage

Describe the bug

solidity-coverage is known to polyfill the contracts with loads of custom events used to measure test coverage. It seems that something done by them makes truffle-assertions not see the event.

Here's the error output:

{ AssertionError: Event filter for PayInterest returned no results
  Events emitted in tx 0xd88f11f66a6e2dde445150891914b4b6b4d5200a719acc0585e9d4626b0fbcb8:
  ----------------------------------------------------------------------------------------
  WithdrawFromStream(0: 1, 1: 0x6Ecc55fF73ca55367c29298F23813efa54cbAc94, 2: 499725001, __length__: 3, streamId: 1, recipient: 0x6Ecc55fF73ca55367c29298F23813efa54cbAc94, amount: 499725001)
  WithdrawFromStream(0: 1, 1: 0x6Ecc55fF73ca55367c29298F23813efa54cbAc94, 2: 499725001, __length__: 3, streamId: 1, recipient: 0x6Ecc55fF73ca55367c29298F23813efa54cbAc94, amount: 499725001)
  PayInterest(0: 1, 1: 225000, 2: 225000, 3: 49999, __length__: 4, streamId: 1, senderInterest: 225000, recipientInterest: 225000, sablierInterest: 49999)
  PayInterest(0: 1, 1: 225000, 2: 225000, 3: 49999, __length__: 4, streamId: 1, senderInterest: 225000, recipientInterest: 225000, sablierInterest: 49999)

Yeah, it's weird, there are two PayInterest events logged but they are somehow neglected. I suspect that truffle-assertions expects the event to be the second after WithdrawFromStream? Not sure.

Example test code

The issue occurred in the sablier monorepo. Sorry, as of creating this issue, I have not yet pushed my local work on solidity-coverage. I'll come back here and make an update when I push to remote.

Here's how the test looks:

it("pays the interest to the sender of the stream", async function() {
  const balance = await this.cToken.balanceOf(sender);
  const result = await this.sablier.withdrawFromStream(streamId, amount, opts);

  try {
    truffleAssert.eventEmitted(result, "PayInterest", (event) => {
      console.log("event", require("util").inspect(event, false, null, true /* enable colors */));
    });
  } catch (err) {
    console.log({ err });
  }

  const senderInterest = result.logs[1].args.senderInterest;
  const newBalance = await this.cToken.balanceOf(sender);
  balance.should.be.bignumber.equal(newBalance.minus(senderInterest));
});

Expected behavior

The event should be filtered by truffle-assertions because it's definitely emitted.

Environment Information

Truffle version: 5.0.35
Web3 version: 1.2.1
truffle-assertions version: 0.8.2
ganache-cli version: 6.4.1 from https://github.com/frangio/ganache-cli (using this fork because OpenZeppelin uses it)

How can I test the burning of a token with truffle assertions?

Hello, I am developing my first contract professionally. I am using truffle assertions.
I have doubts about how to test that a token is burnt.
I understand that one option would be to verify that the owner of the token is address 0. How do I do this with truffle assertions? do I need to install another library?
Another option would be to check the balance of the user or the burned token. But this is not clear to me.
If someone can tell me how to do it with truffle assertions.
Thanks

Reverts Test For Calling Same Function Twice Incorrectly Fails

I am making a voting app where user's can call "castVote". If the same user calls it twice then it should revert on the second call.

it('should allow only one vote per user', async () => {

  await subject.castVote(newCandidate.id, { from: voter1 });

  const shouldRevert = await subject.castVote(newCandidate.id, { from: voter1 });

  await truffleAssert.reverts(shouldRevert);
})

The weird thing is that the function does revert, but the test doesn't pass...

Here's the error message I'm seeing for the failing test:

Error: Returned error: VM Exception while processing transaction: revert User has already voted! -- Reason given: User has already voted!.

I would expect this test to pass since it is reverting, and I am expecting it to revert...

Here's the repo for this code: https://github.com/JimLynchCodes/Voting-Example

Thanks!

Indentation of getPrettyEmittedEventsString doesn't always make sense

When adding indentation, getPrettyEmittedEventsString assumes that the test is nested only one level deep, within the contract block. When using Mocha.describe, however, tests may be deeply nested, and therefore require more indentation.

Ideally the indentation given by getPrettyEmittedEventsString would match that of the test itself. If that isn't possible, in my opinion, it might be better not to indent at all.

Output event arguments on assertion failure

Hi,

First of all, I would like to say thank you for this awesome and useful library. I'm currently using it in my work. 🙂

Just curious, why the indexed event parameter is not showing up when test error is happening?

This is what I saw:

Events emitted during test:
---------------------------
LogDeleteUser(userAddress: <indexed>, index: 2)
LogUpdateUser(userAddress: <indexed>, index: 2, userEmail: [email protected], userAge: 32)
---------------------------

Maybe a bug?

createTransactionResult not working with Truffle v5

web3 : 1.0.0-beta.36
truffle : 5.0@next
ganache


createTransactionResult
TypeError: allEvents.get is not a function


tried allEvents.on("data", data =>{} ) but could not catch Event launched from constructor..

Support numeric event parameter

Numeric event parameters (e.g. uint256 in solidity) are represented as bn.js instances. It looks like currently it is not possible to check these numbers, as the equality check is not aware of BN and thus fails.

Ideally i would be able to create a filter Object with BN instances. Assume a transaction emits the event "idEvent" with the parameter "id" being an uint256, i would like to do:

truffleAssert.eventEmitted(result, 'IdEvent', {
    id: new BN('1')
})

Describe alternatives you've considered
Another option would be to check the string representation of a BN instance, so one could write the filter like this:

truffleAssert.eventEmitted(result, 'IdEvent', {
    id: '1'
})

(This is what web3.eth.abi.decodeLog does - any BN instance is decoded to it's string representation)

Add JSDocs or convert to TypeScript

In order for editors to give more useful type hints, we can either add JSDoc comments to the code or we can convert it to TypeScript and export the typings.

See also #37

Capturing multiple events

@rkalis thanks for the great work here.

I am using truffle-assertions in my project but have a hard time figuring out how to extract two separate events from two calls to an oracle that are made one after the other. I am also not really a javascript programmer, so do excuse any mistakes here but this is what I am doing :

contract("sample", async (accounts) => {
  it("do something", async () => {
    let firstCallbackToOracle = await getFirstEvent(oracle.LogResult({fromBlock:'latest'}));
    await truffleAssert.createTransactionResult(oracle, firstCallbackToOracle.transactionHash);
    let secondCallbackToOracle = await getFirstEvent(oracle.LogResult({fromBlock:'latest'}));
    await truffleAssert.createTransactionResult(oracle, secondCallbackToOracle.transactionHash);
  });

  const getFirstEvent = (_event) => {
    return new Promise((resolve, reject) => {
      _event.once('data', resolve).once('error', reject)
    });
  }
});

What I get from such a test in truffle (v5.1.53) is -
Error: Timeout of 300000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

The oracle calls back and I do not see any issue with why a timeout should occur, and I also see test cases with single callbacks work well, and this leads to me think I am doing something wrong with how multiple callbacks have to be listened to and confirmed.

Your advice will be appreciated.

Make "reverts" automatically unpack promises?

Is your feature request related to a problem?

I was writing some tests, and I had forgotten to await the reverts function itself...

Here's the correct syntax:

await truffleAssert.reverts(ownerStorage.getCount.call(accounts[0], { from: accounts[1] }));

I was just writing the function like this:

truffleAssert.reverts(ownerStorage.getCount.call(accounts[0], { from: accounts[1] }));

The problem is that in the second way the function always passes.

It doesn't make a big explosion or fail- instead is passes fine even when the source code does not revert, which is pretty dangerous imo because now your tests are no longer reliably telling you that everything works.

Describe the solution you'd like

Either some kind of compiler error (only when passing in a promise) or syntax hi-lighter warning or something to let people know, "hey, you need to await truffleAssert.reverts in order for it to be doing what you think it's doing".

Make web3 an optional dependency

I use truffle-assertions in a typescript truffle project and it works great. However, it is currently the only package that explicitly adds web3 as a dependency. Without it, my dependency tree would be much smaller. It is usually not needed as it is provided by a global truffle installation. I was wondering if you could make web3 an optional dependency?

truffleAssert.reverts not working but error msg is displayed instead

Describe the bug
When I run a test using truffleAssert.reverts(), I get the following error:

Error: Returned error: VM Exception while processing transaction: revert no more new tickets available -- Reason given: no more new tickets available.

Which is great, because it means the modifier works as expected.
However the test fails, and this should not happen - as this is the exact point I want to prove.

Example test code

it('It should NOT be possible to do buy new tickets if supply has run out', async () => { 
  let t = await instance.buyTicket({ value: 1e+18, from: attendee2 });
  truffleAssert.reverts(t, "no more new tickets available");
});

also tried without reason string -> same result

Expected behavior
test should be successful as revert is thrown correctly.

Environment Information
"truffle": "^5.0.3",
"truffle-assertions": "^0.8.0"

thank you!

PS: Event testing works really fine and helped me a lot, thanks for the great work!

Cannot check events emitted inside a constructor

I'm making ERC20 tokens and I emit a transfer event during the deployment of the contract (transfer of all tokens from address(0) to the owner) and I want to test that the event works well but it's look like it's not the case. (works fine with other blockchain calls like transfer or burn).

let instance = await Metacoin.new(param1);

truffleAssert.prettyPrintEmittedEvents(instance);

return
TypeError: Cannot read property 'length' of undefined

Same for truffleAssert.eventEmitted

Revert reason string not working in Ganache desktop app

I have a function in my Smart Contract that only shall be executed by the Smart Contract owner:

 function test(address _from, address _to, uint256 _value) public returns (bool success) {
    require(msg.sender == contract_owner);
  }

In my test I try to use your truffleAssert.reverts function:

it('should not allow transfers between token holders', async () => {
   const cuatre = await Cuatre.deployed()
   await truffleAssert.reverts(cuatre.transferFrom(accountOne, accountTwo, amount, { from: accountOne }), "only owner")
})

But running the test via truffle test fails with the following output:

  1. Contract: Test Cuatre smart contract
    should not allow transfers between token holders:
    AssertionError: Expected to fail with revert, but failed with: Error: VM Exception while processing transaction: revert
    at fails (node_modules/truffle-assertions/index.js:139:13)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Am I doing something wrong?

Revert reason string not working with Ropsten

Hi,

i have a problem with truffleAssert during truffle test. On local ganache blockchain test is passed because revert string is the same of that indicate in javascript test code. When i run test with the same code on ropsten using truffle-hdwallet-provider module, it returns this error:

AssertionError: Expected to fail with SafeMath: subtraction overflow, but failed with: StatusError: Transaction: 0x9b3b35d6d42be4c8fb17e8e7c540a4090a1d36e0ac7b60f5888662b3c9d19385 exited with an error (status 0).
Please check that the transaction:
- satisfies all conditions set by Solidity require statements.
- does not trigger a Solidity revert statement.

It seems that revert error string is not that indicated in solidity code but a transaction error generic.
How can i fix this, please?

Thanks

Question : also possible to check the index from an event?

What I want to to check that Event-1 is submitted before Event-2.

truffleAssert.eventEmitted(result, 'Event-1', (ev) => {
    return ev.index == 0;
});

truffleAssert.eventEmitted(result, 'Event-2', (ev) => {
    return ev.index == 1;
});

Is this possible?

Change the logic so that a "return" is optional in the "eventEmitted".

Currently I just use the default assertions to check the properties + values from an event:

truffleAssert.eventEmitted(result, 'AddSupplierEvent', (ev) => {
    assert.isNotEmpty(ev.from);
    assert.equal(ev.id, supplier1);
    assert.equal(ev.name, 'Supplier 1');
    return true;
});

What I really would like to write is:

truffleAssert.eventEmitted(result, 'AddSupplierEvent', (ev) => {
    assert.isNotEmpty(ev.from);
    assert.equal(ev.id, supplier1);
    assert.equal(ev.name, 'Supplier 1');
});

Is this possible with a code change?

Version 1.0

For Version 1.0, the package needs the following:

  • Continuous Integration set up
  • Full test coverage
  • All tests passing
  • Graceful handling of incorrect parameter types
  • Linting/Consistent styling
  • Typescript bindings
  • Sustainable solution to #6

can not install with truffle-hdwallet-provider installed

Describe the bug

install fails if truffle-hdwallet-provider is already installed

$ npm install [email protected]
$ npm install npm install truffle-assertions

npm ERR! path /home/sum/DEV/test_HDWalletProvider_nonce/node_modules/web3-providers-ws/node_modules/websocket
npm ERR! code EISGIT
npm ERR! git /home/sum/DEV/test_HDWalletProvider_nonce/node_modules/web3-providers-ws/node_modules/websocket: Appears to be a git repo or submodule.
npm ERR! git     /home/sum/DEV/test_HDWalletProvider_nonce/node_modules/web3-providers-ws/node_modules/websocket
npm ERR! git Refusing to remove it. Update manually,
npm ERR! git or move it out of the way first.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/sum/.npm/_logs/2019-07-19T08_24_41_215Z-debug.log

Example test code

$ npm install [email protected]
$ npm install npm install truffle-assertions

Expected behavior
no error

Environment Information
Truffle v5.0.27 (core: 5.0.27)
Node v10.16.0
[email protected]

2019-07-19T08_24_41_215Z-debug.log

Assigning emitted event parameter to variable

This may sound silly but I am unable to assign an indexed event parameter in a variable.

Let’s say, we have :

var result;
truffleAssert.eventEmitted(tx, EventName, (ev)=> { return ev.param; });

How do we assign ev.param to result ? When I assign it inside the scope of eventEmitted, I get an error stating ‘can’t convert undefined or null to object’. But I also see that the event is emitted in truffle test log.

Another thing I notice is that the truffle test log also prints ‘can’t decode event’ - is getting the ‘can’t assign null to object’ related to this ?

I am using TruffleSuite 5x.

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.