//SPDX-License-Identifier: MIT pragma solidity >= 0.4.15 < 0.9.0; library AssertUint { uint8 constant ZERO = uint8(bytes1('0')); uint8 constant A = uint8(bytes1('a')); /* Event: TestEvent Fired when an assertion is made. Params: result (bool) - Whether or not the assertion holds. message (string) - A message to display if the assertion does not hold. */ event TestEvent(bool indexed result, string message); // ************************************** uint ************************************** /* Function: equal(uint) Assert that two (256 bit) unsigned integers are equal. : A == B Params: A (uint) - The first uint. B (uint) - The second uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function equal(uint a, uint b, string memory message) public returns (bool result) { result = (a == b); if (result) _report(result, message); else _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); } /* Function: notEqual(uint) Assert that two (256 bit) unsigned integers are not equal. : A != B Params: A (uint) - The first uint. B (uint) - The second uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function notEqual(uint a, uint b, string memory message) public returns (bool result) { result = (a != b); if (result) _report(result, message); else _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); } /* Function: isAbove(uint) Assert that the uint 'A' is greater than the uint 'B'. : A > B Params: A (uint) - The first uint. B (uint) - The second uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function isAbove(uint a, uint b, string memory message) public returns (bool result) { result = (a > b); if (result) _report(result, message); else _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); } /* Function: isAtLeast(uint) Assert that the uint 'A' is greater than or equal to the uint 'B'. : A >= B Params: A (uint) - The first uint. B (uint) - The second uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function isAtLeast(uint a, uint b, string memory message) public returns (bool result) { result = (a >= b); if (result) _report(result, message); else _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); } /* Function: isBelow(uint) Assert that the uint 'A' is lesser than the uint 'B'. : A < B Params: A (uint) - The first uint. B (uint) - The second uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function isBelow(uint a, uint b, string memory message) public returns (bool result) { result = (a < b); if (result) _report(result, message); else _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); } /* Function: isAtMost(uint) Assert that the uint 'A' is lesser than or equal to the uint 'B'. : A <= B Params: A (uint) - The first uint. B (uint) - The second uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function isAtMost(uint a, uint b, string memory message) public returns (bool result) { result = (a <= b); if (result) _report(result, message); else _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); } /* Function: isZero(uint) Assert that a (256 bit) unsigned integer is 0. : number == 0 Params: number (uint) - The uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function isZero(uint number, string memory message) public returns (bool result) { result = (number == 0); if (result) _report(result, message); else _report(result, _appendTagged(_tag(number, "Tested"), message)); } /* Function: isNotZero(uint) Assert that a (256 bit) unsigned integer is not 0. : number != 0 Params: number (uint) - The uint. message (string) - A message that is sent if the assertion fails. Returns: result (bool) - The result. */ function isNotZero(uint number, string memory message) public returns (bool result) { result = (number != 0); if (result) _report(result, message); else _report(result, _appendTagged(_tag(number, "Tested"), message)); } /******************************** internal ********************************/ /* Function: _report Internal function for triggering . Params: result (bool) - The test result (true or false). message (string) - The message that is sent if the assertion fails. */ function _report(bool result, string memory message) internal { if(result) emit TestEvent(true, ""); else emit TestEvent(false, message); } /* Function: _utoa(uint) Convert an unsigned integer to a string. Params: n (uint) - The unsigned integer. radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f Returns: result (string) - The resulting string. */ function _utoa(uint n, uint8 radix) internal pure returns (string memory) { if (n == 0 || radix < 2 || radix > 16) return '0'; bytes memory bts = new bytes(256); uint i; while (n > 0) { bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii. n /= radix; } // Reverse bytes memory rev = new bytes(i); for (uint j = 0; j < i; j++) rev[j] = bts[i - j - 1]; return string(rev); } /* Function: _utoa(uint8) Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9', numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte. Params: u (uint8) - The unsigned 8-bit integer. Returns: result (string) - The ASCII byte. */ function _utoa(uint8 u) internal pure returns (bytes1) { if (u < 10) return bytes1(u + ZERO); else if (u < 16) return bytes1(u - 10 + A); else return 0; } /* function htoa(address addr) constant returns (string) { bytes memory bts = new bytes(40); bytes20 addrBts = bytes20(addr); for (uint i = 0; i < 20; i++) { bts[2*i] = addrBts[i] % 16; bts[2*i + 1] = (addrBts[i] / 16) % 16; } return string(bts); } */ /* Function: _tag(string) Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value". Params: value (string) - The value. tag (string) - The tag. Returns: result (string) - "tag: value" */ function _tag(string memory value, string memory tag) internal pure returns (string memory) { bytes memory valueB = bytes(value); bytes memory tagB = bytes(tag); uint vl = valueB.length; uint tl = tagB.length; bytes memory newB = new bytes(vl + tl + 2); uint i; uint j; for (i = 0; i < tl; i++) newB[j++] = tagB[i]; newB[j++] = ':'; newB[j++] = ' '; for (i = 0; i < vl; i++) newB[j++] = valueB[i]; return string(newB); } /* Function: _tag(uint) Add a tag to an uint. Params: value (uint) - The value. tag (string) - The tag. Returns: result (string) - "tag: _utoa(value)" */ function _tag(uint value, string memory tag) internal pure returns (string memory) { string memory nstr = _utoa(value, 10); return _tag(nstr, tag); } /* Function: _appendTagged(string) Append a tagged value to a string. Params: tagged (string) - The tagged value. str (string) - The string. Returns: result (string) - "str (tagged)" */ function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) { bytes memory taggedB = bytes(tagged); bytes memory strB = bytes(str); uint sl = strB.length; uint tl = taggedB.length; bytes memory newB = new bytes(sl + tl + 3); uint i; uint j; for (i = 0; i < sl; i++) newB[j++] = strB[i]; newB[j++] = ' '; newB[j++] = '('; for (i = 0; i < tl; i++) newB[j++] = taggedB[i]; newB[j++] = ')'; return string(newB); } /* Function: _appendTagged(string, string) Append two tagged values to a string. Params: tagged0 (string) - The first tagged value. tagged1 (string) - The second tagged value. str (string) - The string. Returns: result (string) - "str (tagged0, tagged1)" */ function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) { bytes memory tagged0B = bytes(tagged0); bytes memory tagged1B = bytes(tagged1); bytes memory strB = bytes(str); uint sl = strB.length; uint t0l = tagged0B.length; uint t1l = tagged1B.length; bytes memory newB = new bytes(sl + t0l + t1l + 5); uint i; uint j; for (i = 0; i < sl; i++) newB[j++] = strB[i]; newB[j++] = ' '; newB[j++] = '('; for (i = 0; i < t0l; i++) newB[j++] = tagged0B[i]; newB[j++] = ','; newB[j++] = ' '; for (i = 0; i < t1l; i++) newB[j++] = tagged1B[i]; newB[j++] = ')'; return string(newB); } }