truffle-assertions
Advanced tools
Comparing version 0.7.1 to 0.7.2
156
index.js
const AssertionError = require('assertion-error'); | ||
/* global web3 */ | ||
@@ -7,3 +8,3 @@ /* Creates a new assertion message, containing the passedAssertionMessage and | ||
*/ | ||
createAssertionMessage = (passedMessage, defaultMessage) => { | ||
const createAssertionMessage = (passedMessage, defaultMessage) => { | ||
let assertionMessage = defaultMessage; | ||
@@ -14,5 +15,5 @@ if (passedMessage) { | ||
return assertionMessage; | ||
} | ||
}; | ||
assertEventListNotEmpty = (list, passedMessage, defaultMessage) => { | ||
const assertEventListNotEmpty = (list, passedMessage, defaultMessage) => { | ||
const assertionMessage = createAssertionMessage(passedMessage, defaultMessage); | ||
@@ -22,5 +23,5 @@ if (!Array.isArray(list) || list.length === 0) { | ||
} | ||
} | ||
}; | ||
assertEventListEmpty = (list, passedMessage, defaultMessage) => { | ||
const assertEventListEmpty = (list, passedMessage, defaultMessage) => { | ||
const assertionMessage = createAssertionMessage(passedMessage, defaultMessage); | ||
@@ -30,6 +31,6 @@ if (Array.isArray(list) && list.length !== 0) { | ||
} | ||
} | ||
}; | ||
/* Returns event string in the form of EventType(arg1, arg2, ...) */ | ||
getPrettyEventString = (eventType, args) => { | ||
const getPrettyEventString = (eventType, args) => { | ||
let argString = ''; | ||
@@ -41,3 +42,3 @@ Object.entries(args).forEach(([key, value]) => { | ||
return `${eventType}(${argString})`; | ||
} | ||
}; | ||
@@ -47,21 +48,21 @@ /* Returns a list of all emitted events in a transaction, | ||
*/ | ||
getPrettyEmittedEventsString = (result) => { | ||
const getPrettyEmittedEventsString = (result, indentationSize) => { | ||
const indentation = ' '.repeat(indentationSize); | ||
if (result.logs.length === 0) { | ||
return ` No events emitted in tx ${result.tx}\n`; | ||
return `${indentation}No events emitted in tx ${result.tx}\n`; | ||
} | ||
let string = ` Events emitted in tx ${result.tx}:\n`; | ||
string += ` ----------------------------------------------------------------------------------------\n`; | ||
for (const emittedEvent of result.logs) { | ||
string += ` ${getPrettyEventString(emittedEvent.event, emittedEvent.args)}\n`; | ||
} | ||
string += ` ----------------------------------------------------------------------------------------\n`; | ||
let string = `${indentation}Events emitted in tx ${result.tx}:\n`; | ||
string += `${indentation}----------------------------------------------------------------------------------------\n`; | ||
result.logs.forEach((emittedEvent) => { | ||
string += `${indentation}${getPrettyEventString(emittedEvent.event, emittedEvent.args)}\n`; | ||
}); | ||
string += `${indentation}----------------------------------------------------------------------------------------\n`; | ||
return string; | ||
} | ||
}; | ||
assertEventEmittedFromTxResult = (result, eventType, filter, message) => { | ||
const assertEventEmittedFromTxResult = (result, eventType, filter, message) => { | ||
/* Filter correct event types */ | ||
const events = result.logs.filter((entry) => { | ||
return entry.event === eventType; | ||
}); | ||
//TODO: Move the getPrettyEmittedEventsString to the assertion functions | ||
const events = result.logs.filter(entry => entry.event === eventType); | ||
// TODO: Move the getPrettyEmittedEventsString to the assertion functions | ||
assertEventListNotEmpty(events, message, `Event of type ${eventType} was not emitted\n${getPrettyEmittedEventsString(result)}`); | ||
@@ -75,17 +76,14 @@ | ||
/* Filter correct arguments */ | ||
let eventArgs = events.map((entry) => { | ||
return entry.args; | ||
}); | ||
let eventArgs = events.map(entry => entry.args); | ||
eventArgs = eventArgs.filter(filter); | ||
assertEventListNotEmpty(eventArgs, message, `Event filter for ${eventType} returned no results\n${getPrettyEmittedEventsString(result)}`); | ||
} | ||
}; | ||
assertEventNotEmittedFromTxResult = (result, eventType, filter, message) => { | ||
const assertEventNotEmittedFromTxResult = (result, eventType, filter, message) => { | ||
/* Filter correct event types */ | ||
const events = result.logs.filter((entry) => { | ||
return entry.event === eventType; | ||
}); | ||
const events = result.logs.filter(entry => entry.event === eventType); | ||
/* Only check filtered events if there is no provided filter function */ | ||
if (filter == undefined || filter === null) { | ||
if (filter === undefined || filter === null) { | ||
assertEventListEmpty(events, message, `Event of type ${eventType} was emitted\n${getPrettyEmittedEventsString(result)}`); | ||
@@ -96,10 +94,8 @@ return; | ||
/* Filter correct arguments */ | ||
let eventArgs = events.map((entry) => { | ||
return entry.args; | ||
}); | ||
let eventArgs = events.map(entry => entry.args); | ||
eventArgs = eventArgs.filter(filter); | ||
assertEventListEmpty(eventArgs, message, `Event filter for ${eventType} returned results\n${getPrettyEmittedEventsString(result)}`); | ||
} | ||
}; | ||
createTransactionResult = async (contract, transactionHash) => { | ||
const createTransactionResult = async (contract, transactionHash) => { | ||
/* Web3 1.x uses contract.getPastEvents, Web3 0.x uses contract.allEvents() */ | ||
@@ -110,25 +106,25 @@ /* TODO: truffle-assertions 1.0 will only support Web3 1.x / Truffle v5 */ | ||
const { blockNumber } = transactionReceipt; | ||
const eventList = await contract.getPastEvents("allEvents", {fromBlock: blockNumber, toBlock: blockNumber}); | ||
const eventList = await contract.getPastEvents('allEvents', { fromBlock: blockNumber, toBlock: blockNumber }); | ||
return { | ||
tx: transactionHash, | ||
receipt: transactionReceipt, | ||
logs: eventList.filter(ev => ev.transactionHash === transactionHash) | ||
logs: eventList.filter(ev => ev.transactionHash === transactionHash), | ||
}; | ||
} else { | ||
return new Promise((resolve, reject) => { | ||
const transactionReceipt = web3.eth.getTransactionReceipt(transactionHash); | ||
const { blockNumber } = transactionReceipt; | ||
contract.allEvents({fromBlock: blockNumber, toBlock: blockNumber}).get((error, events) => { | ||
if (error) reject(error); | ||
resolve({ | ||
tx: transactionHash, | ||
receipt: transactionReceipt, | ||
logs: events.filter(ev => ev.transactionHash === transactionHash) | ||
}); | ||
} | ||
return new Promise((resolve, reject) => { | ||
const transactionReceipt = web3.eth.getTransactionReceipt(transactionHash); | ||
const { blockNumber } = transactionReceipt; | ||
contract.allEvents({ fromBlock: blockNumber, toBlock: blockNumber }).get((error, events) => { | ||
if (error) reject(error); | ||
resolve({ | ||
tx: transactionHash, | ||
receipt: transactionReceipt, | ||
logs: events.filter(ev => ev.transactionHash === transactionHash), | ||
}); | ||
}); | ||
} | ||
} | ||
}); | ||
}; | ||
passes = async (asyncFn, message) => { | ||
const passes = async (asyncFn, message) => { | ||
try { | ||
@@ -140,12 +136,14 @@ await asyncFn; | ||
} | ||
} | ||
}; | ||
fails = async (asyncFn, errorType, reason, message) => { | ||
const fails = async (asyncFn, errorType, reason, message) => { | ||
try { | ||
await asyncFn; | ||
} catch (error) { | ||
if (errorType && !error.message.includes(errorType) || | ||
reason && !error.message.includes(reason)) { | ||
if (errorType && !error.message.includes(errorType)) { | ||
const assertionMessage = createAssertionMessage(message, `Expected to fail with ${errorType}, but failed with: ${error}`); | ||
throw new AssertionError(assertionMessage); | ||
} else if (reason && !error.message.includes(reason)) { | ||
const assertionMessage = createAssertionMessage(message, `Expected to fail with ${reason}, but failed with: ${error}`); | ||
throw new AssertionError(assertionMessage); | ||
} | ||
@@ -157,10 +155,10 @@ // Error was handled by errorType or reason | ||
throw new AssertionError(assertionMessage); | ||
} | ||
}; | ||
ErrorType = { | ||
REVERT: "revert", | ||
INVALID_OPCODE: "invalid opcode", | ||
OUT_OF_GAS: "out of gas", | ||
INVALID_JUMP: "invalid JUMP" | ||
} | ||
const ErrorType = { | ||
REVERT: 'revert', | ||
INVALID_OPCODE: 'invalid opcode', | ||
OUT_OF_GAS: 'out of gas', | ||
INVALID_JUMP: 'invalid JUMP', | ||
}; | ||
@@ -174,18 +172,18 @@ module.exports = { | ||
}, | ||
prettyPrintEmittedEvents: (result) => { | ||
console.log(getPrettyEmittedEventsString(result)); | ||
prettyPrintEmittedEvents: (result, indentationSize) => { | ||
console.log(getPrettyEmittedEventsString(result, indentationSize)); | ||
}, | ||
createTransactionResult: (contract, transactionHash) => { | ||
return createTransactionResult(contract, transactionHash); | ||
}, | ||
passes: async (asyncFn, message) => { | ||
return passes(asyncFn, message); | ||
}, | ||
fails: async (asyncFn, errorType, reason, message) => { | ||
return fails(asyncFn, errorType, reason, message); | ||
}, | ||
reverts: async (asyncFn, reason, message) => { | ||
return fails(asyncFn, ErrorType.REVERT, reason, message); | ||
}, | ||
ErrorType: ErrorType | ||
} | ||
createTransactionResult: (contract, transactionHash) => ( | ||
createTransactionResult(contract, transactionHash) | ||
), | ||
passes: async (asyncFn, message) => ( | ||
passes(asyncFn, message) | ||
), | ||
fails: async (asyncFn, errorType, reason, message) => ( | ||
fails(asyncFn, errorType, reason, message) | ||
), | ||
reverts: async (asyncFn, reason, message) => ( | ||
fails(asyncFn, ErrorType.REVERT, reason, message) | ||
), | ||
ErrorType, | ||
}; |
{ | ||
"name": "truffle-assertions", | ||
"version": "0.7.1", | ||
"version": "0.7.2", | ||
"description": "Additional assertions and utilities for testing Ethereum smart contracts in Truffle unit tests", | ||
@@ -9,3 +9,10 @@ "main": "index.js", | ||
], | ||
"scripts": {}, | ||
"scripts": { | ||
"test": "nyc mocha", | ||
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov", | ||
"lint": "eslint index.js test/*.js" | ||
}, | ||
"nyc": { | ||
"temp-directory": "./node_modules/.nyc_output" | ||
}, | ||
"keywords": [ | ||
@@ -33,3 +40,15 @@ "truffle", | ||
"web3": "^1.0.0-beta.35" | ||
}, | ||
"devDependencies": { | ||
"chai": "^4.2.0", | ||
"chai-as-promised": "^7.1.1", | ||
"codecov": "^3.1.0", | ||
"coveralls": "^3.0.2", | ||
"eslint": "^5.6.1", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-plugin-import": "^2.14.0", | ||
"mocha": "^5.2.0", | ||
"nyc": "^13.0.1", | ||
"sinon": "^7.1.1" | ||
} | ||
} |
# truffle-assertions | ||
[![npm version](https://badge.fury.io/js/truffle-assertions.svg)](https://www.npmjs.com/package/truffle-assertions) | ||
[![npm](https://img.shields.io/npm/dt/truffle-assertions.svg)](https://www.npmjs.com/package/truffle-assertions) | ||
[![npm](https://img.shields.io/npm/l/truffle-assertions.svg)](https://www.npmjs.com/package/truffle-assertions) | ||
[![Build Status](https://travis-ci.org/rkalis/truffle-assertions.svg)](https://travis-ci.org/rkalis/truffle-assertions) | ||
[![Coverage Status](https://img.shields.io/codecov/c/github/rkalis/truffle-assertions.svg)](https://codecov.io/gh/rkalis/truffle-assertions/) | ||
[![NPM Version](https://img.shields.io/npm/v/truffle-assertions.svg)](https://www.npmjs.com/package/truffle-assertions) | ||
[![NPM Monthly Downloads](https://img.shields.io/npm/dm/truffle-assertions.svg)](https://www.npmjs.com/package/truffle-assertions) | ||
[![NPM License](https://img.shields.io/npm/l/truffle-assertions.svg)](https://www.npmjs.com/package/truffle-assertions) | ||
@@ -209,3 +211,7 @@ This package adds additional assertions that can be used to test Ethereum smart contracts inside Truffle tests. | ||
## Related projects | ||
- [truffle-events](https://github.com/zulhfreelancer/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`. |
17192
217
10
158