diff --git a/denops/@denops-private/service.ts b/denops/@denops-private/service.ts index 0e1f1392..b49e1427 100644 --- a/denops/@denops-private/service.ts +++ b/denops/@denops-private/service.ts @@ -151,12 +151,7 @@ class Plugin { } catch (e) { // Show a warning message when Deno module cache issue is detected // https://github.com/vim-denops/denops.vim/issues/358 - if ( - e instanceof TypeError && - e.message.startsWith( - "Could not find constraint in the list of versions: ", - ) - ) { + if (isDenoCacheIssueError(e)) { console.warn("*".repeat(80)); console.warn(`Deno module cache issue is detected.`); console.warn( @@ -200,6 +195,18 @@ function resolveScriptUrl(script: string): string { } } +// See https://github.com/vim-denops/denops.vim/issues/358 for details +function isDenoCacheIssueError(e: unknown): boolean { + const expects = [ + "Could not find constraint in the list of versions: ", // Deno 1.40? + "Could not find version of ", // Deno 1.38 + ] as const; + if (e instanceof TypeError) { + return expects.some((expect) => e.message.startsWith(expect)); + } + return false; +} + // NOTE: // Vim/Neovim does not handle JavaScript Error instance thus use string instead function toVimError(err: unknown): string { diff --git a/denops/@denops-private/service_test.ts b/denops/@denops-private/service_test.ts index 3842da4b..511a28d2 100644 --- a/denops/@denops-private/service_test.ts +++ b/denops/@denops-private/service_test.ts @@ -22,6 +22,9 @@ const scriptInvalid = const scriptInvalidConstraint = new URL("./testdata/dummy_invalid_constraint_plugin.ts", import.meta.url) .href; +const scriptInvalidConstraint2 = + new URL("./testdata/dummy_invalid_constraint_plugin2.ts", import.meta.url) + .href; Deno.test("Service", async (t) => { const meta: Meta = { @@ -189,6 +192,48 @@ Deno.test("Service", async (t) => { }, ); + await t.step( + "load() loads plugin and emits autocmd events (could not find version)", + async () => { + const c = stub(console, "warn"); + const s = stub(host, "call"); + try { + await service.load("dummyFailConstraint2", scriptInvalidConstraint2); + const expects = [ + "********************************************************************************", + "Deno module cache issue is detected.", + "Execute 'call denops#cache#update(#{reload: v:true})' and restart Vim/Neovim.", + "See https://github.com/vim-denops/denops.vim/issues/358 for more detail.", + "********************************************************************************", + ]; + assertSpyCalls(c, expects.length); + for (let i = 0; i < expects.length; i++) { + assertSpyCall(c, i, { + args: [expects[i]], + }); + } + assertSpyCalls(s, 2); + assertSpyCall(s, 0, { + args: [ + "denops#api#cmd", + "doautocmd User DenopsSystemPluginPre:dummyFailConstraint2", + {}, + ], + }); + assertSpyCall(s, 1, { + args: [ + "denops#api#cmd", + "doautocmd User DenopsSystemPluginFail:dummyFailConstraint2", + {}, + ], + }); + } finally { + s.restore(); + c.restore(); + } + }, + ); + await t.step( "load() does nothing when the plugin is already loaded", async () => { diff --git a/denops/@denops-private/testdata/dummy_invalid_constraint_plugin2.ts b/denops/@denops-private/testdata/dummy_invalid_constraint_plugin2.ts new file mode 100644 index 00000000..d0d8c59c --- /dev/null +++ b/denops/@denops-private/testdata/dummy_invalid_constraint_plugin2.ts @@ -0,0 +1,8 @@ +import type { Entrypoint } from "https://deno.land/x/denops_core@v6.1.0/mod.ts"; + +export const main: Entrypoint = (_denops) => { + // Mimic the situation + throw new TypeError( + "Could not find version of '@std/path' that matches specified version constraint '0.225.2'", + ); +};