package com.onthelevel.core.sensors

import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class EmaTest {

    @Test
    fun `first sample passes through unfiltered`() {
        assertEquals(5.0, Ema(0.15).update(5.0, 0.0), 1e-9)
    }

    @Test
    fun `converges toward a constant input`() {
        val ema = Ema(0.15)
        ema.update(0.0, 0.0)
        var value = 0.0
        repeat(100) { value = ema.update(10.0, 0.02) }
        assertEquals(10.0, value, 1e-3)
    }

    @Test
    fun `one time constant covers ~63 percent of a step`() {
        val ema = Ema(1.0)
        ema.update(0.0, 0.0)
        val afterOneTau = ema.update(1.0, 1.0)
        assertEquals(0.632, afterOneTau, 0.01)
    }

    @Test
    fun `same elapsed time yields same smoothing regardless of sample rate`() {
        val fast = Ema(0.5)
        val slow = Ema(0.5)
        fast.update(0.0, 0.0)
        slow.update(0.0, 0.0)
        var fastValue = 0.0
        repeat(10) { fastValue = fast.update(1.0, 0.01) } // 100 ms in 10 steps
        val slowValue = slow.update(1.0, 0.1)             // 100 ms in 1 step
        assertTrue(kotlin.math.abs(fastValue - slowValue) < 0.02)
    }
}
