test: add store, parse, and diff specs

Problem: need test coverage for core data operations, inline
metadata parsing, and buffer diff algorithm.

Solution: add busted specs for store CRUD, round-trip
preservation, parse body/command_add with configurable date
syntax, and diff create/delete/update/copy/move operations.
This commit is contained in:
Barrett Ruth 2026-02-24 15:10:09 -05:00 committed by Barrett Ruth
parent dfe09ef721
commit 8bd6bf8a6a
4 changed files with 483 additions and 0 deletions

139
spec/diff_spec.lua Normal file
View file

@ -0,0 +1,139 @@
require('spec.helpers')
local config = require('todo.config')
local store = require('todo.store')
describe('diff', function()
local tmpdir
local diff = require('todo.diff')
before_each(function()
tmpdir = vim.fn.tempname()
vim.fn.mkdir(tmpdir, 'p')
vim.g.todo = { data_path = tmpdir .. '/tasks.json' }
config.reset()
store.unload()
store.load()
end)
after_each(function()
vim.fn.delete(tmpdir, 'rf')
vim.g.todo = nil
config.reset()
end)
describe('parse_buffer', function()
it('parses headers and tasks', function()
local lines = {
'School',
'/1/ Do homework',
'/2/ ! Read chapter 5',
'',
'Errands',
'/3/ Buy groceries',
}
local result = diff.parse_buffer(lines)
assert.are.equal(6, #result)
assert.are.equal('header', result[1].type)
assert.are.equal('School', result[1].category)
assert.are.equal('task', result[2].type)
assert.are.equal(1, result[2].id)
assert.are.equal('Do homework', result[2].description)
assert.are.equal('School', result[2].category)
assert.are.equal('task', result[3].type)
assert.are.equal(1, result[3].priority)
assert.are.equal('blank', result[4].type)
assert.are.equal('Errands', result[6].category)
end)
it('handles new tasks without ids', function()
local lines = {
'Inbox',
' New task here',
}
local result = diff.parse_buffer(lines)
assert.are.equal(2, #result)
assert.are.equal('task', result[2].type)
assert.is_nil(result[2].id)
assert.are.equal('New task here', result[2].description)
end)
end)
describe('apply', function()
it('creates new tasks from buffer lines', function()
local lines = {
'Inbox',
' First task',
' Second task',
}
diff.apply(lines)
store.unload()
store.load()
local tasks = store.active_tasks()
assert.are.equal(2, #tasks)
assert.are.equal('First task', tasks[1].description)
assert.are.equal('Second task', tasks[2].description)
end)
it('deletes tasks removed from buffer', function()
store.add({ description = 'Keep me' })
store.add({ description = 'Delete me' })
store.save()
local lines = {
'Inbox',
'/1/ Keep me',
}
diff.apply(lines)
store.unload()
store.load()
local active = store.active_tasks()
assert.are.equal(1, #active)
assert.are.equal('Keep me', active[1].description)
local deleted = store.get(2)
assert.are.equal('deleted', deleted.status)
end)
it('updates modified tasks', function()
store.add({ description = 'Original' })
store.save()
local lines = {
'Inbox',
'/1/ Renamed',
}
diff.apply(lines)
store.unload()
store.load()
local task = store.get(1)
assert.are.equal('Renamed', task.description)
end)
it('handles duplicate ids as copies', function()
store.add({ description = 'Original' })
store.save()
local lines = {
'Inbox',
'/1/ Original',
'/1/ Copy of original',
}
diff.apply(lines)
store.unload()
store.load()
local tasks = store.active_tasks()
assert.are.equal(2, #tasks)
end)
it('moves tasks between categories', function()
store.add({ description = 'Moving task', category = 'Inbox' })
store.save()
local lines = {
'Work',
'/1/ Moving task',
}
diff.apply(lines)
store.unload()
store.load()
local task = store.get(1)
assert.are.equal('Work', task.category)
end)
end)
end)