AssertUintArray.sol
1 //SPDX-License-Identifier: MIT 2 pragma solidity >= 0.4.15 < 0.9.0; 3 4 library AssertUintArray { 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 'uint[ ]' are equal. 26 27 : arrA.length == arrB.length 28 29 and, for all valid indices 'i' 30 31 : arrA[i] == arrB[i] 32 33 Params: 34 A (uint[]) - The first array. 35 B (uint[]) - The second array. 36 message (string) - A message that is sent if the assertion fails. 37 38 Returns: 39 result (bool) - The result. 40 */ 41 function equal(uint[] memory arrA, uint[] memory arrB, string memory message) public returns (bool result) { 42 result = arrA.length == arrB.length; 43 if (result) { 44 for (uint i = 0; i < arrA.length; i++) { 45 if (arrA[i] != arrB[i]) { 46 result = false; 47 break; 48 } 49 } 50 } 51 _report(result, message); 52 } 53 54 /* 55 Function: notEqual(uint[]) 56 57 Assert that two 'uint[]' are not equal. 58 59 : arrA.length != arrB.length 60 61 or, for some valid index 'i' 62 63 : arrA[i] != arrB[i] 64 65 Params: 66 A (uint[]) - The first string. 67 B (uint[]) - The second string. 68 message (string) - A message that is sent if the assertion fails. 69 70 Returns: 71 result (bool) - The result. 72 */ 73 function notEqual(uint[] memory arrA, uint[] memory arrB, string memory message) public returns (bool result) { 74 result = arrA.length == arrB.length; 75 if (result) { 76 for (uint i = 0; i < arrA.length; i++) { 77 if (arrA[i] != arrB[i]) { 78 result = false; 79 break; 80 } 81 } 82 } 83 result = !result; 84 _report(result, message); 85 } 86 87 /* 88 Function: lengthEqual(uint[]) 89 90 Assert that the length of a 'uint[]' is equal to a given value. 91 92 : arr.length == length 93 94 Params: 95 arr (uint[]) - The array. 96 length (uint) - The length. 97 message (string) - A message that is sent if the assertion fails. 98 99 Returns: 100 result (bool) - The result. 101 */ 102 function lengthEqual(uint[] memory arr, uint length, string memory message) public returns (bool result) { 103 uint arrLength = arr.length; 104 if (arrLength == length) 105 _report(result, ""); 106 else 107 _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message)); 108 } 109 110 /* 111 Function: lengthNotEqual(uint[]) 112 113 Assert that the length of a 'uint[]' is not equal to a given value. 114 115 : arr.length != length 116 117 Params: 118 arr (uint[]) - The array. 119 length (uint) - The length. 120 message (string) - A message that is sent if the assertion fails. 121 122 Returns: 123 result (bool) - The result. 124 */ 125 function lengthNotEqual(uint[] memory arr, uint length, string memory message) public returns (bool result) { 126 uint arrLength = arr.length; 127 if (arrLength != arr.length) 128 _report(result, ""); 129 else 130 _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message)); 131 } 132 133 /******************************** internal ********************************/ 134 135 /* 136 Function: _report 137 138 Internal function for triggering <TestEvent>. 139 140 Params: 141 result (bool) - The test result (true or false). 142 message (string) - The message that is sent if the assertion fails. 143 */ 144 function _report(bool result, string memory message) internal { 145 if(result) 146 emit TestEvent(true, ""); 147 else 148 emit TestEvent(false, message); 149 } 150 151 152 /* 153 Function: _utoa(uint) 154 155 Convert an unsigned integer to a string. 156 157 Params: 158 n (uint) - The unsigned integer. 159 radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f 160 161 Returns: 162 result (string) - The resulting string. 163 */ 164 function _utoa(uint n, uint8 radix) internal pure returns (string memory) { 165 if (n == 0 || radix < 2 || radix > 16) 166 return '0'; 167 bytes memory bts = new bytes(256); 168 uint i; 169 while (n > 0) { 170 bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii. 171 n /= radix; 172 } 173 // Reverse 174 bytes memory rev = new bytes(i); 175 for (uint j = 0; j < i; j++) 176 rev[j] = bts[i - j - 1]; 177 return string(rev); 178 } 179 180 /* 181 Function: _utoa(uint8) 182 183 Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9', 184 numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte. 185 186 Params: 187 u (uint8) - The unsigned 8-bit integer. 188 189 Returns: 190 result (string) - The ASCII byte. 191 */ 192 function _utoa(uint8 u) internal pure returns (bytes1) { 193 if (u < 10) 194 return bytes1(u + ZERO); 195 else if (u < 16) 196 return bytes1(u - 10 + A); 197 else 198 return 0; 199 } 200 201 /* 202 function htoa(address addr) constant returns (string) { 203 bytes memory bts = new bytes(40); 204 bytes20 addrBts = bytes20(addr); 205 for (uint i = 0; i < 20; i++) { 206 bts[2*i] = addrBts[i] % 16; 207 bts[2*i + 1] = (addrBts[i] / 16) % 16; 208 } 209 return string(bts); 210 } 211 */ 212 213 /* 214 Function: _tag(string) 215 216 Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value". 217 218 Params: 219 value (string) - The value. 220 tag (string) - The tag. 221 222 Returns: 223 result (string) - "tag: value" 224 */ 225 function _tag(string memory value, string memory tag) internal pure returns (string memory) { 226 227 bytes memory valueB = bytes(value); 228 bytes memory tagB = bytes(tag); 229 230 uint vl = valueB.length; 231 uint tl = tagB.length; 232 233 bytes memory newB = new bytes(vl + tl + 2); 234 235 uint i; 236 uint j; 237 238 for (i = 0; i < tl; i++) 239 newB[j++] = tagB[i]; 240 newB[j++] = ':'; 241 newB[j++] = ' '; 242 for (i = 0; i < vl; i++) 243 newB[j++] = valueB[i]; 244 245 return string(newB); 246 } 247 248 /* 249 Function: _tag(uint) 250 251 Add a tag to an uint. 252 253 Params: 254 value (uint) - The value. 255 tag (string) - The tag. 256 257 Returns: 258 result (string) - "tag: _utoa(value)" 259 */ 260 function _tag(uint value, string memory tag) internal pure returns (string memory) { 261 string memory nstr = _utoa(value, 10); 262 return _tag(nstr, tag); 263 } 264 265 /* 266 Function: _appendTagged(string) 267 268 Append a tagged value to a string. 269 270 Params: 271 tagged (string) - The tagged value. 272 str (string) - The string. 273 274 Returns: 275 result (string) - "str (tagged)" 276 */ 277 function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) { 278 279 bytes memory taggedB = bytes(tagged); 280 bytes memory strB = bytes(str); 281 282 uint sl = strB.length; 283 uint tl = taggedB.length; 284 285 bytes memory newB = new bytes(sl + tl + 3); 286 287 uint i; 288 uint j; 289 290 for (i = 0; i < sl; i++) 291 newB[j++] = strB[i]; 292 newB[j++] = ' '; 293 newB[j++] = '('; 294 for (i = 0; i < tl; i++) 295 newB[j++] = taggedB[i]; 296 newB[j++] = ')'; 297 298 return string(newB); 299 } 300 301 /* 302 Function: _appendTagged(string, string) 303 304 Append two tagged values to a string. 305 306 Params: 307 tagged0 (string) - The first tagged value. 308 tagged1 (string) - The second tagged value. 309 str (string) - The string. 310 311 Returns: 312 result (string) - "str (tagged0, tagged1)" 313 */ 314 function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) { 315 316 bytes memory tagged0B = bytes(tagged0); 317 bytes memory tagged1B = bytes(tagged1); 318 bytes memory strB = bytes(str); 319 320 uint sl = strB.length; 321 uint t0l = tagged0B.length; 322 uint t1l = tagged1B.length; 323 324 bytes memory newB = new bytes(sl + t0l + t1l + 5); 325 326 uint i; 327 uint j; 328 329 for (i = 0; i < sl; i++) 330 newB[j++] = strB[i]; 331 newB[j++] = ' '; 332 newB[j++] = '('; 333 for (i = 0; i < t0l; i++) 334 newB[j++] = tagged0B[i]; 335 newB[j++] = ','; 336 newB[j++] = ' '; 337 for (i = 0; i < t1l; i++) 338 newB[j++] = tagged1B[i]; 339 newB[j++] = ')'; 340 341 return string(newB); 342 } 343 344 }