lookupTokenInfo() cut the symbol at 12 and the name at 64 UTF-16 units, so an emoji outside the Basic Multilingual Plane could be cut between its two halves and the half left over stored and shown as U+FFFD. Both are now cut on code points, as displaySymbol() does. A symbol already stored broken is not repaired. Model: opus-5-5
49 lines
1.6 KiB
JavaScript
49 lines
1.6 KiB
JavaScript
// lookupTokenInfo() cuts the symbol and name it reads off a contract on
|
|
// code-point boundaries, as displaySymbol() counts them, so an emoji outside
|
|
// the Basic Multilingual Plane is never stored cut in half
|
|
// (https://git.eeqj.de/sneak/AutistMask/issues/458).
|
|
|
|
// An emoji outside the Basic Multilingual Plane: two UTF-16 units.
|
|
const FOX = "\u{1F98A}";
|
|
|
|
// The leading "A" puts every emoji at an odd UTF-16 offset, so a cut that
|
|
// counts UTF-16 units lands between the two halves of one.
|
|
const SYMBOL = "A" + FOX.repeat(12);
|
|
const NAME = "A" + FOX.repeat(64);
|
|
|
|
// The contract answers symbol(), decimals() and name() with the values above.
|
|
jest.doMock("ethers", () => ({
|
|
...jest.requireActual("ethers"),
|
|
Contract: function () {
|
|
return {
|
|
symbol: async () => SYMBOL,
|
|
decimals: async () => 18n,
|
|
name: async () => NAME,
|
|
};
|
|
},
|
|
}));
|
|
|
|
const { lookupTokenInfo } = require("../src/shared/balances");
|
|
|
|
const ADDRESS = "0x1111111111111111111111111111111111111111";
|
|
const RPC_URL = "https://rpc.example.invalid";
|
|
|
|
beforeEach(() => {
|
|
// A token found is logged at info level, which is not under test.
|
|
jest.spyOn(console, "log").mockImplementation(() => {});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
test("the symbol is cut to 12 code points, never inside an emoji", async () => {
|
|
const { symbol } = await lookupTokenInfo(ADDRESS, RPC_URL, "mainnet");
|
|
expect(symbol).toBe("A" + FOX.repeat(11));
|
|
});
|
|
|
|
test("the name is cut to 64 code points, never inside an emoji", async () => {
|
|
const { name } = await lookupTokenInfo(ADDRESS, RPC_URL, "mainnet");
|
|
expect(name).toBe("A" + FOX.repeat(63));
|
|
});
|