import { describe, it, expect } from 'vitest';
import { op_and } from './and.js';
describe('AND (0x16)', () => {
it('performs basic AND', () => {
const frame = createFrame({ stack: [0b1100n, 0b1010n] });
expect(op_and(frame)).toBeNull();
expect(frame.stack[0]).toBe(0b1000n);
});
it('extracts address mask', () => {
const packed = 0x000000000000000000000000deadbeefn;
const mask = (1n << 160n) - 1n;
const frame = createFrame({ stack: [packed, mask] });
expect(op_and(frame)).toBeNull();
expect(frame.stack[0]).toBe(0xdeadbeefn);
});
it('handles identity (AND with all ones)', () => {
const MAX = (1n << 256n) - 1n;
const value = 0x123456n;
const frame = createFrame({ stack: [value, MAX] });
expect(op_and(frame)).toBeNull();
expect(frame.stack[0]).toBe(value);
});
it('handles null element (AND with zero)', () => {
const frame = createFrame({ stack: [0x123456n, 0n] });
expect(op_and(frame)).toBeNull();
expect(frame.stack[0]).toBe(0n);
});
it('is commutative', () => {
const a = 0xAAAAn;
const b = 0x5555n;
const frame1 = createFrame({ stack: [a, b] });
const frame2 = createFrame({ stack: [b, a] });
op_and(frame1);
op_and(frame2);
expect(frame1.stack[0]).toBe(frame2.stack[0]);
});
it('returns StackUnderflow with insufficient stack', () => {
const frame = createFrame({ stack: [0x123n] });
expect(op_and(frame)).toEqual({ type: 'StackUnderflow' });
});
it('returns OutOfGas when insufficient gas', () => {
const frame = createFrame({ stack: [0x123n, 0x456n], gasRemaining: 2n });
expect(op_and(frame)).toEqual({ type: 'OutOfGas' });
});
});