Change reverts API

- Enables postfix syntax: `call().reverts(reason)`
- Removes doesNotRevert etc; uses `check not` instead
- Removes waitFor(); return Future instead
This commit is contained in:
Mark Spanbroek 2022-09-20 09:53:28 +02:00 committed by markspanbroek
parent d001ee8e01
commit cac6026b34
3 changed files with 47 additions and 114 deletions

View File

@ -20,30 +20,22 @@ proc revertReason*(e: ref JsonRpcProviderError): string =
except JsonParsingError: except JsonParsingError:
return "" return ""
template reverts*(body: untyped): untyped = proc reverts*[T](call: Future[T]): Future[bool] {.async.} =
let asyncproc = proc(): Future[bool] {.async.} =
try: try:
body when T is void:
await call
else:
discard await call # TODO test this
return false return false
except JsonRpcProviderError: except JsonRpcProviderError:
return true return true # TODO: check that error started with revert prefix
waitFor asyncproc()
template revertsWith*(reason: string, body: untyped): untyped = proc reverts*[T](call: Future[T], reason: string): Future[bool] {.async.} =
let asyncproc = proc(): Future[bool] {.async.} =
try: try:
body when T is void:
await call
else:
discard await call # TODO test this
return false return false
except JsonRpcProviderError as e: except JsonRpcProviderError as error:
return reason == revertReason(e) return reason == error.revertReason
waitFor asyncproc()
template doesNotRevert*(body: untyped): untyped =
let asyncproc = proc(): Future[bool] {.async.} =
return not reverts(body)
waitFor asyncproc()
template doesNotRevertWith*(reason: string, body: untyped): untyped =
let asyncproc = proc(): Future[bool] {.async.} =
return not revertsWith(reason, body)
waitFor asyncproc()

View File

@ -3,7 +3,7 @@ author = "Nim Ethers Authors"
description = "Tests for Nim Ethers library" description = "Tests for Nim Ethers library"
license = "MIT" license = "MIT"
requires "asynctest >= 0.3.0 & < 0.4.0" requires "asynctest >= 0.3.2 & < 0.4.0"
requires "questionable >= 0.10.3 & < 0.11.0" requires "questionable >= 0.10.3 & < 0.11.0"
task test, "Run the test suite": task test, "Run the test suite":

View File

@ -14,112 +14,55 @@ suite "Testing helpers":
fmt"reverted with reason string '{revertReason}'" fmt"reverted with reason string '{revertReason}'"
} }
test "can use block syntax async": test "checks that call reverts":
let ethCallAsync = proc() {.async.} = proc call() {.async.} =
raise newException(JsonRpcProviderError, $rpcResponse) raise newException(JsonRpcProviderError, $rpcResponse)
check: check await call().reverts()
reverts:
await ethCallAsync()
test "can use block syntax sync": test "checks reason for revert":
let ethCall = proc() = proc call() {.async.} =
raise newException(JsonRpcProviderError, $rpcResponse) raise newException(JsonRpcProviderError, $rpcResponse)
check: check await call().reverts(revertReason)
reverts:
ethCall()
test "can use parameter syntax async":
let ethCallAsync = proc() {.async.} =
raise newException(JsonRpcProviderError, $rpcResponse)
check:
reverts (await ethCallAsync())
test "can use parameter syntax sync":
let ethCall = proc() =
raise newException(JsonRpcProviderError, $rpcResponse)
check:
reverts ethCall()
test "successfully checks revert reason async":
let ethCallAsync = proc() {.async.} =
raise newException(JsonRpcProviderError, $rpcResponse)
check:
revertsWith revertReason:
await ethCallAsync()
test "successfully checks revert reason sync":
let ethCall = proc() =
raise newException(JsonRpcProviderError, $rpcResponse)
check:
revertsWith revertReason:
ethCall()
test "correctly indicates there was no revert": test "correctly indicates there was no revert":
let ethCall = proc() = discard proc call() {.async.} = discard
check: check not await call().reverts()
doesNotRevert:
ethCall()
test "revert only checks JsonRpcProviderErrors": test "reverts only checks JsonRpcProviderErrors":
let ethCall = proc() = proc call() {.async.} =
raise newException(ContractError, "test") raise newException(ContractError, "test")
var success = false expect ContractError:
check await call().reverts()
try: test "reverts with reason only checks JsonRpcProviderErrors":
check: proc call() {.async.} =
reverts:
ethCall()
except ContractError:
success = true
check success
test "revertsWith only checks JsonRpcProviderErrors":
let ethCall = proc() =
raise newException(ContractError, "test") raise newException(ContractError, "test")
var success = false expect ContractError:
check await call().reverts(revertReason)
try: test "reverts with reason is false when there is no revert":
check: proc call() {.async.} = discard
revertsWith revertReason:
ethCall()
except ContractError:
success = true
check success
test "revertsWith is false when there is no revert": check not await call().reverts(revertReason)
let ethCall = proc() = discard
check: test "reverts is false when the revert reason doesn't match":
doesNotRevertWith revertReason: proc call() {.async.} =
ethCall()
test "revertsWith is false when the revert reason doesn't match":
let ethCall = proc() =
raise newException(JsonRpcProviderError, "other reason") raise newException(JsonRpcProviderError, "other reason")
check: check not await call().reverts(revertReason)
doesNotRevertWith revertReason:
ethCall()
test "revertsWith handles non-standard revert prefix": test "revert handles non-standard revert prefix":
let nonStdMsg = fmt"Provider VM Exception: reverted with {revertReason}" let nonStdMsg = fmt"Provider VM Exception: reverted with {revertReason}"
let nonStdRpcResponse = %* { "message": nonStdMsg } let nonStdRpcResponse = %* { "message": nonStdMsg }
let ethCall = proc() = proc call() {.async.} =
raise newException(JsonRpcProviderError, $nonStdRpcResponse) raise newException(JsonRpcProviderError, $nonStdRpcResponse)
check: check await call().reverts(nonStdMsg)
revertsWith nonStdMsg:
ethCall()
type type
TestHelpers* = ref object of Contract TestHelpers* = ref object of Contract
@ -127,7 +70,7 @@ type
method revertsWith*(self: TestHelpers, method revertsWith*(self: TestHelpers,
revertReason: string) {.base, contract, view.} revertReason: string) {.base, contract, view.}
suite "Testing helpers - current provider": suite "Testing helpers - provider":
var helpersContract: TestHelpers var helpersContract: TestHelpers
var provider: JsonRpcProvider var provider: JsonRpcProvider
@ -145,7 +88,5 @@ suite "Testing helpers - current provider":
teardown: teardown:
discard await provider.send("evm_revert", @[snapshot]) discard await provider.send("evm_revert", @[snapshot])
test "revert prefix is emitted from current provider": test "revert works with provider":
check: check await helpersContract.revertsWith(revertReason).reverts(revertReason)
revertsWith revertReason:
await helpersContract.revertsWith(revertReason)