refactor: organize tests and dry (#49)
* refactor(store): convert singleton to Store.new() factory
Problem: store.lua used module-level _data singleton, making
project-local stores impossible and creating hidden global state.
Solution: introduce Store metatable with all operations as instance
methods. M.new(path) constructs an instance; M.resolve_path()
searches upward for .pending.json and falls back to
config.get().data_path. Singleton module API is removed.
* refactor(diff): accept store instance as parameter
Problem: diff.apply called store singleton methods directly, coupling
it to global state and preventing use with project-local stores.
Solution: change signature to apply(lines, s, hidden_ids?) where s is
a pending.Store instance. All store operations now go through s.
* refactor(buffer): add set_store/store accessors, drop singleton dep
Problem: buffer.lua imported store directly and called singleton
methods, preventing it from working with per-project store instances.
Solution: add module-level _store, M.set_store(s), and M.store()
accessors. open() and render() use _store instead of the singleton.
init.lua will call buffer.set_store(s) before buffer.open().
* refactor(complete,health,sync,plugin): update callers to store instance API
Problem: complete.lua, health.lua, sync/gcal.lua, and plugin/pending.lua
all called singleton store methods directly.
Solution: complete.lua uses buffer.store() for category lookups;
health.lua uses store.new(store.resolve_path()) and reports the
resolved path; gcal.lua calls require('pending').store() for task
access; plugin tab-completion creates ephemeral store instances via
store.new(store.resolve_path()). Add 'init' to the subcommands list.
* feat(init): thread Store instance through init, add :Pending init
Problem: init.lua called singleton store methods throughout, and there
was no way to create a project-local .pending.json file.
Solution: add module-level _store and private get_store() that
lazy-constructs via store.new(store.resolve_path()). Add public
M.store() accessor used by specs and sync backends. M.open() calls
buffer.set_store(get_store()) before buffer.open(). All store
callsites converted to get_store():method(). goto_file() and
add_here() derive the data directory from get_store().path.
Add M.init() which creates .pending.json in cwd and dispatches from
M.command() as ':Pending init'.
* test: update all specs for Store instance API
Problem: every spec used the old singleton API (store.unload(),
store.load(), store.add(), etc.) and diff.apply(lines, hidden).
Solution: lower-level specs (store, diff, views, complete, file) use
s = store.new(path); s:load() directly. Higher-level specs (archive,
edit, filter, status, sync) reset package.loaded['pending'] in
before_each and use pending.store() to access the live instance.
diff.apply calls updated to diff.apply(lines, s, hidden_ids).
* docs(pending): document :Pending init and store resolution
Add *pending-store-resolution* section explaining upward .pending.json
discovery and fallback to the global data_path. Document :Pending init
under COMMANDS. Add a cross-reference from the data_path config field.
* ci: format
* ci: remove unused variable
This commit is contained in:
parent
dbd76d6759
commit
41bda24570
19 changed files with 819 additions and 703 deletions
|
|
@ -356,6 +356,13 @@ COMMANDS *pending-commands*
|
|||
Equivalent to the `U` buffer-local key (see |pending-mappings|). Up to 20
|
||||
levels of undo are persisted across sessions.
|
||||
|
||||
*:Pending-init*
|
||||
:Pending init
|
||||
Create a project-local `.pending.json` file in the current working
|
||||
directory. After creation, `:Pending` will use this file instead of the
|
||||
global store (see |pending-store-resolution|). Errors if `.pending.json`
|
||||
already exists in the current directory.
|
||||
|
||||
*:PendingTab*
|
||||
:PendingTab
|
||||
Open the task buffer in a new tab.
|
||||
|
|
@ -614,9 +621,11 @@ All fields are optional. Unset fields use the defaults shown above.
|
|||
*pending.Config*
|
||||
Fields: ~
|
||||
{data_path} (string)
|
||||
Path to the JSON file where tasks are stored.
|
||||
Path to the global JSON file where tasks are stored.
|
||||
Default: `stdpath('data') .. '/pending/tasks.json'`.
|
||||
The directory is created automatically on first save.
|
||||
See |pending-store-resolution| for how the active
|
||||
store is chosen at runtime.
|
||||
|
||||
{default_view} ('category'|'priority', default: 'category')
|
||||
The view to use when the buffer is opened for the
|
||||
|
|
@ -1060,10 +1069,31 @@ Checks performed: ~
|
|||
- Discovers sync backends under `lua/pending/sync/` and runs each backend's
|
||||
`health()` function if it exists (e.g. gcal checks for `curl` and `openssl`)
|
||||
|
||||
==============================================================================
|
||||
STORE RESOLUTION *pending-store-resolution*
|
||||
|
||||
When pending.nvim opens the task buffer it resolves which store file to use:
|
||||
|
||||
1. Search upward from `vim.fn.getcwd()` for a file named `.pending.json`.
|
||||
2. If found, use that file as the active store (project-local store).
|
||||
3. If not found, fall back to `data_path` from |pending-config| (global
|
||||
store).
|
||||
|
||||
This means placing a `.pending.json` file in a project root makes that
|
||||
project use an isolated task list. Tasks in the project store are completely
|
||||
separate from tasks in the global store; there is no aggregation.
|
||||
|
||||
To create a project-local store in the current directory: >vim
|
||||
:Pending init
|
||||
<
|
||||
|
||||
The `:checkhealth pending` report shows which store file is currently active.
|
||||
|
||||
==============================================================================
|
||||
DATA FORMAT *pending-data*
|
||||
|
||||
Tasks are stored as JSON at `data_path`. The file is safe to edit by hand and
|
||||
Tasks are stored as JSON at the active store path (see
|
||||
|pending-store-resolution|). The file is safe to edit by hand and
|
||||
is forward-compatible — unknown fields are preserved on every read/write cycle
|
||||
via the `_extra` table.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue