aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* feat: implement gloss-fetch network layerCraig Jennings20 hours7-20/+274
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Walks the `gloss-fetch--sources' registry in the order set by the `gloss-fetch-sources' defcustom and aggregates per-source results into the public `gloss-fetch-definitions' shape. The Wiktionary REST fetcher GETs the page-definition endpoint, parses JSON, walks only English (`en') entries, and HTML-strips each sense via `libxml-parse-html-region'. A sense whose strip fails is dropped while the source keeps its `:ok' status with N-1 entries. The HTTP-status taxonomy is five values: `:ok', `:no-defs' (404 or no English senses on a 200), `:rate-limited' (429), `:server-error' (5xx, malformed JSON, schema mismatch, 4xx other than 404 or 429), and `:unreachable' (nil from `url-retrieve-synchronously', or a signaled error). The `:reason' string carries technical detail to *gloss-debug* and never reaches the user. libxml is probed once per session at first fetch. When absent, online fetch is disabled package-wide and every call signals `user-error' with the install hint. `url-retrieve-synchronously' is wrapped with the `gloss-fetch-timeout' defcustom (default 5 seconds). Tested with `make test'. 60 of 62 tests pass. The two pending failures load Wiktionary fixtures via `gloss-test--load-wiktionary-fixture', which is provided on a parallel branch and will pass once both branches land. The implementation has been verified against the captured fixtures end-to-end (anaphora returns 4 senses, SBIR returns 2, matching the design's expected counts).
* test: add gloss-fetch test suite (red phase)Craig Jennings20 hours9-0/+509
| | | | | | | | | | | | | | | | Eight test files cover the network layer's public and internal contract. The boundary mock is `url-retrieve-synchronously', wrapped by a small `testutil-gloss-fetch' helper that builds response buffers in the shape the url library returns. Tests cover the 200 happy paths (anaphora and SBIR fixtures), 404 to :no-defs, 5xx and 4xx-other and malformed JSON to :server-error, 429 to :rate-limited, nil-from-url to :unreachable, the libxml availability probe (one-shot, signals user-error when absent), the registry walker ordering, and the pure HTML strip helper across N/B/E. Tests fail on missing `gloss-fetch--*' functions, as expected for red phase.
* test: add Wiktionary fixture loader helperCraig Jennings21 hours2-0/+54
| | | | | | | | Append `gloss-test--load-wiktionary-fixture' to tests/testutil-gloss.el. It takes a fixture name (e.g. "anaphora") and returns the raw JSON body from tests/fixtures/wiktionary-NAME.json, or signals `error' with the full path when the file isn't there. The helper resolves the fixtures directory from a `defconst' captured at load time. That way it works the same whether a test file requires testutil-gloss directly or pulls it in transitively through `make test'. Three ERT cases under tests/test-testutil-gloss--load-wiktionary-fixture.el cover Normal (anaphora loads as a non-empty JSON string), Boundary (the smallest fixture, 404, loads), and Error (a missing fixture raises with the path embedded in the message). Verified with `make test': 35 passed, 0 unexpected.
* chore: capture Wiktionary REST fixtures for replayCraig Jennings21 hours5-0/+5
| | | | | | Save raw response bodies from the Wiktionary REST endpoint under tests/fixtures/. The fetch layer can replay them with a cl-letf on url-retrieve-synchronously instead of hitting the network in tests. The five fixtures cover the cases that matter for the parser. anaphora is the simple single-sense English entry. SBIR is an acronym with multiple senses. API is highly polysemous and multi-language (en, fr, id, la, pt). hapax-legomenon is the multi-word case, so it exercises URL-encoding for the space. The 404 fixture captures the JSON error body Wiktionary returns when a term isn't there.
* refactor: extract missing-glossary test helperCraig Jennings25 hours5-43/+34
| | | | | | | | Four tests across lookup, list, find-buffer-position, and first-call-creates-file shared the same boilerplate. Each let-bound gloss-file to a randomized nonexistent path, wrapped in unwind-protect, reset the cache, and cleaned up file and buffer afterward. Extracted as gloss-test--with-missing-glossary in testutil-gloss.el, parallel to the existing gloss-test--with-temp-glossary. The four call sites drop from 8-10 lines each to 2-3. Tested by running the full 32-test suite. All 32 pass in 0.21 seconds.
* feat: implement gloss-core data layerCraig Jennings25 hours2-18/+271
| | | | | | | | | | Public API: gloss-core-lookup, gloss-core-save, gloss-core-list, gloss-core-find-buffer-position. Save inserts entries at the alphabetical position (case-insensitive compare), creates the file and parent directory on first call, prompts on collision via completing-read over Replace/Append/Cancel, and updates the in-memory cache directly. Lookup checks gloss-file's mtime against the cached load time. If disk is newer than the buffer, it reverts the buffer first. Out-of-band edits land on the next read. Parser failures during reload preserve the existing cache and surface a one-line message. Tested by the 32-test suite from the previous commit. All 32 pass in 0.16 seconds. The defgroup and defcustoms (gloss-file, gloss-debug) live here rather than in gloss.el. That keeps the data layer self-contained when tests load it directly without the orchestration layer.
* test: add gloss-core test suite (red phase)Craig Jennings25 hours9-0/+481
| | | | | | | | The commit lands eight per-function test files and a shared testutil. 32 tests across Normal/Boundary/Error categories cover the public API (lookup, save, list, find-buffer-position) and the internals that need observable behavior tests (mtime invalidation, corrupt-file resilience, alphabetical insert, first-call file creation). All 32 fail with void-function on the gloss-core symbols. That is the intended red-phase signal. The next commit lands the implementation that turns them green. testutil-gloss provides a with-temp-glossary macro. It binds gloss-file to a temp file, resets the cache before and after, and cleans up the visiting buffer.
* chore: scaffold gloss packageCraig Jennings26 hours18-0/+2042
Five layered files per the design at docs/design/gloss.org. gloss-core for the data layer, gloss-fetch for the network layer, gloss-display for the UI, gloss-drill for the spaced-repetition export, and gloss.el as the entry point. All five are skeletons. Implementation comes next. The Makefile delegates to ert with the usual unit, integration, and per-file targets. It also runs paren and lint passes. The package is licensed GPL-3.0-or-later. README is a placeholder pointing at the design doc.