import { describe, it, expect } from 'vitest';
import { exp } from './0x0a_EXP.js';
describe('EXP (0x0a)', () => {
it('computes base^exponent', () => {
const frame = createFrame([2n, 3n]);
expect(exp(frame)).toBeNull();
expect(frame.stack).toEqual([8n]); // 2^3 = 8
});
it('handles exponent of 0', () => {
const frame = createFrame([999n, 0n]);
expect(exp(frame)).toBeNull();
expect(frame.stack).toEqual([1n]); // Any^0 = 1
});
it('handles base of 0', () => {
const frame = createFrame([0n, 5n]);
expect(exp(frame)).toBeNull();
expect(frame.stack).toEqual([0n]); // 0^5 = 0
});
it('handles 0^0 case', () => {
const frame = createFrame([0n, 0n]);
expect(exp(frame)).toBeNull();
expect(frame.stack).toEqual([1n]); // EVM: 0^0 = 1
});
it('handles overflow wrapping', () => {
const frame = createFrame([2n, 256n]);
expect(exp(frame)).toBeNull();
expect(frame.stack).toEqual([0n]); // 2^256 wraps to 0
});
it('computes 10^18', () => {
const frame = createFrame([10n, 18n]);
expect(exp(frame)).toBeNull();
expect(frame.stack).toEqual([1000000000000000000n]);
});
it('consumes base gas when exponent is 0', () => {
const frame = createFrame([999n, 0n], 100n);
expect(exp(frame)).toBeNull();
expect(frame.gasRemaining).toBe(90n); // 100 - 10
});
it('consumes dynamic gas for 1-byte exponent', () => {
const frame = createFrame([2n, 255n], 1000n);
expect(exp(frame)).toBeNull();
expect(frame.gasRemaining).toBe(940n); // 1000 - 60
});
it('consumes dynamic gas for 2-byte exponent', () => {
const frame = createFrame([2n, 256n], 1000n);
expect(exp(frame)).toBeNull();
expect(frame.gasRemaining).toBe(890n); // 1000 - 110
});
it('returns StackUnderflow with insufficient stack', () => {
const frame = createFrame([5n]);
expect(exp(frame)).toEqual({ type: 'StackUnderflow' });
});
it('returns OutOfGas when insufficient gas', () => {
const frame = createFrame([2n, 256n], 50n);
expect(exp(frame)).toEqual({ type: 'OutOfGas' });
});
});