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