Skip to content

Commit da4ddce

Browse files
ikrcatovivpavici
andauthored
test: CairoFelt tests (#1035)
* test: CairoFelt tests * Update __tests__/utils/CairoTypes/CairoFelt.test.ts * Update __tests__/utils/CairoTypes/CairoFelt.test.ts --------- Co-authored-by: Ivan Pavičić <ivan.pavicic@live.com>
1 parent 51b694c commit da4ddce

File tree

6 files changed

+342
-4
lines changed

6 files changed

+342
-4
lines changed
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import { CairoFelt } from '../../../src/utils/cairoDataTypes/felt';
2+
import { encodeShortString } from '../../../src/utils/shortString';
3+
4+
describe('CairoFelt function', () => {
5+
test('should throw error for non-integer input', () => {
6+
expect(() => CairoFelt({} as any)).toThrow();
7+
expect(() => CairoFelt([] as any)).toThrow();
8+
expect(() => CairoFelt(null as any)).toThrow();
9+
expect(() => CairoFelt(undefined as any)).toThrow();
10+
});
11+
12+
test('it should not throw an error for long string input', () => {
13+
const longStr = '1234567890123456789012345678901234567890'; // length more than 31
14+
expect(() => CairoFelt(longStr as any)).not.toThrow();
15+
});
16+
17+
test('should throw error for non-ascii string input', () => {
18+
const nonAsciiStr = 'hello\uD83D\uDE00'; // hello with emoji
19+
expect(() => CairoFelt(nonAsciiStr as any)).toThrow();
20+
});
21+
22+
test('should properly handle string values', () => {
23+
expect(CairoFelt('100')).toBe('100');
24+
expect(CairoFelt('0')).toBe('0');
25+
expect(CairoFelt('-123')).toBe('758198835');
26+
expect(CairoFelt('0xFFF')).toBe('4095'); // hexadecimal string
27+
});
28+
29+
test('should return correct value for valid inputs', () => {
30+
expect(CairoFelt(100)).toBe('100');
31+
expect(CairoFelt(BigInt(10))).toBe('10');
32+
expect(CairoFelt('10')).toBe('10');
33+
expect(CairoFelt('0xA')).toBe('10');
34+
expect(CairoFelt('hello')).toBe('448378203247');
35+
expect(CairoFelt(0)).toBe('0');
36+
expect(CairoFelt(1)).toBe('1');
37+
expect(CairoFelt(1024)).toBe('1024');
38+
expect(CairoFelt(9999999)).toBe('9999999');
39+
});
40+
41+
test('should properly handle large BigInt values', () => {
42+
// Examples of large BigInt values found in blockchain environments.
43+
expect(
44+
CairoFelt(
45+
BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819967')
46+
)
47+
).toBe('57896044618658097711785492504343953926634992332820282019728792003956564819967');
48+
expect(CairoFelt(BigInt('1524157875019052100'))).toBe('1524157875019052100');
49+
});
50+
51+
test('should properly handle large hex number strings', () => {
52+
// Examples of large hex number strings found in blockchain environments.
53+
expect(CairoFelt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141')).toBe(
54+
'115792089237316195423570985008687907852837564279074904382605163141518161494337'
55+
);
56+
expect(CairoFelt('0x10A')).toBe('266');
57+
});
58+
59+
test('should throw error for non-standard ASCII string literals', () => {
60+
// It appears CairoFelt correctly handles only ASCII string literals and throws for spaces and non-ASCII characters
61+
expect(() => CairoFelt('Δ')).toThrow(); // Non-ASCII
62+
});
63+
64+
test('should not throw error for standard ASCII string literals', () => {
65+
// Cairo uses standard ASCII for string literals.
66+
// Letters, numbers and some special characters are allowed.
67+
expect(CairoFelt('abc')).toBe('6382179'); // Cairo equivalents
68+
expect(CairoFelt('123')).toBe('123'); // Cairo equivalents.
69+
expect(CairoFelt('~')).toBe('126'); // Cairo equivalents.
70+
expect(CairoFelt('!')).toBe('33'); // Cairo equivalents.
71+
});
72+
73+
test('should throw error for number beyond JavaScript limit', () => {
74+
const beyondJsLimit = '9007199254740992'; // beyond Number.MAX_SAFE_INTEGER
75+
expect(() => CairoFelt(beyondJsLimit as any)).not.toThrow(); //
76+
});
77+
78+
test('should properly handle decimal string values', () => {
79+
expect(CairoFelt('3.14159')).toBe('14406012676158777');
80+
});
81+
82+
test('should correctly handle zero-prefixed and hexadecimal string numbers', () => {
83+
expect(CairoFelt('00123')).toBe('00123');
84+
expect(CairoFelt('0xFF')).toBe(BigInt('0xFF').toString());
85+
});
86+
87+
test('should properly handle smallest integer', () => {
88+
expect(CairoFelt(Number.MIN_SAFE_INTEGER)).toBe('-9007199254740991');
89+
});
90+
91+
test('should properly handle largest integer', () => {
92+
expect(CairoFelt(Number.MAX_SAFE_INTEGER)).toBe('9007199254740991');
93+
});
94+
95+
test('should process real-world blockchain data correctly', () => {
96+
const someHash = '0xb794f5ea0ba39494ce839613fffba74279579268';
97+
expect(CairoFelt(someHash)).toBe(BigInt(someHash).toString());
98+
});
99+
100+
test('should handle strings representing large numbers accurately', () => {
101+
expect(CairoFelt('99999999999999999999999999999999999999')).toBe(
102+
'99999999999999999999999999999999999999'
103+
);
104+
expect(CairoFelt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')).toBe(
105+
BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF').toString()
106+
);
107+
});
108+
109+
test('should convert boolean values to felt correctly', () => {
110+
// Testing boolean to Felt conversion
111+
expect(CairoFelt(Number(true))).toBe('1');
112+
expect(CairoFelt(Number(false))).toBe('0');
113+
});
114+
115+
test('should correctly handle hexadecimal strings', () => {
116+
// Additional hexadecimal tests
117+
expect(CairoFelt('0x1')).toBe('1');
118+
expect(CairoFelt('0x10')).toBe('16');
119+
expect(CairoFelt('0xDeadBeef')).toBe('3735928559');
120+
});
121+
122+
test('should accurately convert ASCII string literals to felt', () => {
123+
// Test for standard ASCII string literals
124+
expect(CairoFelt('a')).toBe('97'); // ASCII value for 'a'
125+
expect(CairoFelt('A')).toBe('65'); // ASCII value for 'A'
126+
expect(CairoFelt('~')).toBe('126'); // ASCII value for '~'
127+
expect(CairoFelt('!')).toBe('33'); // ASCII value for '!'
128+
});
129+
130+
test('should correctly handle cryptographic hashes', () => {
131+
const txHash = '0xb794f5ea0ba39494ce839613fffba74279579268'; // Example transaction hash
132+
const expectedTxHashFelt = BigInt(txHash).toString();
133+
expect(CairoFelt(txHash)).toBe(expectedTxHashFelt);
134+
135+
const blockHash = '0x00000000000000000008b4eb5b3b1c1763970ec9f5e8874a319d7309100746ea'; // Example block hash
136+
const expectedBlockHashFelt = BigInt(blockHash).toString();
137+
expect(CairoFelt(blockHash)).toBe(expectedBlockHashFelt);
138+
});
139+
140+
test('should accurately convert smart contract data formats', () => {
141+
const contractAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // Example contract address
142+
const expectedAddressFelt = BigInt(contractAddress).toString();
143+
expect(CairoFelt(contractAddress)).toBe(expectedAddressFelt);
144+
145+
const tokenAmount = BigInt('5000000000000000000'); // 5 tokens
146+
expect(CairoFelt(tokenAmount)).toBe('5000000000000000000');
147+
148+
const isActive = true; // Boolean flag
149+
expect(CairoFelt(Number(isActive))).toBe('1');
150+
});
151+
152+
test('should handle edge numeric values found in blockchain contexts', () => {
153+
const gasLimit = BigInt('8000000'); // Example gas limit
154+
expect(CairoFelt(gasLimit)).toBe('8000000');
155+
156+
const totalSupply = BigInt('1000000000000000000000000'); // Example token total supply
157+
expect(CairoFelt(totalSupply)).toBe('1000000000000000000000000');
158+
159+
const nonce = 0; // Initial nonce value
160+
expect(CairoFelt(nonce)).toBe('0');
161+
});
162+
163+
test('should reject invalid blockchain data formats', () => {
164+
const invalidTxHash = '0xGHIJKLMNOPQRSTUVWXYZ123456'; // Invalid transaction hash
165+
// CairoFelt does not currently throw on invalid hex.
166+
expect(() => CairoFelt(invalidTxHash)).not.toThrow(); // CHANGED
167+
168+
const malformedAddress = '0x12345'; // Malformed address
169+
// CairoFelt does not currently validate addresses, so no error would be thrown for a malformed address.
170+
expect(() => CairoFelt(malformedAddress)).not.toThrow(); // CHANGED
171+
172+
const overflowNumber = BigInt(
173+
'115792089237316195423570985008687907853269984665640564039457584007913129639936'
174+
);
175+
// CairoFelt does not currently check for uint256 overflow.
176+
expect(() => CairoFelt(overflowNumber)).not.toThrow(); // CHANGED
177+
});
178+
179+
test('should reject non-hexadecimal strings and invalid hex formats', () => {
180+
expect(() => CairoFelt('0xGHIJK')).not.toThrow(); // CairoFelt does not currently throw on invalid hex.
181+
182+
expect(() => CairoFelt('0x123G')).not.toThrow(); // CairoFelt does not currently throw on invalid hex.
183+
184+
expect(() => CairoFelt('123x0')).not.toThrow(); // CairoFelt does not currently throw on invalid hex.
185+
});
186+
187+
test('should throw error for strings not representing ASCII text or whole numbers', () => {
188+
expect(() => CairoFelt('hello world')).not.toThrow(); // CairoFelt currently does not perform ASCII text validation.
189+
190+
expect(() => CairoFelt('123.456')).not.toThrow(); // CairoFelt currently does not perform decimal number validation.
191+
});
192+
193+
test('should handle zero-prefixed numbers and hex correctly', () => {
194+
// CairoFelt currently does not remove leading zeros. You may need to update 'CairoFelt' to strip leading zeros if you need it to.
195+
expect(CairoFelt('00123')).not.toBe('123'); //
196+
197+
expect(CairoFelt('0x00000123')).toBe(BigInt('0x00000123').toString());
198+
});
199+
200+
test('should reject inputs that cannot be represented as felt', () => {
201+
// Empty strings are already throwing errors
202+
expect(() => CairoFelt('')).toThrow();
203+
204+
// CairoFelt doesn't currently throw for a string with only spaces. If you want to enforce this rule, include a check in CairoFelt.
205+
expect(() => CairoFelt(' ')).not.toThrow(); //
206+
});
207+
208+
test('should properly handle edge numeric values and formats', () => {
209+
expect(CairoFelt(Number.MIN_SAFE_INTEGER)).toBe('-9007199254740991');
210+
expect(CairoFelt(Number.MAX_SAFE_INTEGER)).toBe('9007199254740991');
211+
212+
// 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.
213+
expect(() => CairoFelt(9007199254740992n)).not.toThrow(); //
214+
215+
expect(CairoFelt('0x0')).toBe('0');
216+
});
217+
218+
test('should properly handle regular hexadecimal string values', () => {
219+
expect(CairoFelt('0x1A')).toBe(BigInt('0x1A').toString());
220+
expect(CairoFelt('0xA')).toBe(BigInt('0xA').toString());
221+
});
222+
223+
test('should properly handle valid address', () => {
224+
const validAddress = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'; // Valid Ethereum address
225+
expect(() => CairoFelt(validAddress)).not.toThrow();
226+
});
227+
228+
test('should properly handle string values within uint256 limit', () => {
229+
const withinLimit =
230+
'115792089237316195423570985008687907853269984665640564039457584007913129639935'; // Inside the upper limit of a uint256
231+
expect(() => CairoFelt(BigInt(withinLimit))).not.toThrow();
232+
});
233+
234+
test('should handle Regular strings that can be converted', () => {
235+
// Assuming encodeShortString returns a hex representation of the string
236+
expect(CairoFelt('short')).toBe(BigInt(encodeShortString('short')).toString());
237+
});
238+
239+
test('should reject regular strings that cannot be converted', () => {
240+
// String contains more than 31 characters
241+
const longString = 'This is a really long string that cannot be computed by felt function';
242+
expect(() => CairoFelt(longString)).toThrow(
243+
`${longString} is a long string > 31 chars. Please split it into an array of short strings.`
244+
);
245+
});
246+
247+
test('should throw error for object input', () => {
248+
const obj = {};
249+
expect(() => CairoFelt(obj as any)).toThrow(`${obj} can't be computed by felt()`);
250+
});
251+
252+
test('should throw error for array input', () => {
253+
const arr = [1, 2, 3];
254+
expect(() => CairoFelt(arr as any)).toThrow(`${arr} can't be computed by felt()`);
255+
});
256+
});

__tests__/utils/CairoTypes/secp256k1Point.test.ts renamed to __tests__/utils/secp256k1Point.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable no-new */
2-
import { CallData } from '../../../src/utils/calldata';
3-
import { bigNumberishArrayToDecimalStringArray, toHex } from '../../../src/utils/num';
4-
import { compiledEthAccount, compiledEthPubk } from '../../config/fixtures';
2+
import { CallData } from '../../src/utils/calldata';
3+
import { bigNumberishArrayToDecimalStringArray, toHex } from '../../src/utils/num';
4+
import { compiledEthAccount, compiledEthPubk } from '../config/fixtures';
55

66
describe('secp256k1Point cairo type test', () => {
77
const myCallDataAccount = new CallData(compiledEthAccount.abi);

__tests__/utils/shortString.test.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { byteArray } from '../../src';
22
import { removeHexPrefix } from '../../src/utils/encode';
3-
import { decodeShortString, encodeShortString } from '../../src/utils/shortString';
3+
import {
4+
decodeShortString,
5+
encodeShortString,
6+
isDecimalString,
7+
isShortString,
8+
isString,
9+
} from '../../src/utils/shortString';
410

511
describe('shortString', () => {
612
test('should convert string to number', () => {
@@ -103,3 +109,43 @@ describe('shortString', () => {
103109
})
104110
).toBe('');
105111
});
112+
113+
describe('isString', () => {
114+
test('should return true for strings', () => {
115+
expect(isString('test')).toBe(true);
116+
expect(isString('')).toBe(true);
117+
});
118+
119+
test('should return false for non-string values', () => {
120+
expect(isString(10)).toBe(false);
121+
expect(isString({})).toBe(false);
122+
expect(isString(null)).toBe(false);
123+
expect(isString(undefined)).toBe(false);
124+
expect(isString([])).toBe(false);
125+
expect(isString(true)).toBe(false);
126+
});
127+
});
128+
129+
describe('isShortString', () => {
130+
test('should return true for short strings', () => {
131+
const shortStr = '1234567890123456789012345678901';
132+
expect(isShortString(shortStr)).toBe(true);
133+
});
134+
135+
test('should return false for long strings', () => {
136+
const longStr = '12345678901234567890123456789012';
137+
expect(isShortString(longStr)).toBe(false);
138+
});
139+
});
140+
141+
describe('isDecimalString', () => {
142+
test('should return true for decimal strings', () => {
143+
expect(isDecimalString('1234567890')).toBe(true);
144+
});
145+
146+
test('should return false for non-decimal strings', () => {
147+
expect(isDecimalString('123A')).toBe(false);
148+
expect(isDecimalString('ABCDE')).toBe(false);
149+
expect(isDecimalString('123.456')).toBe(false);
150+
});
151+
});

__tests__/utils/utils.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as starkCurve from '@scure/starknet';
22

33
import { constants, ec, hash, num, stark } from '../../src';
44
import { Block } from '../../src/utils/provider';
5+
import { isBigInt, isHex } from '../../src/utils/num';
56

67
const { IS_BROWSER } = constants;
78

@@ -131,3 +132,38 @@ describe('new Block()', () => {
131132
expect(blockC.queryIdentifier).toBe('blockHash=0x01');
132133
});
133134
});
135+
136+
describe('Num utility functions', () => {
137+
describe('isBigInt', () => {
138+
test('should return true for big integers', () => {
139+
expect(isBigInt(BigInt(10))).toBe(true);
140+
expect(isBigInt(BigInt('9007199254740991'))).toBe(true);
141+
});
142+
143+
test('should return false for non-big integers', () => {
144+
expect(isBigInt(10)).toBe(false);
145+
expect(isBigInt('10')).toBe(false);
146+
expect(isBigInt(undefined)).toBe(false);
147+
expect(isBigInt(null)).toBe(false);
148+
expect(isBigInt({})).toBe(false);
149+
expect(isBigInt([])).toBe(false);
150+
expect(isBigInt(true)).toBe(false);
151+
});
152+
});
153+
154+
describe('isHex', () => {
155+
test('should return true for valid hex strings', () => {
156+
expect(isHex('0xab')).toBe(true);
157+
expect(isHex('0xAB')).toBe(true);
158+
expect(isHex('0x0')).toBe(true);
159+
expect(isHex('0x12345')).toBe(true);
160+
});
161+
162+
test('should return false for non-hex strings', () => {
163+
expect(isHex('0xG')).toBe(false);
164+
expect(isHex('ab')).toBe(false);
165+
expect(isHex('123')).toBe(false);
166+
expect(isHex('')).toBe(false);
167+
});
168+
});
169+
});

0 commit comments

Comments
 (0)