jekyll-client-search 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +121 -0
- data/LICENSE +22 -0
- data/NOTICE +49 -0
- data/README.developer.md +204 -0
- data/README.md +948 -0
- data/assets/adapters/elasticlunr.js +59 -0
- data/assets/adapters/minisearch.js +57 -0
- data/assets/adapters/semantic.js +154 -0
- data/assets/client-search-base.js +294 -0
- data/assets/client-search-related.js +176 -0
- data/assets/includes/related-articles.html +36 -0
- data/assets/layouts/post-with-related.html +54 -0
- data/assets/query-embedders/ollama-api.js +63 -0
- data/assets/query-embedders/transformers-worker.js +130 -0
- data/assets/query-embedders/transformers.js +223 -0
- data/docs/assets/icon-256.png +0 -0
- data/docs/assets/icon.svg +133 -0
- data/lib/jekyll/client_search/configuration.rb +152 -0
- data/lib/jekyll/client_search/configuration_accessors.rb +48 -0
- data/lib/jekyll/client_search/document_builder.rb +66 -0
- data/lib/jekyll/client_search/embedder_config_page.rb +14 -0
- data/lib/jekyll/client_search/embedding_configuration.rb +95 -0
- data/lib/jekyll/client_search/generator.rb +134 -0
- data/lib/jekyll/client_search/index_cache.rb +82 -0
- data/lib/jekyll/client_search/live_search_configuration.rb +70 -0
- data/lib/jekyll/client_search/ollama_embedding_adapter.rb +59 -0
- data/lib/jekyll/client_search/query_embedder_configuration.rb +127 -0
- data/lib/jekyll/client_search/related_analyzer.rb +152 -0
- data/lib/jekyll/client_search/related_configuration.rb +103 -0
- data/lib/jekyll/client_search/related_page.rb +14 -0
- data/lib/jekyll/client_search/related_tag.rb +76 -0
- data/lib/jekyll/client_search/runtime_config_page.rb +30 -0
- data/lib/jekyll/client_search/search_index_page.rb +15 -0
- data/lib/jekyll/client_search/search_tag.rb +100 -0
- data/lib/jekyll/client_search/tasks.rb +137 -0
- data/lib/jekyll/client_search/version.rb +7 -0
- data/lib/jekyll/client_search.rb +25 -0
- data/lib/jekyll-client-search.rb +3 -0
- metadata +104 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b07a5519cf45012ce0d198cedfe93e1e93e939ed9d9221386af87c10854f0cf4
|
|
4
|
+
data.tar.gz: 630a3dd0f345e4e263c8228ac3a565610b435723860dac1125e86bf780d072b1
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0d53f70fa2e1f37facfebe56ebf3384f3d5c376672e08f93cc5a3a761b03a294843b0cf236cbda9ffa7a7ace87261683a525f3a5e12e9da61592946cc878024a
|
|
7
|
+
data.tar.gz: 458dc19c9c0ad2b6c017057694b1af2103d918f16584205ec7c144a5e696fcb0d5609508fa414a7cb91facccf39a75dcd0c1c3e8c8a8e67bac8d1a09665419b5
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-08-25
|
|
4
|
+
|
|
5
|
+
- Add a pluggable search engine architecture with a base runtime and adapters.
|
|
6
|
+
- Support `minisearch`, `elasticlunr`, and `semantic` engines via `engine` config.
|
|
7
|
+
- Split the browser runtime into `client-search-base.js` (engine-agnostic shell
|
|
8
|
+
that owns the two-stage search strategy) and per-engine adapters under
|
|
9
|
+
`assets/adapters/` that act as pure translators.
|
|
10
|
+
- Add ElasticLunr adapter that translates the uniform query model into
|
|
11
|
+
ElasticLunr's native API.
|
|
12
|
+
- Add semantic adapter that ranks documents by cosine similarity against
|
|
13
|
+
pre-computed embeddings, supports async/typed-array query vectors, caches
|
|
14
|
+
query embeddings, and ignores stale asynchronous results.
|
|
15
|
+
- Add packaged query embedders for semantic search: transformers.js running
|
|
16
|
+
entirely in the browser (default) and an Ollama-compatible remote HTTP API.
|
|
17
|
+
Generate browser embedder configuration from `_config.yml`, support fully
|
|
18
|
+
self-hosted library/model/WASM assets, and apply model-specific asymmetric
|
|
19
|
+
document/query prefixes for EmbeddingGemma and Nomic.
|
|
20
|
+
- Pin transformers.js, run browser model inference in a Web Worker, add
|
|
21
|
+
loading progress, retry/timeout controls, query truncation, strict finite
|
|
22
|
+
vector/dimension validation, and main-thread fallback.
|
|
23
|
+
- Add optional engine-aware live search with configurable minimum length,
|
|
24
|
+
lexical/semantic debounce, URL synchronization, stale-result protection,
|
|
25
|
+
and cancellation of obsolete remote API requests.
|
|
26
|
+
- Add optional build-time related-article analysis combining shared tags,
|
|
27
|
+
exact/parent categories, and vector similarity above a configurable cutoff.
|
|
28
|
+
Write relations to a separate JSON artifact and provide a lightweight
|
|
29
|
+
browser renderer with relevance/newest sorting; search results can also be
|
|
30
|
+
sorted by relevance or publication date, and lexical indexes can omit
|
|
31
|
+
temporary analysis embeddings.
|
|
32
|
+
- Add `{% related_articles %}` Liquid tag for one-line adoption in any post
|
|
33
|
+
layout. Supports `sort:date` and `no_scripts` parameters; renders nothing
|
|
34
|
+
when related is disabled.
|
|
35
|
+
- Add `{% search_form %}` Liquid tag for config-driven search form + scripts.
|
|
36
|
+
Outputs the form HTML, status/results containers, and all runtime scripts
|
|
37
|
+
(engine library, runtime config, embedder config, query embedder, base
|
|
38
|
+
runtime, adapter) in the correct order based on `_config.yml`. Supports
|
|
39
|
+
`scripts_only` and `no_scripts` modes. Changing engines requires zero
|
|
40
|
+
template changes.
|
|
41
|
+
- Enable live search by default for lexical engines (MiniSearch, ElasticLunr)
|
|
42
|
+
and disable by default for semantic (to avoid embedding every keystroke).
|
|
43
|
+
Form submission always remains available. Set `live_search.enabled: false`
|
|
44
|
+
to restore submit-only behavior.
|
|
45
|
+
- Add `engine_url`, `engine_sri`, and `engine_crossorigin` config options
|
|
46
|
+
with per-engine CDN defaults (MiniSearch 7.2.0, ElasticLunr 0.9.5).
|
|
47
|
+
Override to self-host or pin a version; set `engine_sri` for Subresource
|
|
48
|
+
Integrity.
|
|
49
|
+
- Add rake tasks `jekyll_client_search:reference_files` (list, diff, and
|
|
50
|
+
status of reference files) and `jekyll_client_search:install` (copy
|
|
51
|
+
reference layouts/includes into the consuming site, with overwrite
|
|
52
|
+
protection for modified copies).
|
|
53
|
+
- Ship reference `_includes/related-articles.html` and
|
|
54
|
+
`_layouts/post-with-related.html` for copy-paste adoption.
|
|
55
|
+
- Extend `client-search-related.js` with `renderItem` callback for custom
|
|
56
|
+
list item rendering, `filter` callback for narrowing visible relations,
|
|
57
|
+
richer default rendering (date, shared tags, shared categories, excerpt),
|
|
58
|
+
and `data-related-sort` attribute support for the Liquid tag.
|
|
59
|
+
- Add fixture site demo page (`spec/fixtures/site/related-test.html`) and
|
|
60
|
+
post layout (`spec/fixtures/site/_layouts/post.html`) exercising all
|
|
61
|
+
related-articles adoption paths. Add system tests verifying relations file
|
|
62
|
+
structure, runtime asset copying, Liquid tag rendering, demo page content,
|
|
63
|
+
self-exclusion, and score sorting.
|
|
64
|
+
- Add embedding generation at build time via a local Ollama server using
|
|
65
|
+
the `ollama-ruby` gem (optional dependency, lazy-loaded).
|
|
66
|
+
- Add incremental indexing via an atomically written content-hash cache
|
|
67
|
+
(`.jekyll-client-search-cache.json`) — unchanged documents reuse cached
|
|
68
|
+
embeddings only when the provider, model, endpoint, and schema match.
|
|
69
|
+
- Add configurable Ollama connection/read timeouts and fail semantic builds by
|
|
70
|
+
default when an embedding cannot be generated.
|
|
71
|
+
- Report browser query-embedding failures as unavailable instead of presenting
|
|
72
|
+
them as valid zero-result searches.
|
|
73
|
+
- Load only `cgi/escape` for Ruby 3.5 compatibility.
|
|
74
|
+
- Add uniform JS test suite parameterized over all adapters — the same
|
|
75
|
+
assertions run against each engine.
|
|
76
|
+
- Add Ruby system tests that build an 80-post fixture of 40 Wikipedia articles
|
|
77
|
+
and 40 unique arXiv papers per engine, plus JS system tests for baseline
|
|
78
|
+
results (AND, OR fallback, cross-domain) in jsdom.
|
|
79
|
+
- Add Ollama integration tests that generate real embeddings via a local
|
|
80
|
+
Ollama server with `embeddinggemma:300m` and verify cache reuse.
|
|
81
|
+
- Add RuboCop, ESLint, SimpleCov thresholds, and Ruby/JavaScript dependency
|
|
82
|
+
audits to CI.
|
|
83
|
+
- Add reproducible performance history for cold, warm, incremental, index-size,
|
|
84
|
+
query-embedding, and engine-core search latency measurements.
|
|
85
|
+
- Correct fixture documentation and make the Wikipedia/arXiv regeneration
|
|
86
|
+
scripts remove dated outputs correctly; arXiv regeneration now deduplicates
|
|
87
|
+
paper IDs across category queries and records the actual per-paper license.
|
|
88
|
+
- Add `wikipedia_oldid` and permanent revision links to all Wikipedia fixture
|
|
89
|
+
posts so the exact downloaded version can be referenced as articles change.
|
|
90
|
+
- Remove arXiv fixture posts from the repository due to mixed/restrictive
|
|
91
|
+
licenses (some papers use CC BY-NC, CC BY-NC-ND, or arXiv non-exclusive
|
|
92
|
+
licenses that do not clearly permit redistribution). Developers run
|
|
93
|
+
`download_arxiv.rb` locally to fetch them. The committed baseline JSON
|
|
94
|
+
and semantic embeddings remain as stable test artifacts. See
|
|
95
|
+
README.developer.md and NOTICE for details.
|
|
96
|
+
- Add README.developer.md with fixture setup and LLM/vector testing
|
|
97
|
+
instructions, and a NOTICE file with source attribution.
|
|
98
|
+
- Make JS system, gold, comparison, and meta tests consume required committed
|
|
99
|
+
baseline fixtures directly, eliminating order-dependent test setup and skips.
|
|
100
|
+
- Preserve `#` as the safe link fallback for incomplete index records.
|
|
101
|
+
- Document `jekyll-pagefind` as a recommended alternative for users who
|
|
102
|
+
want Pagefind's HTML-crawling indexing approach.
|
|
103
|
+
- Add a safe Jekyll generator for MiniSearch JSON indexes.
|
|
104
|
+
- Support posts and configurable custom collections.
|
|
105
|
+
- Optionally include titled Jekyll pages.
|
|
106
|
+
- Include searchable title, excerpt, content, categories, and tags fields.
|
|
107
|
+
- Copy the browser runtime asset into the consuming site's assets directory.
|
|
108
|
+
- Add RSpec coverage for configuration and document normalization.
|
|
109
|
+
- Add Gundestrup.dk as the local integration test platform.
|
|
110
|
+
- Validate configuration and reject unsafe output paths.
|
|
111
|
+
- Deduplicate indexed documents and normalize searchable metadata.
|
|
112
|
+
- Harden browser result rendering with DOM APIs and same-origin URLs.
|
|
113
|
+
- Add runtime asset, generated page, page indexing, disabled mode, and edge-case tests.
|
|
114
|
+
- Add browser runtime behavior and URL-safety tests with Node.js and jsdom.
|
|
115
|
+
- Standardize development on Ruby 3.4.10 and test supported Ruby 3.2, 3.3,
|
|
116
|
+
and 3.4 versions in CI with Bundler 4.0.9.
|
|
117
|
+
- License the gem under AGPL-3.0-or-later.
|
|
118
|
+
- Rename gem from `jekyll-elasticlunr-search` to `jekyll-client-search`.
|
|
119
|
+
- Replace Elasticlunr.js browser runtime with MiniSearch 7.2.0.
|
|
120
|
+
- Implement two-stage search: exact AND with prefix, then fuzzy OR fallback.
|
|
121
|
+
- Change configuration key from `elasticlunr_search` to `client_search`.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 Svend Gundestrup
|
|
5
|
+
|
|
6
|
+
This project is free software: you can redistribute it and/or modify it under
|
|
7
|
+
the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
+
Software Foundation, either version 3 of the License, or (at your option) any
|
|
9
|
+
later version.
|
|
10
|
+
|
|
11
|
+
This project is distributed in the hope that it will be useful, but WITHOUT
|
|
12
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
13
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
14
|
+
details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License along
|
|
17
|
+
with this project. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
18
|
+
|
|
19
|
+
The complete license text is available from the Free Software Foundation at:
|
|
20
|
+
https://www.gnu.org/licenses/agpl-3.0.txt
|
|
21
|
+
|
|
22
|
+
SPDX-License-Identifier: AGPL-3.0-or-later
|
data/NOTICE
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
jekyll-client-search — Test Fixture Attribution
|
|
2
|
+
================================================
|
|
3
|
+
|
|
4
|
+
This repository includes test fixture posts derived from publicly available
|
|
5
|
+
sources. Each fixture post records its source, license, and a permanent link
|
|
6
|
+
in its YAML frontmatter.
|
|
7
|
+
|
|
8
|
+
Wikipedia articles (40 posts)
|
|
9
|
+
-----------------------------
|
|
10
|
+
Location: spec/fixtures/site/_posts/*-wikipedia-*.md
|
|
11
|
+
Source: Wikipedia — The Free Encyclopedia
|
|
12
|
+
License: CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0/)
|
|
13
|
+
Link: Each post has a `wikipedia_oldid` field and a `source_url` pointing
|
|
14
|
+
to a permanent revision link (https://en.wikipedia.org/w/index.php?oldid=XXXX)
|
|
15
|
+
so the exact downloaded version can be referenced even as Wikipedia
|
|
16
|
+
articles change over time.
|
|
17
|
+
|
|
18
|
+
The download script (spec/fixtures/download_wikipedia.rb) is kept for
|
|
19
|
+
reference and regeneration but does not need to be re-run — the Wikipedia
|
|
20
|
+
fixtures are committed under their CC BY-SA 3.0 license with attribution.
|
|
21
|
+
|
|
22
|
+
arXiv papers (40 posts — NOT committed)
|
|
23
|
+
---------------------------------------
|
|
24
|
+
Location: spec/fixtures/site/_posts/*-arxiv-*.md (gitignored)
|
|
25
|
+
Source: arXiv.org
|
|
26
|
+
License: Varies per paper — arXiv non-exclusive license, CC BY 4.0,
|
|
27
|
+
CC BY-NC-SA 4.0, or CC BY-NC-ND 4.0. Each paper's actual license
|
|
28
|
+
is recorded in its frontmatter by the download script.
|
|
29
|
+
|
|
30
|
+
arXiv fixture posts are NOT committed to this repository because some
|
|
31
|
+
papers use licenses that restrict redistribution (non-commercial, no
|
|
32
|
+
derivatives, or arXiv-only distribution rights). Developers who need the
|
|
33
|
+
full 80-post fixture set must run the download script locally:
|
|
34
|
+
|
|
35
|
+
ruby spec/fixtures/download_arxiv.rb
|
|
36
|
+
|
|
37
|
+
See README.developer.md for details.
|
|
38
|
+
|
|
39
|
+
Committed test artifacts
|
|
40
|
+
------------------------
|
|
41
|
+
The following committed JSON files are generated test artifacts derived
|
|
42
|
+
from the fixture posts. They contain indexed/search-processed data (titles,
|
|
43
|
+
excerpts, tokenized content, embedding vectors), not the raw article text:
|
|
44
|
+
|
|
45
|
+
spec/fixtures/baseline/search-index-baseline.json
|
|
46
|
+
spec/fixtures/baseline/semantic-embeddings.json
|
|
47
|
+
|
|
48
|
+
These are kept as stable gold-standard fixtures so that tests can run
|
|
49
|
+
without requiring developers to download the arXiv papers or run Ollama.
|
data/README.developer.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Developer Guide — jekyll-client-search
|
|
2
|
+
|
|
3
|
+
This guide explains how to set up the full test fixture set for local
|
|
4
|
+
development. Most tests run without any special setup, but a few require
|
|
5
|
+
fixture data that is not committed to the repository for licensing reasons.
|
|
6
|
+
See [README.md](README.md) for user-facing configuration and usage docs.
|
|
7
|
+
|
|
8
|
+
## Quick start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
rbenv install 3.4.10 # if not already installed
|
|
12
|
+
rbenv local 3.4.10
|
|
13
|
+
bundle install
|
|
14
|
+
npm ci
|
|
15
|
+
bundle exec rspec # Ruby tests (176 examples; 7 opt-in Ollama examples pending)
|
|
16
|
+
npm test # JavaScript tests (130 tests)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Both test suites pass with only the committed Wikipedia fixtures and the
|
|
20
|
+
committed baseline JSON artifacts. No network access or external services
|
|
21
|
+
are required for the default test run.
|
|
22
|
+
|
|
23
|
+
## Build-time related articles
|
|
24
|
+
|
|
25
|
+
The optional related-analysis pass writes `search-relations.json` separately
|
|
26
|
+
from the normal search index. It combines exact shared tags/categories and
|
|
27
|
+
hierarchical category parents with vector similarity when embeddings are
|
|
28
|
+
available. Semantic relations use a configurable similarity cutoff; there is
|
|
29
|
+
no default five-item limit. `client-search-related.js` renders the relations
|
|
30
|
+
on an article page without loading an embedding model.
|
|
31
|
+
|
|
32
|
+
For a MiniSearch site, set `embedding.include_in_index: false` (the default
|
|
33
|
+
when the selected engine is not semantic) to use Ollama vectors during the
|
|
34
|
+
build and omit them from the public search index.
|
|
35
|
+
|
|
36
|
+
### Adoption paths
|
|
37
|
+
|
|
38
|
+
Three adoption paths are documented in [README.md](README.md#related-articles):
|
|
39
|
+
|
|
40
|
+
1. **`{% related_articles %}` Liquid tag** — one-line in any post layout
|
|
41
|
+
2. **`{% include related-articles.html %}`** — reference include file shipped
|
|
42
|
+
at `assets/includes/related-articles.html`
|
|
43
|
+
3. **Drop-in layout** — reference post layout shipped at
|
|
44
|
+
`assets/layouts/post-with-related.html`
|
|
45
|
+
|
|
46
|
+
The JS helper (`assets/client-search-related.js`) also supports `renderItem`
|
|
47
|
+
and `filter` callbacks for custom rendering and filtering.
|
|
48
|
+
|
|
49
|
+
### Fixture site demo
|
|
50
|
+
|
|
51
|
+
The fixture site (`spec/fixtures/site/`) has related articles enabled in its
|
|
52
|
+
`_config.yml`. It includes:
|
|
53
|
+
|
|
54
|
+
- `_layouts/post.html` — minimal post layout using `{% related_articles %}`
|
|
55
|
+
- `related-test.html` — demo page at `/related-test/` exercising all five
|
|
56
|
+
variants: default Liquid tag, `sort:date` + `no_scripts`, custom
|
|
57
|
+
`renderItem`, `filter`, and raw JSON link
|
|
58
|
+
|
|
59
|
+
System tests in `spec/system_spec.rb` verify the relations file structure,
|
|
60
|
+
runtime asset copying, Liquid tag rendering in post pages, demo page
|
|
61
|
+
content, self-exclusion, and score sorting.
|
|
62
|
+
|
|
63
|
+
### Related test files
|
|
64
|
+
|
|
65
|
+
| File | Description |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `spec/related_analyzer_spec.rb` | Unit tests for the relation analyzer |
|
|
68
|
+
| `spec/related_tag_spec.rb` | Unit tests for the `{% related_articles %}` Liquid tag |
|
|
69
|
+
| `spec/search_tag_spec.rb` | Unit tests for the `{% search_form %}` Liquid tag |
|
|
70
|
+
| `spec/tasks_spec.rb` | Unit tests for the rake tasks (reference_files, install) |
|
|
71
|
+
| `spec/system_spec.rb` | System tests building the fixture site with related and search_form |
|
|
72
|
+
| `test/related.test.js` | JS tests for the related renderer (default, renderItem, filter, sort) |
|
|
73
|
+
|
|
74
|
+
## What is committed
|
|
75
|
+
|
|
76
|
+
| Artifact | Committed? | Why |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Wikipedia fixture posts (40) | Yes | CC BY-SA 3.0 allows redistribution with attribution |
|
|
79
|
+
| arXiv fixture posts (40) | **No** | Mixed/restrictive licenses — see below |
|
|
80
|
+
| Baseline search-index JSON | Yes | Generated test artifact (indexed data, not raw text) |
|
|
81
|
+
| Semantic embeddings JSON | Yes | Generated test artifact (embedding vectors) |
|
|
82
|
+
| Download scripts | Yes | Kept for reference and regeneration |
|
|
83
|
+
|
|
84
|
+
## When you need the arXiv fixtures
|
|
85
|
+
|
|
86
|
+
The arXiv fixture posts are needed only for:
|
|
87
|
+
|
|
88
|
+
1. **Ruby system tests that build the fixture site** — without arXiv posts,
|
|
89
|
+
these tests run with 40 Wikipedia posts instead of 80 and skip the
|
|
90
|
+
baseline comparison (the baseline was generated from the full 80-post
|
|
91
|
+
set).
|
|
92
|
+
|
|
93
|
+
2. **Ollama integration tests** (`OLLAMA_INTEGRATION=1`) — these build the
|
|
94
|
+
full 80-post index with real embeddings and require both Wikipedia and
|
|
95
|
+
arXiv posts.
|
|
96
|
+
|
|
97
|
+
3. **Regenerating the baseline JSON** — `ruby spec/fixtures/generate_baseline.rb`
|
|
98
|
+
requires all 80 posts.
|
|
99
|
+
|
|
100
|
+
### Downloading arXiv fixtures
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
ruby spec/fixtures/download_arxiv.rb
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This script:
|
|
107
|
+
- Fetches 40 recent arXiv papers from 5 CS/AI subfields
|
|
108
|
+
- Downloads each PDF and extracts text with `pdftotext`
|
|
109
|
+
- Records the actual per-paper license in each post's frontmatter
|
|
110
|
+
- Writes posts to `spec/fixtures/site/_posts/`
|
|
111
|
+
- Requires `pdftotext` (available via `brew install poppler` on macOS)
|
|
112
|
+
|
|
113
|
+
The arXiv API returns versioned papers (e.g. `2608.23419v1`). Running the
|
|
114
|
+
script at different times will return different papers, but a specific
|
|
115
|
+
version is permanent — arXiv never changes a published version.
|
|
116
|
+
|
|
117
|
+
### Downloading Wikipedia fixtures (optional)
|
|
118
|
+
|
|
119
|
+
The Wikipedia fixtures are already committed. You only need this script if
|
|
120
|
+
you want to regenerate them (e.g. to get newer article versions):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
ruby spec/fixtures/download_wikipedia.rb
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Each Wikipedia post includes a `wikipedia_oldid` field with a permanent
|
|
127
|
+
link to the exact revision that was downloaded.
|
|
128
|
+
|
|
129
|
+
## LLM / vector search testing
|
|
130
|
+
|
|
131
|
+
### Without Ollama (default)
|
|
132
|
+
|
|
133
|
+
Semantic search tests run without a local Ollama server. They use committed
|
|
134
|
+
real-model embedding vectors (`spec/fixtures/baseline/semantic-embeddings.json`)
|
|
135
|
+
injected into the committed baseline index. This covers the browser-side
|
|
136
|
+
cosine similarity adapter and cross-engine comparison tests.
|
|
137
|
+
|
|
138
|
+
### With Ollama (opt-in integration tests)
|
|
139
|
+
|
|
140
|
+
To run the full integration tests that call a real Ollama server:
|
|
141
|
+
|
|
142
|
+
1. Install [Ollama](https://ollama.ai/)
|
|
143
|
+
|
|
144
|
+
2. Pull the required model:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
ollama pull embeddinggemma:300m
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
3. Run the integration tests:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
OLLAMA_INTEGRATION=1 bundle exec rspec spec/ollama_integration_spec.rb
|
|
154
|
+
OLLAMA_INTEGRATION=1 bundle exec rspec spec/llm_injection_spec.rb
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
These tests:
|
|
158
|
+
- Build the full 80-post index with real Ollama embeddings
|
|
159
|
+
- Verify embedding dimensions and validity
|
|
160
|
+
- Test semantic search quality with concept queries
|
|
161
|
+
- Generate the semantic index used by JS comparison tests
|
|
162
|
+
- Require arXiv fixture posts to be downloaded first
|
|
163
|
+
|
|
164
|
+
### Regenerating committed test artifacts
|
|
165
|
+
|
|
166
|
+
If you need to regenerate the baseline or semantic gold fixtures (e.g.
|
|
167
|
+
after changing the document builder or fixture content):
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# 1. Ensure all 80 fixture posts are present
|
|
171
|
+
ruby spec/fixtures/download_arxiv.rb
|
|
172
|
+
|
|
173
|
+
# 2. Regenerate the baseline index (without embeddings)
|
|
174
|
+
ruby spec/fixtures/generate_baseline.rb
|
|
175
|
+
|
|
176
|
+
# 3. Run the Ollama integration test to generate the semantic index
|
|
177
|
+
OLLAMA_INTEGRATION=1 bundle exec rspec spec/ollama_integration_spec.rb
|
|
178
|
+
|
|
179
|
+
# 4. Regenerate the semantic gold fixture from the built index
|
|
180
|
+
ruby spec/fixtures/generate_semantic_gold.rb
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Test categories
|
|
184
|
+
|
|
185
|
+
| Tag | Description | Requires arXiv? | Requires Ollama? |
|
|
186
|
+
|---|---|---|---|
|
|
187
|
+
| `:unit` | Ruby unit tests | No | No |
|
|
188
|
+
| `:system` | Ruby system tests (build fixture site) | Partially | No |
|
|
189
|
+
| `:integration` | Ruby integration tests | No | No |
|
|
190
|
+
| `:ollama_integration` | Real Ollama server tests | Yes | Yes |
|
|
191
|
+
|
|
192
|
+
Run a specific category:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
bundle exec rspec --tag unit
|
|
196
|
+
bundle exec rspec --tag system
|
|
197
|
+
bundle exec rspec --tag ollama_integration
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## CI
|
|
201
|
+
|
|
202
|
+
The CI pipeline runs `bundle exec rspec` and `npm test` without arXiv
|
|
203
|
+
fixtures or Ollama. The committed baseline JSON and semantic embeddings
|
|
204
|
+
ensure all tests pass in CI without external dependencies.
|