import XCTest
@testable import Physarum
final class AudioTuningCodableTests: XCTestCase {
// A `_tuning.json` written before the balance constants existed must still decode:
// the synthesised decoder would throw on the missing keys and drop the user into the
// corrupt-file fallback, silently losing values tuned on the device.
func testDecodesLegacyFileWithoutBalanceKeys() throws {
let legacy = Data(#"{"envCoef":0.3,"gateLo":0.05,"gateHi":0.25}"#.utf8)
let t = try JSONDecoder().decode(AudioTuning.self, from: legacy)
XCTAssertEqual(t.envCoef, 0.3, accuracy: 1e-6)
XCTAssertEqual(t.gateLo, 0.05, accuracy: 1e-6)
XCTAssertEqual(t.gateHi, 0.25, accuracy: 1e-6)
XCTAssertTrue(t.adaptiveBalance)
XCTAssertEqual(t.peakTau, 4.0, accuracy: 1e-6)
XCTAssertEqual(t.valleyTau, 8.0, accuracy: 1e-6)
XCTAssertEqual(t.minSpan, 0.08, accuracy: 1e-6)
}
func testRoundTripPreservesAllFields() throws {
var t = AudioTuning()
t.peakTau = 6.5
t.adaptiveBalance = false
let data = try JSONEncoder().encode(t)
let back = try JSONDecoder().decode(AudioTuning.self, from: data)
XCTAssertEqual(back, t)
}
func testDefaultsMatchSpec() {
let t = AudioTuning()
XCTAssertEqual(t.peakFloor, 0.02, accuracy: 1e-6)
XCTAssertEqual(t.bandGateLo, 0.06, accuracy: 1e-6)
XCTAssertEqual(t.bandGateHi, 0.15, accuracy: 1e-6)
}
}