summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/repeat_resolver.lua9
-rw-r--r--tests/run.lua42
2 files changed, 48 insertions, 3 deletions
diff --git a/lua/clever_f/repeat_resolver.lua b/lua/clever_f/repeat_resolver.lua
index 5368c49..2924bd6 100644
--- a/lua/clever_f/repeat_resolver.lua
+++ b/lua/clever_f/repeat_resolver.lua
@@ -166,9 +166,14 @@ function RepeatResolver:evaluate_timeout()
fail("repeat clock must return finite milliseconds", 2)
end
local record = resolver_records[self]
- local elapsed_ms = current_time - record.state.repeat_timestamp_ms
+ local elapsed_ms = M.truncate_elapsed_ms(
+ current_time - record.state.repeat_timestamp_ms
+ )
record.transitions:SetRepeatTimestamp(current_time)
- return nil, M.truncate_elapsed_ms(elapsed_ms)
+ if elapsed_ms <= timeout then
+ return M.Decision.REPEAT, elapsed_ms
+ end
+ return nil, elapsed_ms
end
RepeatResolver.check_timeout = RepeatResolver.evaluate_timeout
diff --git a/tests/run.lua b/tests/run.lua
index 76ac8bf..17d5b4b 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -3873,7 +3873,7 @@ test("Positive repeat timeout reads and stores the current clock", function()
})
local decision, elapsed_ms = resolver:evaluate_timeout()
- same(nil, decision)
+ same(repeat_resolver.Decision.REPEAT, decision)
same(100, elapsed_ms)
same(125.75, state.repeat_timestamp_ms)
local reads = 0
@@ -3895,6 +3895,46 @@ test("Elapsed repeat milliseconds truncate toward zero", function()
end, "finite")
end)
+test("Timely repeat keeps equality and restarts each interval", function()
+ local state, transitions = fresh_sequence_state()
+ transitions:SetRepeatTimestamp(100)
+ local host = MemoryHost.new({
+ configuration = { repeat_timeout_ms = 100 },
+ time_values_ms = { 200, 299.9 },
+ })
+ local resolver = repeat_resolver.new({
+ clock = host,
+ policy = policy.new(host),
+ })
+
+ local first_decision, first_elapsed = resolver:evaluate_timeout()
+ same(repeat_resolver.Decision.REPEAT, first_decision)
+ same(100, first_elapsed)
+ same(200, state.repeat_timestamp_ms)
+
+ local second_decision, second_elapsed = resolver:evaluate_timeout()
+ same(repeat_resolver.Decision.REPEAT, second_decision)
+ same(99, second_elapsed)
+ same(299.9, state.repeat_timestamp_ms)
+end)
+
+test("Zero repeat timeout keeps repetition without reading time", function()
+ fresh_sequence_state()
+ local host = MemoryHost.new({
+ configuration = { repeat_timeout_ms = 0 },
+ time_values_ms = { 1000000 },
+ })
+ local resolver = repeat_resolver.new({
+ clock = host,
+ policy = policy.new(host),
+ })
+
+ same(repeat_resolver.Decision.REPEAT, resolver:evaluate_timeout())
+ for _, operation in ipairs(host:operations()) do
+ falsy(operation.operation == "read_time_ms")
+ end
+end)
+
for _, item in ipairs(tests) do
local ok, failure = xpcall(item.body, debug.traceback)
if not ok then