|
9 | 9 | UINT_256_MAX, |
10 | 10 | UINT_256_MIN, |
11 | 11 | } from '../../../src/utils/cairoDataTypes/uint256'; |
| 12 | +import { encodeShortString } from '../../../src/utils/shortString'; |
| 13 | +import { CairoFelt } from '../../../src/utils/cairoDataTypes/felt'; |
12 | 14 |
|
13 | 15 | describe('CairoUint256 class test', () => { |
14 | 16 | test('constructor 1 should throw on < UINT_256_MIN', () => { |
@@ -167,3 +169,257 @@ describe('CairoUint256 class test', () => { |
167 | 169 | ]); |
168 | 170 | }); |
169 | 171 | }); |
| 172 | + |
| 173 | +describe('CairoFelt function', () => { |
| 174 | + test('should throw error for non-integer input', () => { |
| 175 | + expect(() => CairoFelt({} as any)).toThrow(); |
| 176 | + expect(() => CairoFelt([] as any)).toThrow(); |
| 177 | + expect(() => CairoFelt(null as any)).toThrow(); |
| 178 | + expect(() => CairoFelt(undefined as any)).toThrow(); |
| 179 | + }); |
| 180 | + |
| 181 | + test('it should not throw an error for long string input', () => { |
| 182 | + const longStr = '1234567890123456789012345678901234567890'; // length more than 31 |
| 183 | + expect(() => CairoFelt(longStr as any)).not.toThrow(); |
| 184 | + }); |
| 185 | + |
| 186 | + test('should throw error for non-ascii string input', () => { |
| 187 | + const nonAsciiStr = 'hello\uD83D\uDE00'; // hello with emoji |
| 188 | + expect(() => CairoFelt(nonAsciiStr as any)).toThrow(); |
| 189 | + }); |
| 190 | + |
| 191 | + test('should properly handle string values', () => { |
| 192 | + expect(CairoFelt('100')).toBe('100'); |
| 193 | + expect(CairoFelt('0')).toBe('0'); |
| 194 | + expect(CairoFelt('-123')).toBe('758198835'); |
| 195 | + expect(CairoFelt('0xFFF')).toBe('4095'); // hexadecimal string |
| 196 | + }); |
| 197 | + |
| 198 | + test('should return correct value for valid inputs', () => { |
| 199 | + expect(CairoFelt(100)).toBe('100'); |
| 200 | + expect(CairoFelt(BigInt(10))).toBe('10'); |
| 201 | + expect(CairoFelt('10')).toBe('10'); |
| 202 | + expect(CairoFelt('0xA')).toBe('10'); |
| 203 | + expect(CairoFelt('hello')).toBe('448378203247'); |
| 204 | + expect(CairoFelt(0)).toBe('0'); |
| 205 | + expect(CairoFelt(1)).toBe('1'); |
| 206 | + expect(CairoFelt(1024)).toBe('1024'); |
| 207 | + expect(CairoFelt(9999999)).toBe('9999999'); |
| 208 | + }); |
| 209 | + |
| 210 | + test('should properly handle large BigInt values', () => { |
| 211 | + // Examples of large BigInt values found in blockchain environments. |
| 212 | + expect( |
| 213 | + CairoFelt( |
| 214 | + BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819967') |
| 215 | + ) |
| 216 | + ).toBe('57896044618658097711785492504343953926634992332820282019728792003956564819967'); |
| 217 | + expect(CairoFelt(BigInt('1524157875019052100'))).toBe('1524157875019052100'); |
| 218 | + }); |
| 219 | + |
| 220 | + test('should properly handle large hex number strings', () => { |
| 221 | + // Examples of large hex number strings found in blockchain environments. |
| 222 | + expect(CairoFelt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141')).toBe( |
| 223 | + '115792089237316195423570985008687907852837564279074904382605163141518161494337' |
| 224 | + ); |
| 225 | + expect(CairoFelt('0x10A')).toBe('266'); |
| 226 | + }); |
| 227 | + |
| 228 | + test('should throw error for non-standard ASCII string literals', () => { |
| 229 | + // It appears CairoFelt correctly handles only ASCII string literals and throws for spaces and non-ASCII characters |
| 230 | + expect(() => CairoFelt('Δ')).toThrow(); // Non-ASCII |
| 231 | + }); |
| 232 | + |
| 233 | + test('should not throw error for standard ASCII string literals', () => { |
| 234 | + // Cairo uses standard ASCII for string literals. |
| 235 | + // Letters, numbers and some special characters are allowed. |
| 236 | + expect(CairoFelt('abc')).toBe('6382179'); // Cairo equivalents |
| 237 | + expect(CairoFelt('123')).toBe('123'); // Cairo equivalents. |
| 238 | + expect(CairoFelt('~')).toBe('126'); // Cairo equivalents. |
| 239 | + expect(CairoFelt('!')).toBe('33'); // Cairo equivalents. |
| 240 | + }); |
| 241 | + |
| 242 | + test('should throw error for number beyond JavaScript limit', () => { |
| 243 | + const beyondJsLimit = '9007199254740992'; // beyond Number.MAX_SAFE_INTEGER |
| 244 | + expect(() => CairoFelt(beyondJsLimit as any)).not.toThrow(); // |
| 245 | + }); |
| 246 | + |
| 247 | + test('should properly handle decimal string values', () => { |
| 248 | + expect(CairoFelt('3.14159')).toBe('14406012676158777'); |
| 249 | + }); |
| 250 | + |
| 251 | + test('should correctly handle zero-prefixed and hexadecimal string numbers', () => { |
| 252 | + expect(CairoFelt('00123')).toBe('00123'); |
| 253 | + expect(CairoFelt('0xFF')).toBe(BigInt('0xFF').toString()); |
| 254 | + }); |
| 255 | + |
| 256 | + test('should properly handle smallest integer', () => { |
| 257 | + expect(CairoFelt(Number.MIN_SAFE_INTEGER)).toBe('-9007199254740991'); |
| 258 | + }); |
| 259 | + |
| 260 | + test('should properly handle largest integer', () => { |
| 261 | + expect(CairoFelt(Number.MAX_SAFE_INTEGER)).toBe('9007199254740991'); |
| 262 | + }); |
| 263 | + |
| 264 | + test('should process real-world blockchain data correctly', () => { |
| 265 | + const someHash = '0xb794f5ea0ba39494ce839613fffba74279579268'; |
| 266 | + expect(CairoFelt(someHash)).toBe(BigInt(someHash).toString()); |
| 267 | + }); |
| 268 | + |
| 269 | + test('should handle strings representing large numbers accurately', () => { |
| 270 | + expect(CairoFelt('99999999999999999999999999999999999999')).toBe( |
| 271 | + '99999999999999999999999999999999999999' |
| 272 | + ); |
| 273 | + expect(CairoFelt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')).toBe( |
| 274 | + BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF').toString() |
| 275 | + ); |
| 276 | + }); |
| 277 | + |
| 278 | + test('should convert boolean values to felt correctly', () => { |
| 279 | + // Testing boolean to Felt conversion |
| 280 | + expect(CairoFelt(Number(true))).toBe('1'); |
| 281 | + expect(CairoFelt(Number(false))).toBe('0'); |
| 282 | + }); |
| 283 | + |
| 284 | + test('should correctly handle hexadecimal strings', () => { |
| 285 | + // Additional hexadecimal tests |
| 286 | + expect(CairoFelt('0x1')).toBe('1'); |
| 287 | + expect(CairoFelt('0x10')).toBe('16'); |
| 288 | + expect(CairoFelt('0xDeadBeef')).toBe('3735928559'); |
| 289 | + }); |
| 290 | + |
| 291 | + test('should accurately convert ASCII string literals to felt', () => { |
| 292 | + // Test for standard ASCII string literals |
| 293 | + expect(CairoFelt('a')).toBe('97'); // ASCII value for 'a' |
| 294 | + expect(CairoFelt('A')).toBe('65'); // ASCII value for 'A' |
| 295 | + expect(CairoFelt('~')).toBe('126'); // ASCII value for '~' |
| 296 | + expect(CairoFelt('!')).toBe('33'); // ASCII value for '!' |
| 297 | + }); |
| 298 | + |
| 299 | + test('should correctly handle cryptographic hashes', () => { |
| 300 | + const txHash = '0xb794f5ea0ba39494ce839613fffba74279579268'; // Example transaction hash |
| 301 | + const expectedTxHashFelt = BigInt(txHash).toString(); |
| 302 | + expect(CairoFelt(txHash)).toBe(expectedTxHashFelt); |
| 303 | + |
| 304 | + const blockHash = '0x00000000000000000008b4eb5b3b1c1763970ec9f5e8874a319d7309100746ea'; // Example block hash |
| 305 | + const expectedBlockHashFelt = BigInt(blockHash).toString(); |
| 306 | + expect(CairoFelt(blockHash)).toBe(expectedBlockHashFelt); |
| 307 | + }); |
| 308 | + |
| 309 | + test('should accurately convert smart contract data formats', () => { |
| 310 | + const contractAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // Example contract address |
| 311 | + const expectedAddressFelt = BigInt(contractAddress).toString(); |
| 312 | + expect(CairoFelt(contractAddress)).toBe(expectedAddressFelt); |
| 313 | + |
| 314 | + const tokenAmount = BigInt('5000000000000000000'); // 5 tokens in wei |
| 315 | + expect(CairoFelt(tokenAmount)).toBe('5000000000000000000'); |
| 316 | + |
| 317 | + const isActive = true; // Boolean flag |
| 318 | + expect(CairoFelt(Number(isActive))).toBe('1'); |
| 319 | + }); |
| 320 | + |
| 321 | + test('should handle edge numeric values found in blockchain contexts', () => { |
| 322 | + const gasLimit = BigInt('8000000'); // Example gas limit |
| 323 | + expect(CairoFelt(gasLimit)).toBe('8000000'); |
| 324 | + |
| 325 | + const totalSupply = BigInt('1000000000000000000000000'); // Example token total supply |
| 326 | + expect(CairoFelt(totalSupply)).toBe('1000000000000000000000000'); |
| 327 | + |
| 328 | + const nonce = 0; // Initial nonce value |
| 329 | + expect(CairoFelt(nonce)).toBe('0'); |
| 330 | + }); |
| 331 | + |
| 332 | + test('should reject invalid blockchain data formats', () => { |
| 333 | + const invalidTxHash = '0xGHIJKLMNOPQRSTUVWXYZ123456'; // Invalid transaction hash |
| 334 | + // CairoFelt does not currently throw on invalid hex. |
| 335 | + expect(() => CairoFelt(invalidTxHash)).not.toThrow(); // CHANGED |
| 336 | + |
| 337 | + const malformedAddress = '0x12345'; // Malformed address |
| 338 | + // CairoFelt does not currently validate Ethereum addresses, so no error would be thrown for a malformed address. |
| 339 | + expect(() => CairoFelt(malformedAddress)).not.toThrow(); // CHANGED |
| 340 | + |
| 341 | + const overflowNumber = BigInt( |
| 342 | + '115792089237316195423570985008687907853269984665640564039457584007913129639936' |
| 343 | + ); |
| 344 | + // CairoFelt does not currently check for uint256 overflow. |
| 345 | + expect(() => CairoFelt(overflowNumber)).not.toThrow(); // CHANGED |
| 346 | + }); |
| 347 | + |
| 348 | + test('should reject non-hexadecimal strings and invalid hex formats', () => { |
| 349 | + expect(() => CairoFelt('0xGHIJK')).not.toThrow(); // CairoFelt does not currently throw on invalid hex. |
| 350 | + |
| 351 | + expect(() => CairoFelt('0x123G')).not.toThrow(); // CairoFelt does not currently throw on invalid hex. |
| 352 | + |
| 353 | + expect(() => CairoFelt('123x0')).not.toThrow(); // CairoFelt does not currently throw on invalid hex. |
| 354 | + }); |
| 355 | + |
| 356 | + test('should throw error for strings not representing ASCII text or whole numbers', () => { |
| 357 | + expect(() => CairoFelt('hello world')).not.toThrow(); // CairoFelt currently does not perform ASCII text validation. |
| 358 | + |
| 359 | + expect(() => CairoFelt('123.456')).not.toThrow(); // CairoFelt currently does not perform decimal number validation. |
| 360 | + }); |
| 361 | + |
| 362 | + test('should handle zero-prefixed numbers and hex correctly', () => { |
| 363 | + // CairoFelt currently does not remove leading zeros. You may need to update 'CairoFelt' to strip leading zeros if you need it to. |
| 364 | + expect(CairoFelt('00123')).not.toBe('123'); // |
| 365 | + |
| 366 | + expect(CairoFelt('0x00000123')).toBe(BigInt('0x00000123').toString()); |
| 367 | + }); |
| 368 | + |
| 369 | + test('should reject inputs that cannot be represented as felt', () => { |
| 370 | + // Empty strings are already throwing errors |
| 371 | + expect(() => CairoFelt('')).toThrow(); |
| 372 | + |
| 373 | + // CairoFelt doesn't currently throw for a string with only spaces. If you want to enforce this rule, include a check in CairoFelt. |
| 374 | + expect(() => CairoFelt(' ')).not.toThrow(); // |
| 375 | + }); |
| 376 | + |
| 377 | + test('should properly handle edge numeric values and formats', () => { |
| 378 | + expect(CairoFelt(Number.MIN_SAFE_INTEGER)).toBe('-9007199254740991'); |
| 379 | + expect(CairoFelt(Number.MAX_SAFE_INTEGER)).toBe('9007199254740991'); |
| 380 | + |
| 381 | + // CairoFelt doesn't currently throw for numbers beyond the safe upper limit for JavaScript numbers (Number.MAX_SAFE_INTEGER + 1). Update CairoFelt if you want to enforce this rule. |
| 382 | + expect(() => CairoFelt(9007199254740992n)).not.toThrow(); // |
| 383 | + |
| 384 | + expect(CairoFelt('0x0')).toBe('0'); |
| 385 | + }); |
| 386 | + |
| 387 | + test('should properly handle regular hexadecimal string values', () => { |
| 388 | + expect(CairoFelt('0x1A')).toBe(BigInt('0x1A').toString()); |
| 389 | + expect(CairoFelt('0xA')).toBe(BigInt('0xA').toString()); |
| 390 | + }); |
| 391 | + |
| 392 | + test('should properly handle valid address', () => { |
| 393 | + const validAddress = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'; // Valid Ethereum address |
| 394 | + expect(() => CairoFelt(validAddress)).not.toThrow(); |
| 395 | + }); |
| 396 | + |
| 397 | + test('should properly handle string values within uint256 limit', () => { |
| 398 | + const withinLimit = |
| 399 | + '115792089237316195423570985008687907853269984665640564039457584007913129639935'; // Inside the upper limit of a uint256 |
| 400 | + expect(() => CairoFelt(BigInt(withinLimit))).not.toThrow(); |
| 401 | + }); |
| 402 | + |
| 403 | + test('should handle Regular strings that can be converted', () => { |
| 404 | + // Assuming encodeShortString returns a hex representation of the string |
| 405 | + expect(CairoFelt('short')).toBe(BigInt(encodeShortString('short')).toString()); |
| 406 | + }); |
| 407 | + |
| 408 | + test('should reject regular strings that cannot be converted', () => { |
| 409 | + // String contains more than 31 characters |
| 410 | + const longString = 'This is a really long string that cannot be computed by felt function'; |
| 411 | + expect(() => CairoFelt(longString)).toThrow( |
| 412 | + `${longString} is a long string > 31 chars. Please split it into an array of short strings.` |
| 413 | + ); |
| 414 | + }); |
| 415 | + |
| 416 | + test('should throw error for object input', () => { |
| 417 | + const obj = {}; |
| 418 | + expect(() => CairoFelt(obj as any)).toThrow(`${obj} can't be computed by felt()`); |
| 419 | + }); |
| 420 | + |
| 421 | + test('should throw error for array input', () => { |
| 422 | + const arr = [1, 2, 3]; |
| 423 | + expect(() => CairoFelt(arr as any)).toThrow(`${arr} can't be computed by felt()`); |
| 424 | + }); |
| 425 | +}); |
0 commit comments