From 7ea2cb2c451de7038a7895162f725c2a8adc5b7f Mon Sep 17 00:00:00 2001 From: Gitkbc Date: Fri, 20 Mar 2026 00:24:05 +0530 Subject: [PATCH] feat: add progress_path helper with basic tests Refactored to return sprite sequence (aligned with ticker/spinner), removed percent-based logic, and updated docs/tests accordingly. --- spec/14-progress_spec.lua | 42 ++++++++++++++++++++++++++++++--------- src/terminal/progress.lua | 29 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/spec/14-progress_spec.lua b/spec/14-progress_spec.lua index 23808038..d04139de 100644 --- a/spec/14-progress_spec.lua +++ b/spec/14-progress_spec.lua @@ -2,7 +2,6 @@ local helpers = require "spec.helpers" describe("terminal.progress", function() - local progress local t local utils @@ -23,20 +22,15 @@ describe("terminal.progress", function() color = require "terminal.text.color" end) - teardown(function() helpers.unload() end) - before_each(function() helpers.clear_output() end) - - describe("spinner()", function() - it("uses visible width for colored sprites (ignores ANSI)", function() local red_sprite = color.fore_seq("red") .. COLORED_SPRITE_CHAR local expected_width = width.utf8swidth(utils.strip_ansi(red_sprite)) @@ -50,7 +44,6 @@ describe("terminal.progress", function() assert.are.equal(red_sprite .. t.cursor.position.left_seq(expected_width), helpers.get_output()) end) - it("uses visible width for colored done_sprite", function() local done_sprite = color.fore_seq("green") .. DONE_MESSAGE_TEXT local done_width = width.utf8swidth(utils.strip_ansi(done_sprite)) @@ -65,7 +58,6 @@ describe("terminal.progress", function() assert.are.equal(done_sprite .. t.cursor.position.left_seq(done_width), helpers.get_output()) end) - it("works correctly for plain sprites without ANSI", function() local spinner = progress.spinner({ sprites = { [0] = "", PLAIN_SPRITE_CHAR }, @@ -80,7 +72,39 @@ describe("terminal.progress", function() helpers.get_output() ) end) - end) + describe("progress_path()", function() + it("returns the correct number of frames", function() + local result = progress.progress_path(5) + assert.are.equal(5, #result) + end) + + it("shows the runner moving toward the start position", function() + local result = progress.progress_path(4, "S", ">") + assert.are.equal("S...>", result[1]) + assert.are.equal("S..>", result[2]) + assert.are.equal("S.>", result[3]) + assert.are.equal("S>", result[4]) + end) + + it("uses default icons when none are provided", function() + local result = progress.progress_path(3) + assert.are.equal("📍..🚙", result[1]) + assert.are.equal("📍.🚙", result[2]) + assert.are.equal("📍🚙", result[3]) + end) + + it("works with custom icons", function() + local result = progress.progress_path(3, "[", "O") + assert.are.equal("[..O", result[1]) + assert.are.equal("[.O", result[2]) + assert.are.equal("[O", result[3]) + end) + + it("handles zero width", function() + local result = progress.progress_path(0) + assert.are.equal(0, #result) + end) + end) end) diff --git a/src/terminal/progress.lua b/src/terminal/progress.lua index 920b7fe5..d51cee58 100644 --- a/src/terminal/progress.lua +++ b/src/terminal/progress.lua @@ -134,6 +134,35 @@ end +--- Path progress animation where a runner moves toward the start position. +-- Returns a table of animation frames for use as a sprite sequence with `spinner()`. +-- +-- Example: +-- local frames = M.progress_path(5, "📍", "🚙") +-- -- frames[1] = "📍....🚙" +-- -- frames[5] = "📍🚙" +-- +-- @tparam[opt=20] number width number of animation frames (not visual width) +-- @tparam[opt="📍"] string start_icon icon at the start (left) position +-- @tparam[opt="🚙"] string runner_icon icon representing the runner +-- @treturn table array of animation frame strings +function M.progress_path(width, start_icon, runner_icon) + width = width or 20 + start_icon = start_icon or "📍" + runner_icon = runner_icon or "🚙" + + local result = {} + + for i = 1, width do + local dots = string.rep(".", width - i) + result[i] = start_icon .. dots .. runner_icon + end + + return result +end + + + --- Create a text/led ticker like sprite-sequence for use with a progress spinner. -- @tparam string text the text to display -- @tparam[opt=40] number width the width of the ticker, in characters