local prequire = require('std.prequire') describe('std.prequire', function() before_each(function() package.loaded['std.prequire'] = nil prequire = require('std.prequire') end) describe('loading existing modules', function() it('should return the actual module for existing modules', function() local result = prequire('std.const') assert.is_table(result) assert.is_string(result.os_background) end) it('should return the first successfully loaded module as first_mod', function() local result = prequire('std.const', 'std.map') assert.is_table(result) assert.equal('table', type(result)) end) it('should handle multiple existing modules', function() local modules = nil prequire('std.const', 'std.map', function(const, map) modules = { const, map } end) assert.is_table(modules) ---@cast modules table assert.is_table(modules[1]) assert.is_table(modules[2]) end) end) describe('loading missing modules', function() it('should return a proxy for missing modules', function() local result = prequire('this_module_does_not_exist_12345') assert.is_table(result) end) it('should not crash when calling on proxy (__call returns self)', function() local proxy = prequire('missing_module_12345') local call_result = proxy() assert.equal(proxy, call_result) end) it('should not crash when indexing on proxy (__index returns self)', function() local proxy = prequire('missing_module_12345') local result = proxy.foo assert.equal(proxy, result) local nested = proxy.foo.bar.baz assert.equal(proxy, nested) end) it('should return recursive proxy for nested access', function() local proxy = prequire('missing_module_67890') assert.equal(proxy, proxy.foo) assert.equal(proxy, proxy.foo.bar) assert.equal(proxy, proxy.foo.bar.baz.qux) end) end) describe('proxy_cache memoization', function() it('should return the same proxy on repeated calls for same missing module', function() local proxy1 = prequire('missing_module_same_123') local proxy2 = prequire('missing_module_same_123') assert.equal(proxy1, proxy2) end) it('should return different proxies for different missing modules', function() local proxy1 = prequire('missing_module_a_123') local proxy2 = prequire('missing_module_b_456') assert.is_not_nil(proxy1) assert.is_not_nil(proxy2) assert.are_not_equal(proxy1, proxy2) end) end) describe('callback behavior', function() it('should call callback with loaded modules in order', function() local received = nil prequire('std.const', 'std.map', function(const, map) received = { const = const, map = map } end) ---@cast received table assert.is_table(received.const) assert.is_table(received.map) end) it('should NOT call callback when module is missing - returns proxy instead', function() -- When any module fails to load, callback is not called; proxy is returned local received = 'not_called' local result = prequire('missing_for_callback', function(missing) received = missing end) -- Callback was not called because module is missing assert.equal('not_called', received) -- But we got a proxy back assert.is_table(result) assert.equal(result, result.anything) end) it('should call callback only when ALL modules load successfully', function() -- callback is only called when no modules fail local called_with_args = nil prequire('std.const', function(const) called_with_args = { const } end) assert.is_table(called_with_args) ---@cast called_with_args table assert.is_table(called_with_args[1]) end) it('should pass all loaded modules before callback', function() local received_args = nil prequire('std.const', 'std.map', 'std.table', function(...) received_args = { ... } end) ---@cast received_args table assert.equal(3, #received_args) end) it('should handle mixed existing and missing - callback NOT called', function() -- When there's a missing module, callback is skipped and proxy is returned ---@type any local received = 'not_called' local result = prequire('std.const', 'missing_mod_xyz', function(const, missing) received = { const = const, missing = missing } end) assert.equal('not_called', received) -- Result is the proxy for the missing module assert.is_table(result) end) end) describe('return value behavior', function() it('should return first_mod when module loads successfully', function() local result = prequire('std.const') assert.is_table(result) assert.is_string(result.os_background) end) it('should return proxy when module fails to load', function() local result = prequire('definitely_missing_module_xyz') assert.is_table(result) assert.equal(result, result.anyfield) end) end) describe('error notification', function() it('should call vim.notify_once for missing modules', function() local notify_called = false local original_notify_once = vim.notify_once rawset(vim, 'notify_once', function(msg, level) notify_called = true return original_notify_once(msg, level) end) prequire('missing_notify_module') rawset(vim, 'notify_once', original_notify_once) assert.is_true(notify_called) end) end) describe('stack trace printing', function() it('should not crash when printing stack trace for missing modules', function() -- This is harder to test directly, but we can verify it doesn't crash local result = prequire('missing_trace_module') assert.is_table(result) end) end) describe('integration with std modules', function() it('should successfully load std.map', function() local map_mod = prequire('std.map') assert.is_table(map_mod) end) it('should successfully load std.user_command', function() local uc_mod = prequire('std.user_command') assert.is_table(uc_mod) end) it('should successfully load std.table module', function() local table_mod = prequire('std.table') assert.is_table(table_mod) end) it('should successfully load std.table.join function', function() local join_func = prequire('std.table.join') assert.is_function(join_func) end) end) describe('edge cases', function() it('should handle empty string module name', function() local result = pcall(function() return prequire('') end) assert.is_true(result) end) it('should handle callback as only argument', function() local called = false local result = prequire(function() called = true end) assert.is_true(called) end) end) end)