277 lines
No EOL
9.7 KiB
Lua
277 lines
No EOL
9.7 KiB
Lua
-- Unit tests for date parsing and formatting utilities
|
|
local date_utils = require('notex.utils.date')
|
|
|
|
describe("date utilities", function()
|
|
|
|
describe("parse_date", function()
|
|
it("should parse ISO 8601 dates", function()
|
|
local timestamp = date_utils.parse_date("2023-12-25")
|
|
assert.is_not_nil(timestamp)
|
|
|
|
local formatted = os.date("%Y-%m-%d", timestamp)
|
|
assert.equals("2023-12-25", formatted)
|
|
end)
|
|
|
|
it("should parse ISO 8601 datetimes", function()
|
|
local timestamp = date_utils.parse_date("2023-12-25T10:30:00")
|
|
assert.is_not_nil(timestamp)
|
|
|
|
local formatted = os.date("%Y-%m-%d %H:%M:%S", timestamp)
|
|
assert.equals("2023-12-25 10:30:00", formatted)
|
|
end)
|
|
|
|
it("should parse ISO 8601 with timezone", function()
|
|
local timestamp = date_utils.parse_date("2023-12-25T10:30:00+02:00")
|
|
assert.is_not_nil(timestamp)
|
|
|
|
-- Should be converted to UTC
|
|
local utc_formatted = os.date("%Y-%m-%d %H:%M:%S", timestamp)
|
|
assert.equals("2023-12-25 08:30:00", utc_formatted)
|
|
end)
|
|
|
|
it("should parse relative dates", function()
|
|
-- Test 1 day ago
|
|
local one_day_ago = os.time() - 86400
|
|
local timestamp = date_utils.parse_date("1d")
|
|
assert.is_true(math.abs(timestamp - one_day_ago) < 60) -- Within 1 minute
|
|
|
|
-- Test 1 hour ago
|
|
local one_hour_ago = os.time() - 3600
|
|
timestamp = date_utils.parse_date("1h")
|
|
assert.is_true(math.abs(timestamp - one_hour_ago) < 60) -- Within 1 minute
|
|
end)
|
|
|
|
it("should parse natural dates", function()
|
|
local timestamp = date_utils.parse_date("2023-12-25")
|
|
assert.is_not_nil(timestamp)
|
|
|
|
local formatted = os.date("%Y-%m-%d", timestamp)
|
|
assert.equals("2023-12-25", formatted)
|
|
end)
|
|
|
|
it("should return nil for invalid dates", function()
|
|
local timestamp = date_utils.parse_date("invalid date")
|
|
assert.is_nil(timestamp)
|
|
|
|
timestamp = date_utils.parse_date("")
|
|
assert.is_nil(timestamp)
|
|
|
|
timestamp = date_utils.parse_date(nil)
|
|
assert.is_nil(timestamp)
|
|
end)
|
|
|
|
it("should parse common date formats", function()
|
|
-- MM/DD/YYYY
|
|
local timestamp = date_utils.parse_date("12/25/2023")
|
|
assert.is_not_nil(timestamp)
|
|
|
|
-- MM-DD-YYYY
|
|
timestamp = date_utils.parse_date("12-25-2023")
|
|
assert.is_not_nil(timestamp)
|
|
end)
|
|
end)
|
|
|
|
describe("format_date", function()
|
|
it("should format timestamp to string", function()
|
|
local timestamp = os.time({year = 2023, month = 12, day = 25, hour = 10, min = 30, sec = 0})
|
|
local formatted = date_utils.format_date(timestamp, "%Y-%m-%d %H:%M:%S")
|
|
assert.equals("2023-12-25 10:30:00", formatted)
|
|
end)
|
|
|
|
it("should use default format", function()
|
|
local timestamp = os.time({year = 2023, month = 12, day = 25})
|
|
local formatted = date_utils.format_date(timestamp)
|
|
assert.equals("2023-12-25", formatted)
|
|
end)
|
|
|
|
it("should handle nil timestamp", function()
|
|
local formatted = date_utils.format_date(nil)
|
|
assert.equals("", formatted)
|
|
end)
|
|
end)
|
|
|
|
describe("get_relative_time", function()
|
|
it("should return 'just now' for recent times", function()
|
|
local current_time = os.time()
|
|
local relative = date_utils.get_relative_time(current_time)
|
|
assert.equals("just now", relative)
|
|
end)
|
|
|
|
it("should return minutes ago", function()
|
|
local timestamp = os.time() - 120 -- 2 minutes ago
|
|
local relative = date_utils.get_relative_time(timestamp)
|
|
assert.equals("2 minutes ago", relative)
|
|
end)
|
|
|
|
it("should return hours ago", function()
|
|
local timestamp = os.time() - 7200 -- 2 hours ago
|
|
local relative = date_utils.get_relative_time(timestamp)
|
|
assert.equals("2 hours ago", relative)
|
|
end)
|
|
|
|
it("should return days ago", function()
|
|
local timestamp = os.time() - 172800 -- 2 days ago
|
|
local relative = date_utils.get_relative_time(timestamp)
|
|
assert.equals("2 days ago", relative)
|
|
end)
|
|
|
|
it("should return months ago", function()
|
|
local timestamp = os.time() - (60 * 86400) -- ~2 months ago
|
|
local relative = date_utils.get_relative_time(timestamp)
|
|
assert.matches("months ago", relative)
|
|
end)
|
|
|
|
it("should return years ago", function()
|
|
local timestamp = os.time() - (365 * 86400) -- ~1 year ago
|
|
local relative = date_utils.get_relative_time(timestamp)
|
|
assert.matches("year ago", relative)
|
|
end)
|
|
|
|
it("should handle singular forms", function()
|
|
local timestamp = os.time() - 60 -- 1 minute ago
|
|
local relative = date_utils.get_relative_time(timestamp)
|
|
assert.equals("1 minute ago", relative)
|
|
|
|
timestamp = os.time() - 3600 -- 1 hour ago
|
|
relative = date_utils.get_relative_time(timestamp)
|
|
assert.equals("1 hour ago", relative)
|
|
end)
|
|
end)
|
|
|
|
describe("get_month_number", function()
|
|
it("should convert month names to numbers", function()
|
|
assert.equals(1, date_utils.get_month_number("January"))
|
|
assert.equals(12, date_utils.get_month_number("December"))
|
|
assert.equals(6, date_utils.get_month_number("June"))
|
|
end)
|
|
|
|
it("should handle short month names", function()
|
|
assert.equals(1, date_utils.get_month_number("Jan"))
|
|
assert.equals(12, date_utils.get_month_number("Dec"))
|
|
assert.equals(6, date_utils.get_month_number("Jun"))
|
|
end)
|
|
|
|
it("should be case insensitive", function()
|
|
assert.equals(1, date_utils.get_month_number("JANUARY"))
|
|
assert.equals(1, date_utils.get_month_number("january"))
|
|
assert.equals(1, date_utils.get_month_number("jan"))
|
|
end)
|
|
|
|
it("should return nil for invalid month names", function()
|
|
assert.is_nil(date_utils.get_month_number("NotAMonth"))
|
|
assert.is_nil(date_utils.get_month_number(""))
|
|
end)
|
|
end)
|
|
|
|
describe("get_month_name", function()
|
|
it("should convert month numbers to names", function()
|
|
assert.equals("January", date_utils.get_month_name(1))
|
|
assert.equals("December", date_utils.get_month_name(12))
|
|
assert.equals("June", date_utils.get_month_name(6))
|
|
end)
|
|
|
|
it("should return short names when requested", function()
|
|
assert.equals("Jan", date_utils.get_month_name(1, true))
|
|
assert.equals("Dec", date_utils.get_month_name(12, true))
|
|
assert.equals("Jun", date_utils.get_month_name(6, true))
|
|
end)
|
|
|
|
it("should return nil for invalid month numbers", function()
|
|
assert.is_nil(date_utils.get_month_name(0))
|
|
assert.is_nil(date_utils.get_month_name(13))
|
|
assert.is_nil(date_utils.get_month_name(-1))
|
|
end)
|
|
end)
|
|
|
|
describe("is_valid_date", function()
|
|
it("should validate correct dates", function()
|
|
assert.is_true(date_utils.is_valid_date("2023-12-25"))
|
|
assert.is_true(date_utils.is_valid_date("2023-12-25T10:30:00"))
|
|
assert.is_true(date_utils.is_valid_date("1d"))
|
|
end)
|
|
|
|
it("should reject invalid dates", function()
|
|
assert.is_false(date_utils.is_valid_date("invalid"))
|
|
assert.is_false(date_utils.is_valid_date(""))
|
|
assert.is_false(date_utils.is_valid_date(nil))
|
|
end)
|
|
end)
|
|
|
|
describe("add_time", function()
|
|
it("should add time to timestamp", function()
|
|
local timestamp = os.time({year = 2023, month = 12, day = 25})
|
|
local new_timestamp = date_utils.add_time(timestamp, 1, "days")
|
|
|
|
local expected = os.time({year = 2023, month = 12, day = 26})
|
|
assert.equals(expected, new_timestamp)
|
|
end)
|
|
|
|
it("should add different time units", function()
|
|
local timestamp = os.time({year = 2023, month = 12, day = 25, hour = 10})
|
|
|
|
-- Add hours
|
|
local new_timestamp = date_utils.add_time(timestamp, 2, "hours")
|
|
local expected = os.time({year = 2023, month = 12, day = 25, hour = 12})
|
|
assert.equals(expected, new_timestamp)
|
|
|
|
-- Add minutes
|
|
new_timestamp = date_utils.add_time(timestamp, 30, "minutes")
|
|
expected = os.time({year = 2023, month = 12, day = 25, hour = 10, min = 30})
|
|
assert.equals(expected, new_timestamp)
|
|
end)
|
|
end)
|
|
|
|
describe("get_date_range", function()
|
|
it("should calculate date range", function()
|
|
local range = date_utils.get_date_range("2023-12-25", "2023-12-27")
|
|
|
|
assert.is_not_nil(range)
|
|
assert.equals(2, range.duration_days)
|
|
assert.equals("2023-12-25", range.start_formatted)
|
|
assert.equals("2023-12-27", range.end_formatted)
|
|
end)
|
|
|
|
it("should return nil for invalid dates", function()
|
|
local range = date_utils.get_date_range("invalid", "2023-12-27")
|
|
assert.is_nil(range)
|
|
end)
|
|
end)
|
|
|
|
describe("get_week_bounds", function()
|
|
it("should get week start and end", function()
|
|
local week_bounds = date_utils.get_week_bounds()
|
|
|
|
assert.is_not_nil(week_bounds.start_timestamp)
|
|
assert.is_not_nil(week_bounds.end_timestamp)
|
|
assert.is_not_nil(week_bounds.start_formatted)
|
|
assert.is_not_nil(week_bounds.end_formatted)
|
|
|
|
-- Should be 7 days apart
|
|
local duration = week_bounds.end_timestamp - week_bounds.start_timestamp
|
|
assert.equals(6 * 86400, duration) -- 6 days in seconds
|
|
end)
|
|
end)
|
|
|
|
describe("get_month_bounds", function()
|
|
it("should get month start and end", function()
|
|
local month_bounds = date_utils.get_month_bounds(os.time({year = 2023, month = 12, day = 15}))
|
|
|
|
assert.is_not_nil(month_bounds.start_timestamp)
|
|
assert.is_not_nil(month_bounds.end_timestamp)
|
|
assert.equals("2023-12-01", month_bounds.start_formatted)
|
|
assert.equals("2023-12-31", month_bounds.end_formatted)
|
|
end)
|
|
end)
|
|
|
|
describe("get_timezones", function()
|
|
it("should return list of timezones", function()
|
|
local timezones = date_utils.get_timezones()
|
|
|
|
assert.is_table(timezones)
|
|
assert.is_true(#timezones > 0)
|
|
assert.is_true(vim.tbl_contains(timezones, "UTC"))
|
|
assert.is_true(vim.tbl_contains(timezones, "America/New_York"))
|
|
end)
|
|
end)
|
|
|
|
end) |