-
Notifications
You must be signed in to change notification settings - Fork 333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(test): assertApproxEq, assertNotEq, assertFalse #38
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
e17d6f0
feat(test): assertApproxEq, assertNotEq, assertFalse
OliverNChalk 1e3b6a2
refactor: yoink assertApproxEq from t11s
OliverNChalk fb089f0
feat(test): yoink assertRelApproxEq from t11s
OliverNChalk dfaa2d5
style(test): align multi-line log messages for character alignment
OliverNChalk 7e73c21
fix(test): correct yoink/translation errors
OliverNChalk 1a78d1b
feat(test): add more bool asserts, t11s assertFalse
OliverNChalk 3e8d693
feat(test): add assertEq(bool, err)
OliverNChalk b61c6c4
feat(test): add assertEq(bytes, bytes)
OliverNChalk 51ff84f
refactor(test): standardized approx eq assertion naming
OliverNChalk 3e0ef00
refactor(test): drop assertNotEq as it's bad practice
OliverNChalk 1f08a76
refactor(test): improve assertEq(bool,bool) error messaging
OliverNChalk f0e1ba9
fix(test): remove duplicate assertEq(bool,bool)
OliverNChalk 03355c9
fix(test): use log instead of log_named_string
OliverNChalk 2c23374
feat(test): add int256 impls for assertApproxEqRel
OliverNChalk 924456a
style(test): re-order code and group overloads together
OliverNChalk 99a36d8
style(test): use single STD-ASSERTIONS code region
OliverNChalk 3c15901
style(test): declare assertFalse before assertEq
OliverNChalk 113b11c
style(test): add STD-CHEATS code region
OliverNChalk b434995
style: add STD-ERRORS & STD-STORAGE delimters
OliverNChalk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,10 @@ abstract contract Test is DSTest { | |
Vm public constant vm = Vm(HEVM_ADDRESS); | ||
StdStorage internal stdstore; | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
STD-CHEATS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
// Skip forward or rewind time by the specified number of seconds | ||
function skip(uint256 time) public { | ||
vm.warp(block.timestamp + time); | ||
|
@@ -139,8 +143,207 @@ abstract contract Test is DSTest { | |
addr := create(0, add(bytecode, 0x20), mload(bytecode)) | ||
} | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
STD-ASSERTIONS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
function assertFalse(bool data) internal virtual { | ||
assertTrue(!data); | ||
} | ||
|
||
function assertFalse(bool data, string memory err) internal virtual { | ||
assertTrue(!data, err); | ||
} | ||
|
||
function assertEq(bool a, bool b) internal { | ||
if (a != b) { | ||
emit log ("Error: a == b not satisfied [bool]"); | ||
emit log_named_string (" Expected", b ? "true" : "false"); | ||
emit log_named_string (" Actual", a ? "true" : "false"); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertEq(bool a, bool b, string memory err) internal { | ||
if (a != b) { | ||
emit log_named_string("Error", err); | ||
emit log_named_string(" Expected", b ? "true" : "false"); | ||
emit log_named_string(" Actual", a ? "true" : "false"); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertEq(bytes memory a, bytes memory b) internal virtual { | ||
if (keccak256(a) != keccak256(b)) { | ||
emit log ("Error: a == b not satisfied [bytes]"); | ||
emit log_named_bytes(" Expected", b); | ||
emit log_named_bytes(" Actual", a); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { | ||
if (keccak256(a) != keccak256(b)) { | ||
emit log_named_string ("Error", err); | ||
emit log_named_bytes (" Expected", b); | ||
emit log_named_bytes (" Actual", a); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqAbs( | ||
uint256 a, | ||
uint256 b, | ||
uint256 maxDelta | ||
) internal virtual { | ||
uint256 delta = a > b ? a - b : b - a; | ||
|
||
if (delta > maxDelta) { | ||
emit log ("Error: a ~= b not satisfied [uint]"); | ||
emit log_named_uint (" Expected", b); | ||
emit log_named_uint (" Actual", a); | ||
emit log_named_uint (" Max Delta", maxDelta); | ||
emit log_named_uint (" Delta", delta); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqAbs( | ||
uint256 a, | ||
uint256 b, | ||
uint256 maxDelta, | ||
string memory err | ||
) internal virtual { | ||
uint256 delta = a > b ? a - b : b - a; | ||
|
||
if (delta > maxDelta) { | ||
emit log_named_string ("Error", err); | ||
emit log_named_uint (" Expected", b); | ||
emit log_named_uint (" Actual", a); | ||
emit log_named_uint (" Max Delta", maxDelta); | ||
emit log_named_uint (" Delta", delta); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqAbs( | ||
int256 a, | ||
int256 b, | ||
int256 maxDelta | ||
) internal virtual { | ||
int256 delta = a > b ? a - b : b - a; | ||
|
||
if (delta > maxDelta) { | ||
emit log ("Error: a ~= b not satisfied [int]"); | ||
emit log_named_int (" Expected", b); | ||
emit log_named_int (" Actual", a); | ||
emit log_named_int (" Max Delta", maxDelta); | ||
emit log_named_int (" Delta", delta); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqAbs( | ||
int256 a, | ||
int256 b, | ||
int256 maxDelta, | ||
string memory err | ||
) internal virtual { | ||
int256 delta = a > b ? a - b : b - a; | ||
|
||
if (delta > maxDelta) { | ||
emit log_named_string ("Error", err); | ||
emit log_named_int (" Expected", b); | ||
emit log_named_int (" Actual", a); | ||
emit log_named_int (" Max Delta", maxDelta); | ||
emit log_named_int (" Delta", delta); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqRel( | ||
uint256 a, | ||
uint256 b, | ||
uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% | ||
) internal virtual { | ||
if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. | ||
|
||
uint256 percentDelta = ((a > b ? a - b : b - a) * 1e18) / b; | ||
|
||
if (percentDelta > maxPercentDelta) { | ||
emit log ("Error: a ~= b not satisfied [uint]"); | ||
emit log_named_uint (" Expected", b); | ||
emit log_named_uint (" Actual", a); | ||
emit log_named_decimal_uint (" Max % Delta", maxPercentDelta, 18); | ||
emit log_named_decimal_uint (" % Delta", percentDelta, 18); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqRel( | ||
uint256 a, | ||
uint256 b, | ||
uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% | ||
string memory err | ||
) internal virtual { | ||
if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. | ||
|
||
uint256 percentDelta = ((a > b ? a - b : b - a) * 1e18) / b; | ||
|
||
if (percentDelta > maxPercentDelta) { | ||
emit log_named_string ("Error", err); | ||
emit log_named_uint (" Expected", b); | ||
emit log_named_uint (" Actual", a); | ||
emit log_named_decimal_uint (" Max % Delta", maxPercentDelta, 18); | ||
emit log_named_decimal_uint (" % Delta", percentDelta, 18); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqRel( | ||
int256 a, | ||
int256 b, | ||
int256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% | ||
) internal virtual { | ||
if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. | ||
|
||
int256 percentDelta = ((a > b ? a - b : b - a) * 1e18) / b; | ||
|
||
if (percentDelta > maxPercentDelta) { | ||
emit log ("Error: a ~= b not satisfied [uint]"); | ||
emit log_named_int (" Expected", b); | ||
emit log_named_int (" Actual", a); | ||
emit log_named_decimal_int (" Max % Delta", maxPercentDelta, 18); | ||
emit log_named_decimal_int (" % Delta", percentDelta, 18); | ||
fail(); | ||
} | ||
} | ||
|
||
function assertApproxEqRel( | ||
int256 a, | ||
int256 b, | ||
int256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% | ||
string memory err | ||
) internal virtual { | ||
if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too. | ||
|
||
int256 percentDelta = ((a > b ? a - b : b - a) * 1e18) / b; | ||
|
||
if (percentDelta > maxPercentDelta) { | ||
emit log_named_string ("Error", err); | ||
emit log_named_int (" Expected", b); | ||
emit log_named_int (" Actual", a); | ||
emit log_named_decimal_int (" Max % Delta", maxPercentDelta, 18); | ||
emit log_named_decimal_int (" % Delta", percentDelta, 18); | ||
fail(); | ||
} | ||
} | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
STD-ERRORS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
library stdError { | ||
bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); | ||
|
@@ -159,19 +362,22 @@ library stdError { | |
struct StdStorage { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here "STD-STORAGE" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done, can resolve if happy |
||
mapping (address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; | ||
mapping (address => mapping(bytes4 => mapping(bytes32 => bool))) finds; | ||
|
||
bytes32[] _keys; | ||
bytes4 _sig; | ||
uint256 _depth; | ||
address _target; | ||
bytes32 _set; | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
STD-STORAGE | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
library stdStorage { | ||
event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint slot); | ||
event WARNING_UninitedSlot(address who, uint slot); | ||
|
||
Vm private constant vm_std_store = Vm(address(uint160(uint256(keccak256('hevm cheat code'))))); | ||
|
||
function sigs( | ||
|
@@ -192,8 +398,8 @@ library stdStorage { | |
// if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); | ||
function find( | ||
StdStorage storage self | ||
) | ||
internal | ||
) | ||
internal | ||
returns (uint256) | ||
{ | ||
address who = self._target; | ||
|
@@ -212,7 +418,7 @@ library stdStorage { | |
(, bytes memory rdat) = who.staticcall(cald); | ||
fdat = bytesToBytes32(rdat, 32*field_depth); | ||
} | ||
|
||
(bytes32[] memory reads, ) = vm_std_store.accesses(address(who)); | ||
if (reads.length == 1) { | ||
bytes32 curr = vm_std_store.load(who, reads[0]); | ||
|
@@ -239,7 +445,7 @@ library stdStorage { | |
(success, rdat) = who.staticcall(cald); | ||
fdat = bytesToBytes32(rdat, 32*field_depth); | ||
} | ||
|
||
if (success && fdat == bytes32(hex"1337")) { | ||
// we found which of the slots is the actual one | ||
emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); | ||
|
@@ -259,7 +465,7 @@ library stdStorage { | |
delete self._target; | ||
delete self._sig; | ||
delete self._keys; | ||
delete self._depth; | ||
delete self._depth; | ||
|
||
return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; | ||
} | ||
|
@@ -343,7 +549,7 @@ library stdStorage { | |
delete self._target; | ||
delete self._sig; | ||
delete self._keys; | ||
delete self._depth; | ||
delete self._depth; | ||
} | ||
|
||
function bytesToBytes32(bytes memory b, uint offset) public pure returns (bytes32) { | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a header here before
stdError
"STD-ERRORS" to separate them from the assertions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, can resolve if happy