@ensdomains/hardhat-chai-matchers-viem 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/esm/constants.js +21 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/errors.js +21 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/matchers/constants.js +21 -0
- package/dist/esm/matchers/constants.js.map +1 -0
- package/dist/esm/matchers/contract.js +49 -0
- package/dist/esm/matchers/contract.js.map +1 -0
- package/dist/esm/matchers/toBeReverted.js +81 -0
- package/dist/esm/matchers/toBeReverted.js.map +1 -0
- package/dist/esm/matchers/toBeRevertedWithCustomError.js +94 -0
- package/dist/esm/matchers/toBeRevertedWithCustomError.js.map +1 -0
- package/dist/esm/matchers/toBeRevertedWithPanic.js +80 -0
- package/dist/esm/matchers/toBeRevertedWithPanic.js.map +1 -0
- package/dist/esm/matchers/toBeRevertedWithString.js +75 -0
- package/dist/esm/matchers/toBeRevertedWithString.js.map +1 -0
- package/dist/esm/matchers/toBeRevertedWithoutReason.js +65 -0
- package/dist/esm/matchers/toBeRevertedWithoutReason.js.map +1 -0
- package/dist/esm/matchers/toEmitEvent.js +94 -0
- package/dist/esm/matchers/toEmitEvent.js.map +1 -0
- package/dist/esm/matchers/utils/assertIsNotNull.js +7 -0
- package/dist/esm/matchers/utils/assertIsNotNull.js.map +1 -0
- package/dist/esm/matchers/utils/buildAssert.js +36 -0
- package/dist/esm/matchers/utils/buildAssert.js.map +1 -0
- package/dist/esm/matchers/utils/getCallFlag.js +16 -0
- package/dist/esm/matchers/utils/getCallFlag.js.map +1 -0
- package/dist/esm/matchers/utils/getReturnDataFromError.js +53 -0
- package/dist/esm/matchers/utils/getReturnDataFromError.js.map +1 -0
- package/dist/esm/matchers/utils/getRevertErrorData.js +13 -0
- package/dist/esm/matchers/utils/getRevertErrorData.js.map +1 -0
- package/dist/esm/matchers/utils/getTransactionReceipt.js +6 -0
- package/dist/esm/matchers/utils/getTransactionReceipt.js.map +1 -0
- package/dist/esm/matchers/utils/isValidTransactionHash.js +6 -0
- package/dist/esm/matchers/utils/isValidTransactionHash.js.map +1 -0
- package/dist/esm/matchers/utils/matchArgs.js +32 -0
- package/dist/esm/matchers/utils/matchArgs.js.map +1 -0
- package/dist/esm/matchers/utils.js +37 -0
- package/dist/esm/matchers/utils.js.map +1 -0
- package/dist/esm/matchers/withArgs.js +11 -0
- package/dist/esm/matchers/withArgs.js.map +1 -0
- package/dist/esm/matchers.js +21 -0
- package/dist/esm/matchers.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/constants.d.ts +16 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/errors.d.ts +15 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/matchers/constants.d.ts +11 -0
- package/dist/types/matchers/constants.d.ts.map +1 -0
- package/dist/types/matchers/contract.d.ts +2 -0
- package/dist/types/matchers/contract.d.ts.map +1 -0
- package/dist/types/matchers/toBeReverted.d.ts +2 -0
- package/dist/types/matchers/toBeReverted.d.ts.map +1 -0
- package/dist/types/matchers/toBeRevertedWithCustomError.d.ts +2 -0
- package/dist/types/matchers/toBeRevertedWithCustomError.d.ts.map +1 -0
- package/dist/types/matchers/toBeRevertedWithPanic.d.ts +2 -0
- package/dist/types/matchers/toBeRevertedWithPanic.d.ts.map +1 -0
- package/dist/types/matchers/toBeRevertedWithString.d.ts +2 -0
- package/dist/types/matchers/toBeRevertedWithString.d.ts.map +1 -0
- package/dist/types/matchers/toBeRevertedWithoutReason.d.ts +2 -0
- package/dist/types/matchers/toBeRevertedWithoutReason.d.ts.map +1 -0
- package/dist/types/matchers/toEmitEvent.d.ts +2 -0
- package/dist/types/matchers/toEmitEvent.d.ts.map +1 -0
- package/dist/types/matchers/utils/assertIsNotNull.d.ts +2 -0
- package/dist/types/matchers/utils/assertIsNotNull.d.ts.map +1 -0
- package/dist/types/matchers/utils/buildAssert.d.ts +24 -0
- package/dist/types/matchers/utils/buildAssert.d.ts.map +1 -0
- package/dist/types/matchers/utils/getCallFlag.d.ts +8 -0
- package/dist/types/matchers/utils/getCallFlag.d.ts.map +1 -0
- package/dist/types/matchers/utils/getReturnDataFromError.d.ts +48 -0
- package/dist/types/matchers/utils/getReturnDataFromError.d.ts.map +1 -0
- package/dist/types/matchers/utils/getRevertErrorData.d.ts +2 -0
- package/dist/types/matchers/utils/getRevertErrorData.d.ts.map +1 -0
- package/dist/types/matchers/utils/getTransactionReceipt.d.ts +3 -0
- package/dist/types/matchers/utils/getTransactionReceipt.d.ts.map +1 -0
- package/dist/types/matchers/utils/isValidTransactionHash.d.ts +3 -0
- package/dist/types/matchers/utils/isValidTransactionHash.d.ts.map +1 -0
- package/dist/types/matchers/utils/matchArgs.d.ts +7 -0
- package/dist/types/matchers/utils/matchArgs.d.ts.map +1 -0
- package/dist/types/matchers/utils.d.ts +12 -0
- package/dist/types/matchers/utils.d.ts.map +1 -0
- package/dist/types/matchers/withArgs.d.ts +2 -0
- package/dist/types/matchers/withArgs.d.ts.map +1 -0
- package/dist/types/matchers.d.ts +2 -0
- package/dist/types/matchers.d.ts.map +1 -0
- package/dist/types/types.d.ts +107 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +51 -0
- package/src/constants.ts +25 -0
- package/src/errors.ts +25 -0
- package/src/index.ts +7 -0
- package/src/matchers/constants.ts +25 -0
- package/src/matchers/contract.ts +89 -0
- package/src/matchers/toBeReverted.ts +103 -0
- package/src/matchers/toBeRevertedWithCustomError.ts +136 -0
- package/src/matchers/toBeRevertedWithPanic.ts +110 -0
- package/src/matchers/toBeRevertedWithString.ts +103 -0
- package/src/matchers/toBeRevertedWithoutReason.ts +83 -0
- package/src/matchers/toEmitEvent.ts +159 -0
- package/src/matchers/utils/assertIsNotNull.ts +12 -0
- package/src/matchers/utils/buildAssert.ts +58 -0
- package/src/matchers/utils/getCallFlag.ts +20 -0
- package/src/matchers/utils/getReturnDataFromError.ts +61 -0
- package/src/matchers/utils/getRevertErrorData.ts +15 -0
- package/src/matchers/utils/getTransactionReceipt.ts +8 -0
- package/src/matchers/utils/isValidTransactionHash.ts +6 -0
- package/src/matchers/utils/matchArgs.ts +42 -0
- package/src/matchers/utils.ts +88 -0
- package/src/matchers/withArgs.ts +17 -0
- package/src/matchers.ts +24 -0
- package/src/types.ts +233 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 ENS Labs Limited
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# hardhat-chai-matchers-viem
|
|
2
|
+
|
|
3
|
+
## This plugin is based on the existing `@nomicfoundation/hardhat-chai-matchers`. If you are using ethers, you should use that instead.
|
|
4
|
+
|
|
5
|
+
### Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @ensdomains/hardhat-chai-matchers-viem
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
In your hardhat config:
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import("@ensdomains/hardhat-chai-matchers-viem");
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Getting started
|
|
18
|
+
|
|
19
|
+
Deploy contracts with `deployContract` and pass them into `expect` to use matchers from this plugin:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { expect } from "chai";
|
|
23
|
+
import hre from "hardhat";
|
|
24
|
+
|
|
25
|
+
it("works", async () => {
|
|
26
|
+
const example = await hre.viem.deployContract("ExampleContract", []);
|
|
27
|
+
await expect(example)
|
|
28
|
+
.write("revertWithSomeCustomError")
|
|
29
|
+
.toBeRevertedWithCustomError("SomeCustomError");
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
To speed up tests, you should use hardhat fixtures:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
|
|
37
|
+
import { expect } from "chai";
|
|
38
|
+
import hre from "hardhat";
|
|
39
|
+
|
|
40
|
+
async function deployExample() {
|
|
41
|
+
const example = await hre.viem.deployContract("ExampleContract", []);
|
|
42
|
+
return example;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
it("works", async () => {
|
|
46
|
+
const example = await loadFixture(deployExample);
|
|
47
|
+
await expect(example)
|
|
48
|
+
.write("revertWithSomeCustomError")
|
|
49
|
+
.toBeRevertedWithCustomError("SomeCustomError");
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Available matchers
|
|
54
|
+
|
|
55
|
+
- `expect(contract).read(...)`
|
|
56
|
+
- `expect(contract).write(...)`
|
|
57
|
+
- `.toBeReverted()`
|
|
58
|
+
- `.toBeRevertedWithCustomError(...)`
|
|
59
|
+
- `.withArgs(...)`
|
|
60
|
+
- `.toBeRevertedWithoutReason()`
|
|
61
|
+
- `.toBeRevertedWithPanic(...)`
|
|
62
|
+
- `.toBeRevertedWithString(...)`
|
|
63
|
+
- `.toEmitEvent(...)`
|
|
64
|
+
- `.withArgs(...)`
|
|
65
|
+
- `.toEmitEventFrom(...)`
|
|
66
|
+
- `.withArgs(...)`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// https://docs.soliditylang.org/en/v0.8.16/control-structures.html#panic-via-assert-and-error-via-require
|
|
2
|
+
export const panicReasons = {
|
|
3
|
+
1: "An `assert` condition failed",
|
|
4
|
+
17: "Arithmetic operation resulted in underflow or overflow",
|
|
5
|
+
18: "Division or modulo by zero (e.g. `5 / 0` or `23 % 0`)",
|
|
6
|
+
33: "Attempted to convert to an invalid type",
|
|
7
|
+
34: "Attempted to access a storage byte array that is incorrectly encoded",
|
|
8
|
+
49: "Performed `.pop()` on an empty array",
|
|
9
|
+
50: "Array index is out of bounds",
|
|
10
|
+
65: "Allocated too much memory or created an array which is too large",
|
|
11
|
+
81: "Attempted to call a zero-initialized variable of internal function type",
|
|
12
|
+
};
|
|
13
|
+
export const maxKnownPanicCode = 81;
|
|
14
|
+
export const getKnownPanicReason = (code) => {
|
|
15
|
+
if (code <= maxKnownPanicCode) {
|
|
16
|
+
return panicReasons[Number(code)];
|
|
17
|
+
}
|
|
18
|
+
return "Unknown panic code";
|
|
19
|
+
};
|
|
20
|
+
export const anyValueSymbol = Symbol.for("hh-viem-chai-matchers:anyValue");
|
|
21
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,CAAC,EAAE,8BAA8B;IACjC,EAAE,EAAE,wDAAwD;IAC5D,EAAE,EAAE,uDAAuD;IAC3D,EAAE,EAAE,yCAAyC;IAC7C,EAAE,EAAE,sEAAsE;IAC1E,EAAE,EAAE,sCAAsC;IAC1C,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,kEAAkE;IACtE,EAAE,EAAE,yEAAyE;CACrE,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAW,CAAC;AAE7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAClD,IAAI,IAAI,IAAI,iBAAiB,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAc,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,oBAA6B,CAAC;AACvC,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HardhatPluginError } from "hardhat/plugins.js";
|
|
2
|
+
export class HardhatChaiMatchersError extends HardhatPluginError {
|
|
3
|
+
constructor(message, parent) {
|
|
4
|
+
super("hardhat-chai-viem-matchers", message, parent);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* This class is used to assert assumptions in our implementation. Chai's
|
|
9
|
+
* AssertionError should be used for user assertions.
|
|
10
|
+
*/
|
|
11
|
+
export class HardhatChaiMatchersAssertionError extends HardhatChaiMatchersError {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(`Assertion error: ${message}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class HardhatChaiMatchersNonChainableMatcherError extends HardhatChaiMatchersError {
|
|
17
|
+
constructor(matcherName, previousMatcherName) {
|
|
18
|
+
super(`The matcher '${matcherName}' cannot be chained after '${previousMatcherName}'. For more information, please refer to the documentation at: https://hardhat.org/chaining-async-matchers.`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,OAAO,wBAAyB,SAAQ,kBAAkB;IAC9D,YAAY,OAAe,EAAE,MAAc;QACzC,KAAK,CAAC,4BAA4B,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,iCAAkC,SAAQ,wBAAwB;IAC7E,YAAY,OAAe;QACzB,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,2CAA4C,SAAQ,wBAAwB;IACvF,YAAY,WAAmB,EAAE,mBAA2B;QAC1D,KAAK,CACH,gBAAgB,WAAW,8BAA8B,mBAAmB,6GAA6G,CAC1L,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,YAAY,CAAC;AAEpB,GAAG,CAAC,cAAc,CAAC,CAAC;AACpB,GAAG,CAAC,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// export const ASSERTION_ABORTED = "hh-chai-matchers-assertion-aborted";
|
|
2
|
+
export const PREVIOUS_MATCHER_NAME = "previousMatcherName";
|
|
3
|
+
// export const CHANGE_ETHER_BALANCE_MATCHER = "changeEtherBalance";
|
|
4
|
+
// export const CHANGE_ETHER_BALANCES_MATCHER = "changeEtherBalances";
|
|
5
|
+
// export const CHANGE_TOKEN_BALANCE_MATCHER = "changeTokenBalance";
|
|
6
|
+
// export const CHANGE_TOKEN_BALANCES_MATCHER = "changeTokenBalances";
|
|
7
|
+
// export const EMIT_MATCHER = "emit";
|
|
8
|
+
export const TO_BE_REVERTED_MATCHER = "toBeReverted";
|
|
9
|
+
export const TO_BE_REVERTED_WITH_CUSTOM_ERROR_MATCHER = "toBeRevertedWithCustomError";
|
|
10
|
+
export const TO_BE_REVERTED_WITHOUT_REASON_MATCHER = "toBeRevertedWithoutReason";
|
|
11
|
+
export const TO_BE_REVERTED_WITH_PANIC_MATCHER = "toBeRevertedWithPanic";
|
|
12
|
+
export const TO_BE_REVERTED_WITH_STRING_MATCHER = "toBeRevertedWithString";
|
|
13
|
+
export const TO_EMIT_EVENT_MATCHER = "toEmitEvent";
|
|
14
|
+
export const TO_EMIT_EVENT_FROM_MATCHER = "toEmitEventFrom";
|
|
15
|
+
export const WRITE_MATCHER = "write";
|
|
16
|
+
export const READ_MATCHER = "read";
|
|
17
|
+
// export const REVERTED_WITH_MATCHER = "revertedWith";
|
|
18
|
+
// export const REVERTED_WITH_CUSTOM_ERROR_MATCHER = "revertedWithCustomError";
|
|
19
|
+
// export const REVERTED_WITH_PANIC_MATCHER = "revertedWithPanic";
|
|
20
|
+
// export const REVERTED_WITHOUT_REASON_MATCHER = "revertedWithoutReason";
|
|
21
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/matchers/constants.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAA8B,CAAC;AAEpE,oEAAoE;AACpE,sEAAsE;AACtE,oEAAoE;AACpE,sEAAsE;AACtE,sCAAsC;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,cAAuB,CAAC;AAC9D,MAAM,CAAC,MAAM,wCAAwC,GACnD,6BAAsC,CAAC;AACzC,MAAM,CAAC,MAAM,qCAAqC,GAChD,2BAAoC,CAAC;AACvC,MAAM,CAAC,MAAM,iCAAiC,GAC5C,uBAAgC,CAAC;AACnC,MAAM,CAAC,MAAM,kCAAkC,GAC7C,wBAAiC,CAAC;AACpC,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAsB,CAAC;AAC5D,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAA0B,CAAC;AACrE,MAAM,CAAC,MAAM,aAAa,GAAG,OAAgB,CAAC;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAe,CAAC;AAC5C,uDAAuD;AACvD,+EAA+E;AAC/E,kEAAkE;AAClE,0EAA0E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { READ_MATCHER, WRITE_MATCHER } from "./constants.js";
|
|
2
|
+
import { getNegated, setReadResult, setWriteResult } from "./utils.js";
|
|
3
|
+
export function supportContract(Assertion) {
|
|
4
|
+
Assertion.addMethod(WRITE_MATCHER, function (...matcherArgs) {
|
|
5
|
+
const negated = getNegated(this);
|
|
6
|
+
if (negated) {
|
|
7
|
+
throw new Error("The `write` matcher cannot be negated");
|
|
8
|
+
}
|
|
9
|
+
const subject = this._obj;
|
|
10
|
+
if (!subject || typeof subject !== "object") {
|
|
11
|
+
throw new Error("The `write` matcher can only be used with a contract");
|
|
12
|
+
}
|
|
13
|
+
if (!("write" in subject) ||
|
|
14
|
+
typeof subject["write"] !== "object" ||
|
|
15
|
+
!subject["write"]) {
|
|
16
|
+
throw new Error("The `write` matcher can only be used with a contract that has write functions");
|
|
17
|
+
}
|
|
18
|
+
const [functionName, ...argsAndOptions] = matcherArgs;
|
|
19
|
+
if (typeof functionName !== "string") {
|
|
20
|
+
throw new Error("The `write` matcher must be called with a function name");
|
|
21
|
+
}
|
|
22
|
+
const writeFunction = subject["write"][functionName];
|
|
23
|
+
setWriteResult(this, writeFunction(...argsAndOptions));
|
|
24
|
+
return this;
|
|
25
|
+
});
|
|
26
|
+
Assertion.addMethod(READ_MATCHER, function (...matcherArgs) {
|
|
27
|
+
const negated = getNegated(this);
|
|
28
|
+
if (negated) {
|
|
29
|
+
throw new Error("The `read` matcher cannot be negated");
|
|
30
|
+
}
|
|
31
|
+
const subject = this._obj;
|
|
32
|
+
if (!subject || typeof subject !== "object") {
|
|
33
|
+
throw new Error("The `read` matcher can only be used with a contract");
|
|
34
|
+
}
|
|
35
|
+
if (!("read" in subject) ||
|
|
36
|
+
typeof subject["read"] !== "object" ||
|
|
37
|
+
!subject["read"]) {
|
|
38
|
+
throw new Error("The `read` matcher can only be used with a contract that has read functions");
|
|
39
|
+
}
|
|
40
|
+
const [functionName, ...argsAndOptions] = matcherArgs;
|
|
41
|
+
if (typeof functionName !== "string") {
|
|
42
|
+
throw new Error("The `read` matcher must be called with a function name");
|
|
43
|
+
}
|
|
44
|
+
const readFunction = subject["read"][functionName];
|
|
45
|
+
setReadResult(this, readFunction(...argsAndOptions));
|
|
46
|
+
return this;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/matchers/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvE,MAAM,UAAU,eAAe,CAAC,SAA+B;IAC7D,SAAS,CAAC,SAAS,CACjB,aAAa,EACb,UAAsC,GAAG,WAAsB;QAC7D,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,OAAO,GAAY,IAAI,CAAC,IAAI,CAAC;QAEnC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QAED,IACE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;YACrB,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,QAAQ;YACpC,CAAC,OAAO,CAAC,OAAO,CAAC,EACjB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,YAAY,EAAE,GAAG,cAAc,CAAC,GAAG,WAAW,CAAC;QAEtD,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CACpC,YAA+C,CACI,CAAC;QAEtD,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;QAEvD,OAAO,IAAI,CAAC;IACd,CAAC,CACF,CAAC;IACF,SAAS,CAAC,SAAS,CACjB,YAAY,EACZ,UAAsC,GAAG,WAAsB;QAC7D,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,OAAO,GAAY,IAAI,CAAC,IAAI,CAAC;QAEnC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QAED,IACE,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC;YACpB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,QAAQ;YACnC,CAAC,OAAO,CAAC,MAAM,CAAC,EAChB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,YAAY,EAAE,GAAG,cAAc,CAAC,GAAG,WAAW,CAAC;QAEtD,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CACb,wDAAwD,CACzD,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAClC,YAA8C,CACK,CAAC;QAEtD,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;QAErD,OAAO,IAAI,CAAC;IACd,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { TO_BE_REVERTED_MATCHER } from "./constants.js";
|
|
2
|
+
import { getNegated, preventAsyncMatcherChaining } from "./utils.js";
|
|
3
|
+
import { assertIsNotNull } from "./utils/assertIsNotNull.js";
|
|
4
|
+
import { buildAssert } from "./utils/buildAssert.js";
|
|
5
|
+
import { getCall } from "./utils/getCallFlag.js";
|
|
6
|
+
import { getReturnDataFromError } from "./utils/getReturnDataFromError.js";
|
|
7
|
+
import { getTransactionReceipt } from "./utils/getTransactionReceipt.js";
|
|
8
|
+
import { isValidTransactionHash } from "./utils/isValidTransactionHash.js";
|
|
9
|
+
export function supportReverted(Assertion) {
|
|
10
|
+
Assertion.addMethod(TO_BE_REVERTED_MATCHER, async function () {
|
|
11
|
+
const negated = getNegated(this);
|
|
12
|
+
const subject = this._obj;
|
|
13
|
+
preventAsyncMatcherChaining(this, {
|
|
14
|
+
matcherName: TO_BE_REVERTED_MATCHER,
|
|
15
|
+
});
|
|
16
|
+
const functionCall = getCall(this, TO_BE_REVERTED_MATCHER);
|
|
17
|
+
const onSuccess = async (value) => {
|
|
18
|
+
const assert = buildAssert(!!negated, onSuccess);
|
|
19
|
+
if (functionCall.kind === "read") {
|
|
20
|
+
assert({
|
|
21
|
+
condition: false,
|
|
22
|
+
messageFalse: "Expected transaction to be reverted",
|
|
23
|
+
messageTrue: "Expected transaction NOT to be reverted",
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!isValidTransactionHash(value))
|
|
28
|
+
throw new TypeError(`Expected a valid transaction hash, but got '${value}'`);
|
|
29
|
+
const receipt = await getTransactionReceipt(value);
|
|
30
|
+
assertIsNotNull(receipt, "receipt");
|
|
31
|
+
assert({
|
|
32
|
+
condition: receipt.status === "reverted",
|
|
33
|
+
messageFalse: "Expected transaction to be reverted",
|
|
34
|
+
messageTrue: "Expected transaction NOT to be reverted",
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const onError = (error) => {
|
|
38
|
+
const assert = buildAssert(!!negated, onError);
|
|
39
|
+
const returnData = getReturnDataFromError(subject, error);
|
|
40
|
+
if (returnData.kind === "unknown-local")
|
|
41
|
+
throw error;
|
|
42
|
+
if (returnData.kind === "empty") {
|
|
43
|
+
assert({
|
|
44
|
+
condition: true,
|
|
45
|
+
messageTrue: "Expected transaction NOT to be reverted",
|
|
46
|
+
});
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (returnData.kind === "unknown-contract") {
|
|
50
|
+
assert({
|
|
51
|
+
condition: true,
|
|
52
|
+
messageTrue: `Expected transaction NOT to be reverted, but it reverted with unknown error`,
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (returnData.kind === "panic") {
|
|
57
|
+
assert({
|
|
58
|
+
condition: true,
|
|
59
|
+
messageTrue: `Expected transaction NOT to be reverted, but it reverted with panic code ${returnData.code} (${returnData.description})`,
|
|
60
|
+
});
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (returnData.kind === "error") {
|
|
64
|
+
assert({
|
|
65
|
+
condition: true,
|
|
66
|
+
messageTrue: `Expected transaction NOT to be reverted, but it reverted with reason '${returnData.reason}'`,
|
|
67
|
+
});
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
assert({
|
|
71
|
+
condition: true,
|
|
72
|
+
messageTrue: `Expected transaction NOT to be reverted, but it reverted with custom error '${returnData.name}'`,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const derivedPromise = functionCall.promise.then(onSuccess, onError);
|
|
76
|
+
this.then = derivedPromise.then.bind(derivedPromise);
|
|
77
|
+
this.catch = derivedPromise.catch.bind(derivedPromise);
|
|
78
|
+
return this;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=toBeReverted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBeReverted.js","sourceRoot":"","sources":["../../../src/matchers/toBeReverted.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAE3E,MAAM,UAAU,eAAe,CAAC,SAA+B;IAC7D,SAAS,CAAC,SAAS,CACjB,sBAAsB,EACtB,KAAK;QACH,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAiB,IAAI,CAAC,IAAI,CAAC;QAExC,2BAA2B,CAAC,IAAI,EAAE;YAChC,WAAW,EAAE,sBAAsB;SACpC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,KAAK,EAAE,KAAc,EAAE,EAAE;YACzC,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAEjD,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACjC,MAAM,CAAC;oBACL,SAAS,EAAE,KAAK;oBAChB,YAAY,EAAE,qCAAqC;oBACnD,WAAW,EAAE,yCAAyC;iBACvD,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC;gBAChC,MAAM,IAAI,SAAS,CACjB,+CAA+C,KAAK,GAAG,CACxD,CAAC;YAEJ,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;YACnD,eAAe,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACpC,MAAM,CAAC;gBACL,SAAS,EAAE,OAAO,CAAC,MAAM,KAAK,UAAU;gBACxC,YAAY,EAAE,qCAAqC;gBACnD,WAAW,EAAE,yCAAyC;aACvD,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/C,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE1D,IAAI,UAAU,CAAC,IAAI,KAAK,eAAe;gBAAE,MAAM,KAAK,CAAC;YAErD,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAChC,MAAM,CAAC;oBACL,SAAS,EAAE,IAAI;oBACf,WAAW,EAAE,yCAAyC;iBACvD,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,UAAU,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC3C,MAAM,CAAC;oBACL,SAAS,EAAE,IAAI;oBACf,WAAW,EAAE,6EAA6E;iBAC3F,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAChC,MAAM,CAAC;oBACL,SAAS,EAAE,IAAI;oBACf,WAAW,EAAE,4EAA4E,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,WAAW,GAAG;iBACvI,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAChC,MAAM,CAAC;oBACL,SAAS,EAAE,IAAI;oBACf,WAAW,EAAE,yEAAyE,UAAU,CAAC,MAAM,GAAG;iBAC3G,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,CAAC;gBACL,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,+EAA+E,UAAU,CAAC,IAAI,GAAG;aAC/G,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEpE,IAAY,CAAC,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7D,IAAY,CAAC,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAEhE,OAAO,IAAI,CAAC;IACd,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { TO_BE_REVERTED_WITH_CUSTOM_ERROR_MATCHER } from "./constants.js";
|
|
2
|
+
import { getNegated, getWithArgs, preventAsyncMatcherChaining, } from "./utils.js";
|
|
3
|
+
import { buildAssert } from "./utils/buildAssert.js";
|
|
4
|
+
import { getCall } from "./utils/getCallFlag.js";
|
|
5
|
+
import { getReturnDataFromError } from "./utils/getReturnDataFromError.js";
|
|
6
|
+
import { formatMatchError, matchArgs } from "./utils/matchArgs.js";
|
|
7
|
+
export function supportRevertedWithCustomError(Assertion) {
|
|
8
|
+
Assertion.addMethod(TO_BE_REVERTED_WITH_CUSTOM_ERROR_MATCHER, function (expectedCustomErrorName) {
|
|
9
|
+
const negated = getNegated(this);
|
|
10
|
+
const subject = this._obj;
|
|
11
|
+
if (typeof expectedCustomErrorName !== "string")
|
|
12
|
+
throw new TypeError(`Expected a string, but got '${expectedCustomErrorName}'`);
|
|
13
|
+
// this doesn't work with overloaded errors
|
|
14
|
+
const foundError = subject.abi.find((i) => i.type === "error" && i.name === expectedCustomErrorName);
|
|
15
|
+
if (!foundError)
|
|
16
|
+
throw new Error(`The error '${expectedCustomErrorName}' was not found in the contract ABI`);
|
|
17
|
+
preventAsyncMatcherChaining(this, {
|
|
18
|
+
matcherName: TO_BE_REVERTED_WITH_CUSTOM_ERROR_MATCHER,
|
|
19
|
+
});
|
|
20
|
+
const functionCall = getCall(this, TO_BE_REVERTED_WITH_CUSTOM_ERROR_MATCHER);
|
|
21
|
+
const onSuccess = async () => {
|
|
22
|
+
const assert = buildAssert(!!negated, onSuccess);
|
|
23
|
+
assert({
|
|
24
|
+
condition: false,
|
|
25
|
+
messageFalse: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it didn't revert`,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const onError = (error) => {
|
|
29
|
+
const assert = buildAssert(!!negated, onError);
|
|
30
|
+
const returnData = getReturnDataFromError(subject, error);
|
|
31
|
+
const withArgs = getWithArgs(this);
|
|
32
|
+
if (returnData.kind === "unknown-local")
|
|
33
|
+
throw error;
|
|
34
|
+
if (returnData.kind === "empty") {
|
|
35
|
+
assert({
|
|
36
|
+
condition: false,
|
|
37
|
+
messageFalse: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted without a reason`,
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (returnData.kind === "unknown-contract") {
|
|
42
|
+
assert({
|
|
43
|
+
condition: false,
|
|
44
|
+
messageFalse: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with unknown error`,
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (returnData.kind === "panic") {
|
|
49
|
+
assert({
|
|
50
|
+
condition: false,
|
|
51
|
+
messageFalse: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with panic code ${returnData.code} (${returnData.description})`,
|
|
52
|
+
});
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (returnData.kind === "error") {
|
|
56
|
+
assert({
|
|
57
|
+
condition: false,
|
|
58
|
+
messageFalse: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with reason '${returnData.reason}'`,
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// this also doesn't work with overloaded errors
|
|
63
|
+
if (returnData.name !== expectedCustomErrorName) {
|
|
64
|
+
assert({
|
|
65
|
+
condition: false,
|
|
66
|
+
messageFalse: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}', but it reverted with custom error '${returnData.name}'`,
|
|
67
|
+
});
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!withArgs) {
|
|
71
|
+
assert({
|
|
72
|
+
condition: true,
|
|
73
|
+
messageTrue: `Expected transaction NOT to be reverted with custom error '${expectedCustomErrorName}', but it was`,
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const argsAreEqual = matchArgs(withArgs, returnData.args);
|
|
78
|
+
assert({
|
|
79
|
+
condition: argsAreEqual,
|
|
80
|
+
messageFalse: formatMatchError({
|
|
81
|
+
msg: `Expected transaction to be reverted with custom error '${expectedCustomErrorName}' and matching arguments, but it was`,
|
|
82
|
+
expected: withArgs,
|
|
83
|
+
actual: returnData.args,
|
|
84
|
+
}),
|
|
85
|
+
messageTrue: `Expected transaction NOT to be reverted with custom error '${expectedCustomErrorName}' and matching arguments, but it was`,
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
const derivedPromise = functionCall.promise.then(onSuccess, onError);
|
|
89
|
+
this.then = derivedPromise.then.bind(derivedPromise);
|
|
90
|
+
this.catch = derivedPromise.catch.bind(derivedPromise);
|
|
91
|
+
return this;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=toBeRevertedWithCustomError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBeRevertedWithCustomError.js","sourceRoot":"","sources":["../../../src/matchers/toBeRevertedWithCustomError.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { getKnownPanicReason } from "../constants.js";
|
|
2
|
+
import { TO_BE_REVERTED_WITH_PANIC_MATCHER } from "./constants.js";
|
|
3
|
+
import { getNegated, preventAsyncMatcherChaining } from "./utils.js";
|
|
4
|
+
import { buildAssert } from "./utils/buildAssert.js";
|
|
5
|
+
import { getCall } from "./utils/getCallFlag.js";
|
|
6
|
+
import { getReturnDataFromError } from "./utils/getReturnDataFromError.js";
|
|
7
|
+
export function supportRevertedWithPanic(Assertion) {
|
|
8
|
+
Assertion.addMethod(TO_BE_REVERTED_WITH_PANIC_MATCHER, async function (expectedCode) {
|
|
9
|
+
const negated = getNegated(this);
|
|
10
|
+
const subject = this._obj;
|
|
11
|
+
if (typeof expectedCode !== "bigint" &&
|
|
12
|
+
typeof expectedCode !== "undefined")
|
|
13
|
+
throw new TypeError(`Expected a bigint or undefined, but got '${expectedCode}'`);
|
|
14
|
+
preventAsyncMatcherChaining(this, {
|
|
15
|
+
matcherName: TO_BE_REVERTED_WITH_PANIC_MATCHER,
|
|
16
|
+
});
|
|
17
|
+
const functionCall = getCall(this, TO_BE_REVERTED_WITH_PANIC_MATCHER);
|
|
18
|
+
const formattedExpectedCode = expectedCode
|
|
19
|
+
? `panic code ${expectedCode} (${getKnownPanicReason(expectedCode)})`
|
|
20
|
+
: "some panic code";
|
|
21
|
+
const onSuccess = async () => {
|
|
22
|
+
const assert = buildAssert(!!negated, onSuccess);
|
|
23
|
+
assert({
|
|
24
|
+
condition: false,
|
|
25
|
+
messageFalse: `Expected transaction to be reverted with ${formattedExpectedCode}, but it didn't revert`,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const onError = (error) => {
|
|
29
|
+
const assert = buildAssert(!!negated, onError);
|
|
30
|
+
const returnData = getReturnDataFromError(subject, error);
|
|
31
|
+
if (returnData.kind === "unknown-local")
|
|
32
|
+
throw error;
|
|
33
|
+
if (returnData.kind === "empty") {
|
|
34
|
+
assert({
|
|
35
|
+
condition: false,
|
|
36
|
+
messageFalse: `Expected transaction to be reverted with ${formattedExpectedCode}, but it reverted without a reason`,
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (returnData.kind === "unknown-contract") {
|
|
41
|
+
assert({
|
|
42
|
+
condition: false,
|
|
43
|
+
messageFalse: `Expected transaction to be reverted with ${formattedExpectedCode}, but it reverted with unknown error`,
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (returnData.kind === "error") {
|
|
48
|
+
assert({
|
|
49
|
+
condition: false,
|
|
50
|
+
messageFalse: `Expected transaction to be reverted with ${formattedExpectedCode}, but it reverted with reason '${returnData.reason}'`,
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (returnData.kind === "custom") {
|
|
55
|
+
assert({
|
|
56
|
+
condition: false,
|
|
57
|
+
messageFalse: `Expected transaction to be reverted with ${formattedExpectedCode}, but it reverted with custom error '${returnData.name}'`,
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (expectedCode !== undefined) {
|
|
62
|
+
assert({
|
|
63
|
+
condition: returnData.code === expectedCode,
|
|
64
|
+
messageFalse: `Expected transaction to be reverted with ${formattedExpectedCode}, but it reverted with panic code ${returnData.code} (${returnData.description})`,
|
|
65
|
+
messageTrue: `Expected transaction NOT to be reverted with ${formattedExpectedCode}, but it was`,
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
assert({
|
|
70
|
+
condition: true,
|
|
71
|
+
messageTrue: `Expected transaction NOT to be reverted with ${formattedExpectedCode}, but it reverted with panic code ${returnData.code} (${returnData.description})`,
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const derivedPromise = functionCall.promise.then(onSuccess, onError);
|
|
75
|
+
this.then = derivedPromise.then.bind(derivedPromise);
|
|
76
|
+
this.catch = derivedPromise.catch.bind(derivedPromise);
|
|
77
|
+
return this;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=toBeRevertedWithPanic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBeRevertedWithPanic.js","sourceRoot":"","sources":["../../../src/matchers/toBeRevertedWithPanic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TO_BE_REVERTED_WITH_STRING_MATCHER } from "./constants.js";
|
|
2
|
+
import { getNegated, preventAsyncMatcherChaining } from "./utils.js";
|
|
3
|
+
import { buildAssert } from "./utils/buildAssert.js";
|
|
4
|
+
import { getCall } from "./utils/getCallFlag.js";
|
|
5
|
+
import { getReturnDataFromError } from "./utils/getReturnDataFromError.js";
|
|
6
|
+
export function supportRevertedWithString(Assertion) {
|
|
7
|
+
Assertion.addMethod(TO_BE_REVERTED_WITH_STRING_MATCHER, async function (expectedReason) {
|
|
8
|
+
const negated = getNegated(this);
|
|
9
|
+
const subject = this._obj;
|
|
10
|
+
if (!(expectedReason instanceof RegExp) &&
|
|
11
|
+
typeof expectedReason !== "string")
|
|
12
|
+
throw new TypeError(`Expected a string or a regular expression, but got '${expectedReason}'`);
|
|
13
|
+
preventAsyncMatcherChaining(this, {
|
|
14
|
+
matcherName: TO_BE_REVERTED_WITH_STRING_MATCHER,
|
|
15
|
+
});
|
|
16
|
+
const functionCall = getCall(this, TO_BE_REVERTED_WITH_STRING_MATCHER);
|
|
17
|
+
const expectedReasonString = expectedReason instanceof RegExp
|
|
18
|
+
? expectedReason.source
|
|
19
|
+
: expectedReason;
|
|
20
|
+
const onSuccess = async () => {
|
|
21
|
+
const assert = buildAssert(!!negated, onSuccess);
|
|
22
|
+
assert({
|
|
23
|
+
condition: false,
|
|
24
|
+
messageFalse: `Expected transaction to be reverted with reason '${expectedReasonString}', but it didn't revert`,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
const onError = (error) => {
|
|
28
|
+
const assert = buildAssert(!!negated, onError);
|
|
29
|
+
const returnData = getReturnDataFromError(subject, error);
|
|
30
|
+
if (returnData.kind === "unknown-local")
|
|
31
|
+
throw error;
|
|
32
|
+
if (returnData.kind === "empty") {
|
|
33
|
+
assert({
|
|
34
|
+
condition: false,
|
|
35
|
+
messageFalse: `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted without a reason`,
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (returnData.kind === "unknown-contract") {
|
|
40
|
+
assert({
|
|
41
|
+
condition: false,
|
|
42
|
+
messageFalse: `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with unknown error`,
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (returnData.kind === "panic") {
|
|
47
|
+
assert({
|
|
48
|
+
condition: false,
|
|
49
|
+
messageFalse: `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with panic code ${returnData.code} (${returnData.description})`,
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (returnData.kind === "custom") {
|
|
54
|
+
assert({
|
|
55
|
+
condition: false,
|
|
56
|
+
messageFalse: `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with custom error '${returnData.name}'`,
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const matchesExpectedReason = expectedReason instanceof RegExp
|
|
61
|
+
? expectedReason.test(returnData.reason)
|
|
62
|
+
: expectedReason === returnData.reason;
|
|
63
|
+
assert({
|
|
64
|
+
condition: matchesExpectedReason,
|
|
65
|
+
messageFalse: `Expected transaction to be reverted with reason '${expectedReasonString}', but it reverted with reason '${returnData.reason}'`,
|
|
66
|
+
messageTrue: `Expected transaction NOT to be reverted with reason '${expectedReasonString}', but it was`,
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const derivedPromise = functionCall.promise.then(onSuccess, onError);
|
|
70
|
+
this.then = derivedPromise.then.bind(derivedPromise);
|
|
71
|
+
this.catch = derivedPromise.catch.bind(derivedPromise);
|
|
72
|
+
return this;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=toBeRevertedWithString.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBeRevertedWithString.js","sourceRoot":"","sources":["../../../src/matchers/toBeRevertedWithString.ts"],"names":[],"mappings":"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"}
|