import { describe, it, expect } from 'vitest';
import { signextend } from './0x0b_SIGNEXTEND.js';
describe('SIGNEXTEND (0x0b)', () => {
it('extends positive 1-byte value', () => {
const frame = createFrame([0n, 0x7fn]);
expect(signextend(frame)).toBeNull();
expect(frame.stack).toEqual([0x7fn]); // Positive, stays same
});
it('extends negative 1-byte value', () => {
const frame = createFrame([0n, 0xffn]);
expect(signextend(frame)).toBeNull();
const MAX = (1n << 256n) - 1n;
expect(frame.stack).toEqual([MAX]); // All 1s
});
it('extends negative 2-byte value', () => {
const frame = createFrame([1n, 0x8000n]);
expect(signextend(frame)).toBeNull();
// Sign bit at position 15 set, extend with 1s
const MAX = (1n << 256n) - 1n;
const expected = (MAX & ~0x7fffn) | 0x8000n;
expect(frame.stack).toEqual([expected]);
});
it('clears upper bits when sign bit is 0', () => {
const frame = createFrame([0n, 0x123n]);
expect(signextend(frame)).toBeNull();
expect(frame.stack).toEqual([0x23n]); // Keep lower 8 bits only
});
it('handles byte index 31 (no extension)', () => {
const MAX = (1n << 256n) - 1n;
const frame = createFrame([31n, MAX]);
expect(signextend(frame)).toBeNull();
expect(frame.stack).toEqual([MAX]); // No change
});
it('handles byte index > 31 (no extension)', () => {
const frame = createFrame([32n, 0xffn]);
expect(signextend(frame)).toBeNull();
expect(frame.stack).toEqual([0xffn]); // No change
});
it('handles zero value', () => {
const frame = createFrame([0n, 0n]);
expect(signextend(frame)).toBeNull();
expect(frame.stack).toEqual([0n]);
});
it('returns StackUnderflow with insufficient stack', () => {
const frame = createFrame([0n]);
expect(signextend(frame)).toEqual({ type: 'StackUnderflow' });
});
it('returns OutOfGas when insufficient gas', () => {
const frame = createFrame([0n, 0x7fn], 4n);
expect(signextend(frame)).toEqual({ type: 'OutOfGas' });
});
});