fix: correct buffer parser and timestamp test

Problem: parse_buffer classified /id/-prefixed task lines as headers
because '/' matches the '^%S' header pattern. Store timestamp test
was flaky when add and update ran within the same second.

Solution: check for task line patterns (id prefix or 2-space indent)
before falling through to the header branch. Backdate the initial
modified timestamp in the store update test.
This commit is contained in:
Barrett Ruth 2026-02-24 15:19:59 -05:00
parent 6cb5ae9dda
commit edd16f6ecf
2 changed files with 25 additions and 27 deletions

View file

@ -26,36 +26,34 @@ function M.parse_buffer(lines)
local current_category = nil local current_category = nil
for i, line in ipairs(lines) do for i, line in ipairs(lines) do
local id, body = line:match('^/(%d+)/( .+)$')
if not id then
body = line:match('^( .+)$')
end
if line == '' then if line == '' then
table.insert(result, { type = 'blank', lnum = i }) table.insert(result, { type = 'blank', lnum = i })
elseif id or body then
local stripped = body:match('^ (.+)$') or body
local priority = 0
if stripped:match('^! ') then
priority = 1
stripped = stripped:sub(3)
end
local description, metadata = parse.body(stripped)
if description and description ~= '' then
table.insert(result, {
type = 'task',
id = id and tonumber(id) or nil,
description = description,
priority = priority,
category = metadata.cat or current_category or config.get().default_category,
due = metadata.due,
lnum = i,
})
end
elseif line:match('^%S') then elseif line:match('^%S') then
current_category = line current_category = line
table.insert(result, { type = 'header', category = line, lnum = i }) table.insert(result, { type = 'header', category = line, lnum = i })
else
local id, body = line:match('^/(%d+)/( .+)$')
if not id then
body = line:match('^( .+)$')
end
if body then
local stripped = body:match('^ (.+)$') or body
local priority = 0
if stripped:match('^! ') then
priority = 1
stripped = stripped:sub(3)
end
local description, metadata = parse.body(stripped)
if description and description ~= '' then
table.insert(result, {
type = 'task',
id = id and tonumber(id) or nil,
description = description,
priority = priority,
category = metadata.cat or current_category or config.get().default_category,
due = metadata.due,
lnum = i,
})
end
end
end end
end end

View file

@ -106,11 +106,11 @@ describe('store', function()
it('updates fields and sets modified', function() it('updates fields and sets modified', function()
store.load() store.load()
local t = store.add({ description = 'Original' }) local t = store.add({ description = 'Original' })
local original_modified = t.modified t.modified = '2025-01-01T00:00:00Z'
store.update(t.id, { description = 'Updated' }) store.update(t.id, { description = 'Updated' })
local updated = store.get(t.id) local updated = store.get(t.id)
assert.are.equal('Updated', updated.description) assert.are.equal('Updated', updated.description)
assert.is_not.equal(original_modified, updated.modified) assert.is_not.equal('2025-01-01T00:00:00Z', updated.modified)
end) end)
it('sets end timestamp on completion', function() it('sets end timestamp on completion', function()