Skip to content

Commit 0a9872f

Browse files
committed
test: verify snacks works without telescope
Regression test for the telescope hard dependency bug. Blocks telescope from the Lua loader, then verifies all three pickers work with Snacks alone.
1 parent 208442b commit 0a9872f

1 file changed

Lines changed: 211 additions & 0 deletions

File tree

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
--- Integration Tests: Snacks without Telescope installed
2+
--- Verifies that the Snacks adapter works when telescope.nvim is not available
3+
--- Regression test for GitHub issue #40
4+
5+
local has_snacks = pcall(require, 'snacks')
6+
if not has_snacks then
7+
return
8+
end
9+
10+
local helpers = require('spec.e2e.adapters.helpers')
11+
local e2e_helpers = require('spec.helpers.e2e_helpers')
12+
13+
--- Temporarily block all telescope modules from being required
14+
--- @return function restore Call to restore telescope availability
15+
local function block_telescope()
16+
local blocked = {}
17+
local saved = {}
18+
19+
-- Save and remove all loaded telescope modules
20+
for key, value in pairs(package.loaded) do
21+
if key:match('^telescope') then
22+
saved[key] = value
23+
package.loaded[key] = nil
24+
end
25+
end
26+
27+
-- Also clear telescope-orgmode adapter cache so it reloads cleanly
28+
package.loaded['telescope-orgmode.adapters.telescope'] = nil
29+
30+
-- Install a loader that blocks telescope requires
31+
-- LuaJIT/Lua 5.1 uses package.loaders, Lua 5.2+ uses package.searchers
32+
local searchers = package.searchers or package.loaders
33+
local function blocker(modname)
34+
if modname:match('^telescope%.') or modname == 'telescope' then
35+
return function()
36+
error('telescope is not installed (blocked by test)')
37+
end
38+
end
39+
end
40+
table.insert(searchers, 1, blocker)
41+
42+
-- Return restore function
43+
return function()
44+
-- Remove blocker
45+
for i, s in ipairs(searchers) do
46+
if s == blocker then
47+
table.remove(searchers, i)
48+
break
49+
end
50+
end
51+
52+
-- Restore saved modules
53+
for key, value in pairs(saved) do
54+
package.loaded[key] = value
55+
end
56+
end
57+
end
58+
59+
describe('[Integration: Snacks without Telescope]', function()
60+
local restore_telescope
61+
62+
before_each(function()
63+
e2e_helpers.create_test_org_files()
64+
e2e_helpers.setup_orgmode_with_test_files()
65+
-- Reset telescope-orgmode module cache to force fresh adapter loading
66+
package.loaded['telescope-orgmode'] = nil
67+
package.loaded['telescope-orgmode.adapters.snacks'] = nil
68+
package.loaded['telescope-orgmode.entry_maker.headlines'] = nil
69+
package.loaded['telescope-orgmode.entry_maker.orgfiles'] = nil
70+
restore_telescope = block_telescope()
71+
end)
72+
73+
after_each(function()
74+
-- Clean up pickers first (before restoring telescope)
75+
pcall(function()
76+
local picker = e2e_helpers.get_current_picker_snacks()
77+
if picker then
78+
e2e_helpers.close_picker_snacks(picker)
79+
end
80+
end)
81+
helpers.close_all_pickers()
82+
helpers.close_all_buffers()
83+
84+
-- Restore telescope availability for other tests
85+
if restore_telescope then
86+
restore_telescope()
87+
end
88+
end)
89+
90+
describe('module loading', function()
91+
it('should load entry_maker/headlines without telescope', function()
92+
assert.has_no.errors(function()
93+
require('telescope-orgmode.entry_maker.headlines')
94+
end)
95+
end)
96+
97+
it('should load entry_maker/orgfiles without telescope', function()
98+
assert.has_no.errors(function()
99+
require('telescope-orgmode.entry_maker.orgfiles')
100+
end)
101+
end)
102+
103+
it('should load snacks adapter without telescope', function()
104+
assert.has_no.errors(function()
105+
require('telescope-orgmode.adapters.snacks')
106+
end)
107+
end)
108+
end)
109+
110+
describe('data pipeline', function()
111+
it('should load headlines via get_entries without telescope', function()
112+
local headlines = require('telescope-orgmode.entry_maker.headlines')
113+
local results, widths = headlines.get_entries({})
114+
assert.is_table(results)
115+
assert.is_true(#results > 0, 'should return headlines from test org files')
116+
assert.is_table(widths)
117+
118+
-- Verify entry structure
119+
local entry = results[1]
120+
assert.is_string(entry.filename)
121+
assert.is_table(entry.headline)
122+
end)
123+
124+
it('should load orgfiles via get_entries without telescope', function()
125+
local orgfiles = require('telescope-orgmode.entry_maker.orgfiles')
126+
local results = orgfiles.get_entries({})
127+
assert.is_table(results)
128+
assert.is_true(#results > 0, 'should return org files from test setup')
129+
130+
-- Verify entry structure
131+
local entry = results[1]
132+
assert.is_string(entry.filename)
133+
end)
134+
135+
it('should format headline segments for snacks display without telescope', function()
136+
local headlines = require('telescope-orgmode.entry_maker.headlines')
137+
local highlight_lib = require('telescope-orgmode.lib.highlights')
138+
139+
local results, widths = headlines.get_entries({})
140+
assert.is_true(#results > 0)
141+
142+
-- This is what the snacks adapter calls for each entry
143+
local opts = { widths = widths, show_location = true, show_tags = true }
144+
local segments, text = highlight_lib.get_headline_segments(results[1].headline, results[1].filename, opts)
145+
assert.is_table(segments)
146+
assert.is_true(#segments > 0, 'should produce display segments')
147+
assert.is_string(text)
148+
assert.is_true(#text > 0, 'should produce search text')
149+
end)
150+
end)
151+
152+
describe('picker creation', function()
153+
it('should open search_headings picker without telescope', function()
154+
local tom = require('telescope-orgmode')
155+
tom.setup({ adapter = 'snacks' })
156+
157+
local ok, err = pcall(tom.search_headings)
158+
assert.is_true(ok, 'search_headings should work without telescope: ' .. tostring(err))
159+
160+
pcall(function()
161+
local picker = e2e_helpers.get_current_picker_snacks()
162+
if picker then
163+
e2e_helpers.close_picker_snacks(picker)
164+
end
165+
end)
166+
end)
167+
168+
it('should open refile_heading picker without telescope', function()
169+
local tom = require('telescope-orgmode')
170+
tom.setup({ adapter = 'snacks' })
171+
172+
local ok, err = pcall(tom.refile_heading)
173+
assert.is_true(ok, 'refile_heading should work without telescope: ' .. tostring(err))
174+
175+
pcall(function()
176+
local picker = e2e_helpers.get_current_picker_snacks()
177+
if picker then
178+
e2e_helpers.close_picker_snacks(picker)
179+
end
180+
end)
181+
end)
182+
183+
it('should open insert_link picker without telescope', function()
184+
vim.cmd('new')
185+
local tom = require('telescope-orgmode')
186+
tom.setup({ adapter = 'snacks' })
187+
188+
local ok, err = pcall(tom.insert_link)
189+
assert.is_true(ok, 'insert_link should work without telescope: ' .. tostring(err))
190+
191+
pcall(function()
192+
local picker = e2e_helpers.get_current_picker_snacks()
193+
if picker then
194+
e2e_helpers.close_picker_snacks(picker)
195+
end
196+
end)
197+
vim.cmd('bdelete!')
198+
end)
199+
end)
200+
201+
describe('error handling', function()
202+
it('should show clear error when adapter fails and telescope unavailable', function()
203+
local tom = require('telescope-orgmode')
204+
tom.setup({ adapter = 'nonexistent' })
205+
206+
local ok, err = pcall(tom.search_headings)
207+
assert.is_false(ok, 'should error for invalid adapter without telescope fallback')
208+
assert.matches('not available', tostring(err))
209+
end)
210+
end)
211+
end)

0 commit comments

Comments
 (0)