pending.nvim/spec/store_spec.lua
2026-02-24 15:21:44 -05:00

189 lines
5.3 KiB
Lua

require('spec.helpers')
local config = require('pending.config')
local store = require('pending.store')
describe('store', function()
local tmpdir
before_each(function()
tmpdir = vim.fn.tempname()
vim.fn.mkdir(tmpdir, 'p')
vim.g.pending = { data_path = tmpdir .. '/tasks.json' }
config.reset()
store.unload()
end)
after_each(function()
vim.fn.delete(tmpdir, 'rf')
vim.g.pending = nil
config.reset()
end)
describe('load', function()
it('returns empty data when no file exists', function()
local data = store.load()
assert.are.equal(1, data.version)
assert.are.equal(1, data.next_id)
assert.are.same({}, data.tasks)
end)
it('loads existing data', function()
local path = config.get().data_path
local f = io.open(path, 'w')
f:write(vim.json.encode({
version = 1,
next_id = 3,
tasks = {
{
id = 1,
description = 'Pending one',
status = 'pending',
entry = '2026-01-01T00:00:00Z',
modified = '2026-01-01T00:00:00Z',
},
{
id = 2,
description = 'Pending two',
status = 'done',
entry = '2026-01-01T00:00:00Z',
modified = '2026-01-01T00:00:00Z',
},
},
}))
f:close()
local data = store.load()
assert.are.equal(3, data.next_id)
assert.are.equal(2, #data.tasks)
assert.are.equal('Pending one', data.tasks[1].description)
assert.are.equal('done', data.tasks[2].status)
end)
it('preserves unknown fields', function()
local path = config.get().data_path
local f = io.open(path, 'w')
f:write(vim.json.encode({
version = 1,
next_id = 2,
tasks = {
{
id = 1,
description = 'Pending',
status = 'pending',
entry = '2026-01-01T00:00:00Z',
modified = '2026-01-01T00:00:00Z',
custom_field = 'hello',
},
},
}))
f:close()
store.load()
local task = store.get(1)
assert.is_not_nil(task._extra)
assert.are.equal('hello', task._extra.custom_field)
end)
end)
describe('add', function()
it('creates a task with incremented id', function()
store.load()
local t1 = store.add({ description = 'First' })
local t2 = store.add({ description = 'Second' })
assert.are.equal(1, t1.id)
assert.are.equal(2, t2.id)
assert.are.equal('pending', t1.status)
assert.are.equal('Inbox', t1.category)
end)
it('uses provided category', function()
store.load()
local t = store.add({ description = 'Test', category = 'Work' })
assert.are.equal('Work', t.category)
end)
end)
describe('update', function()
it('updates fields and sets modified', function()
store.load()
local t = store.add({ description = 'Original' })
t.modified = '2025-01-01T00:00:00Z'
store.update(t.id, { description = 'Updated' })
local updated = store.get(t.id)
assert.are.equal('Updated', updated.description)
assert.is_not.equal('2025-01-01T00:00:00Z', updated.modified)
end)
it('sets end timestamp on completion', function()
store.load()
local t = store.add({ description = 'Test' })
assert.is_nil(t['end'])
store.update(t.id, { status = 'done' })
local updated = store.get(t.id)
assert.is_not_nil(updated['end'])
end)
end)
describe('delete', function()
it('marks task as deleted', function()
store.load()
local t = store.add({ description = 'To delete' })
store.delete(t.id)
local deleted = store.get(t.id)
assert.are.equal('deleted', deleted.status)
assert.is_not_nil(deleted['end'])
end)
end)
describe('save and round-trip', function()
it('persists and reloads correctly', function()
store.load()
store.add({ description = 'Persisted', category = 'Work', priority = 1 })
store.save()
store.unload()
store.load()
local tasks = store.active_tasks()
assert.are.equal(1, #tasks)
assert.are.equal('Persisted', tasks[1].description)
assert.are.equal('Work', tasks[1].category)
assert.are.equal(1, tasks[1].priority)
end)
it('round-trips unknown fields', function()
local path = config.get().data_path
local f = io.open(path, 'w')
f:write(vim.json.encode({
version = 1,
next_id = 2,
tasks = {
{
id = 1,
description = 'Pending',
status = 'pending',
entry = '2026-01-01T00:00:00Z',
modified = '2026-01-01T00:00:00Z',
_gcal_event_id = 'abc123',
},
},
}))
f:close()
store.load()
store.save()
store.unload()
store.load()
local task = store.get(1)
assert.are.equal('abc123', task._extra._gcal_event_id)
end)
end)
describe('active_tasks', function()
it('excludes deleted tasks', function()
store.load()
store.add({ description = 'Active' })
local t2 = store.add({ description = 'To delete' })
store.delete(t2.id)
local active = store.active_tasks()
assert.are.equal(1, #active)
assert.are.equal('Active', active[1].description)
end)
end)
end)