AssertAddressArray.sol
1 //SPDX-License-Identifier: MIT 2 pragma solidity >= 0.4.15 < 0.9.0; 3 4 library AssertAddressArray { 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 // ************************************** address[] ************************************** 21 22 /* 23 Function: equal(address[]) 24 25 Assert that two 'address[]' 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 (address[]) - The first array. 35 B (address[]) - 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(address[] memory arrA, address[] 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(address[]) 56 57 Assert that two 'address[]' 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 (address[]) - The first string. 67 B (address[]) - 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(address[] memory arrA, address[] 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(address[]) 89 90 Assert that the length of an 'address[]' is equal to a given value. 91 92 : arr.length == length 93 94 Params: 95 arr (address[]) - 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(address[] 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(address[]) 112 113 Assert that the length of an 'address[]' is not equal to a given value. 114 115 : arr.length != length 116 117 Params: 118 arr (address[]) - 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(address[] 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 Function: _utoa(uint) 153 154 Convert an unsigned integer to a string. 155 156 Params: 157 n (uint) - The unsigned integer. 158 radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f 159 160 Returns: 161 result (string) - The resulting string. 162 */ 163 function _utoa(uint n, uint8 radix) internal pure returns (string memory) { 164 if (n == 0 || radix < 2 || radix > 16) 165 return '0'; 166 bytes memory bts = new bytes(256); 167 uint i; 168 while (n > 0) { 169 bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii. 170 n /= radix; 171 } 172 // Reverse 173 bytes memory rev = new bytes(i); 174 for (uint j = 0; j < i; j++) 175 rev[j] = bts[i - j - 1]; 176 return string(rev); 177 } 178 179 /* 180 Function: _utoa(uint8) 181 182 Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9', 183 numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte. 184 185 Params: 186 u (uint8) - The unsigned 8-bit integer. 187 188 Returns: 189 result (string) - The ASCII byte. 190 */ 191 function _utoa(uint8 u) internal pure returns (bytes1) { 192 if (u < 10) 193 return bytes1(u + ZERO); 194 else if (u < 16) 195 return bytes1(u - 10 + A); 196 else 197 return 0; 198 } 199 200 /* 201 function htoa(address addr) constant returns (string) { 202 bytes memory bts = new bytes(40); 203 bytes20 addrBts = bytes20(addr); 204 for (uint i = 0; i < 20; i++) { 205 bts[2*i] = addrBts[i] % 16; 206 bts[2*i + 1] = (addrBts[i] / 16) % 16; 207 } 208 return string(bts); 209 } 210 */ 211 212 /* 213 Function: _tag(string) 214 215 Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value". 216 217 Params: 218 value (string) - The value. 219 tag (string) - The tag. 220 221 Returns: 222 result (string) - "tag: value" 223 */ 224 function _tag(string memory value, string memory tag) internal pure returns (string memory) { 225 226 bytes memory valueB = bytes(value); 227 bytes memory tagB = bytes(tag); 228 229 uint vl = valueB.length; 230 uint tl = tagB.length; 231 232 bytes memory newB = new bytes(vl + tl + 2); 233 234 uint i; 235 uint j; 236 237 for (i = 0; i < tl; i++) 238 newB[j++] = tagB[i]; 239 newB[j++] = ':'; 240 newB[j++] = ' '; 241 for (i = 0; i < vl; i++) 242 newB[j++] = valueB[i]; 243 244 return string(newB); 245 } 246 247 /* 248 Function: _tag(uint) 249 250 Add a tag to an uint. 251 252 Params: 253 value (uint) - The value. 254 tag (string) - The tag. 255 256 Returns: 257 result (string) - "tag: _utoa(value)" 258 */ 259 function _tag(uint value, string memory tag) internal pure returns (string memory) { 260 string memory nstr = _utoa(value, 10); 261 return _tag(nstr, tag); 262 } 263 264 /* 265 Function: _appendTagged(string, string) 266 267 Append two tagged values to a string. 268 269 Params: 270 tagged0 (string) - The first tagged value. 271 tagged1 (string) - The second tagged value. 272 str (string) - The string. 273 274 Returns: 275 result (string) - "str (tagged0, tagged1)" 276 */ 277 function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) { 278 279 bytes memory tagged0B = bytes(tagged0); 280 bytes memory tagged1B = bytes(tagged1); 281 bytes memory strB = bytes(str); 282 283 uint sl = strB.length; 284 uint t0l = tagged0B.length; 285 uint t1l = tagged1B.length; 286 287 bytes memory newB = new bytes(sl + t0l + t1l + 5); 288 289 uint i; 290 uint j; 291 292 for (i = 0; i < sl; i++) 293 newB[j++] = strB[i]; 294 newB[j++] = ' '; 295 newB[j++] = '('; 296 for (i = 0; i < t0l; i++) 297 newB[j++] = tagged0B[i]; 298 newB[j++] = ','; 299 newB[j++] = ' '; 300 for (i = 0; i < t1l; i++) 301 newB[j++] = tagged1B[i]; 302 newB[j++] = ')'; 303 304 return string(newB); 305 } 306 }