use spectral_vm::field::Goldilocks;
use spectral_vm::vm::{SovereignVM, SpectralOp, InstructionRecord};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vm_creation() {
let mem_size = 1024;
let vm = SovereignVM::new(mem_size);
assert_eq!(vm.registers.len(), 32); assert_eq!(vm.memory.len(), mem_size);
assert!(vm.instruction_trace.is_empty());
}
#[test]
fn test_vm_basic_execution() {
let mut vm = SovereignVM::new(1024);
vm.registers[2] = Goldilocks::from_i64(10);
vm.registers[3] = Goldilocks::from_i64(20);
let instr = ((SpectralOp::S_ADD as u64) << 16) | (1 << 8) | 2;
vm.execute_instruction(instr);
assert_eq!(vm.registers[1].0, 30);
assert_eq!(vm.instruction_trace.len(), 1);
}
#[test]
fn test_vm_memory_operations() {
let mut vm = SovereignVM::new(1024);
vm.registers[1] = Goldilocks::from_i64(100); vm.registers[2] = Goldilocks::from_i64(42);
let store_instr = ((SpectralOp::S_STORE as u64) << 16) | (1 << 8) | 2;
vm.execute_instruction(store_instr);
vm.registers[3] = Goldilocks::from_i64(0); let load_instr = ((SpectralOp::S_LOAD as u64) << 16) | (3 << 8) | 1;
vm.execute_instruction(load_instr);
assert_eq!(vm.registers[3].0, 42);
}
#[test]
fn test_vm_arithmetic_operations() {
let mut vm = SovereignVM::new(1024);
vm.registers[1] = Goldilocks::from_i64(6);
vm.registers[2] = Goldilocks::from_i64(7);
let mul_instr = ((SpectralOp::S_MUL as u64) << 16) | (0 << 8) | 1; vm.execute_instruction(mul_instr);
assert_eq!(vm.registers[0].0, 42);
vm.registers[3] = Goldilocks::from_i64(100);
vm.registers[4] = Goldilocks::from_i64(25);
let sub_instr = ((SpectralOp::S_SUB as u64) << 16) | (5 << 8) | 3; vm.execute_instruction(sub_instr);
assert_eq!(vm.registers[5].0, 75);
}
#[test]
fn test_vm_instruction_trace() {
let mut vm = SovereignVM::new(1024);
vm.registers[1] = Goldilocks::from_i64(10);
vm.registers[2] = Goldilocks::from_i64(20);
let add_instr = ((SpectralOp::S_ADD as u64) << 16) | (0 << 8) | 1;
vm.execute_instruction(add_instr);
let mul_instr = ((SpectralOp::S_MUL as u64) << 16) | (3 << 8) | 2;
vm.execute_instruction(mul_instr);
assert_eq!(vm.instruction_trace.len(), 2);
let trace0 = &vm.instruction_trace[0];
assert_eq!(trace0.op, SpectralOp::S_ADD);
assert_eq!(trace0.operand1.0, 10);
assert_eq!(trace0.operand2.0, 0); assert_eq!(trace0.result.0, 10); }
#[test]
fn test_vm_edge_cases() {
let mut vm = SovereignVM::new(1024);
vm.registers[0] = Goldilocks::from_i64(0);
vm.registers[1] = Goldilocks::from_i64(42);
let add_instr = ((SpectralOp::S_ADD as u64) << 16) | (2 << 8) | 0;
vm.execute_instruction(add_instr);
assert_eq!(vm.registers[2].0, 42);
let invalid_instr = ((SpectralOp::S_ADD as u64) << 16) | (99 << 8) | 0; vm.execute_instruction(invalid_instr);
}
#[test]
fn test_vm_memory_bounds() {
let mut vm = SovereignVM::new(1024);
vm.registers[0] = Goldilocks::from_i64(100);
vm.registers[1] = Goldilocks::from_i64(999);
let store_instr = ((SpectralOp::S_STORE as u64) << 16) | (0 << 8) | 1;
vm.execute_instruction(store_instr);
assert_eq!(vm.memory[100].0, 999);
}
#[test]
fn test_instruction_record_creation() {
let record = InstructionRecord {
pc: 42,
op: SpectralOp::S_ADD,
operand1: Goldilocks::from_i64(10),
operand2: Goldilocks::from_i64(20),
result: Goldilocks::from_i64(30),
clk: Goldilocks::from_i64(1),
};
assert_eq!(record.pc, 42);
assert_eq!(record.result.0, 30);
assert_eq!(record.clk.0, 1);
}
#[test]
fn test_vm_serialization() {
let mut vm = SovereignVM::new(1024);
vm.registers[0] = Goldilocks::from_i64(123);
let serialized = serde_json::to_string(&vm.registers).unwrap();
let deserialized: Vec<Goldilocks> = serde_json::from_str(&serialized).unwrap();
assert_eq!(vm.registers[0], deserialized[0]);
}
}