import XCTest
@testable import Physarum
import PhysarumEngine
final class MutateTests: XCTestCase {
func testMutateStaysWithinDescriptorRange() {
let state = AppState()
var g = SeededGenerator(seed: 11)
for _ in 0..<20 { state.mutate(strength: 0.15, using: &g) }
for d in ParamRegistry.all {
let v = d.get(state.edited)
XCTAssertGreaterThanOrEqual(v, d.range.lowerBound - 0.5, "\(d.idKey)")
XCTAssertLessThanOrEqual(v, d.range.upperBound + 0.5, "\(d.idKey)")
}
}
func testMutateRespectsLocks() {
let state = AppState()
state.toggleLock(.sensorDistance(1))
let d = ParamRegistry.all.first { $0.id == .sensorDistance(1) }!
let locked = d.get(state.edited)
var g = SeededGenerator(seed: 22)
state.mutate(strength: 0.3, using: &g)
XCTAssertEqual(d.get(state.edited), locked, accuracy: 1e-4)
}
func testMutateLeavesDiscreteEnumsUnchanged() {
let state = AppState()
let spawn = state.edited.spawnPattern
let blend = state.edited.blendMode
var g = SeededGenerator(seed: 33)
state.mutate(strength: 0.5, using: &g)
XCTAssertEqual(state.edited.spawnPattern, spawn)
XCTAssertEqual(state.edited.blendMode, blend)
}
func testMutatePushesUndo() {
let state = AppState()
let before = state.undoStack.count
var g = SeededGenerator(seed: 44)
state.mutate(using: &g)
XCTAssertEqual(state.undoStack.count, before + 1)
}
}