/ test / common / utils / MoreAssert.t.sol
MoreAssert.t.sol
  1  pragma solidity >=0.6.0;
  2  
  3  library MoreAssert {
  4  
  5      uint8 constant ZERO = uint8(byte('0'));
  6      uint8 constant A = uint8(byte('a'));
  7  
  8      function equal(uint a, uint b, uint base, string memory message)
  9          internal pure returns (bool result) {
 10          
 11          if (a == b) return true;
 12          uint diff = (a > b) ? (a - b) : (b - a);
 13          result = (a > b) ? (a / diff > base) : (b / diff > base);
 14          if (!result) {
 15               revert(_appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
 16          }
 17      }
 18  
 19      function _appendTagged(string memory tagged0, string memory tagged1, string memory str)
 20          internal pure returns (string memory) {
 21  
 22          bytes memory tagged0B = bytes(tagged0);
 23          bytes memory tagged1B = bytes(tagged1);
 24          bytes memory strB = bytes(str);
 25  
 26          uint sl = strB.length;
 27          uint t0l = tagged0B.length;
 28          uint t1l = tagged1B.length;
 29  
 30          bytes memory newB = new bytes(sl + t0l + t1l + 5);
 31  
 32          uint i;
 33          uint j;
 34  
 35          for (i = 0; i < sl; i++)
 36              newB[j++] = strB[i];
 37          newB[j++] = ' ';
 38          newB[j++] = '(';
 39          for (i = 0; i < t0l; i++)
 40              newB[j++] = tagged0B[i];
 41          newB[j++] = ',';
 42          newB[j++] = ' ';
 43          for (i = 0; i < t1l; i++)
 44              newB[j++] = tagged1B[i];
 45          newB[j++] = ')';
 46  
 47          return string(newB);
 48      }
 49  
 50      function _tag(uint value, string memory tag) internal pure returns (string memory) {
 51          string memory nstr = _utoa(value, 10);
 52          return _tag(nstr, tag);
 53      }
 54  
 55      function _tag(string memory value, string memory tag) internal pure returns (string memory) {
 56  
 57          bytes memory valueB = bytes(value);
 58          bytes memory tagB = bytes(tag);
 59  
 60          uint vl = valueB.length;
 61          uint tl = tagB.length;
 62  
 63          bytes memory newB = new bytes(vl + tl + 2);
 64  
 65          uint i;
 66          uint j;
 67  
 68          for (i = 0; i < tl; i++)
 69              newB[j++] = tagB[i];
 70          newB[j++] = ':';
 71          newB[j++] = ' ';
 72          for (i = 0; i < vl; i++)
 73              newB[j++] = valueB[i];
 74  
 75          return string(newB);
 76      }
 77  
 78      function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
 79          if (n == 0 || radix < 2 || radix > 16)
 80              return '0';
 81          bytes memory bts = new bytes(256);
 82          uint i;
 83          while (n > 0) {
 84              bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
 85              n /= radix;
 86          }
 87          // Reverse
 88          bytes memory rev = new bytes(i);
 89          for (uint j = 0; j < i; j++)
 90              rev[j] = bts[i - j - 1];
 91          return string(rev);
 92      }
 93  
 94      function _utoa(uint8 u) internal pure returns (byte) {
 95          if (u < 10)
 96              return byte(u + ZERO);
 97          else if (u < 16)
 98              return byte(u - 10 + A);
 99          else
100              return 0;
101      }
102  }