AssertUint.sol
1 //SPDX-License-Identifier: MIT 2 pragma solidity >= 0.4.15 < 0.9.0; 3 4 library AssertUint { 5 6 uint8 constant ZERO = uint8(bytes1('0')); 7 uint8 constant A = uint8(bytes1('a')); 8 9 /* 10 Event: TestEvent 11 12 Fired when an assertion is made. 13 14 Params: 15 result (bool) - Whether or not the assertion holds. 16 message (string) - A message to display if the assertion does not hold. 17 */ 18 event TestEvent(bool indexed result, string message); 19 20 // ************************************** uint ************************************** 21 22 /* 23 Function: equal(uint) 24 25 Assert that two (256 bit) unsigned integers are equal. 26 27 : A == B 28 29 Params: 30 A (uint) - The first uint. 31 B (uint) - The second uint. 32 message (string) - A message that is sent if the assertion fails. 33 34 Returns: 35 result (bool) - The result. 36 */ 37 function equal(uint a, uint b, string memory message) public returns (bool result) { 38 result = (a == b); 39 if (result) 40 _report(result, message); 41 else 42 _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); 43 } 44 45 /* 46 Function: notEqual(uint) 47 48 Assert that two (256 bit) unsigned integers are not equal. 49 50 : A != B 51 52 Params: 53 A (uint) - The first uint. 54 B (uint) - The second uint. 55 message (string) - A message that is sent if the assertion fails. 56 57 Returns: 58 result (bool) - The result. 59 */ 60 function notEqual(uint a, uint b, string memory message) public returns (bool result) { 61 result = (a != b); 62 if (result) 63 _report(result, message); 64 else 65 _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); 66 } 67 68 /* 69 Function: isAbove(uint) 70 71 Assert that the uint 'A' is greater than the uint 'B'. 72 73 : A > B 74 75 Params: 76 A (uint) - The first uint. 77 B (uint) - The second uint. 78 message (string) - A message that is sent if the assertion fails. 79 80 Returns: 81 result (bool) - The result. 82 */ 83 function isAbove(uint a, uint b, string memory message) public returns (bool result) { 84 result = (a > b); 85 if (result) 86 _report(result, message); 87 else 88 _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); 89 } 90 91 /* 92 Function: isAtLeast(uint) 93 94 Assert that the uint 'A' is greater than or equal to the uint 'B'. 95 96 : A >= B 97 98 Params: 99 A (uint) - The first uint. 100 B (uint) - The second uint. 101 message (string) - A message that is sent if the assertion fails. 102 103 Returns: 104 result (bool) - The result. 105 */ 106 function isAtLeast(uint a, uint b, string memory message) public returns (bool result) { 107 result = (a >= b); 108 if (result) 109 _report(result, message); 110 else 111 _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); 112 } 113 114 /* 115 Function: isBelow(uint) 116 117 Assert that the uint 'A' is lesser than the uint 'B'. 118 119 : A < B 120 121 Params: 122 A (uint) - The first uint. 123 B (uint) - The second uint. 124 message (string) - A message that is sent if the assertion fails. 125 126 Returns: 127 result (bool) - The result. 128 */ 129 function isBelow(uint a, uint b, string memory message) public returns (bool result) { 130 result = (a < b); 131 if (result) 132 _report(result, message); 133 else 134 _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); 135 } 136 137 /* 138 Function: isAtMost(uint) 139 140 Assert that the uint 'A' is lesser than or equal to the uint 'B'. 141 142 : A <= B 143 144 Params: 145 A (uint) - The first uint. 146 B (uint) - The second uint. 147 message (string) - A message that is sent if the assertion fails. 148 149 Returns: 150 result (bool) - The result. 151 */ 152 function isAtMost(uint a, uint b, string memory message) public returns (bool result) { 153 result = (a <= b); 154 if (result) 155 _report(result, message); 156 else 157 _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message)); 158 } 159 160 /* 161 Function: isZero(uint) 162 163 Assert that a (256 bit) unsigned integer is 0. 164 165 : number == 0 166 167 Params: 168 number (uint) - The uint. 169 message (string) - A message that is sent if the assertion fails. 170 171 Returns: 172 result (bool) - The result. 173 */ 174 function isZero(uint number, string memory message) public returns (bool result) { 175 result = (number == 0); 176 if (result) 177 _report(result, message); 178 else 179 _report(result, _appendTagged(_tag(number, "Tested"), message)); 180 } 181 182 /* 183 Function: isNotZero(uint) 184 185 Assert that a (256 bit) unsigned integer is not 0. 186 187 : number != 0 188 189 Params: 190 number (uint) - The uint. 191 message (string) - A message that is sent if the assertion fails. 192 193 Returns: 194 result (bool) - The result. 195 */ 196 function isNotZero(uint number, string memory message) public returns (bool result) { 197 result = (number != 0); 198 if (result) 199 _report(result, message); 200 else 201 _report(result, _appendTagged(_tag(number, "Tested"), message)); 202 } 203 204 /******************************** internal ********************************/ 205 206 /* 207 Function: _report 208 209 Internal function for triggering <TestEvent>. 210 211 Params: 212 result (bool) - The test result (true or false). 213 message (string) - The message that is sent if the assertion fails. 214 */ 215 function _report(bool result, string memory message) internal { 216 if(result) 217 emit TestEvent(true, ""); 218 else 219 emit TestEvent(false, message); 220 } 221 222 223 /* 224 Function: _utoa(uint) 225 226 Convert an unsigned integer to a string. 227 228 Params: 229 n (uint) - The unsigned integer. 230 radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f 231 232 Returns: 233 result (string) - The resulting string. 234 */ 235 function _utoa(uint n, uint8 radix) internal pure returns (string memory) { 236 if (n == 0 || radix < 2 || radix > 16) 237 return '0'; 238 bytes memory bts = new bytes(256); 239 uint i; 240 while (n > 0) { 241 bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii. 242 n /= radix; 243 } 244 // Reverse 245 bytes memory rev = new bytes(i); 246 for (uint j = 0; j < i; j++) 247 rev[j] = bts[i - j - 1]; 248 return string(rev); 249 } 250 251 /* 252 Function: _utoa(uint8) 253 254 Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9', 255 numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte. 256 257 Params: 258 u (uint8) - The unsigned 8-bit integer. 259 260 Returns: 261 result (string) - The ASCII byte. 262 */ 263 function _utoa(uint8 u) internal pure returns (bytes1) { 264 if (u < 10) 265 return bytes1(u + ZERO); 266 else if (u < 16) 267 return bytes1(u - 10 + A); 268 else 269 return 0; 270 } 271 272 /* 273 function htoa(address addr) constant returns (string) { 274 bytes memory bts = new bytes(40); 275 bytes20 addrBts = bytes20(addr); 276 for (uint i = 0; i < 20; i++) { 277 bts[2*i] = addrBts[i] % 16; 278 bts[2*i + 1] = (addrBts[i] / 16) % 16; 279 } 280 return string(bts); 281 } 282 */ 283 284 /* 285 Function: _tag(string) 286 287 Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value". 288 289 Params: 290 value (string) - The value. 291 tag (string) - The tag. 292 293 Returns: 294 result (string) - "tag: value" 295 */ 296 function _tag(string memory value, string memory tag) internal pure returns (string memory) { 297 298 bytes memory valueB = bytes(value); 299 bytes memory tagB = bytes(tag); 300 301 uint vl = valueB.length; 302 uint tl = tagB.length; 303 304 bytes memory newB = new bytes(vl + tl + 2); 305 306 uint i; 307 uint j; 308 309 for (i = 0; i < tl; i++) 310 newB[j++] = tagB[i]; 311 newB[j++] = ':'; 312 newB[j++] = ' '; 313 for (i = 0; i < vl; i++) 314 newB[j++] = valueB[i]; 315 316 return string(newB); 317 } 318 319 /* 320 Function: _tag(uint) 321 322 Add a tag to an uint. 323 324 Params: 325 value (uint) - The value. 326 tag (string) - The tag. 327 328 Returns: 329 result (string) - "tag: _utoa(value)" 330 */ 331 function _tag(uint value, string memory tag) internal pure returns (string memory) { 332 string memory nstr = _utoa(value, 10); 333 return _tag(nstr, tag); 334 } 335 336 /* 337 Function: _appendTagged(string) 338 339 Append a tagged value to a string. 340 341 Params: 342 tagged (string) - The tagged value. 343 str (string) - The string. 344 345 Returns: 346 result (string) - "str (tagged)" 347 */ 348 function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) { 349 350 bytes memory taggedB = bytes(tagged); 351 bytes memory strB = bytes(str); 352 353 uint sl = strB.length; 354 uint tl = taggedB.length; 355 356 bytes memory newB = new bytes(sl + tl + 3); 357 358 uint i; 359 uint j; 360 361 for (i = 0; i < sl; i++) 362 newB[j++] = strB[i]; 363 newB[j++] = ' '; 364 newB[j++] = '('; 365 for (i = 0; i < tl; i++) 366 newB[j++] = taggedB[i]; 367 newB[j++] = ')'; 368 369 return string(newB); 370 } 371 372 /* 373 Function: _appendTagged(string, string) 374 375 Append two tagged values to a string. 376 377 Params: 378 tagged0 (string) - The first tagged value. 379 tagged1 (string) - The second tagged value. 380 str (string) - The string. 381 382 Returns: 383 result (string) - "str (tagged0, tagged1)" 384 */ 385 function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) { 386 387 bytes memory tagged0B = bytes(tagged0); 388 bytes memory tagged1B = bytes(tagged1); 389 bytes memory strB = bytes(str); 390 391 uint sl = strB.length; 392 uint t0l = tagged0B.length; 393 uint t1l = tagged1B.length; 394 395 bytes memory newB = new bytes(sl + t0l + t1l + 5); 396 397 uint i; 398 uint j; 399 400 for (i = 0; i < sl; i++) 401 newB[j++] = strB[i]; 402 newB[j++] = ' '; 403 newB[j++] = '('; 404 for (i = 0; i < t0l; i++) 405 newB[j++] = tagged0B[i]; 406 newB[j++] = ','; 407 newB[j++] = ' '; 408 for (i = 0; i < t1l; i++) 409 newB[j++] = tagged1B[i]; 410 newB[j++] = ')'; 411 412 return string(newB); 413 } 414 415 }