66 lines
2.9 KiB
C++
66 lines
2.9 KiB
C++
// Standalone tests for reasampler::util::elapsedAtLeast — no VST3, no REAPER, no framework.
|
|
// Same fast assert loop as the sibling pure tests.
|
|
//
|
|
// Covers: the ordinary in-range case; the exact boundary (elapsed == interval opens the
|
|
// gate, elapsed == interval - 1 does not); the zero/zero first-call case; and the
|
|
// GetTickCount() WRAPAROUND — the one property in this idiom a reader has to think about.
|
|
// A `now` that has numerically wrapped past `since` must still open the gate once the true
|
|
// forward elapsed time reaches `interval`, never wedge it shut.
|
|
|
|
#include "../src/core/util/elapsed_at_least.h"
|
|
|
|
#include <cstdio>
|
|
#include <limits>
|
|
|
|
using namespace reasampler::util;
|
|
|
|
static int g_fail = 0;
|
|
#define CHECK(cond) do { if(!(cond)) { \
|
|
std::printf("FAIL line %d: %s\n", __LINE__, #cond); ++g_fail; } } while(0)
|
|
|
|
static void testOrdinaryCase() {
|
|
CHECK(elapsedAtLeast(1000u, 0u, 500u)); // well past the interval
|
|
CHECK(!elapsedAtLeast(400u, 0u, 500u)); // not there yet
|
|
}
|
|
|
|
static void testExactBoundary() {
|
|
CHECK(elapsedAtLeast(500u, 0u, 500u)); // exactly the interval: gate opens
|
|
CHECK(!elapsedAtLeast(499u, 0u, 500u)); // one ms short: gate stays shut
|
|
}
|
|
|
|
static void testZeroZeroFirstCallOpensImmediately() {
|
|
// A zero-initialized "last fired" tick (lastDetectTick's documented default) must not
|
|
// block the very first call.
|
|
CHECK(elapsedAtLeast(0u, 0u, 0u));
|
|
CHECK(elapsedAtLeast(1u, 0u, 0u));
|
|
}
|
|
|
|
// GetTickCount() wraps every ~49.7 days (2^32 ms). `since` sits near the top of the range;
|
|
// `now` has wrapped back around to a small value. Unsigned subtraction computes the correct
|
|
// forward distance (the gap to UINT_MAX plus the distance past zero) rather than reading as
|
|
// a huge negative gap that a signed/naive comparison would misinterpret as "not yet".
|
|
static void testWraparoundOpensRatherThanWedgesShut() {
|
|
const unsigned int kMax = std::numeric_limits<unsigned int>::max();
|
|
const unsigned int since = kMax - 49u; // 50 ms of headroom before the counter wraps
|
|
const unsigned int interval = 500u;
|
|
|
|
// 450 ms after the wrap: 51 ms (headroom to wrap) + 450 ms = 501 ms true elapsed -> open.
|
|
CHECK(elapsedAtLeast(450u, since, interval));
|
|
// 439 ms after the wrap: 51 + 439 = 490 ms true elapsed -> still shut.
|
|
CHECK(!elapsedAtLeast(439u, since, interval));
|
|
// Exactly at the wrap instant (now == 0): 51 ms true elapsed -> shut.
|
|
CHECK(!elapsedAtLeast(0u, since, interval));
|
|
// now == since (no time passed, mid-wrap-approach): never wedges into "always open".
|
|
CHECK(!elapsedAtLeast(since, since, interval));
|
|
}
|
|
|
|
int main() {
|
|
testOrdinaryCase();
|
|
testExactBoundary();
|
|
testZeroZeroFirstCallOpensImmediately();
|
|
testWraparoundOpensRatherThanWedgesShut();
|
|
if (g_fail == 0) std::printf("elapsed_at_least: all tests passed\n");
|
|
else std::printf("elapsed_at_least: %d FAILED\n", g_fail);
|
|
return g_fail == 0 ? 0 : 1;
|
|
}
|