UNPKG

@ethereum-waffle/chai

Version:

A sweet set of chai matchers for your blockchain testing needs.

81 lines 4.14 kB
import { utils } from 'ethers'; import { keccak256, toUtf8Bytes } from 'ethers/lib/utils'; import { callPromise } from '../call-promise'; import { waitForPendingTransaction } from './misc/transaction'; import { supportWithArgs } from './withArgs'; import { supportWithNamedArgs } from './withNamedArgs'; export function supportEmit(Assertion) { const filterLogsWithTopics = (logs, topic, contractAddress) => logs.filter((log) => log.topics.includes(topic)) .filter((log) => log.address && (contractAddress === undefined || log.address.toLowerCase() === contractAddress.toLowerCase())); const assertEmit = (assertion, frag, isNegated, from) => { const topic = keccak256(toUtf8Bytes(frag.format())); const receipt = assertion.txReceipt; assertion.args = filterLogsWithTopics(receipt.logs, topic, from); const isCurrentlyNegated = assertion.__flags.negate === true; assertion.__flags.negate = isNegated; assertion.assert(assertion.args.length > 0, `Expected event "${frag.name}" to be emitted, but it wasn't`, `Expected event "${frag.name}" NOT to be emitted, but it was`); assertion.__flags.negate = isCurrentlyNegated; }; Assertion.addMethod('emit', function (contractOrEventSig, eventName) { if (typeof this._obj === 'string') { if (typeof contractOrEventSig === 'string') { throw new Error('The emit by event signature matcher must be called on a transaction'); } // Handle specific case of using transaction hash to specify transaction. Done for backwards compatibility. this.callPromise = waitForPendingTransaction(this._obj, contractOrEventSig.provider) .then(txReceipt => { this.txReceipt = txReceipt; }); } else { callPromise(this); } const isNegated = this.__flags.negate === true; this.callPromise = this.callPromise.then(() => { if (!('txReceipt' in this)) { throw new Error('The emit matcher must be called on a transaction'); } let eventFragment; if (typeof contractOrEventSig === 'string') { try { eventFragment = utils.EventFragment.from(contractOrEventSig); } catch (e) { throw new Error(`Invalid event signature: "${contractOrEventSig}"`); } assertEmit(this, eventFragment, isNegated); } else if (eventName) { try { eventFragment = contractOrEventSig.interface.getEvent(eventName); } catch (e) { // ignore error } if (eventFragment === undefined) { this.assert(this.__flags.negate, `Expected event "${eventName}" to be emitted, but it doesn't` + ' exist in the contract. Please make sure you\'ve compiled' + ' its latest version before running the test.', `WARNING: Expected event "${eventName}" NOT to be emitted.` + ' The event wasn\'t emitted because it doesn\'t' + ' exist in the contract. Please make sure you\'ve compiled' + ' its latest version before running the test.', eventName, ''); return; } assertEmit(this, eventFragment, isNegated, contractOrEventSig.address); this.contract = contractOrEventSig; } else { throw new Error('The emit matcher must be called with a contract and an event name or an event signature'); } }); this.then = this.callPromise.then.bind(this.callPromise); this.catch = this.callPromise.catch.bind(this.callPromise); this.eventName = eventName; this.txMatcher = 'emit'; return this; }); supportWithArgs(Assertion); supportWithNamedArgs(Assertion); } //# sourceMappingURL=emit.js.map