From 587cad6d396b0a507f87e83369b156b7dad20635 Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 8 Feb 2024 23:41:36 +0100 Subject: Generate rolling chart with activity --- activity.lua | 47 +++++++++++++++++++++++++++-------------------- activity/dates.lua | 10 ++++++++++ spec/activity_spec.lua | 40 ++++++++++++++++++++++++++++++++-------- spec/dates_spec.lua | 18 ++++++++++++++++++ 4 files changed, 87 insertions(+), 28 deletions(-) diff --git a/activity.lua b/activity.lua index 405dc05..e0f6c07 100644 --- a/activity.lua +++ b/activity.lua @@ -4,18 +4,42 @@ local activity = {} local +function level (count) + if 0 < count and count <= 2 then + return 1 + end + if 2 < count and count <= 4 then + return 2 + end + if 4 < count and count <= 6 then + return 3 + end + if 6 < count then + return 4 + end + return 0 +end + + +local function generate_rolling (lookup, format, date) date = date or os.date"*t" local rows = "" local weekdays = {"", "Mon", "", "Wed", "", "Fri", ""} + local function year_and_day (week, weekday) + local days = week * 7 + date.wday - weekday + local at = dates.before(date, days) + return at.year, dates.day_of_year(at) + end + for index, weekday in pairs(weekdays) do rows = rows .. format.label(weekday) for week=0,51 do - rows = rows .. format.cell(0) + rows = rows .. format.cell(level(lookup(year_and_day(52 - week, index)))) end if date.wday >= index then - rows = rows .. format.cell(0) + rows = rows .. format.cell(level(lookup(year_and_day(0, index)))) else rows = rows .. format.spot() end @@ -35,22 +59,6 @@ function activity.generate_table (year, lookup, format, ...) return week * 7 + weekday - first_weekday + 1 end - local function level (count) - if 0 < count and count <= 2 then - return 1 - end - if 2 < count and count <= 4 then - return 2 - end - if 4 < count and count <= 6 then - return 3 - end - if 6 < count then - return 4 - end - return 0 - end - local function day_level (first_weekday, week, weekday) return level(lookup(year, day_of_year(first_weekday, week, weekday))) end @@ -81,8 +89,7 @@ function activity.generate_table (year, lookup, format, ...) for index, weekday in pairs(weekdays) do rows = rows .. row(weekday, index, start_from, index >= start_from, index <= end_at) end - return - format.start_document"Activity" .. format.start_table() .. rows .. format.end_table() .. format.end_document() + return format.start_document"Activity" .. format.start_table() .. rows .. format.end_table() .. format.end_document() end diff --git a/activity/dates.lua b/activity/dates.lua index 038ea6b..d5c7de1 100644 --- a/activity/dates.lua +++ b/activity/dates.lua @@ -1,4 +1,7 @@ local dates = {} +local one_day = os.difftime( + os.time{year=1970, month=1, day=2}, + os.time{year=1970, month=1, day=1}) function dates.days_in (year) @@ -29,4 +32,11 @@ function dates.day_of_year (date) end +function dates.before (date, days) + local time = os.time(date) - days * one_day + date = os.date("*t", time) + return {year=date.year, month=date.month, day=date.day} +end + + return dates diff --git a/spec/activity_spec.lua b/spec/activity_spec.lua index 581b0ba..38338e8 100644 --- a/spec/activity_spec.lua +++ b/spec/activity_spec.lua @@ -43,21 +43,26 @@ Fri 0000000000000000000000000000000000000000000000000000_ ]] -describe("Generator", function() - describe("shall generate correct table for year", function() - local function lookup (year, day) return 0 end +local +function always_zero (...) + return 0 +end + +describe("Yearly chart generator", function() + describe("shall generate empty table for year", function() it("2024", function() - assert.are.equal(Y2024, activity.generate_table(2024, lookup, plain)) + assert.are.equal(Y2024, activity.generate_table(2024, always_zero, plain)) end) it("2023", function() - assert.are.equal(Y2023, activity.generate_table(2023, lookup, plain)) + assert.are.equal(Y2023, activity.generate_table(2023, always_zero, plain)) end) it("2020", function() - assert.are.equal(Y2020, activity.generate_table(2020, lookup, plain)) + assert.are.equal(Y2020, activity.generate_table(2020, always_zero, plain)) end) + end) describe("shall put activity into cells for", function() @@ -76,9 +81,28 @@ describe("Generator", function() assert.are.equal(Y2024:gsub("0", "1"), activity.generate_table(2024, lookup, plain)) end) end) +end) + + +describe("Rolling chart generator", function() + it("shall generate empty table", function() + local date = os.date("*t", os.time{year=2024, month=2, day=8}) + assert.are.equal(ROLL, activity.generate_table("rolling", always_zero, plain, date)) + end) - it("shall support generating rolling table", function() + it("shall put activity into cells", function() local date = os.date("*t", os.time{year=2024, month=2, day=8}) - assert.are.equal(ROLL, activity.generate_table("rolling", lookup, plain, date)) + + local function lookup (year, day) + if year == 2023 and day >= 36 then + return 1 + end + if year == 2024 and day <= 39 then + return 1 + end + return 0 + end + + assert.are.equal(ROLL:gsub("0", "1"), activity.generate_table("rolling", lookup, plain, date)) end) end) diff --git a/spec/dates_spec.lua b/spec/dates_spec.lua index a8b5a71..d820080 100644 --- a/spec/dates_spec.lua +++ b/spec/dates_spec.lua @@ -44,3 +44,21 @@ describe("First week day of", function() assert.are.equal(4, dates.first_week_day(2020)) end) end) + + +describe("Day 5 days before", function() + it("3 Mar 2023 is 26 Feb", function() + local date = {year=2023, month=3, day=3} + assert.are.same({year=2023, month=2, day=26}, dates.before(date, 5)) + end) + + it("3 Mar 2024 is 27 Feb", function() + local date = {year=2024, month=3, day=3} + assert.are.same({year=2024, month=2, day=27}, dates.before(date, 5)) + end) + + it("2 Jan 2024 is 28 Dec 2023", function() + local date = {year=2024, month=1, day=2} + assert.are.same({year=2023, month=12, day=28}, dates.before(date, 5)) + end) +end) -- cgit v1.1