import { describe, it, expect } from 'vitest';
import { handler_0xa4_LOG4 } from './0xa4_LOG4.js';
describe('LOG4 (0xa4)', () => {
it('emits log with 4 topics and empty data', () => {
const topic0 = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan;
const topic1 = 0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbn;
const topic2 = 0xccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccn;
const topic3 = 0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddn;
const frame = createFrame({
stack: [topic3, topic2, topic1, topic0, 0n, 0n],
gasRemaining: 1000000n,
});
const err = handler_0xa4_LOG4(frame);
expect(err).toBeNull();
expect(frame.logs).toHaveLength(1);
expect(frame.logs[0].topics).toEqual([topic0, topic1, topic2, topic3]);
expect(frame.gasRemaining).toBe(998125n);
});
it('emits log with 4 topics and data', () => {
const frame = createFrame({
memory: new Map([[0, 0xde], [1, 0xad], [2, 0xbe], [3, 0xef]]),
stack: [0x4444n, 0x3333n, 0x2222n, 0x1111n, 4n, 0n],
gasRemaining: 1000000n,
});
handler_0xa4_LOG4(frame);
const log = frame.logs[0];
expect(log.topics).toEqual([0x1111n, 0x2222n, 0x3333n, 0x4444n]);
expect(log.data).toEqual(new Uint8Array([0xde, 0xad, 0xbe, 0xef]));
});
it('returns WriteProtection in static context', () => {
const frame = createFrame({ isStatic: true, stack: [0n, 0n, 0n, 0n, 0n, 0n] });
const err = handler_0xa4_LOG4(frame);
expect(err).toEqual({ type: "WriteProtection" });
});
it('returns StackUnderflow with 5 items', () => {
const frame = createFrame({ stack: [0n, 0n, 0n, 0n, 0n] });
const err = handler_0xa4_LOG4(frame);
expect(err).toEqual({ type: "StackUnderflow" });
});
it('handles boundary topic values', () => {
const max = (1n << 256n) - 1n;
const frame = createFrame({
stack: [max, 0n, max, 0n, 0n, 0n],
gasRemaining: 1000000n,
});
handler_0xa4_LOG4(frame);
expect(frame.logs[0].topics).toEqual([0n, max, 0n, max]);
});
it('expands memory correctly with large data', () => {
const frame = createFrame({
stack: [0xffff, 0xffff, 0xffff, 0xffff, 1000n, 0n],
gasRemaining: 100000n,
});
handler_0xa4_LOG4(frame);
// Memory expands to cover offset 0 + length 1000 = 1000 bytes
// Word-aligned to 1024 bytes (32 words * 32)
expect(frame.memorySize).toBe(1024);
});
});